From e05ca2c628ad3a4e0f00a43d10edec395443f716 Mon Sep 17 00:00:00 2001
From: andreas <andreas@5a81b35b-ba03-0410-adc8-b2c5c5119f08>
Date: Wed, 9 Jun 2010 19:49:06 +0000
Subject: [PATCH] merged changes in trunk from 2190 to 2367 into new shell
 branch

git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/branches/new_shell@2368 5a81b35b-ba03-0410-adc8-b2c5c5119f08
---
 .gitignore                                    |    4 +
 CMakeLists.txt                                |   30 +-
 CTestConfig.cmake                             |   31 +
 cmake_support/OST.cmake                       |   53 +-
 doc/conf/conf.py                              |    8 +-
 doc/make.py                                   |   48 +
 examples/dokk/datafiles/dengue/levelF.ini     |    7 +-
 examples/dokk/datafiles/dengue/top_ten.ini    |   18 +-
 examples/seq/seq_viewer.py                    |    4 +
 examples/seq/sh2.aln                          |  214 ++++
 examples/surf/test_rsurf.py                   |   26 -
 modules/CMakeLists.txt                        |    3 +-
 modules/base/doc/base.rst                     |    9 +
 modules/base/doc/generic.rst                  |  157 +++
 modules/base/pymod/CMakeLists.txt             |    2 +-
 modules/base/pymod/__init__.py                |    1 +
 modules/base/pymod/export_logger.cc           |    2 +-
 modules/base/pymod/settings.py                |   41 +-
 modules/base/pymod/stutil.py                  |   95 ++
 modules/base/pymod/wrap_base.cc               |   12 +
 modules/base/src/CMakeLists.txt               |   11 +-
 .../src/export_helper/pair_to_tuple_conv.hh   |   37 +
 modules/base/src/export_helper/vector.hh      |   46 +
 modules/base/src/integrity_error.hh           |    6 +-
 modules/base/src/invalid_handle.hh            |    6 +-
 modules/base/src/pod_vector.hh                |    2 +-
 modules/base/src/test_utils/compare_files.cc  |   55 +
 .../compare_files.hh}                         |   15 +-
 modules/bindings/pymod/msms.py                |   10 +-
 modules/bindings/tests/test_msms.py           |    5 +-
 modules/config/CMakeLists.txt                 |    1 +
 modules/config/base.hh                        |    2 +-
 modules/conop/doc/conop.rst                   |    4 +-
 modules/conop/src/chemdict_tool.cc            |   12 +
 modules/conop/src/compound_lib.cc             |    2 +-
 modules/conop/src/conop.cc                    |  245 ++--
 modules/conop/src/heuristic_builder.cc        |    8 +-
 modules/doc/external.rst                      |  111 ++
 modules/doc/install.rst                       |  108 ++
 modules/doc/intro.rst                         |  368 ++++++
 modules/doc/newmodule.rst                     |  301 +++++
 modules/geom/doc/composite.rst                |  529 ++++++++
 modules/geom/doc/geom.rst                     |   11 +-
 modules/geom/doc/mat.rst                      |  167 +++
 modules/geom/doc/vec.rst                      |    9 +-
 modules/geom/pymod/export_composite2.cc       |    2 +
 modules/geom/pymod/export_composite3.cc       |   35 +-
 modules/geom/pymod/export_vec2.cc             |    1 +
 modules/geom/pymod/export_vec3.cc             |    1 +
 modules/geom/pymod/export_vec4.cc             |    1 +
 modules/geom/pymod/export_vecmat3_op.cc       |    1 +
 modules/geom/src/vecmat3_op.hh                |    6 +-
 modules/gfx/pymod/export_entity.cc            |   10 +-
 modules/gfx/pymod/export_map.cc               |   20 +
 modules/gfx/pymod/export_surface.cc           |    4 -
 modules/gfx/src/entity.cc                     |    2 +-
 modules/gfx/src/gfx_object.cc                 |    2 +-
 modules/gfx/src/impl/entity_detail.cc         |    6 +-
 modules/gfx/src/impl/map_octree.cc            |   34 +-
 modules/gfx/src/impl/map_octree.hh            |    6 +-
 modules/gfx/src/map_iso.cc                    |  147 ++-
 modules/gfx/src/map_iso.hh                    |   81 +-
 modules/gfx/src/scene.cc                      |    2 +
 modules/gfx/src/surface.cc                    |  165 ---
 modules/gfx/src/surface.hh                    |   18 -
 modules/gfx/tests/CMakeLists.txt              |    6 +-
 modules/gfx/tests/test_ent_pov_export.cc      |   46 +-
 modules/gfx/tests/test_map_octree.cc          |   10 +-
 modules/gui/pymod/CMakeLists.txt              |    4 +-
 modules/gui/pymod/export_gosty.cc             |    5 -
 modules/gui/pymod/export_overlay.cc           |    4 +-
 modules/gui/pymod/export_sequence_viewer.cc   |   81 +-
 modules/gui/pymod/export_tool.cc              |    6 +-
 .../gui/pymod/scene/color_options_widget.py   |   50 +-
 .../gui/pymod/scene/color_select_widget.py    |    8 +
 .../gui/pymod/scene/combo_options_widget.py   |    8 +-
 modules/gui/pymod/scene/inspector_widget.py   |   12 +-
 modules/gui/pymod/scene/map_level_widget.py   |  246 ++++
 modules/gui/pymod/scene/preset_widget.py      |   14 +-
 modules/gui/pymod/scene/render_mode_widget.py |    4 +-
 .../gui/pymod/scene/render_options_widget.py  |  117 +-
 .../gui/pymod/scene/scene_selection_helper.py |  106 ++
 .../gui/pymod/scene/toolbar_options_widget.py |    2 +-
 .../gui/pymod/scene/uniform_color_widget.py   |   38 +-
 modules/gui/pymod/scene/wireframe_widget.py   |  103 ++
 modules/gui/pymod/wrap_gui.cc                 |    2 -
 modules/gui/share/CMakeLists.txt              |    2 +
 modules/gui/share/icons/find_icon.png         |  Bin 0 -> 488 bytes
 modules/gui/share/icons/menubar_icon.png      |  Bin 0 -> 301 bytes
 modules/gui/src/CMakeLists.txt                |   92 +-
 modules/gui/src/data_viewer/mask_overlay.cc   |   14 +
 modules/gui/src/data_viewer/mask_overlay.hh   |    2 +
 modules/gui/src/file_browser.cc               |   61 +-
 modules/gui/src/file_browser.hh               |    3 +
 modules/gui/src/file_loader.cc                |   61 +-
 modules/gui/src/file_loader.hh                |   11 +-
 modules/gui/src/file_type_dialog.cc           |   17 +-
 modules/gui/src/file_type_dialog.hh           |    4 +
 modules/gui/src/gosty_app.cc                  |   15 +-
 modules/gui/src/gosty_app.hh                  |    5 +-
 modules/gui/src/main.cc                       |    1 -
 .../gui/src/plot_viewer/plot_viewer_panel.cc  |    2 +-
 modules/gui/src/python_shell/dir_model.cc     |    1 -
 modules/gui/src/scene_selection.cc            |   17 +
 modules/gui/src/scene_selection.hh            |    3 +
 modules/gui/src/scene_win/context_menu.cc     |   34 +-
 modules/gui/src/scene_win/context_menu.hh     |    5 +-
 modules/gui/src/scene_win/gfx_scene_node.cc   |    4 +-
 modules/gui/src/scene_win/render_mode_node.cc |    4 +-
 modules/gui/src/scene_win/render_mode_node.hh |    3 +-
 .../gui/src/scene_win/render_modes_node.cc    |    3 +
 modules/gui/src/scene_win/scene_win.cc        |    2 +
 modules/gui/src/scene_win/scene_win_model.cc  |   30 +
 modules/gui/src/scene_win/scene_win_model.hh  |    6 +
 modules/gui/src/sequence/sequence_model.cc    |  265 ----
 modules/gui/src/sequence/sequence_viewer.cc   |  179 ---
 modules/gui/src/sequence/view_object.cc       |  232 ----
 .../align_properties_painter.cc               |   78 ++
 .../align_properties_painter.hh}              |   33 +-
 .../sequence_viewer/alignment_view_object.cc  |  212 ++++
 .../sequence_viewer/alignment_view_object.hh  |   61 +
 .../src/sequence_viewer/background_painter.cc |   51 +
 .../sequence_viewer/background_painter.hh}    |   30 +-
 .../{sequence => sequence_viewer}/base_row.cc |    3 +
 .../{sequence => sequence_viewer}/base_row.hh |    1 +
 .../src/sequence_viewer/base_view_object.cc   |  144 +++
 .../base_view_object.hh}                      |   60 +-
 .../sequence_viewer/conservation_painter.cc}  |   34 +-
 .../sequence_viewer/conservation_painter.hh   |   44 +
 .../{sequence => sequence_viewer}/painter.hh  |    0
 .../secstr_row.cc                             |    2 +-
 .../secstr_row.hh                             |    2 +-
 .../seq_secstr_painter.cc                     |    0
 .../seq_secstr_painter.hh                     |    0
 .../seq_selection_painter.cc                  |   24 +-
 .../seq_selection_painter.hh                  |    3 +
 .../seq_text_painter.cc                       |    2 +-
 .../seq_text_painter.hh                       |    0
 .../sequence_delegate.cc                      |    0
 .../sequence_delegate.hh                      |    0
 .../gui/src/sequence_viewer/sequence_item.cc  |  494 --------
 .../gui/src/sequence_viewer/sequence_item.hh  |  153 ---
 .../gui/src/sequence_viewer/sequence_model.cc |  466 +++++++
 .../sequence_model.hh                         |   44 +-
 .../sequence_row.cc                           |   32 +-
 .../sequence_row.hh                           |    8 +-
 .../gui/src/sequence_viewer/sequence_scene.cc |  134 --
 .../gui/src/sequence_viewer/sequence_scene.hh |   67 -
 .../sequence_viewer/sequence_search_bar.cc    |   34 +-
 .../sequence_viewer/sequence_search_bar.hh    |   15 +-
 .../sequence_table_view.cc                    |   65 +-
 .../sequence_table_view.hh                    |    4 +-
 .../sequence_viewer/sequence_view_object.cc   |  213 ++++
 .../sequence_view_object.hh}                  |   63 +-
 .../src/sequence_viewer/sequence_viewer.cc    |  479 +++++---
 .../src/sequence_viewer/sequence_viewer.hh    |   94 +-
 .../sequence_viewer/sequence_viewer_base.cc   |  237 ----
 .../sequence_viewer/sequence_viewer_base.hh   |   99 --
 .../tick_painter.cc                           |    0
 .../tick_painter.hh                           |    0
 .../title_row.cc                              |    9 +-
 .../title_row.hh                              |    0
 modules/img/alg/doc/alg.rst                   |   67 +
 modules/img/alg/src/highest_peak_search_3d.cc |   56 +-
 modules/img/alg/src/histogram.hh              |    4 +
 modules/img/alg/tests/test_discrete_shrink.cc |    2 +-
 modules/img/alg/tests/test_filter.cc          |    7 +-
 modules/img/alg/tests/test_utils.hh           |    3 +-
 modules/img/alg/tests/tests.hh                |    1 +
 modules/img/base/doc/img.rst                  |  186 +++
 modules/img/base/pymod/export_mask.cc         |    3 +
 modules/img/base/src/CMakeLists.txt           |    4 +-
 modules/img/base/src/function_base.hh         |    1 +
 .../base/src/image_state/image_state_impl.cc  |    4 +-
 .../src/image_state/image_state_visitor.hh    |    6 +-
 modules/img/base/src/mask_info_convert.cc     |  227 ++++
 modules/img/base/src/mask_info_convert.hh     |   38 +
 modules/img/base/src/null_function.hh         |    5 +-
 modules/img/base/src/observable.hh            |    2 +-
 modules/img/base/tests/CMakeLists.txt         |    4 +-
 modules/img/base/tests/test_data.hh           |    1 +
 modules/img/base/tests/test_domains.cc        |    1 +
 modules/img/base/tests/test_extent.hh         |    1 +
 modules/img/base/tests/test_function.hh       |    1 +
 modules/img/base/tests/test_image.cc          |    4 +-
 modules/img/base/tests/test_image.hh          |    1 +
 modules/img/base/tests/test_image_factory.hh  |    1 +
 modules/img/base/tests/test_image_impl.hh     |    1 +
 modules/img/base/tests/test_image_state.hh    |    1 +
 .../base/tests/test_image_state_visitor.hh    |    1 +
 modules/img/base/tests/test_index.hh          |    1 +
 modules/img/base/tests/test_point.hh          |    1 +
 modules/img/base/tests/test_sampling.hh       |    1 +
 modules/img/base/tests/test_size.hh           |    1 +
 modules/img/base/tests/test_transform.hh      |    1 +
 modules/img/base/tests/test_value_holder.hh   |    1 +
 modules/index.rst                             |   38 +-
 modules/io/doc/formats.rst                    |   81 ++
 modules/io/doc/io.rst                         |  103 ++
 modules/io/pymod/__init__.py                  |   40 +-
 modules/io/src/CMakeLists.txt                 |    1 +
 modules/io/src/formatted_line.hh              |  239 ++++
 modules/io/src/mol/CMakeLists.txt             |    4 +
 modules/io/src/mol/entity_io_mae_handler.cc   |    2 +-
 modules/io/src/mol/entity_io_sdf_handler.cc   |  378 +-----
 modules/io/src/mol/entity_io_sdf_handler.hh   |   24 -
 modules/io/src/mol/pdb_reader.cc              |    4 +-
 modules/io/src/mol/pdb_writer.cc              |  242 ++--
 modules/io/src/mol/pdb_writer.hh              |    5 +-
 modules/io/src/mol/sdf_reader.cc              |  275 +++++
 modules/io/src/mol/sdf_reader.hh              |   67 +
 modules/io/src/mol/sdf_writer.cc              |  158 +++
 modules/io/src/mol/sdf_writer.hh              |   61 +
 modules/io/tests/test_io_pdb.cc               |  163 ++-
 modules/io/tests/test_io_sdf.cc               |  184 ++-
 modules/io/tests/testfiles/pdb/alt-loc.pdb    |    3 +
 modules/io/tests/testfiles/pdb/conect.pdb     |   46 +
 modules/io/tests/testfiles/pdb/ter.pdb        |   15 +
 .../{test_in.sdf => sdf/compound.sdf}         |  264 ++--
 .../tests/testfiles/sdf/empty_dataheader.sdf  |   48 +
 modules/io/tests/testfiles/sdf/multiple.sdf   |   72 ++
 modules/io/tests/testfiles/sdf/properties.sdf |   48 +
 modules/io/tests/testfiles/sdf/simple.sdf     |   18 +
 .../tests/testfiles/sdf/wrong_atomcount.sdf   |   18 +
 .../testfiles/sdf/wrong_atomlinelength.sdf    |   18 +
 .../io/tests/testfiles/sdf/wrong_atompos.sdf  |   18 +
 .../testfiles/sdf/wrong_bondatomnumber.sdf    |   18 +
 .../tests/testfiles/sdf/wrong_bondcount.sdf   |   18 +
 .../testfiles/sdf/wrong_bondlinelength.sdf    |   18 +
 .../io/tests/testfiles/sdf/wrong_bondtype.sdf |   18 +
 .../io/tests/testfiles/sdf/wrong_charge.sdf   |   18 +
 .../tests/testfiles/sdf/wrong_dataheader.sdf  |   48 +
 modules/mol/alg/pymod/CMakeLists.txt          |   10 +
 .../mol/alg/pymod/export_entity_to_density.cc |   49 +
 modules/mol/alg/pymod/wrap_mol_alg.cc         |    9 +
 modules/mol/alg/src/CMakeLists.txt            |   21 +-
 .../alg/src/atom_scattering_properties.txt    |   59 +
 modules/mol/alg/src/entity_to_density.cc      |  442 +++++++
 modules/mol/alg/src/entity_to_density.hh      |   79 ++
 modules/mol/base/doc/editors.rst              |    6 +-
 modules/mol/base/doc/entity.rst               |    4 +-
 modules/mol/base/doc/mol.rst                  |    4 +-
 modules/mol/base/pymod/CMakeLists.txt         |    1 +
 modules/mol/base/pymod/export_atom.cc         |    7 +-
 modules/mol/base/pymod/export_atom_view.cc    |    6 +-
 modules/mol/base/pymod/export_chain.cc        |    3 +-
 modules/mol/base/pymod/export_chain_view.cc   |    3 +-
 .../pymod/export_entity_property_mapper.cc    |   68 +
 modules/mol/base/pymod/export_residue.cc      |    4 +-
 modules/mol/base/pymod/export_residue_view.cc |    3 +-
 modules/mol/base/pymod/export_surface.cc      |   13 -
 modules/mol/base/pymod/wrap_mol.cc            |    3 +-
 modules/mol/base/src/atom_base.cc             |    6 -
 modules/mol/base/src/atom_base.hh             |    5 -
 modules/mol/base/src/atom_handle.cc           |    6 +
 modules/mol/base/src/atom_handle.hh           |    7 +
 modules/mol/base/src/atom_view.cc             |   10 +-
 modules/mol/base/src/atom_view.hh             |    5 +
 modules/mol/base/src/chain_handle.cc          |   23 +-
 modules/mol/base/src/coord_source.cc          |    2 +-
 modules/mol/base/src/entity_handle.cc         |   28 +-
 modules/mol/base/src/entity_view.cc           |    6 +-
 modules/mol/base/src/impl/CMakeLists.txt      |    2 -
 modules/mol/base/src/impl/chain_impl_fw.hh    |    1 -
 modules/mol/base/src/impl/entity_impl.cc      |  104 +-
 modules/mol/base/src/impl/entity_impl.hh      |   11 +-
 modules/mol/base/src/impl/rsurf_impl.cc       | 1090 -----------------
 modules/mol/base/src/impl/rsurf_impl.hh       |  207 ----
 modules/mol/base/src/impl/surface_impl.hh     |    2 -
 modules/mol/base/src/impl/surface_impl_fw.hh  |   10 -
 modules/mol/base/src/iterator.cc              |   22 +-
 modules/mol/base/src/iterator.hh              |   16 +-
 modules/mol/base/src/residue_handle.cc        |    4 +-
 modules/mol/base/src/residue_view.cc          |   12 +-
 modules/mol/base/src/surface.hh               |    1 -
 modules/mol/base/src/surface_builder.cc       |   19 +-
 modules/mol/base/src/surface_handle.cc        |    4 +
 modules/mol/base/src/surface_handle.hh        |    3 +
 modules/mol/base/tests/test_view.cc           |   11 +
 modules/qa/src/index.hh                       |    2 +-
 modules/seq/alg/pymod/CMakeLists.txt          |    2 +-
 modules/seq/alg/pymod/__init__.py             |    6 +-
 modules/seq/alg/pymod/mat.py                  |   45 +
 modules/seq/alg/pymod/wrap_seq_alg.cc         |    3 +-
 modules/seq/alg/src/CMakeLists.txt            |    2 +
 modules/seq/alg/src/conservation.cc           |  132 ++
 modules/seq/alg/src/conservation.hh           |   43 +
 modules/seq/base/doc/seq.rst                  |  350 ++++++
 modules/seq/base/pymod/__init__.py            |   98 +-
 .../base/pymod/const_seq_list_export_def.hh   |    4 +-
 modules/seq/base/pymod/export_sequence.cc     |   78 +-
 modules/seq/base/src/CMakeLists.txt           |    2 +
 modules/seq/base/src/aligned_column.cc        |   11 +
 modules/seq/base/src/aligned_column.hh        |    2 +
 modules/seq/base/src/aligned_region.cc        |    9 +-
 modules/seq/base/src/alignment_handle.cc      |   47 +-
 modules/seq/base/src/alignment_handle.hh      |  108 +-
 modules/seq/base/src/impl/sequence_impl.cc    |   16 +-
 .../seq/base/src/impl/sequence_list_impl.hh   |   17 +-
 modules/seq/base/src/sequence_handle.cc       |    5 +
 modules/seq/base/src/sequence_handle.hh       |    2 +
 modules/seq/base/src/views_from_sequences.cc  |   87 ++
 modules/seq/base/src/views_from_sequences.hh  |   36 +
 modules/seq/base/tests/CMakeLists.txt         |    4 +
 modules/seq/base/tests/test_aligned_column.cc |  133 ++
 modules/seq/base/tests/test_aligned_region.cc |  186 +++
 modules/seq/base/tests/test_alignment.cc      |  223 ++++
 modules/seq/base/tests/test_seq.py            |  127 ++
 modules/seq/base/tests/test_sequence.cc       |  163 ++-
 .../seq/base/tests/testfiles/testprotein.pdb  |   15 +
 scripts/init.py                               |    1 -
 311 files changed, 11339 insertions(+), 5269 deletions(-)
 create mode 100644 CTestConfig.cmake
 create mode 100644 doc/make.py
 create mode 100644 examples/seq/seq_viewer.py
 create mode 100644 examples/seq/sh2.aln
 delete mode 100644 examples/surf/test_rsurf.py
 create mode 100644 modules/base/doc/base.rst
 create mode 100644 modules/base/doc/generic.rst
 create mode 100644 modules/base/pymod/stutil.py
 create mode 100644 modules/base/src/export_helper/pair_to_tuple_conv.hh
 create mode 100644 modules/base/src/export_helper/vector.hh
 create mode 100644 modules/base/src/test_utils/compare_files.cc
 rename modules/base/src/{invalid_handle.cc => test_utils/compare_files.hh} (80%)
 create mode 100644 modules/doc/external.rst
 create mode 100644 modules/doc/install.rst
 create mode 100644 modules/doc/intro.rst
 create mode 100644 modules/doc/newmodule.rst
 create mode 100644 modules/geom/doc/composite.rst
 create mode 100644 modules/geom/doc/mat.rst
 create mode 100644 modules/gui/pymod/scene/map_level_widget.py
 create mode 100644 modules/gui/pymod/scene/scene_selection_helper.py
 create mode 100644 modules/gui/pymod/scene/wireframe_widget.py
 create mode 100644 modules/gui/share/icons/find_icon.png
 create mode 100644 modules/gui/share/icons/menubar_icon.png
 delete mode 100644 modules/gui/src/sequence/sequence_model.cc
 delete mode 100644 modules/gui/src/sequence/sequence_viewer.cc
 delete mode 100644 modules/gui/src/sequence/view_object.cc
 create mode 100644 modules/gui/src/sequence_viewer/align_properties_painter.cc
 rename modules/gui/{pymod/sequence_viewer_proxyV2.hh => src/sequence_viewer/align_properties_painter.hh} (70%)
 create mode 100644 modules/gui/src/sequence_viewer/alignment_view_object.cc
 create mode 100644 modules/gui/src/sequence_viewer/alignment_view_object.hh
 create mode 100644 modules/gui/src/sequence_viewer/background_painter.cc
 rename modules/{base/src/integrity_error.cc => gui/src/sequence_viewer/background_painter.hh} (71%)
 rename modules/gui/src/{sequence => sequence_viewer}/base_row.cc (97%)
 rename modules/gui/src/{sequence => sequence_viewer}/base_row.hh (96%)
 create mode 100644 modules/gui/src/sequence_viewer/base_view_object.cc
 rename modules/gui/src/{sequence/sequence_viewer.hh => sequence_viewer/base_view_object.hh} (52%)
 rename modules/gui/{pymod/export_sequence_viewerV2.cc => src/sequence_viewer/conservation_painter.cc} (67%)
 create mode 100644 modules/gui/src/sequence_viewer/conservation_painter.hh
 rename modules/gui/src/{sequence => sequence_viewer}/painter.hh (100%)
 rename modules/gui/src/{sequence => sequence_viewer}/secstr_row.cc (98%)
 rename modules/gui/src/{sequence => sequence_viewer}/secstr_row.hh (95%)
 rename modules/gui/src/{sequence => sequence_viewer}/seq_secstr_painter.cc (100%)
 rename modules/gui/src/{sequence => sequence_viewer}/seq_secstr_painter.hh (100%)
 rename modules/gui/src/{sequence => sequence_viewer}/seq_selection_painter.cc (77%)
 rename modules/gui/src/{sequence => sequence_viewer}/seq_selection_painter.hh (96%)
 rename modules/gui/src/{sequence => sequence_viewer}/seq_text_painter.cc (96%)
 rename modules/gui/src/{sequence => sequence_viewer}/seq_text_painter.hh (100%)
 rename modules/gui/src/{sequence => sequence_viewer}/sequence_delegate.cc (100%)
 rename modules/gui/src/{sequence => sequence_viewer}/sequence_delegate.hh (100%)
 delete mode 100644 modules/gui/src/sequence_viewer/sequence_item.cc
 delete mode 100644 modules/gui/src/sequence_viewer/sequence_item.hh
 create mode 100644 modules/gui/src/sequence_viewer/sequence_model.cc
 rename modules/gui/src/{sequence => sequence_viewer}/sequence_model.hh (61%)
 rename modules/gui/src/{sequence => sequence_viewer}/sequence_row.cc (82%)
 rename modules/gui/src/{sequence => sequence_viewer}/sequence_row.hh (90%)
 delete mode 100644 modules/gui/src/sequence_viewer/sequence_scene.cc
 delete mode 100644 modules/gui/src/sequence_viewer/sequence_scene.hh
 rename modules/gui/src/{sequence => sequence_viewer}/sequence_table_view.cc (87%)
 rename modules/gui/src/{sequence => sequence_viewer}/sequence_table_view.hh (95%)
 create mode 100644 modules/gui/src/sequence_viewer/sequence_view_object.cc
 rename modules/gui/src/{sequence/view_object.hh => sequence_viewer/sequence_view_object.hh} (54%)
 delete mode 100644 modules/gui/src/sequence_viewer/sequence_viewer_base.cc
 delete mode 100644 modules/gui/src/sequence_viewer/sequence_viewer_base.hh
 rename modules/gui/src/{sequence => sequence_viewer}/tick_painter.cc (100%)
 rename modules/gui/src/{sequence => sequence_viewer}/tick_painter.hh (100%)
 rename modules/gui/src/{sequence => sequence_viewer}/title_row.cc (89%)
 rename modules/gui/src/{sequence => sequence_viewer}/title_row.hh (100%)
 create mode 100644 modules/img/alg/doc/alg.rst
 create mode 100644 modules/img/base/doc/img.rst
 create mode 100644 modules/img/base/src/mask_info_convert.cc
 create mode 100644 modules/img/base/src/mask_info_convert.hh
 create mode 100644 modules/io/doc/formats.rst
 create mode 100644 modules/io/doc/io.rst
 create mode 100644 modules/io/src/formatted_line.hh
 create mode 100644 modules/io/src/mol/sdf_reader.cc
 create mode 100644 modules/io/src/mol/sdf_reader.hh
 create mode 100644 modules/io/src/mol/sdf_writer.cc
 create mode 100644 modules/io/src/mol/sdf_writer.hh
 create mode 100644 modules/io/tests/testfiles/pdb/alt-loc.pdb
 create mode 100644 modules/io/tests/testfiles/pdb/conect.pdb
 create mode 100644 modules/io/tests/testfiles/pdb/ter.pdb
 rename modules/io/tests/testfiles/{test_in.sdf => sdf/compound.sdf} (97%)
 create mode 100644 modules/io/tests/testfiles/sdf/empty_dataheader.sdf
 create mode 100644 modules/io/tests/testfiles/sdf/multiple.sdf
 create mode 100644 modules/io/tests/testfiles/sdf/properties.sdf
 create mode 100644 modules/io/tests/testfiles/sdf/simple.sdf
 create mode 100644 modules/io/tests/testfiles/sdf/wrong_atomcount.sdf
 create mode 100644 modules/io/tests/testfiles/sdf/wrong_atomlinelength.sdf
 create mode 100644 modules/io/tests/testfiles/sdf/wrong_atompos.sdf
 create mode 100644 modules/io/tests/testfiles/sdf/wrong_bondatomnumber.sdf
 create mode 100644 modules/io/tests/testfiles/sdf/wrong_bondcount.sdf
 create mode 100644 modules/io/tests/testfiles/sdf/wrong_bondlinelength.sdf
 create mode 100644 modules/io/tests/testfiles/sdf/wrong_bondtype.sdf
 create mode 100644 modules/io/tests/testfiles/sdf/wrong_charge.sdf
 create mode 100644 modules/io/tests/testfiles/sdf/wrong_dataheader.sdf
 create mode 100644 modules/mol/alg/pymod/export_entity_to_density.cc
 create mode 100644 modules/mol/alg/src/atom_scattering_properties.txt
 create mode 100644 modules/mol/alg/src/entity_to_density.cc
 create mode 100644 modules/mol/alg/src/entity_to_density.hh
 create mode 100644 modules/mol/base/pymod/export_entity_property_mapper.cc
 delete mode 100644 modules/mol/base/src/impl/rsurf_impl.cc
 delete mode 100644 modules/mol/base/src/impl/rsurf_impl.hh
 create mode 100644 modules/seq/alg/pymod/mat.py
 create mode 100644 modules/seq/alg/src/conservation.cc
 create mode 100644 modules/seq/alg/src/conservation.hh
 create mode 100644 modules/seq/base/doc/seq.rst
 create mode 100644 modules/seq/base/src/views_from_sequences.cc
 create mode 100644 modules/seq/base/src/views_from_sequences.hh
 create mode 100644 modules/seq/base/tests/test_aligned_column.cc
 create mode 100644 modules/seq/base/tests/test_aligned_region.cc
 create mode 100644 modules/seq/base/tests/test_alignment.cc
 create mode 100644 modules/seq/base/tests/test_seq.py
 create mode 100644 modules/seq/base/tests/testfiles/testprotein.pdb

diff --git a/.gitignore b/.gitignore
index 71a47aca6..da71b5ba0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
 CMakeFiles
 cmake_install.cmake
 stage
+tests
 dng
 gipltng
 ost
@@ -19,5 +20,8 @@ html
 scratch
 pov_*test.pov
 pov_*test.inc
+*-out.pdb
 CMakeLists.txt.user
 OpenStructure.cbp
+DartConfiguration.tcl
+Testing
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b0780e36e..d59bd4654 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,13 +6,15 @@ cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR)
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake_support)
 include(OST)
 
-
-
 project(OpenStructure CXX C)
 
+INCLUDE(CTest)
+ENABLE_TESTING()
 
 option(USE_SHADER "whether to compile with shader support"
        OFF)
+option(SET_RPATH "embed rpath upon make install"
+       OFF)
 option(COMPILE_TMTOOLS "whether to compile the tmalign and tmscore programs"
        OFF)
 option(PROFILE "whether to compile with profiling support"
@@ -28,7 +30,8 @@ option(USE_DOUBLE_PRECISION "whether to compile in double precision"
 option(ENABLE_SPNAV "whether 3DConnexion devices should be supported"
       OFF)
 option(STATIC_PROPERTY_WORKAROUND "workaround for static property bug with some boost/boost_python combinations" OFF)
-option(DEPLOYMENT "switch on deployment settings" OFF)
+option(DEPLOYMENT "switch on deployment settings" OFF)
+option(COMPILE_TESTS "wheter unit tests should be compiled by default" OFF)
 
 if (PREFIX)
   set(CMAKE_INSTALL_PREFIX ${PREFIX})
@@ -218,13 +221,25 @@ include_directories(${Boost_INCLUDE_DIRS}
                     ${TIFF_INCLUDE_DIR}
                     ${SPNAV_INCLUDE_DIR}
                     )
-
+if (UNIX)
+  SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
+  SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
+  if(USE_RPATH)
+    set(_USE_RPATH ON)
+    SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_DIR}")
+    SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+  else()
+    set(_USE_RPATH OFF)
+   SET(CMAKE_INSTALL_RPATH "")
+   SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
+  endif() 
+endif()
 
 
 add_subdirectory(modules)
 add_subdirectory(scripts)
-add_subdirectory(deployment)
-set (FILES_TO_BE_REMOVED stage CMakeFiles)
+add_subdirectory(deployment)
+set(FILES_TO_BE_REMOVED CMakeFiles stage tests)
 set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
                          "${FILES_TO_BE_REMOVED}")
 
@@ -232,6 +247,7 @@ set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
 
 message(STATUS 
         "OpenStructure will be built with the following options:\n"
+        "   RPath in install            (-DUSE_RPATH) : ${_USE_RPATH}\n"
         "   Graphical interface         (-DENABLE_UI) : ${_UI}\n"
         "   OpenGL support             (-DENABLE_GFX) : ${_OPENGL}\n"
         "   Image Processing support   (-DENABLE_IMG) : ${_IMG}\n"        
@@ -245,4 +261,4 @@ message(STATUS
 #set(SPHINX_OPTIONS -c doc/conf -b html -d doc/html/doctrees)
 #add_custom_target(doc COMMAND 
 #                  ${SPHINX} ${SPHINX_OPTIONS} modules doc/html
-#                  VERBATIM)
\ No newline at end of file
+#                  VERBATIM)
diff --git a/CTestConfig.cmake b/CTestConfig.cmake
new file mode 100644
index 000000000..1de92e23a
--- /dev/null
+++ b/CTestConfig.cmake
@@ -0,0 +1,31 @@
+## This file should be placed in the root directory of your project.
+## Then modify the CMakeLists.txt file in the root directory of your
+## project to incorporate the testing dashboard.
+## # The following are required to uses Dart and the Cdash dashboard
+##   ENABLE_TESTING()
+##   INCLUDE(CTest)
+set(CTEST_PROJECT_NAME "OpenStructure")
+set(CTEST_NIGHTLY_START_TIME "00:00:00 MEZ")
+
+set(CTEST_DROP_METHOD "http")
+set(CTEST_DROP_SITE "kb-pdwg1059-06.pz.unibas.ch")
+set(CTEST_DROP_LOCATION "/cdash/submit.php?project=OpenStructure")
+set(CTEST_DROP_SITE_CDASH TRUE)
+
+if ("${CMAKE_NATIVE_ARCH}" MATCHES "64")
+  set(CMAKE_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}64bit")
+endif()
+if (USE_DOUBLE_PRECISION)
+  set(CMAKE_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}-double")
+endif()
+if (NOT ENABLE_IMG)
+  set(CMAKE_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}-no_img")
+endif()
+if (NOT ENABLE_GFX)
+  set(CMAKE_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}-no_gfx")
+endif()
+if (NOT ENABLE_UI)
+  set(CMAKE_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}-no_ui")
+endif()
+
+set(BUILDNAME "${CMAKE_SYSTEM_NAME}")
diff --git a/cmake_support/OST.cmake b/cmake_support/OST.cmake
index 6d04eb292..e46d6f53c 100644
--- a/cmake_support/OST.cmake
+++ b/cmake_support/OST.cmake
@@ -190,12 +190,11 @@ macro(module)
     set_target_properties(${_LIB_NAME} PROPERTIES
                           LIBRARY_OUTPUT_DIRECTORY ${LIB_STAGE_PATH}
                           ARCHIVE_OUTPUT_DIRECTORY ${LIB_STAGE_PATH}
-                          RUNTIME_OUTPUT_DIRECTORY ${LIB_STAGE_PATH}
-                          INSTALL_RPATH "."
-                          INSTALL_NAME_DIR "@rpath")
+                          RUNTIME_OUTPUT_DIRECTORY ${LIB_STAGE_PATH})
     if (APPLE)
       set_target_properties(${_LIB_NAME} PROPERTIES
-                            LINK_FLAGS "-Wl,-rpath,.")
+                            LINK_FLAGS "-Wl,-rpath,."
+                            INSTALL_NAME_DIR "@rpath")
     endif()
     if (WIN32)
       #set_target_properties(${_LIB_NAME} PROPERTIES PREFIX "../")
@@ -390,13 +389,20 @@ macro(pymod)
     endif()
     target_link_libraries("_${_ARG_NAME}" ${_PARENT_LIB_NAME} 
                           ${PYTHON_LIBRARIES} ${BOOST_PYTHON_LIBRARIES})
-    set_target_properties("_${_ARG_NAME}"
-                          PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PYMOD_STAGE_DIR}
-                          INSTALL_NAME_DIR "@rpath")
+    if (_USE_RPATH)
+      set_target_properties("_${_ARG_NAME}"
+                            PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PYMOD_STAGE_DIR}
+                            INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${LIB_DIR}")
+    else()
+      set_target_properties("_${_ARG_NAME}"
+                            PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PYMOD_STAGE_DIR}
+                            INSTALL_RPATH "")
+    endif()
     if (APPLE)
       file(RELATIVE_PATH _REL_PATH "${PYMOD_STAGE_DIR}" "${LIB_STAGE_PATH}")
       set_target_properties(_${_ARG_NAME} PROPERTIES
-                            LINK_FLAGS "-Wl,-rpath,@${_REL_PATH}")
+                            LINK_FLAGS "-Wl,-rpath,@${_REL_PATH}"
+                            INSTALL_NAME_DIR "@rpath")
     endif()                          
     if (NOT WIN32)
       set_target_properties("_${_ARG_NAME}"
@@ -474,6 +480,7 @@ macro(ost_unittest MODULE SOURCE_FILES)
     set(_SOURCES ${SOURCE_FILES})
     set(CPP_TESTS)
     set(PY_TESTS)
+    set(CMAKE_CURRENT_BINARY_DIR "${CMAKE_BINARY_DIR}/tests")
     foreach(src ${_SOURCES})
       if (${src} MATCHES "\\.py$")
        list(APPEND PY_TESTS "${src}")      
@@ -484,22 +491,28 @@ macro(ost_unittest MODULE SOURCE_FILES)
     set(_SOURCES ${CPP_TESTS})
     set(_test_name "${MODULE}_tests")
     if(DEFINED CPP_TESTS)
-      add_executable(${_test_name} EXCLUDE_FROM_ALL ${_SOURCES})
+      if(COMPILE_TESTS)
+        add_executable(${_test_name} ${_SOURCES})
+      else()
+        add_executable(${_test_name} EXCLUDE_FROM_ALL ${_SOURCES})
+      endif()
       if (WIN32)
-        target_link_libraries(${_test_name} "ost_${MODULE}")  
+        target_link_libraries(${_test_name} ${BOOST_UNIT_TEST_LIBRARIES} "ost_${MODULE}")  
         add_custom_target("${_test_name}_run"
                         COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${_test_name}.exe || echo
-                        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
+                        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_BUILD_TYPE}/..
                         COMMENT "running checks for module ${MODULE}"
                         DEPENDS ${_test_name})
+        add_test("${_test_name}" ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${_test_name}.exe)
       else()
         target_link_libraries(${_test_name} ${BOOST_UNIT_TEST_LIBRARIES}
                             "ost_${MODULE}")
         add_custom_target("${_test_name}_run"
-                        COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${_test_name} || echo
-                        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+                        COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${_test_name} || echo 
+                        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                         COMMENT "running checks for module ${MODULE}"
                         DEPENDS ${_test_name})
+        add_test("${_test_name}" ${CMAKE_CURRENT_BINARY_DIR}/${_test_name} )
       endif()
 
       add_dependencies(check "${_test_name}_run")
@@ -513,13 +526,17 @@ macro(ost_unittest MODULE SOURCE_FILES)
     foreach(py_test ${PY_TESTS})
       if(WIN32)
         set (PY_TESTS_CMD "${EXECUTABLE_OUTPUT_PATH}/ost.bat")
+        add_custom_target("${py_test}_run"
+                  CALL "${PY_TESTS_CMD} ${CMAKE_CURRENT_SOURCE_DIR}/${py_test} || echo"
+                  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+                  COMMENT "running checks ${py_test}" VERBATIM)
       else()
         set (PY_TESTS_CMD "${EXECUTABLE_OUTPUT_PATH}/ost")
+        add_custom_target("${py_test}_run"
+                  sh -c "${PY_TESTS_CMD} ${CMAKE_CURRENT_SOURCE_DIR}/${py_test} || echo"
+                  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+                  COMMENT "running checks ${py_test}" VERBATIM)
       endif()
-      add_custom_target("${py_test}_run"
-                  COMMAND ${PY_TESTS_CMD} ${CMAKE_CURRENT_SOURCE_DIR}/${py_test} || echo
-                  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-                  COMMENT "running checks  ${py_test}" VERBATIM)
       add_dependencies("${py_test}_run" ost_scripts "_${MODULE}")
       add_dependencies(check "${py_test}_run")
       if (WIN32)
@@ -626,4 +643,4 @@ macro(get_ost_rev)
     endif()
   endif()
   message("Revision: ${OST_REV}")
-endmacro()
\ No newline at end of file
+endmacro()
diff --git a/doc/conf/conf.py b/doc/conf/conf.py
index d7a1455a1..9e720456c 100644
--- a/doc/conf/conf.py
+++ b/doc/conf/conf.py
@@ -16,8 +16,10 @@ 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.join(os.path.abspath('../..'), 
+                             'stage/lib/openstructure'))
+sys.path.append(os.path.join(os.path.abspath('../..'), 
+                             'stage/lib64/openstructure'))
 # -- General configuration -----------------------------------------------------
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
@@ -86,7 +88,7 @@ exclude_trees = []
 pygments_style = 'sphinx'
 
 # A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
+modindex_common_prefix = ['ost.']
 
 
 # -- Options for HTML output ---------------------------------------------------
diff --git a/doc/make.py b/doc/make.py
new file mode 100644
index 000000000..d5b75c2ab
--- /dev/null
+++ b/doc/make.py
@@ -0,0 +1,48 @@
+import os, sys
+import shutil
+if len(sys.argv)==2:
+  root_dir=sys.argv[1]
+else:
+  root_dir='.'
+
+def _OutputPath(inpath, outdir):
+  parts=inpath.split(os.path.sep)
+  filtered_parts=[outdir]
+  index=parts.index('modules')
+  for part in parts[index+1:]:
+    if part!='doc':
+      filtered_parts.append(part)
+  return os.path.join(*filtered_parts)
+
+def _RequireCopy(in_name, out_name):
+  if not os.path.exists(out_name):
+    return True
+  if os.path.getmtime(in_name)>os.path.getmtime(out_name):
+    return True
+  return False
+def _MkDir(dirname):
+  """
+  Recursively create directories if they don't exist
+  """
+  parts=dirname.split(os.path.sep)
+  for i, d in enumerate(parts):
+    n=os.path.join(*parts[:1+i])
+    if not os.path.exists(n):
+      os.mkdir(n)
+
+def _CollectRstDocs(outdir, dirname, fnames):
+  for fname in fnames:
+    if fname.endswith('.rst'):
+      in_name=os.path.join(dirname, fname)
+      out_name=_OutputPath(in_name, outdir)
+      out_dir=os.path.dirname(out_name)
+      if not os.path.exists(out_dir):
+        _MkDir(out_dir)
+      if _RequireCopy(in_name, out_name):
+        print 'cp %s %s' % (in_name, out_name)
+        os.system('cp %s %s' % (in_name, out_name))
+      
+for sub_dir in ('modules',):
+  os.path.walk(sub_dir, _CollectRstDocs, 'doc/source')
+os.system('sphinx-build -b html -c %s %s %s' % ('doc/conf', 'doc/source', 
+                                                'doc/build'))
\ No newline at end of file
diff --git a/examples/dokk/datafiles/dengue/levelF.ini b/examples/dokk/datafiles/dengue/levelF.ini
index 55afca839..c1e13d14a 100644
--- a/examples/dokk/datafiles/dengue/levelF.ini
+++ b/examples/dokk/datafiles/dengue/levelF.ini
@@ -16,14 +16,15 @@ TEXT_COUNT: 10
 TEXT1: Voil�, la phase d'entrainement du jeu est termin�e ...
 TEXTTIME1: 3000
 
-TEXT2: Au niveau suivant, vous devez approcher/docker le ligand sur la prot�ine aussi bien que possible.
+TEXT2: Au niveau suivant, vous devez approcher/docker le ligand sur la prot�ine 
+  aussi bien que possible.
 TEXTTIME2: 8000
 
 TEXT3: La premi�re cible est une enzyme importante du virus de la dengue.
 TEXTTIME3: 8000
 
-TEXT4: Pour arr�ter le virus de la dengue, placez le ligand, le mieux que vous le pouvez,
-  � l'int�rieur de la prot�ine.
+TEXT4: Pour arr�ter le virus de la dengue, placez le ligand, le mieux que vous le 
+  pouvez, � l'int�rieur de la prot�ine.
 TEXTTIME4: 8000
 
 TEXT5: Vous pouvez lire votre score actuel en haut � gauche de l'�cran. Si vous �tes
diff --git a/examples/dokk/datafiles/dengue/top_ten.ini b/examples/dokk/datafiles/dengue/top_ten.ini
index 30fb5b557..186a0ffdc 100644
--- a/examples/dokk/datafiles/dengue/top_ten.ini
+++ b/examples/dokk/datafiles/dengue/top_ten.ini
@@ -1,6 +1,6 @@
 [10]
-score = 2.80041636229
-name = AAA
+score = 2.58003196716
+name = STU
 
 [1]
 score = 1.06508742174
@@ -23,18 +23,18 @@ score = 1.22069145838
 name = STU
 
 [7]
-score = 1.57162377437
+score = 1.34045518637
 name = STU
 
 [6]
-score = 1.34045518637
-name = STU
+score = 1.32533345222
+name = PAA
 
 [9]
-score = 2.58003196716
-name = STU
-
-[8]
 score = 2.31934833527
 name = ASS
 
+[8]
+score = 1.57162377437
+name = STU
+
diff --git a/examples/seq/seq_viewer.py b/examples/seq/seq_viewer.py
new file mode 100644
index 000000000..2d5239253
--- /dev/null
+++ b/examples/seq/seq_viewer.py
@@ -0,0 +1,4 @@
+aln=io.LoadAlignment('sh2.aln')
+v=gui.SequenceViewerV2()
+v.AddAlignment(aln)
+v.Show()
diff --git a/examples/seq/sh2.aln b/examples/seq/sh2.aln
new file mode 100644
index 000000000..45daa963b
--- /dev/null
+++ b/examples/seq/sh2.aln
@@ -0,0 +1,214 @@
+CLUSTAL 2.0.12 multiple sequence alignment
+
+
+SH2                         -------------------------KP-HPWFFGKIPRAKAEEMLSKQR- 23
+UniRef90_UPI0000EB201F      KAELNGKDGFIPKN-------YIEMKP-HPWFFGKIPRAKAEEMLSKQR- 45
+UniRef90_P62993             KAELNGKDGFIPKN-------YIEMKP-HPWFFGKIPRAKAEEMLSKQR- 78
+UniRef90_P62993-2           KAELNGKDGFIPKN-------YIEMKP-HP-------------------- 59
+UniRef90_P87379             KAELNGKDGFIPKN-------YIEMKA-HPWFFGKIPRAKAEEMLGKQR- 78
+UniRef90_UPI00016E653C      KAELRGKDGFIPKN-------YIEMKA-HPWFYGKIPRAKAEEILNKQR- 78
+UniRef90_UPI00016E653B      KAELRGKDGFIPKN-------YIEMKA-HPWFYGKIPRAKAEEILNKQR- 78
+UniRef90_Q4T656             DQALS-FASLLPVS-------FSAC---CRWFYGKIPRAKAEEILNKQR- 75
+UniRef90_UPI0001555716      KAELNGKDGFIPKN-------YIEMKP-HLWFFGKIPRAYAEEMLGKQL- 388
+UniRef90_UPI000180AF26      KAEQDGKEGLVPMN-------YIQMKP-CEWFARNMTRANAELRL-KNA- 52
+UniRef90_UPI000180AF37      KAEQDGKEGLVPMN-------YIEIKE-CEWFARNMTRANAELRL-KNT- 77
+UniRef90_A8XPY6             KAELDGTEGFIPSN-------YIRMGD-CSWYLGKITRNDAEVLLKKSNV 79
+UniRef90_P29355             KAELDGNEGFIPSN-------YIRMTE-CNWYLGKITRNDAEVLLKKPTV 79
+UniRef90_UPI000186E6C5      RAELDSKEGLIPSN-------YIEMKN-HDWYYGRITRADAEKLLMNK-- 77
+UniRef90_Q08012             RAELDGKEGLIPSN-------YIEMKN-HDWYYGRITRADAEKLLSNK-- 77
+UniRef90_B7P0R2             RAELDSKEGLIPSN-------YIEMKK-HDWYYGRITRADAEKLLSNK-- 77
+UniRef90_D3PIQ8             RAESGGKEGLIPSN-------YIDMKP-HDWYYSRMTRATAEKLLSNK-- 77
+UniRef90_C4WWT7             RAEFEGKEGLIPSN-------YIEMKN-HDWYYGKITRADAEKLLDQQ-- 77
+UniRef90_UPI0000586DB6      -------------------------------------RDGAEELLKND-- 40
+UniRef90_UPI0001CBA623      KAELDGREGFIPKN-------YITMRP-HDWFHGKISRAKAEELLQLQP- 78
+UniRef90_UPI0001CBA624      NAELDGREGLIPKN-------YIEMKP-HEWFHGKISREKAEELLQLQS- 77
+UniRef90_UPI000192619C      KAEQNGKEGFVPKN-------YIQMKP-HSWYYGKIRRSEAEQLLLQEP- 52
+UniRef90_UPI0000521DDC      RAEIDGRMGLVPKN-------YIELKA-HDWYHGKISRVKAEQSLNKPHY 79
+UniRef90_C1LZF7             LAEQEGRTGLIPCN-------YITMRP-HPWYIRHCSRMEAEERLQEIDQ 79
+UniRef90_UPI0000E478D2      LAHQGAKQGLVPEN-------YLKIEKSHPWYVGKISRKVAEEYLMSMP- 80
+UniRef90_UPI0000E49A1C      ----------MGPK-------HTYPEIAMAWFFPTITRKNAELLLMQE-- 31
+UniRef90_A8E5T1             KAELFGREGYIPKN-------YIKVKP-HPWYAGRISRQVAEEILLKRNF 79
+UniRef90_C1C3T6             KAELKGQEGYIPKN-------YIKVKP-HPWYAGRISRQVAEEILLKKRF 79
+UniRef90_Q13588             KAELRGVEGFIPKN-------YIRVKP-HPWYSGRISRQLAEEILMKRNH 79
+UniRef90_UPI0001C606E3      KAELRGAEGFVPKN-------YIHIKP-HPWYSGRISRQLAEEILMKRNQ 79
+UniRef90_Q9CX99             KAELRGAEGFVPKN-------YIRVKP-HPWYSGRISRQLAEETLMKRNH 79
+UniRef90_UPI0000DA3575      GVGLKPIEGMRPTNRTXRIPADIVPSP-HRWYSGRISRQLAEETLMKRNH 86
+UniRef90_UPI0000D9440A      KAELRGAEGFIPKN-------YIQVKP-HPWFAGRISRQFAEEILLRRNH 79
+UniRef90_UPI000155C0E1      RTSLLGGESFFYKN-------IQKLSP-SPWYAGRISRQLAEEVLLKRNH 79
+UniRef90_UPI0000E80FCB      KAELYGCEGFVPKN-------YIKVKP-HPWYAGRISRHVAEELLLKRRY 79
+UniRef90_UPI00016E4BE7      TAELHNRKGFVPKN-------YINLRP-HAWFAGRISRSVAESRLRQRE- 78
+UniRef90_Q503S8             TAEFVNRKGYVPKN-------YISLRP-HAWFAGRISRHVAENRLHQRD- 78
+UniRef90_Q4V9Q1             TAELLGRRGYVPKN-------YINVRP-HTWFVGGISRQAAENRLRPLE- 78
+UniRef90_UPI00017B202F      TAEIQGKRGYIPQN-------YISLLP-YPWFVGRVSRLEAEKRLRWQD- 78
+UniRef90_UPI0000E25B42      KAELGSQEGYVPKN-------FIDIQF-PEWFHEGLSRHQAENLLMGKE- 149
+UniRef90_O75791             KAELGSQEGYVPKN-------FIDIQF-PKWFHEGLSRHQAENLLMGKE- 76
+UniRef90_B7Z8F8             RHKLNP---FSSK----------------RWFHEGLSRHQAENLLMGKE- 50
+UniRef90_UPI00005BC6B6      KAELGSQEGYVPKN-------FIEIEF-PEWFHEGLSRHQAESLLMGKE- 76
+UniRef90_O89100             KAELGSQEGYVPKN-------FIDIEF-PEWFHEGLSRHQAENLLMGKD- 76
+UniRef90_UPI0000EDE7DF      KAELKSHEGYVPKN-------FIDIHI-PGWFHEGISRHEAESLLMGKE- 76
+UniRef90_UPI0000F2E19C      KAELGSQEGYVPKN-------FIDIQF-PSWFHEDISRHDAESLLMGKD- 241
+UniRef90_UPI0000E7F8B9      KAELRSQEGYVPKN-------FIDFHV-PPWFDEKISRHEAESILMNKG- 76
+UniRef90_UPI0000ECD2B7      KAELRSQEGYVPKN-------FIDFHV-PPWFDEKISRHEAESILMNKG- 76
+UniRef90_UPI000194E163      KAELRSHEGYVPKN-------FIDFHV-PHWFDEKISRHEAENLLMSKG- 91
+UniRef90_B5X487             KAELHGQEGFVPQN-------YIERQT-PSWFKETASRSSAEELLMSRE- 76
+UniRef90_Q567F1             KAELHGHEGYVPKN-------YVDRQI-PSWFKESASRGSAEETLMSRE- 76
+                                                                              
+
+SH2                         -------HDGAFLIRESESA--PGDFSL----SVKFGNDVQHFKVLR--D 58
+UniRef90_UPI0000EB201F      -------HDGAFLIRESESA--PGDFSL----SVKFGNDVQHFKVLR--D 80
+UniRef90_P62993             -------HDGAFLIRESESA--PGDFSL----SVKFGNDVQHFKVLR--D 113
+UniRef90_P62993-2           -----------------------------------FGNDVQHFKVLR--D 72
+UniRef90_P87379             -------HDGAFLIRESESA--PGDFSL----SVKFGNDVQHFKVLR--D 113
+UniRef90_UPI00016E653C      -------RDGAFLIRESESA--PGDFSL----SVKYGNDVQHFKVLR--D 113
+UniRef90_UPI00016E653B      -------RDGAFLIRESESA--PGDFSL----SVKYGNDVQHFKVLR--D 113
+UniRef90_Q4T656             -------RDGAFLIRESESA--PGDFSL----SVKYGNDVQHFKVLR--D 110
+UniRef90_UPI0001555716      -------NYGSFFILXXXXP--PGDALTGARSTPRFGNDVQHFKVLR--D 427
+UniRef90_UPI000180AF26      -------LDESFLVRESEST--PGDFSL----SVKTNSGVQHFKVLR--D 87
+UniRef90_UPI000180AF37      -------LDGSFLVRESEST--PGEFSV----SVKTNSGVQHFKVLR--D 112
+UniRef90_A8XPY6             -------RDGHFLVRQCESS--PGEFSI----SVRFQDSVQHFKVLR--D 114
+UniRef90_P29355             -------RDGHFLVRQCESS--PGEFSI----SVRFQDSVQHFKVLR--D 114
+UniRef90_UPI000186E6C5      -------HEGAFLIRVSESS--PGDFSL----SVKCSDGVQHFKVLR--D 112
+UniRef90_Q08012             -------HEGAFLIRISESS--PGDFSL----SVKCPDGVQHFKVLR--D 112
+UniRef90_B7P0R2             -------HEGAFLIRVSESS--PGDFSL----SVRCGDGVQHFKVLR--D 112
+UniRef90_D3PIQ8             -------HEGAFVIRVSESS--PGDFSL----SVKCGDGVQHFKVLR--D 112
+UniRef90_C4WWT7             -------PEGCFLVRISESS--PGDFSL----SVKCGDGVQHFKVLR--D 112
+UniRef90_UPI0000586DB6      -------GDGAFLIRESEGT--PGDYSL----SVKFVDGVQHFKVLR--D 75
+UniRef90_UPI0001CBA623      -------HDGAFLIRESESA--PGDFSL----SVKFKDEVQHFKVLR--D 113
+UniRef90_UPI0001CBA624      -------YDGAFLIRESEST--PGDFSL----SVKFKDGVQNFKILR--D 112
+UniRef90_UPI000192619C      -------HDGAYLIRDSEST--AGDFSL----SVKFNNQVQHFKVLR--D 87
+UniRef90_UPI0000521DDC      -------PDGAFLIRESESS--PGDFSL----SVKYGSAVQHFKVLR--D 114
+UniRef90_C1LZF7             ETAQHLQPDGAFILRQSEAD--GKGFSL----SVKQGCEVLHFKVLQ--D 121
+UniRef90_UPI0000E478D2      -------SDGAFMIRDSESNPDSGNFSL----SVKFRDQVQHFKILT--D 117
+UniRef90_UPI0000E49A1C      -------RNGAFLVRRSESS--EGLYSL----SVKYNESVQHFRILQ--D 66
+UniRef90_A8E5T1             --------VGAFLIRDSESS--PGDFSI----SVNYGHHVQHFKVLRDTE 115
+UniRef90_C1C3T6             --------LGAFLIRDSESS--PGEFSI----SVNYGHHVQHFKVLR--E 113
+UniRef90_Q13588             --------LGAFLIRESESS--PGEFSV----SVNYGDQVQHFKVLR--E 113
+UniRef90_UPI0001C606E3      --------LGAFLIRESESS--PGEFSV----SVNYGDQVQHFKVLR--E 113
+UniRef90_Q9CX99             --------LGAFLIRESESS--PGEFSV----SVNYGDQVQHFKVLR--E 113
+UniRef90_UPI0000DA3575      --------LGAFLIRESESS--PGEFSV----SVNYGDQVQHFKVLR--E 120
+UniRef90_UPI0000D9440A      --------LGAFLIRESESS--PGEFSV----SVNYGNQVQHFKVLR--E 113
+UniRef90_UPI000155C0E1      --------LGAFLIRESESS--PGEFSV----SVNYGDQVQHFKVLR--E 113
+UniRef90_UPI0000E80FCB      --------VGAFLIRESESA--PGEFSI----SVNYGQHVQHFKVLR--E 113
+UniRef90_UPI00016E4BE7      --------CGAFLVRESESA--PGEFSM----SVSYGDHVQHFKVLQD-- 112
+UniRef90_Q503S8             --------CGSFLVRESESA--PGEFSM----SVSYGDHVQHFKVLKD-- 112
+UniRef90_Q4V9Q1             --------CGAFLIRESEST--PGEFSV----SVSYGDHVQHFKVLKD-- 112
+UniRef90_UPI00017B202F      --------PGVFLVRESESA--PGEFSV----SVSYGNRVEHFRVLE--- 111
+UniRef90_UPI0000E25B42      --------VGFFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 183
+UniRef90_O75791             --------VGFFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 110
+UniRef90_B7Z8F8             --------VGFFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 84
+UniRef90_UPI00005BC6B6      --------LGCFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 110
+UniRef90_O89100             --------IGFFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 110
+UniRef90_UPI0000EDE7DF      --------VGSFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 110
+UniRef90_UPI0000F2E19C      --------VGSFIIRASQSS--PGDFSI----SVRHEDDVQHFKVMR--D 275
+UniRef90_UPI0000E7F8B9      --------VGSFIVRASQNS--HGDFSI----SVRHEDDVQHFKVMR--D 110
+UniRef90_UPI0000ECD2B7      --------VGSFIVRASQNS--HGDFSI----SVRHEDDVQHFKVMR--D 110
+UniRef90_UPI000194E163      --------VGCFVVRASQNS--HGDFSI----SVRHEDDVQHFKVMR--D 125
+UniRef90_B5X487             --------VGGFLIRGSQSS--PGEFSI----SVRHEFDVQHFKVMK--D 110
+UniRef90_Q567F1             --------VGAFLIRGSQSS--PGDFSI----SVRHDYDVQHFKVMK--D 110
+                                                                   * :*:::    
+
+SH2                         GAGKYFLWVVKFNSLNELVDYHRSTSVSR---------------NQQIFL 93
+UniRef90_UPI0000EB201F      GAGKYFLWVVKFNSLNELVDYHRSTSVSR---------------NQQIFL 115
+UniRef90_P62993             GAGKYFLWVVKFNSLNELVDYHRSTSVSR---------------NQQIFL 148
+UniRef90_P62993-2           GAGKYFLWVVKFNSLNELVDYHRSTSVSR---------------NQQIFL 107
+UniRef90_P87379             GAGKYFLWVVKFNSLNELVDYHRSTSVSR---------------NQQIFL 148
+UniRef90_UPI00016E653C      GAGKYFLWVVKFNSLNELVEYHRTTSVSR---------------NQQIFL 148
+UniRef90_UPI00016E653B      GAGKYFLWVVKFNSLNELVEYHRTTSVSR---------------NQQIFL 148
+UniRef90_Q4T656             GAGKYFLWVVKFTSLNELVEYHRTTSVSR---------------NQQIFL 145
+UniRef90_UPI0001555716      GAGKYFLWVVKFNSLNELVDYHRSTSVSR---------------NQQIFL 462
+UniRef90_UPI000180AF26      GAGKYFIWLVKFKSLNQLVDYHRTSSVSR---------------SEQILL 122
+UniRef90_UPI000180AF37      GAGKYFIWVVKFSSLNELVVYHRVMTVSG---------------SERIFL 147
+UniRef90_A8XPY6             QNGKYYLWAVKFNSLNELVAYHRTASVSR---------------THTILL 149
+UniRef90_P29355             QNGKYYLWAVKFNSLNELVAYHRTASVSR---------------THTILL 149
+UniRef90_UPI000186E6C5      AQGKFFLWVVKFSSLNELVEYHRTSSVSR---------------SQHVKL 147
+UniRef90_Q08012             AQSKFFLWVVKFNSLNELVEYHRTASVSR---------------SQDVKL 147
+UniRef90_B7P0R2             TLGKFFLWVVKFASLNELVEYHRSASVSR---------------SQDIKL 147
+UniRef90_D3PIQ8             GQGKFFLWVVKFNSLNELVEYHHSASVSR---------------SQDIKL 147
+UniRef90_C4WWT7             AQAKFFLWVVKFDSLNELVDYHRESSVSR---------------SQDVRL 147
+UniRef90_UPI0000586DB6      GAGKYFLWVVKFNSLNQLVEYHRTSSVSR---------------SQTIYL 110
+UniRef90_UPI0001CBA623      GAGKYFLWVVKFNSLNELVEYHRSSSVSR---------------TQTIYL 148
+UniRef90_UPI0001CBA624      GAGKYFLWVVKFNSLNQLVDYHRTSSVSR---------------SEQIFL 147
+UniRef90_UPI000192619C      GAGKYFLWVVKFNSLNQLVEYHRAASVSR---------------SQTIYL 122
+UniRef90_UPI0000521DDC      GAGKYFLWVVKFSSLNELIKYHREQSISR---------------TQQIML 149
+UniRef90_C1LZF7             EAGKYFFWLSKFDSINQLIDHHRKTSISR---------------NRLLTL 156
+UniRef90_UPI0000E478D2      LAGKYFLWVVKFTSINDLVDYHKDNSVSRTQEIVLNEPCVPIEDANQRPQ 167
+UniRef90_UPI0000E49A1C      TAGKFHLWIVKFPSLDALVDYYRTTSVTR---------------ENQVST 101
+UniRef90_A8E5T1             SNGKYYLWEAKFNSLNELVDYYRRHSIAK---------------FHEVFL 150
+UniRef90_C1C3T6             KSGTYFLWETKFGSLNELVEFYRSSSIAK---------------THPVLL 148
+UniRef90_Q13588             ASGKYFLWEEKFNSLNELVDFYRTTTIAK---------------KRQIFL 148
+UniRef90_UPI0001C606E3      ASGKYFLWEEKFNSLNELVDFYRTTTIAK---------------KRQIFL 148
+UniRef90_Q9CX99             ASGKYFLWEEKFNSLNELVDFYRTTTIAK---------------RRQIFL 148
+UniRef90_UPI0000DA3575      ASGKYFLWEEKFNSLNELVDFYRTTTIAK---------------RRQIFL 155
+UniRef90_UPI0000D9440A      NMGKYFLWEEKFNSLNELVDFYRTTTIAK---------------KKQIFL 148
+UniRef90_UPI000155C0E1      RIGKYYLWEEKFNSLNELVDFYRTTTIAK---------------KKQIFL 148
+UniRef90_UPI0000E80FCB      RNGKYFLWEEKFNSLNELVDFYRTTTIAK---------------KQQIFL 148
+UniRef90_UPI00016E4BE7      RGGQYYVWDELFPSLNELVEFYHCNSIAR---------------ERTVLL 147
+UniRef90_Q503S8             REGYYFVWEEIFPSLNQLVDFYKTNSIAK---------------ERTVFL 147
+UniRef90_Q4V9Q1             GLGQYFIWDEVFSSLNQLVDFYRINSIAK---------------ERTVFL 147
+UniRef90_UPI00017B202F      GGGQYCIWEESFCSLNRLVDFYRTHSIAM---------------DKVVCL 146
+UniRef90_UPI0000E25B42      NKGNYFLWTEKFPSLNKLVDYYRTNSISR---------------QKQIFL 218
+UniRef90_O75791             NKGNYFLWTEKFPSLNKLVDYYRTNSISR---------------QKQIFL 145
+UniRef90_B7Z8F8             NKGNYFLWTEKFPSLNKLVDYYRTNSISR---------------QKQIFL 119
+UniRef90_UPI00005BC6B6      NKGNYFLWTEKFPSLNKLVDYYRKNSISK---------------QKQIFL 145
+UniRef90_O89100             TKGNYFLWTEKFPSLNKLVDYYRTTSISK---------------QKQVFL 145
+UniRef90_UPI0000EDE7DF      AKGHYFLWTEKFQSLNRLVEFYKTSSISR---------------QKQIFL 145
+UniRef90_UPI0000F2E19C      AKGHYFLWTEKFQSLNQLVNFYRTSSISK---------------QKQIYL 310
+UniRef90_UPI0000E7F8B9      SKGNYYLWTEKFYSLNKLVDYYRTSTISR---------------QKQILL 145
+UniRef90_UPI0000ECD2B7      SKGNYYLWTEKFYSLNKLVDYYRTSTISR---------------QKQILL 145
+UniRef90_UPI000194E163      SKGSYYLWTEKFHSLNKLVDYYKTSSISR---------------QKQIFL 160
+UniRef90_B5X487             SKGHYFLWSEKFTSLNKLVDFYKNTSISK---------------QRDIYL 145
+UniRef90_Q567F1             KSGHYYLWTEKFTSLNKLVDFYKTTSISK---------------QKEIFL 145
+                              . : .*   * *:: *: .::  :::                 .    
+
+SH2                         RDIEQVP------------------------------------------- 100
+UniRef90_UPI0000EB201F      RDIEQVPQQNSIFSLCQR----TSLTLCSIVSLEASEEENPVVREWSPHS 161
+UniRef90_P62993             RDIEQVP------------------------------------------- 155
+UniRef90_P62993-2           RDIEQVP------------------------------------------- 114
+UniRef90_P87379             RDIEQVPQVHGGDRATS--------------------------------- 165
+UniRef90_UPI00016E653C      REIEQ--------------------------------------------- 153
+UniRef90_UPI00016E653B      REIEQVTQVNVGTHYIN--------------------------------- 165
+UniRef90_Q4T656             RDIEQVTQV----------------------------------------- 154
+UniRef90_UPI0001555716      RDIEQMPQQKSPVCDRLS----FLFCAVNCRACSDGVFHG---------- 498
+UniRef90_UPI000180AF26      RHPIIS-------------------------------------------- 128
+UniRef90_UPI000180AF37      LHPIS--------------------------------------------- 152
+UniRef90_A8XPY6             ADMNV--------------------------------------------- 154
+UniRef90_P29355             SDMNV--------------------------------------------- 154
+UniRef90_UPI000186E6C5      RDMVP--------------------------------------------- 152
+UniRef90_Q08012             RDMIP--------------------------------------------- 152
+UniRef90_B7P0R2             RDMHP--------------------------------------------- 152
+UniRef90_D3PIQ8             KEIIC--------------------------------------------- 152
+UniRef90_C4WWT7             RDMPAATQNG---------------------------------------- 157
+UniRef90_UPI0000586DB6      KDRKS--------------------------------------------- 115
+UniRef90_UPI0001CBA623      LKMHV--------------------------------------------- 153
+UniRef90_UPI0001CBA624      KDKQ---------------------------------------------- 151
+UniRef90_UPI000192619C      KDMTN--------------------------------------------- 127
+UniRef90_UPI0000521DDC      VDLPV--------------------------------------------- 154
+UniRef90_C1LZF7             VDLVPSKRFPTN-------------------------------------- 168
+UniRef90_UPI0000E478D2      PAMQQSR------------------------------------------- 174
+UniRef90_UPI0000E49A1C      QSVEQWS------------------------------------------- 108
+UniRef90_A8E5T1             CDEEQ--------------------------------------------- 155
+UniRef90_C1C3T6             RDEEE--------------------------------------------- 153
+UniRef90_Q13588             RDEEP--------------------------------------------- 153
+UniRef90_UPI0001C606E3      RDEEP--------------------------------------------- 153
+UniRef90_Q9CX99             CDEQP--------------------------------------------- 153
+UniRef90_UPI0000DA3575      CDEQP--------------------------------------------- 160
+UniRef90_UPI0000D9440A      RDEEP--------------------------------------------- 153
+UniRef90_UPI000155C0E1      RDEEQ--------------------------------------------- 153
+UniRef90_UPI0000E80FCB      RDDEQ--------------------------------------------- 153
+UniRef90_UPI00016E4BE7      RDPEQ--------------------------------------------- 152
+UniRef90_Q503S8             RDLDH--------------------------------------------- 152
+UniRef90_Q4V9Q1             RDPEG--------------------------------------------- 152
+UniRef90_UPI00017B202F      RDPPS--------------------------------------------- 151
+UniRef90_UPI0000E25B42      RDRTREDQGHRGNSLDR---RSQGGPHLSGAVGEEIRPSMNRKLSDHPPT 265
+UniRef90_O75791             RDRTREDQGHRGNSLDR---RSQGGPHLSGAVGEEIRPSMNRKLSDHPPT 192
+UniRef90_B7Z8F8             RDRTREDQGHRGNSLDR---RSQGGPHLSGAVGEEIRPSMNRKLSDHPPT 166
+UniRef90_UPI00005BC6B6      RDRTREEQGQRGNSLDR---RSQGGHPLSGAVGEEIRPSMNRKPSDHP-L 191
+UniRef90_O89100             RDGTQ-DQGHRGNSLDR---RSQGGPHPSGTVGEEIRPSVNRKLSDHLPL 191
+UniRef90_UPI0000EDE7DF      RDGTREDQERRGGSLDR---RAQEGLGLGGACGEEIRVPMNRKMSDLHPP 192
+UniRef90_UPI0000F2E19C      RDGGREEQDRWGGSLER---RLQEGLHISGGVGEETRPSTNRKQSDHPPA 357
+UniRef90_UPI0000E7F8B9      RDDSREEKERRGGSLER---MSRDGLHVGGAAAEAHS-SMSKRYVDHP-- 189
+UniRef90_UPI0000ECD2B7      RDDSREEKERRGGSLER---MSRDGLHVGGAAAEAHS-SMSKRYVDHPVP 191
+UniRef90_UPI000194E163      RDNSQEEKERHGGSLER---IGREGFHMGGAAGEDHS-SISKRYVEYPIP 206
+UniRef90_B5X487             RDGSRDDQSPSTPQPLKRGSLPEERS-----YGAPTAATSHRRASDLP-- 188
+UniRef90_Q567F1             RDGSGDE--PRAPPPIK--SQPEVRPPPGGGYGSPQTSSQNRSTTDPT-- 189
+                                                                              
diff --git a/examples/surf/test_rsurf.py b/examples/surf/test_rsurf.py
deleted file mode 100644
index e8818bdac..000000000
--- a/examples/surf/test_rsurf.py
+++ /dev/null
@@ -1,26 +0,0 @@
-scene.SetFog(False)
-
-eh = io.LoadEntity("sdh.pdb")
-ev = eh.Select("cname=A")
-ec=gfx.Entity("p",ev)
-ec.SetRenderMode(gfx.CPK)
-scene.Add(ec)
-scene.SetCenter(ec.GetCenter())
-ec.Hide()
-
-s = mol.BuildSurface(ev,1.5,15.0/57.3)
-gs=gfx.Surface("s",s)
-scene.Add(gs)
-
-# for debug reasons
-rs=mol.RSurf(1.5)
-for a in ev.GetAtomList():
-    rs.AddSphere(a.GetPos(),a.GetRadius(),str(a))
-rs.Build()
-rs.Triangulate(60.0*3.1415/180.0)
-gr=gfx.RSurface("r",rs)
-scene.Add(gr)
-gr.Hide()
-
-
-
diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt
index dd418e1c2..20e102235 100644
--- a/modules/CMakeLists.txt
+++ b/modules/CMakeLists.txt
@@ -3,7 +3,8 @@ file(GLOB ALL_FILES *)
 foreach(fname ${ALL_FILES})
   if(NOT ${fname} MATCHES ".*.svn" 
      AND NOT ${fname} MATCHES ".*CMakeFiles" 
-     AND NOT ${fname} MATCHES ".*main")
+     AND NOT ${fname} MATCHES ".*main"
+     AND NOT ${fname} MATCHES "doc")
       if(IS_DIRECTORY ${fname})
         add_subdirectory(${fname})
       endif()
diff --git a/modules/base/doc/base.rst b/modules/base/doc/base.rst
new file mode 100644
index 000000000..8bec08e98
--- /dev/null
+++ b/modules/base/doc/base.rst
@@ -0,0 +1,9 @@
+:mod:`ost.settings` - Locate Files and Retrieve Preferences
+================================================================================
+
+.. automodule:: ost.settings
+  :synopsis: Helper Functions to Locate Files and Retrieve Preferences
+  :members:
+  
+  
+
diff --git a/modules/base/doc/generic.rst b/modules/base/doc/generic.rst
new file mode 100644
index 000000000..6c2cd34cb
--- /dev/null
+++ b/modules/base/doc/generic.rst
@@ -0,0 +1,157 @@
+Storing Custom Data
+================================================================================
+
+Introduction
+--------------------------------------------------------------------------------
+
+It is often very convenient to store any arbitrary data inside an Entity. A few examples are: 
+
+  * calculated properties of atoms
+  * sequence conservation of a residue
+  * interaction energy of a substructure with its surrounding
+  * fit of a fragment inside an electron density map
+
+In OpenStructure this is supported by the use of generic properties. Most 
+building blocks are derived from :class:`GenericPropertyContainer`, meaning that 
+arbitrary key-value pairs can be stored in them. In essence, the following 
+classes support generic properties:
+
+  * :class:`~mol.EntityHandle` and :class:`~mol.EntityView`
+  * :class:`~mol.ChainHandle` and :class:`~mol.ChainView`
+  * :class:`~ResidueHandle` and :class:`~mol.ResidueView`
+  * :class:`~mol.AtomHandle` and :class:`~mol.AtomView`
+  * :class:`~mol.BondHandle`
+  * :class:`~seq.SequenceHandle` and :class:`~seq.AlignmentHandle`
+
+The view variants will reflect the generic properties of the handle variants.
+
+A generic property key is always a string, and a value can be one of string, float, int or bool. For each of these data types, methods to retrieve and store values are available both in Python and C++.
+
+Storing and Accessing Data
+--------------------------------------------------------------------------------
+
+All OpenStructure building blocks that are :class:`GenericPropContainers`, have 
+four different methods to store generic data, depending on the data type (i.e. 
+string, float, int or bool).
+
+To store a float value with the key 'myfloatprop' in all atoms of an entity:
+
+.. code-block:: python
+  
+  import math
+  for atom in entity.GetAtomList(): 
+    val=5*math.sin(0.4*atom.GetPos().GetX())
+    atom.SetFloatProp("myfloatprop", val)
+  
+If a GenericProp at a given level (i.e. atom, bond, residue, chain or entity) 
+already exists, it will be overwritten. To check if it exists, use:
+
+.. code-block:: python
+  
+  exists=atom.HasProp("myfloatprop")
+  print exists
+    
+To access the value of a generic property, we first check if the property exists
+and then access it, using the method suitable for the data type of the property. 
+For the previously set property "myfloatprop" of the data type real, at the atom 
+level:
+
+.. code-block:: python
+  
+  for atom in entity.GetAtomList(): 
+    if atom.HasProp("myfloatprop"):
+      print atom.GetFloatProp("myfloatprop")
+        
+When trying to access a property that has not been set, or one that has been 
+set, but at a different level, an error is thrown. The same is true when trying 
+to access a property of a different data type, e.g.:
+
+.. code-block:: python
+
+  # all of the following lines will throw errors
+  # error because the property does not exist 
+  print atom.GetFloatProp("unknownprop")
+  
+  # error because the property was set at another level
+  print entity.GetFloatProp("myfloatprop")
+  
+  # error because the data type of the property is different
+  print atom.GetStringProp("myfloatprop")
+      
+
+Use of Generic Properties in Queries
+--------------------------------------------------------------------------------
+
+The :doc:`../mol/base/query` can also be used for numeric generic properties (i.e. bool, 
+int, float), but the syntax is slightly different. To access any generic 
+properties, it needs to be specified that they are generic and at which level 
+they are defined. Therefore, all generic properties start with a 'g', followed 
+by an 'a', 'r' or 'c' for atom, residue or chain level respectively. For more 
+details see :doc:`../mol/base/query`. 
+
+
+API documentation
+--------------------------------------------------------------------------------
+
+.. class:: GenericPropertyContainer
+
+  .. method:: HasProp(key)
+  
+    checks existence of property. Returns true, if the the class contains a
+    property with the given name, false if not.
+  
+  .. method:: GetPropAsString(key)
+  
+    Returns the string representation of a property, or the empty String if 
+    the property addressed by key does not exist. Note that this is not the 
+    same as trying to get a generic float/int/bool property as a string type; 
+    the latter will result in a boost:get exception. Use this method to obtain 
+    a representation suitable for output.
+    
+  .. method:: GetStringProp(key)
+              GetStringProp(key, default_value)
+  
+    Get string property. The first signature raises a GenericPropError error if
+    the property does not exist, the second returns the default value.
+  
+  
+  .. method:: GetFloatProp(key)
+              GetFloatProp(key, default_value)
+   
+    Get float property. The first signature raises a GenericPropError error if
+    the property does not exist, the second returns the default value.
+
+
+  .. method:: GetIntProp(key)
+              GetIntProp(key, default_value)
+
+    Get int property. The first signature raises a GenericPropError error if
+    the property does not exist, the second returns the default value.
+
+  .. method:: GetBoolProp(key)
+              GetBoolProp(key, default_value)
+
+    Get bool property. The first signature raises a GenericPropError error if
+    the property does not exist, the second returns the default value.
+        
+  .. method:: ClearProps()
+    
+    Remove all generic properties
+  
+ 
+  .. method:: SetStringProp(key, value)
+    
+    Set string property, overriding an existing property with the same name
+    
+  .. method:: SetFloatProp(key, value)
+    
+    Set float property, overriding an existing property with the same name
+
+  .. method:: SetIntProp(key, value)
+  
+    Set int property, overriding an existing property with the same name
+  
+  .. method:: SetBoolProp(key, value)
+  
+    Set bool property, overriding a property with the same name
+
diff --git a/modules/base/pymod/CMakeLists.txt b/modules/base/pymod/CMakeLists.txt
index 4eb36a914..22700288a 100644
--- a/modules/base/pymod/CMakeLists.txt
+++ b/modules/base/pymod/CMakeLists.txt
@@ -7,4 +7,4 @@ set(OST_BASE_PYMOD_SOURCES
 
 pymod(NAME base OUTPUT_DIR ost 
       CPP ${OST_BASE_PYMOD_SOURCES} 
-      PY __init__.py settings.py)
+      PY __init__.py settings.py stutil.py)
diff --git a/modules/base/pymod/__init__.py b/modules/base/pymod/__init__.py
index 3d2137f7e..aa723917b 100644
--- a/modules/base/pymod/__init__.py
+++ b/modules/base/pymod/__init__.py
@@ -17,6 +17,7 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 #------------------------------------------------------------------------------
 from _base import *
+from stutil import *
 
 from ost import geom
 from ost import io
diff --git a/modules/base/pymod/export_logger.cc b/modules/base/pymod/export_logger.cc
index b385742e7..deefb408c 100644
--- a/modules/base/pymod/export_logger.cc
+++ b/modules/base/pymod/export_logger.cc
@@ -39,7 +39,7 @@ void pop_verb()
   Logger::Instance().PopVerbosityLevel();
 }
 
-void log_error(const String& m) {LOGN_MESSAGE(m);}
+void log_error(const String& m) {LOGN_ERROR(m);}
 void log_message(const String& m) {LOGN_MESSAGE(m);}
 void log_verbose(const String& m) {LOGN_VERBOSE(m);}
 void log_debug(const String& m) {LOGN_DEBUG(m);}
diff --git a/modules/base/pymod/settings.py b/modules/base/pymod/settings.py
index 1740c3287..298149637 100644
--- a/modules/base/pymod/settings.py
+++ b/modules/base/pymod/settings.py
@@ -3,12 +3,13 @@ import __main__
  
 
 def GetValue(val_key,val_default=None,prefix='OST'):
-  '''
+  """
   Returns the value of the variable val_key if defined, otherwise returns the 
   default value provided by the user (if provided). Search order: 
-  1) environment variable called $prefix_$val_key 
-  2) variable called val_key in .dngrc file
-  '''
+  
+   * environment variable called $prefix_$val_key 
+   * variable called val_key in .ostrc file
+  """
   if prefix:
     env_var_name='%s_%s' % (prefix, val_key)
   else:
@@ -24,6 +25,12 @@ def GetValue(val_key,val_default=None,prefix='OST'):
       return val_default
 
 class FileNotFound(RuntimeError):
+  """
+  Raised when :func:`Locate` is unable to locate a file. The exception contains
+  detailed information on what was tried to locate the file, i.e. search paths, 
+  environment variables and also provides useful hints on how to let Locate know
+  where to find the file.
+  """
   def __init__(self, name, reason):
     self.name=name
     self.reason=reason
@@ -33,21 +40,23 @@ class FileNotFound(RuntimeError):
 def Locate(file_name, explicit_file_name=None, search_paths=[],
            env_name=None, search_system_paths=True):
   """
-  Helper function to locate files. To get the full name of 
-  an executable, let's say qmake, use
+  Helper function to locate files. To get the full name of an executable, let's 
+  say qmake, use
+  
+  .. code-block:: python
 
-  abs_qmake_path=Locate('qmake', env_name='QMAKE_EXECUTABLE')
+    abs_qmake_path=Locate('qmake', env_name='QMAKE_EXECUTABLE')
 
-  First the function checks if an environment variable with the
-  name QMAKE_EXECUTABLE is set. If so, the value of this variable
-  is returned. Next, each directory listed in search_paths is 
-  searched. If the executable could still not be found and
-  search_system_paths is set to True, the binary search paths are
-  searched.
+  First the function checks if an environment variable with the name 
+  QMAKE_EXECUTABLE is set. If so, the value of this variable is returned. Next, 
+  each directory listed in search_paths is searched. If the executable could 
+  still not be found and search_system_paths is set to True, the binary search 
+  paths are searched.
 
-  If the file could not be located, a FileNotFound exception will be raised
-  containing a detail description why Locate failed. The error message is
-  formatted in such a way that it can directly be presented to the user.
+  If the file could not be located, a :exc:`~ost.settings.FileNotFound` 
+  exception will be raised containing a detail description why Locate failed. The 
+  error message is formatted in such a way that it can directly be presented to 
+  the user.
   """
   if type(file_name) is str:
     file_names=[file_name]
diff --git a/modules/base/pymod/stutil.py b/modules/base/pymod/stutil.py
new file mode 100644
index 000000000..2f64beaef
--- /dev/null
+++ b/modules/base/pymod/stutil.py
@@ -0,0 +1,95 @@
+import math
+from ost import mol
+
+def FloatValueExtract(func):
+  """
+  Decorator to wrap functions that take a list of float values. In addition to 
+  passing in a list of float values directly, it is possible to extract the 
+  values from attributes or generic properties.
+  """
+  def _dec(xs, prop=None, attr=None):
+    if prop!=None:
+      if len(xs)==0:
+        return func([])
+      assert attr==None
+      level=mol.Prop.Level.UNSPECIFIED
+      if isinstance(xs[0], mol.AtomBase):
+        level=mol.Prop.Level.ATOM
+      elif isinstance(xs[0], mol.ResidueBase):
+        level=mol.Prop.Level.RESIDUE
+      elif isinstance(xs[0], mol.ChainBase):
+        level=mol.Prop.Level.CHAIN
+      epm=mol.EntityPropertyMapper(prop, level)
+      vals=[]
+      for x in xs:
+        try:
+          vals.append(epm.Get(x))
+        except:
+          pass
+      return func(vals)
+    if attr!=None:
+      vals=[]
+      for x in xs:
+        try:
+          vals.append(getattr(x, attr))
+        except:
+          pass
+      return func(vals)
+    return func(xs)
+  return _dec
+
+@FloatValueExtract  
+def Mean(xs):
+  """
+  Calculate mean of dataset
+  """
+  if len(xs)==0:
+    raise RuntimeError("Can't calculate mean of empty sequence")
+  return sum(xs)/len(xs)
+
+@FloatValueExtract
+def StdDev(xs):
+  """
+  Calculate standard-deviation of dataset
+  
+            | sum[xi-<x>]^2 |
+  sigma=sqrt|---------------|
+            |       n       |
+  """
+  mean=Mean(xs)
+  return math.sqrt(sum([(x-mean)**2 for x in xs])/len(xs))
+
+@FloatValueExtract
+def Min(xs):
+  return min(xs)
+
+@FloatValueExtract
+def Max(xs):
+  return max(xs)
+
+def Correl(xs, ys):
+  """
+  Calculates the correlation coefficient between xs and ys as
+  
+    sum[(xi-<x>)*(yi-<y>)]
+  r=----------------------
+          (n-1)*sx*sy
+          
+  where <x>, <y> are the mean of dataset xs and ys, and, sx and sy are the 
+  standard deviations.
+  """
+  if len(xs)!=len(ys):
+    raise RuntimeError("Can't calculate correl. Sequence lengths do not match.")
+  if len(xs)==1:
+    raise RuntimeError("Can't calculate correl of sequences with length 1.")
+  mean_x=Mean(xs)
+  mean_y=Mean(ys)
+  sigma_x, sigma_y=(0.0, 0.0)
+  cross_term=0.0
+  for x, y in zip(xs, ys):
+    cross_term+=(x-mean_x)*(y-mean_y)
+    sigma_x+=(x-mean_x)**2
+    sigma_y+=(y-mean_y)**2
+  sigma_x=math.sqrt(sigma_x/len(xs))
+  sigma_y=math.sqrt(sigma_y/len(ys))  
+  return cross_term/((len(xs)-1)*sigma_x*sigma_y)
diff --git a/modules/base/pymod/wrap_base.cc b/modules/base/pymod/wrap_base.cc
index c3dd609ec..13bc81155 100644
--- a/modules/base/pymod/wrap_base.cc
+++ b/modules/base/pymod/wrap_base.cc
@@ -20,6 +20,7 @@
 
 #include <boost/python.hpp>
 #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
+#include <ost/export_helper/vector.hh>
 #include <ost/base.hh>
 #include <ost/platform.hh>
 
@@ -38,8 +39,19 @@ BOOST_PYTHON_MODULE(_base)
   export_Logger();
   export_Range();
   export_Units();
+  typedef std::vector<float> FloatList;
+  class_<FloatList>("FloatList", init<>())
+    .def(vector_indexing_suite<FloatList>())
+    .def(ost::VectorAdditions<FloatList>())
+  ;
   
   class_<std::vector<String> >("StringList", init<>())
     .def(vector_indexing_suite<std::vector<String> >())
+  ;
+  
+  typedef std::vector<int> IntList;
+  class_<std::vector<int> >("IntList", init<>())
+    .def(vector_indexing_suite<std::vector<int> >())
+    .def(ost::VectorAdditions<IntList>())
   ;  
 }
diff --git a/modules/base/src/CMakeLists.txt b/modules/base/src/CMakeLists.txt
index ecdc389db..3ca08186a 100644
--- a/modules/base/src/CMakeLists.txt
+++ b/modules/base/src/CMakeLists.txt
@@ -1,13 +1,12 @@
 set(OST_BASE_SOURCES 
 generic_property.cc
-invalid_handle.cc
-integrity_error.cc
 log.cc
 profile.cc
 units.cc
 string_ref.cc
 platform.cc
 message.cc
+test_utils/compare_files.cc
 )
 
 set(OST_BASE_HEADERS
@@ -31,8 +30,14 @@ fixed_string.hh
 tri_matrix.hh
 )
 
+set(OST_EXPORT_HELPERS
+generic_property_def.hh 
+pair_to_tuple_conv.hh 
+vector.hh
+)
 module(NAME base SOURCES ${OST_BASE_SOURCES} 
-       HEADERS generic_property_def.hh IN_DIR export_helper ${OST_BASE_HEADERS}
+       HEADERS ${OST_EXPORT_HELPERS} IN_DIR export_helper 
+       compare_files.hh IN_DIR test_utils ${OST_BASE_HEADERS}
        DEPENDS_ON geom
        HEADER_OUTPUT_DIR ost)
 
diff --git a/modules/base/src/export_helper/pair_to_tuple_conv.hh b/modules/base/src/export_helper/pair_to_tuple_conv.hh
new file mode 100644
index 000000000..eba6ebd9b
--- /dev/null
+++ b/modules/base/src/export_helper/pair_to_tuple_conv.hh
@@ -0,0 +1,37 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#include <boost/python.hpp>
+
+namespace ost {
+
+/// \brief helper to convert between python tuple and std::pair
+/// 
+/// Usage:
+/// 
+/// register_to_python_converter<PairToTupleConverter<T1, T2>, 
+///                              std::pair<T1, T2>>()
+template<class T1, class T2>
+struct PairToTupleConverter {
+  static PyObject* convert(const std::pair<T1, T2>& pair) {
+    boost::python::tuple t=boost::python::make_tuple<T1,T2>(pair.first,
+                                                            pair.second);
+    return boost::python::incref(t.ptr());
+  }
+};
+}
\ No newline at end of file
diff --git a/modules/base/src/export_helper/vector.hh b/modules/base/src/export_helper/vector.hh
new file mode 100644
index 000000000..0b262bf55
--- /dev/null
+++ b/modules/base/src/export_helper/vector.hh
@@ -0,0 +1,46 @@
+#ifndef OST_EXPORT_HELPER_VECTOR_HH
+#define OST_EXPORT_HELPER_VECTOR_HH
+
+# include <boost/python/def_visitor.hpp>
+
+/*
+  Author: Marco Biasini
+ */
+
+namespace ost {
+
+
+template <typename Container>
+class VectorAdditions : 
+  public boost::python::def_visitor<VectorAdditions<Container> > {
+public:
+ template <class Class>
+ void visit(Class& cl) const
+ {
+   cl
+     .def("__str__", &to_string)
+   ;
+ }
+private:
+  static std::string to_string(Container& cl)
+  {
+    std::stringstream ss;
+    ss << "[";
+    bool first=true;
+    for (typename Container::const_iterator
+         i=cl.begin(), e=cl.end(); i!=e; ++i) {
+      if (first) {
+        first=false;
+      } else {
+        ss << ", ";
+      }
+      ss << (*i);
+    }
+    ss << "]";
+    return ss.str();
+  }
+};
+
+}
+
+#endif
diff --git a/modules/base/src/integrity_error.hh b/modules/base/src/integrity_error.hh
index 45c4e263c..ba3271fae 100644
--- a/modules/base/src/integrity_error.hh
+++ b/modules/base/src/integrity_error.hh
@@ -25,9 +25,11 @@
 
 namespace ost {
 
-class DLLEXPORT_OST_BASE IntegrityError : public Error {
+class DLLEXPORT IntegrityError : public Error {
 public:
-  IntegrityError(const String& msg);  
+  IntegrityError(const String& msg):
+    Error(msg)
+  { } 
 };
 
 }
diff --git a/modules/base/src/invalid_handle.hh b/modules/base/src/invalid_handle.hh
index 03814ef7b..fdb56203e 100644
--- a/modules/base/src/invalid_handle.hh
+++ b/modules/base/src/invalid_handle.hh
@@ -27,9 +27,11 @@
 namespace ost {
 
 /// \brief Signals access of member functions of invalid handles
-class DLLEXPORT_OST_BASE InvalidHandle : public Error {
+class DLLEXPORT InvalidHandle : public Error {
 public:
-  InvalidHandle();
+  InvalidHandle()
+    : Error("Can not access invalid handle or view") 
+  {}
 }; 
 
 template <typename H>
diff --git a/modules/base/src/pod_vector.hh b/modules/base/src/pod_vector.hh
index 34a7299e9..a4da274b7 100644
--- a/modules/base/src/pod_vector.hh
+++ b/modules/base/src/pod_vector.hh
@@ -34,7 +34,7 @@ namespace ost {
 /// \brief vector container that treats its data as POD - even if it isn't in 
 ///      the strict sense.
 template <typename T>
-class DLLEXPORT_OST_BASE PodVector {
+class TEMPLATE_DEF_EXPORT PodVector {
 public:
   PodVector(): begin_(NULL), end_(NULL), capacity_(NULL) {}
   typedef T value_type;
diff --git a/modules/base/src/test_utils/compare_files.cc b/modules/base/src/test_utils/compare_files.cc
new file mode 100644
index 000000000..762439021
--- /dev/null
+++ b/modules/base/src/test_utils/compare_files.cc
@@ -0,0 +1,55 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+#include <iostream>
+#include <fstream>
+#include "compare_files.hh"
+
+namespace ost {
+bool compare_files(const String& test, const String& gold_standard)
+{
+  std::ifstream test_stream(test.c_str());
+  std::ifstream gold_stream(gold_standard.c_str());
+  String test_line, gold_line;
+  while (true) {
+    bool test_end=std::getline(test_stream, test_line) != 0;
+    bool gold_end=std::getline(gold_stream, gold_line) != 0;
+    if (!(test_end || gold_end)) {
+      return true;
+    }
+    if (!test_end) {
+      std::cerr << gold_standard << " contains additional line(s):"
+                << std::endl << gold_line;
+      return false;
+    }
+    if (!gold_end) {
+      std::cerr << test << " contains additional line(s):"
+                << std::endl << test_line;
+      return false;
+    }
+    if (gold_line!=test_line) {
+      std::cerr << "line mismatch:" << std::endl << "test: " << test_line
+                << std::endl << "gold: " << gold_line;
+      return false;
+    }
+  }
+  return true;
+}
+
+}
diff --git a/modules/base/src/invalid_handle.cc b/modules/base/src/test_utils/compare_files.hh
similarity index 80%
rename from modules/base/src/invalid_handle.cc
rename to modules/base/src/test_utils/compare_files.hh
index 86a631ad5..8944e0805 100644
--- a/modules/base/src/invalid_handle.cc
+++ b/modules/base/src/test_utils/compare_files.hh
@@ -16,15 +16,18 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
-#include <ost/message.hh>
 
-#include "invalid_handle.hh"
+#ifndef OST_COMPARE_FILES_HH
+#define OST_COMPARE_FILES_HH
+
+#include <ost/base.hh>
+#include <ost/module_config.hh>
 
 namespace ost {
 
-InvalidHandle::InvalidHandle()
-  : Error("Can not access invalid handle or view") {
-    
+bool DLLEXPORT_OST_BASE compare_files(const String& test, 
+                                      const String& gold_standard);  
 }
 
-}
+
+#endif
diff --git a/modules/bindings/pymod/msms.py b/modules/bindings/pymod/msms.py
index a7a3dd13e..7f9e089ff 100644
--- a/modules/bindings/pymod/msms.py
+++ b/modules/bindings/pymod/msms.py
@@ -144,7 +144,10 @@ def CalculateSurfaceArea(entity, density=1.0, radius=1.5,  all_surf=False,
 
   # parse selection
   if no_hydrogens:
-    selection+=" and ele!=H"
+    if selection=="":
+      selection="ele!=H"
+    else:
+      selection+=" and ele!=H"
 
   # setup files for msms
   (msms_data_dir, msms_data_file)=_SetupFiles(entity, selection)
@@ -215,7 +218,10 @@ def CalculateSurface(entity, density=1.0, radius=1.5, all_surf=False,
 
   # parse selection
   if no_hydrogens:
-    selection+=" and ele!=H"
+    if selection=="":
+      selection="ele!=H"
+    else:
+      selection+=" and ele!=H"
 
   # setup files for msms
   
diff --git a/modules/bindings/tests/test_msms.py b/modules/bindings/tests/test_msms.py
index 54c1ab5b8..8cd56ee5a 100755
--- a/modules/bindings/tests/test_msms.py
+++ b/modules/bindings/tests/test_msms.py
@@ -32,4 +32,7 @@ if __name__ == "__main__":
   except(settings.FileNotFound):
     print "Could not find msms executable: ignoring unit tests"
     exit(0)
-  unittest.main()
+  try:
+    unittest.main()
+  except Exception, e:
+    print e
diff --git a/modules/config/CMakeLists.txt b/modules/config/CMakeLists.txt
index e8f153cff..ddf076511 100644
--- a/modules/config/CMakeLists.txt
+++ b/modules/config/CMakeLists.txt
@@ -55,3 +55,4 @@ configure_file(config.hh.in ${CONFIG_HH_FILE})
 add_custom_target(ost_config)
 stage_headers("${OST_CONFIG_HEADERS}" "ost" 
               "ost_config" "" "ost")
+install(FILES ${OST_CONFIG_HEADERS} DESTINATION include/ost)
diff --git a/modules/config/base.hh b/modules/config/base.hh
index 2e279e89d..d119fb8ce 100644
--- a/modules/config/base.hh
+++ b/modules/config/base.hh
@@ -80,7 +80,7 @@ inline Real rint(Real d)
 #pragma warning(disable:4244)
 #pragma warning(disable:4231)
 #pragma warning(disable:4305)
-
+#pragma warning(disable:4351) // turn off "new behavior ... will be default initialized" warning 
 
 #ifndef log2_function
 #define log2_function
diff --git a/modules/conop/doc/conop.rst b/modules/conop/doc/conop.rst
index fb65ee1ad..a7ebe2eaa 100644
--- a/modules/conop/doc/conop.rst
+++ b/modules/conop/doc/conop.rst
@@ -1,7 +1,7 @@
-:mod:`conop` -- Connectivity and Topology of Molecules
+:mod:`~ost.conop` -- Connectivity and Topology of Molecules
 ================================================================================
 
-.. module:: conop
+.. module:: ost.conop
    :synopsis: The conop modules implement different strategies to derive
                connectivity information of molecules.
 
diff --git a/modules/conop/src/chemdict_tool.cc b/modules/conop/src/chemdict_tool.cc
index 79b36b7b1..865425d8c 100644
--- a/modules/conop/src/chemdict_tool.cc
+++ b/modules/conop/src/chemdict_tool.cc
@@ -140,12 +140,23 @@ public:
       } else if (item.GetName()==StringRef("pdbx_modified_date", 18)) {
         compound_->SetModificationDate(conop::Date::FromString(item.GetValue()));
       }
+    } else if (item.GetName()==StringRef("atom_id", 7)) {
+      atom_.name=item.GetValue().str();
+    } else if (item.GetName()==StringRef("alt_atom_id", 11)) {
+      atom_.alt_name=item.GetValue().str();
+    } else if (item.GetName()==StringRef("type_symbol", 11)) {
+      atom_.element=item.GetValue().str();
+    } else if (item.GetName()==StringRef("pdbx_ordinal", 12)) {
+      atom_.ordinal=item.GetValue().to_int().second-1;
     }
   }
   
   virtual void OnEndData()
   {
     if (insert_) {
+      if (compound_->GetAtomSpecs().empty()) {
+        compound_->AddAtom(atom_);
+      }
       lib_->AddCompound(compound_);      
     }
   }
@@ -176,6 +187,7 @@ private:
   static std::map<String, mol::ChemClass> tm_;  
   std::map<String, int>                   atom_map_;
   LoopType                                loop_type_;  
+  conop::AtomSpec                         atom_;
 };
 
 std::map<String, mol::ChemClass> ChemDictParser::tm_=std::map<String, mol::ChemClass>();
diff --git a/modules/conop/src/compound_lib.cc b/modules/conop/src/compound_lib.cc
index 073ea0606..a5c9ad1a7 100644
--- a/modules/conop/src/compound_lib.cc
+++ b/modules/conop/src/compound_lib.cc
@@ -256,7 +256,7 @@ void CompoundLib::LoadAtomsFromDB(CompoundPtr comp, int pk) {
         atom_sp.alt_name=String(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)));        
         atom_sp.element=String(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2))); 
         atom_sp.ordinal=sqlite3_column_int(stmt, 3);  
-        atom_sp.is_leaving=bool(sqlite3_column_int(stmt, 4));
+        atom_sp.is_leaving=bool(sqlite3_column_int(stmt, 4)!=0);
         comp->AddAtom(atom_sp);
       }
   }
diff --git a/modules/conop/src/conop.cc b/modules/conop/src/conop.cc
index e634b6a73..3267e83e0 100644
--- a/modules/conop/src/conop.cc
+++ b/modules/conop/src/conop.cc
@@ -41,28 +41,28 @@ Conopology::Conopology():
   builder_map_["DEFAULT"]=builder_map_["HEURISTIC"];
 
   ele_rad_map_["H"]  = 1.09;
-
+                 
   ele_rad_map_["C"]  = 1.75;
   ele_rad_map_["N"]  = 1.55;
   ele_rad_map_["O"]  = 1.52;
   ele_rad_map_["F"]  = 1.47;
-
-  ele_rad_map_["Na"] = 2.27;
-  ele_rad_map_["Mg"] = 1.73;
-  ele_rad_map_["Si"] = 2.10;
+                 
+  ele_rad_map_["NA"] = 2.27;
+  ele_rad_map_["MG"] = 1.73;
+  ele_rad_map_["SI"] = 2.10;
   ele_rad_map_["P"]  = 1.80;
   ele_rad_map_["S"]  = 1.80;
-  ele_rad_map_["Cl"] = 1.75;
-
+  ele_rad_map_["CL"] = 1.75;
+                 
   ele_rad_map_["K"]  = 2.75;
-  ele_rad_map_["Ca"] = 2.00;
-  ele_rad_map_["Mn"] = 2.00;
-  ele_rad_map_["Fe"] = 2.00;
-  ele_rad_map_["Co"] = 2.00;
-  ele_rad_map_["Ni"] = 1.63;
-  ele_rad_map_["Cu"] = 1.40;
-  ele_rad_map_["Zn"] = 1.39;
-  ele_rad_map_["Br"] = 1.85;
+  ele_rad_map_["CA"] = 2.00;
+  ele_rad_map_["MN"] = 2.00;
+  ele_rad_map_["FE"] = 2.00;
+  ele_rad_map_["CO"] = 2.00;
+  ele_rad_map_["NI"] = 1.63;
+  ele_rad_map_["CU"] = 1.40;
+  ele_rad_map_["ZN"] = 1.39;
+  ele_rad_map_["BR"] = 1.85;
 
   ele_rad_map_["I"]  = 1.98;
 
@@ -70,122 +70,122 @@ Conopology::Conopology():
   // Element masses according to IUPAC standards
   // see http://www.chem.qmul.ac.uk/iupac/AtWt/
   ele_mass_map_["H"]  = 1.00794;
-  ele_mass_map_["He"] = 4.002602;
-  ele_mass_map_["Li"] = 6.941;
-  ele_mass_map_["Be"] = 9.012182;
+  ele_mass_map_["HE"] = 4.002602;
+  ele_mass_map_["LI"] = 6.941;
+  ele_mass_map_["BE"] = 9.012182;
   ele_mass_map_["B"]  = 10.811;
   ele_mass_map_["C"]  = 12.0107;
   ele_mass_map_["N"]  = 14.0067;
   ele_mass_map_["O"]  = 15.9994;
   ele_mass_map_["F"]  = 18.9984032;
-  ele_mass_map_["Ne"] = 20.1797;
-  ele_mass_map_["Na"] = 22.98976928;
-  ele_mass_map_["Mg"] = 24.3050;
-  ele_mass_map_["Al"] = 26.9815386;
-  ele_mass_map_["Si"] = 28.0855;
+  ele_mass_map_["NE"] = 20.1797;
+  ele_mass_map_["NA"] = 22.98976928;
+  ele_mass_map_["MG"] = 24.3050;
+  ele_mass_map_["AL"] = 26.9815386;
+  ele_mass_map_["SI"] = 28.0855;
   ele_mass_map_["P"]  = 30.973762;
   ele_mass_map_["S"]  = 32.065;
-  ele_mass_map_["Cl"] = 35.453;
-  ele_mass_map_["Ar"] = 39.948;
+  ele_mass_map_["CL"] = 35.453;
+  ele_mass_map_["AR"] = 39.948;
   ele_mass_map_["K"]  = 39.0983;
-  ele_mass_map_["Ca"] = 40.078;
-  ele_mass_map_["Sc"] = 44.955912;
-  ele_mass_map_["Ti"] = 47.867;
+  ele_mass_map_["CA"] = 40.078;
+  ele_mass_map_["SC"] = 44.955912;
+  ele_mass_map_["TI"] = 47.867;
   ele_mass_map_["V"]  = 50.9415;
-  ele_mass_map_["Cr"] = 51.9961;
-  ele_mass_map_["Mn"] = 54.938045;
-  ele_mass_map_["Fe"] = 55.845;
-  ele_mass_map_["Co"] = 58.933195;
-  ele_mass_map_["Ni"] = 58.6934;
-  ele_mass_map_["Cu"] = 63.546;
-  ele_mass_map_["Zn"] = 65.38;
-  ele_mass_map_["Ga"] = 69.723;
-  ele_mass_map_["Ge"] = 72.64;
-  ele_mass_map_["As"] = 74.92160;
-  ele_mass_map_["Se"] = 78.96;
-  ele_mass_map_["Br"] = 79.904;
-  ele_mass_map_["Kr"] = 83.798;
-  ele_mass_map_["Rb"] = 85.4678;
-  ele_mass_map_["Sr"] = 87.62;
+  ele_mass_map_["CR"] = 51.9961;
+  ele_mass_map_["MN"] = 54.938045;
+  ele_mass_map_["FE"] = 55.845;
+  ele_mass_map_["CO"] = 58.933195;
+  ele_mass_map_["NI"] = 58.6934;
+  ele_mass_map_["CU"] = 63.546;
+  ele_mass_map_["ZN"] = 65.38;
+  ele_mass_map_["GA"] = 69.723;
+  ele_mass_map_["GE"] = 72.64;
+  ele_mass_map_["AS"] = 74.92160;
+  ele_mass_map_["SE"] = 78.96;
+  ele_mass_map_["BR"] = 79.904;
+  ele_mass_map_["KR"] = 83.798;
+  ele_mass_map_["RB"] = 85.4678;
+  ele_mass_map_["SR"] = 87.62;
   ele_mass_map_["Y"]  = 88.90585;
-  ele_mass_map_["Zr"] = 91.224;
-  ele_mass_map_["Nb"] = 92.90638;
-  ele_mass_map_["Mo"] = 95.96;
-  ele_mass_map_["Tc"] = 98.0;
-  ele_mass_map_["Ru"] = 101.07;
-  ele_mass_map_["Rh"] = 102.90550;
-  ele_mass_map_["Pd"] = 106.42;
-  ele_mass_map_["Ag"] = 107.8682;
-  ele_mass_map_["Cd"] = 112.411;
-  ele_mass_map_["In"] = 114.818;
-  ele_mass_map_["Sn"] = 118.710;
-  ele_mass_map_["Sb"] = 121.760;
-  ele_mass_map_["Te"] = 127.60;
+  ele_mass_map_["ZR"] = 91.224;
+  ele_mass_map_["NB"] = 92.90638;
+  ele_mass_map_["MO"] = 95.96;
+  ele_mass_map_["TC"] = 98.0;
+  ele_mass_map_["RU"] = 101.07;
+  ele_mass_map_["RH"] = 102.90550;
+  ele_mass_map_["PD"] = 106.42;
+  ele_mass_map_["AG"] = 107.8682;
+  ele_mass_map_["CD"] = 112.411;
+  ele_mass_map_["IN"] = 114.818;
+  ele_mass_map_["SN"] = 118.710;
+  ele_mass_map_["SB"] = 121.760;
+  ele_mass_map_["TE"] = 127.60;
   ele_mass_map_["I"]  = 126.90447;
-  ele_mass_map_["Xe"] = 131.293;
-  ele_mass_map_["Cs"] = 132.9054519;
-  ele_mass_map_["Ba"] = 137.327;
-  ele_mass_map_["La"] = 138.90547;
-  ele_mass_map_["Ce"] = 140.116;
-  ele_mass_map_["Pr"] = 140.90765;
-  ele_mass_map_["Nd"] = 144.242;
-  ele_mass_map_["Pm"] = 145.0;
-  ele_mass_map_["Sm"] = 150.36;
-  ele_mass_map_["Eu"] = 151.964;
-  ele_mass_map_["Gd"] = 157.25;
-  ele_mass_map_["Tb"] = 158.92535;
-  ele_mass_map_["Dy"] = 162.500;
-  ele_mass_map_["Ho"] = 164.93032;
-  ele_mass_map_["Er"] = 167.259;
-  ele_mass_map_["Tm"] = 168.93421;
-  ele_mass_map_["Yb"] = 173.054;
-  ele_mass_map_["Lu"] = 174.9668;
-  ele_mass_map_["Hf"] = 178.49;
-  ele_mass_map_["Ta"] = 180.94788;
+  ele_mass_map_["XE"] = 131.293;
+  ele_mass_map_["CS"] = 132.9054519;
+  ele_mass_map_["BA"] = 137.327;
+  ele_mass_map_["LA"] = 138.90547;
+  ele_mass_map_["CE"] = 140.116;
+  ele_mass_map_["PR"] = 140.90765;
+  ele_mass_map_["ND"] = 144.242;
+  ele_mass_map_["PM"] = 145.0;
+  ele_mass_map_["SM"] = 150.36;
+  ele_mass_map_["EU"] = 151.964;
+  ele_mass_map_["GD"] = 157.25;
+  ele_mass_map_["TB"] = 158.92535;
+  ele_mass_map_["DY"] = 162.500;
+  ele_mass_map_["HO"] = 164.93032;
+  ele_mass_map_["ER"] = 167.259;
+  ele_mass_map_["TM"] = 168.93421;
+  ele_mass_map_["YB"] = 173.054;
+  ele_mass_map_["LU"] = 174.9668;
+  ele_mass_map_["HF"] = 178.49;
+  ele_mass_map_["TA"] = 180.94788;
   ele_mass_map_["W"]  = 183.84;
-  ele_mass_map_["Re"] = 186.207;
-  ele_mass_map_["Os"] = 190.23;
-  ele_mass_map_["Ir"] = 192.217;
-  ele_mass_map_["Pt"] = 195.084;
-  ele_mass_map_["Au"] = 196.966569;
-  ele_mass_map_["Hg"] = 200.59;
-  ele_mass_map_["Tl"] = 204.3833;
-  ele_mass_map_["Pb"] = 207.2;
-  ele_mass_map_["Bi"] = 208.98040;
-  ele_mass_map_["Po"] = 209.0;
-  ele_mass_map_["At"] = 210.0;
-  ele_mass_map_["Rn"] = 222.0;
-  ele_mass_map_["Fr"] = 223.0;
-  ele_mass_map_["Ra"] = 226.0;
-  ele_mass_map_["Ac"] = 227.0;
-  ele_mass_map_["Th"] = 232.03806;
-  ele_mass_map_["Pa"] = 231.03588;
+  ele_mass_map_["RE"] = 186.207;
+  ele_mass_map_["OS"] = 190.23;
+  ele_mass_map_["IR"] = 192.217;
+  ele_mass_map_["PT"] = 195.084;
+  ele_mass_map_["AU"] = 196.966569;
+  ele_mass_map_["HG"] = 200.59;
+  ele_mass_map_["TL"] = 204.3833;
+  ele_mass_map_["PB"] = 207.2;
+  ele_mass_map_["BI"] = 208.98040;
+  ele_mass_map_["PO"] = 209.0;
+  ele_mass_map_["AT"] = 210.0;
+  ele_mass_map_["RN"] = 222.0;
+  ele_mass_map_["FR"] = 223.0;
+  ele_mass_map_["RA"] = 226.0;
+  ele_mass_map_["AC"] = 227.0;
+  ele_mass_map_["TH"] = 232.03806;
+  ele_mass_map_["PA"] = 231.03588;
   ele_mass_map_["U"]  = 238.02891;
-  ele_mass_map_["Np"] = 237.0;
-  ele_mass_map_["Pu"] = 244.0;
-  ele_mass_map_["Am"] = 243.0;
-  ele_mass_map_["Cm"] = 247.0;
-  ele_mass_map_["Bk"] = 247.0;
-  ele_mass_map_["Cf"] = 251.0;
-  ele_mass_map_["Es"] = 252.0;
-  ele_mass_map_["Fm"] = 257.0;
-  ele_mass_map_["Md"] = 258.0;
-  ele_mass_map_["No"] = 259.0;
-  ele_mass_map_["Lr"] = 262.0;
-  ele_mass_map_["Rf"] = 267.0;
-  ele_mass_map_["Db"] = 268.0;
-  ele_mass_map_["Sg"] = 271.0;
-  ele_mass_map_["Bh"] = 272.0;
-  ele_mass_map_["Hs"] = 270.0;
-  ele_mass_map_["Mt"] = 276.0;
-  ele_mass_map_["Ds"] = 281.0;
-  ele_mass_map_["Rg"] = 280.0;
-  ele_mass_map_["Cn"] = 285.0;
-  ele_mass_map_["Uut"]= 284.0;
-  ele_mass_map_["Uuq"]= 289.0;
-  ele_mass_map_["Uup"]= 288.0;
-  ele_mass_map_["Uuh"]= 293.0;
-  ele_mass_map_["Uuo"]= 294.0;  
+  ele_mass_map_["NP"] = 237.0;
+  ele_mass_map_["PU"] = 244.0;
+  ele_mass_map_["AM"] = 243.0;
+  ele_mass_map_["CM"] = 247.0;
+  ele_mass_map_["BK"] = 247.0;
+  ele_mass_map_["CF"] = 251.0;
+  ele_mass_map_["ES"] = 252.0;
+  ele_mass_map_["FM"] = 257.0;
+  ele_mass_map_["MD"] = 258.0;
+  ele_mass_map_["NO"] = 259.0;
+  ele_mass_map_["LR"] = 262.0;
+  ele_mass_map_["RF"] = 267.0;
+  ele_mass_map_["DB"] = 268.0;
+  ele_mass_map_["SG"] = 271.0;
+  ele_mass_map_["BH"] = 272.0;
+  ele_mass_map_["HS"] = 270.0;
+  ele_mass_map_["MT"] = 276.0;
+  ele_mass_map_["DS"] = 281.0;
+  ele_mass_map_["RG"] = 280.0;
+  ele_mass_map_["CN"] = 285.0;
+  ele_mass_map_["UUT"]= 284.0;
+  ele_mass_map_["UUQ"]= 289.0;
+  ele_mass_map_["UUP"]= 288.0;
+  ele_mass_map_["UUH"]= 293.0;
+  ele_mass_map_["UUO"]= 294.0;  
 }
 
 void Conopology::RegisterBuilder(const BuilderP& b, const String& name) {
@@ -294,13 +294,18 @@ void Conopology::ConnectAll(const BuilderP& b, mol::EntityHandle eh, int flag)
 
 Real Conopology::GetDefaultAtomRadius(const String& element) const
 {
-  std::map<String,Real>::const_iterator it = ele_rad_map_.find(element);
+  String upper_ele=element;
+  std::transform(upper_ele.begin(),upper_ele.end(),upper_ele.begin(),toupper);  
+  std::map<String,Real>::const_iterator it = ele_rad_map_.find(upper_ele);
   return it==ele_rad_map_.end() ? 1.5 : it->second;
 }
 
 Real Conopology::GetDefaultAtomMass(const String& element) const
 {
-  std::map<String,Real>::const_iterator it = ele_mass_map_.find(element);
+  String upper_ele=element;
+  std::transform(upper_ele.begin(),upper_ele.end(),upper_ele.begin(),toupper);  
+  
+  std::map<String,Real>::const_iterator it = ele_mass_map_.find(upper_ele);
   return it==ele_mass_map_.end() ? 1.0 : it->second;
 }
 
diff --git a/modules/conop/src/heuristic_builder.cc b/modules/conop/src/heuristic_builder.cc
index 5c27610ea..644771764 100644
--- a/modules/conop/src/heuristic_builder.cc
+++ b/modules/conop/src/heuristic_builder.cc
@@ -418,7 +418,13 @@ void HeuristicBuilder::FillResidueProps(mol::ResidueHandle residue) {
     residue.SetChemClass(mol::ChemClass(ret.first.GetChemClass()));
     residue.SetOneLetterCode(ret.first.GetOneLetterCode());    
   } else {
-    residue.SetChemClass(mol::ChemClass(mol::ChemClass::Unknown));
+    if (residue.FindAtom("N") && residue.FindAtom("CA") && 
+        residue.FindAtom("C") && residue.FindAtom("O")) {
+      residue.SetChemClass(mol::ChemClass(mol::ChemClass::LPeptideLinking));
+    } else {
+      residue.SetChemClass(mol::ChemClass(mol::ChemClass::Unknown));
+    }
+
     residue.SetOneLetterCode('?');
   }
 
diff --git a/modules/doc/external.rst b/modules/doc/external.rst
new file mode 100644
index 000000000..7ea3b22db
--- /dev/null
+++ b/modules/doc/external.rst
@@ -0,0 +1,111 @@
+Using External Programs within OpenStructure
+================================================================================
+
+Introduction
+--------------------------------------------------------------------------------
+
+It is often very useful to use external programs to do a specific task. In principle, this can be done by writing out files from OpenStructure and manually running an external program, however, for convenience, this can also be done directly from within OpenStructure using Python commands. 
+
+This tutorial will give you some hints how to do this for a new external program. The process basically consists of four steps:
+
+  * locate the executable of the external program
+  * prepare all necessary files
+  * execute the external program from python
+  * read in generated output
+
+
+Locating the Executable
+--------------------------------------------------------------------------------
+
+There is a helper function available to locate files, and especially executables: :func:`~ost.settings.Locate`. Using this, you can obtain the full path of an executable.
+
+As an example, we would like to obtain the full path of the msms executable (a program to calculate molecular surfaces):
+
+.. code-block:: python
+
+  from ost import settings
+  exe_path=settings.Locate('msms', search_paths=['/opt/app','/home/app'],
+              env_name='MSMS', search_system_paths=True)
+  print exe_path
+  
+The :func:`~ost.settings.Locate` command looks for the program with the name 
+`msms`. If env_name is set, it first looks if an environment variable with the 
+name `MSMS` is set. If not, all paths in search_paths are searched. If the 
+executable could still not be found and search_system_paths is set to True, the 
+binary search paths are searched. If the executable could not be found, a 
+:exc:`~ost.FileNotFound` exception is raised with a detailed description where 
+Locate was searching for the executable.
+    
+Prepare All Files
+--------------------------------------------------------------------------------
+
+The preparation of the necessary files is very dependent on the external program. Often it is useful to generate a temporary directory or file. For this, the python module tempfile is very handy.
+
+An example how to generate a temporary directory, open a file in this directory and write the position and radius of all atoms into this file is shown here:
+
+.. code-block:: python
+
+  import tempfile
+  import os
+  
+  # generate a temporary directory
+  tmp_dir_name=tempfile.mkdtemp()
+  print 'temporary directory:',tmp_dir_name
+  
+  # generate and open a file in the temp directory
+  tmp_file_name=os.path.join(tmp_dir_name,"entity")
+  tmp_file_handle=open(tmp_file_name, 'w')
+  print 'temporary file:',tmp_file_handle
+  
+  # write position and radius of all atoms to file
+  for a in entity.GetAtomList():
+    position=a.GetPos()
+    tmp_file_handle.write('%8.3f %8.3f %8.3f %4.2f\n' % (position[0],
+                          position[1], position[2], a.GetProp().radius))
+                          
+  # close the file
+  tmp_file_handle.close()
+
+Execute the External Program
+--------------------------------------------------------------------------------
+
+The external program can be executed from python using the python module subprocess.
+
+To run the external program msms from the above example, with the temporary file generated before, we can use the following:
+
+.. code-block:: python
+
+  import subprocess
+
+  # set the command to execute
+  command="%s -if %s -of %s" % (exe_path,
+            tmp_file_name, tmp_file_name)
+  print 'command:',command
+
+  # run the executable with the command
+  proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+  stdout_value, stderr_value = proc.communicate()
+
+  #check for successful completion of msms
+  if proc.returncode!=0:
+    print "WARNING: msms error\n", stdout_value
+    raise subprocess.CalledProcessError(proc.returncode, command)
+
+  # print everything written to the command line (stdout)
+  print stdout_value
+    
+Read Generated Output
+--------------------------------------------------------------------------------
+
+The last step includes reading of generated files (like in the case of msms) and/or processing of the generated command line output.
+
+Here we first print the command line output and then load the generated msms surface and print the number of vertex points:
+
+.. code-block:: python
+
+  # print everything written to the command line (stdout)
+  print stdout_value
+  
+  # read msms surface from file
+  surface=io.LoadSurface(tmp_file_name, "msms")
+  print 'number of vertices:',len(surface.GetVertexIDList())
diff --git a/modules/doc/install.rst b/modules/doc/install.rst
new file mode 100644
index 000000000..86c10f7c5
--- /dev/null
+++ b/modules/doc/install.rst
@@ -0,0 +1,108 @@
+Installing OpenStructure
+================================================================================
+
+This document describes how to install OpenStructure from source. If you are not planning to develop code for OpenStructure, you might be better off with one of the binaries available for download.
+
+Installing the Dependencies
+--------------------------------------------------------------------------------
+
+OpenStructure uses a bunch of OpenSource libraries. If you haven't already installed them, please install them now!
+
+ * `CMake <http://cmake.org>`_
+ * `Eigen2 <http://eigen.tuxfamily.org>`_
+ * `Boost <http://boost.org>`_
+ * `libpng <http://www.libpng.org>`_
+ * `Python <http://python.org>`_
+ * `Qt <http://qt.nokia.com>`_
+
+When you enable support for image processing, you will need:
+
+ * `FFTW3 <http://fftw.org>`_. By default, OpenStructure is compiled with single precision and thus also requires FFTW to be compiled with single precision. Most platforms offer this as a second package. If you are compiling manually, use the `--enable-single` option.
+
+ * `libtiff <http://www.libtiff.org>`_
+
+
+
+If you would like to use the graphical user interface, also install:
+
+ * `SIP <http://www.riverbankcomputing.co.uk/software/sip/download>`_.
+ * `PyQt4 <http://www.riverbankcomputing.co.uk/software/pyqt/download>`_.
+
+In case you are compiling under Windows you have to install `Visualstudio
+2008 <http://www.microsoft.com/express/Downloads>`_. to compile the dependecies 
+and OpenStructure. We recommend to compile the dependecies manually. Enter the 
+directories where the dependencies are located in Tools->Options->Projects and 
+Solutions->VC++ directories. Choose 'bin' directories to enter program paths to 
+cmake, qmake and python, 'lib' directories to point to the location(s) of your 
+dependencies.
+
+Checking out the Source
+--------------------------------------------------------------------------------
+
+You can checkout the source from SVN. The repository is located at
+
+   https://dng.biozentrum.unibas.ch/svn/openstructure/trunk
+
+If you are using the commandline client, type in your shell 
+
+   svn co https://ost.biozentrum.unibas.ch/svn/openstructure/trunk
+
+On Windows install svn clients like `tortoisesvn <http://tortoisesvn.tigris.org>`_ and use the function 'checkout' then enter the above mention URL.
+
+
+Configuring
+--------------------------------------------------------------------------------
+
+
+OpenStructure uses `CMake <http://cmake.org>`_ for compiling and building the project. The next required step is to configure the build environment using cmake. You can do that by invoking `cmake` in the project directory (On Windows choose Tools->visualstudio commandline prompt from within visualstudio) :
+
+    cmake . <options>
+
+There are two kinds of options: Options that let you control the building behaviour, enabling and disabling the compilation of certain modules and options that let you tell CMake where to find the dependencies. All of them are passed to CMake with via `-D<opt>=<value>`.
+
+Flag to choose build system
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+On Windows make sure you specify -G"Visual Studio 9 2008"!
+
+Flags to Control the Dependencies
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+By default, `CMake <http://cmake.org>`_ searches the standard directories for dependencies. However, on some systems, this might not be enough. Here is a short description of how CMake figures out what dependencies to take and how you can influence it.
+
+ * Boost is mainly controlled via the `BOOST_ROOT` option. If boost wasn't
+   found, it should be set to the prefix of the boost installation.
+
+ * `QT_QMAKE_EXECUTABLE` defines the exact Qt installation to take. It should 
+   be set to the full path to `qmake`.
+ 
+ * `PYTHON_ROOT` is the Python equivalent of BOOST_ROOT. It should be set to 
+   the prefix path containing the python binary, headers and libraries.
+
+ * `SYS_ROOT` controls the general prefix for searching libraries and headers.
+   By default, it is set to `/`.
+
+Build Options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * `ENABLE_UI` controls whether to build the graphical user interface module. By
+   default it is set to true. 
+ * `ENABLE_IMG` controls whether to build the image processing module. This will
+   enable support for density maps, and general image processing in 1, 2 an 3
+   dimensions. By default it is set to true. 
+
+ * `ENABLE_GFX` controls whether to build the graphics module. By default, this
+   is set to true. If set to none, this implies `ENABLE_UI=NO`.
+   
+ * Shader support is controlled with `USE_SHADER`. By default, no shaders are
+   used.
+   
+ * If `OPTIMIZE` is set to 1, an optimized version of OpenStructure is built.
+
+Building the Project
+--------------------------------------------------------------------------------
+
+Type `make`. If you are using a multi-core machine, you can use the `-j` flag to run
+multiple jobs at once.
+
+On Windows run 'Build OpenStructure' from the build menu.
diff --git a/modules/doc/intro.rst b/modules/doc/intro.rst
new file mode 100644
index 000000000..abf6e6cf9
--- /dev/null
+++ b/modules/doc/intro.rst
@@ -0,0 +1,368 @@
+A gentle introduction to OpenStructure
+================================================================================
+
+In this tutorial you will be learning by example how to use the OpenStructure 
+framework. 
+
+We assume that you already have a version of OpenStructure installed. If not, 
+please refer to :doc:`install`.
+
+
+What will be covered in this tutorial?
+--------------------------------------------------------------------------------
+
+This tutorial is aimed at users that would like to get their hands dirty and 
+execute commands in Python and write scripts rather clicking their way through a 
+shiny user interface. The user interface of OpenStructure is in a very early 
+state anyway that you probably won't go far by clicking you way through...
+
+The first part of the tutorial is a walk-through of the basic functionality you 
+will be using in your everyday work. You will learn how to load structure 
+datasets, inspect, display them in the 3D window and save them. 
+
+
+Getting ready to rumble
+--------------------------------------------------------------------------------
+
+The files we will be using in the tutorial are available in the examples folder 
+that comes with OpenStructure. Depending on your platform, the examples are 
+located at a different location:
+
+ * on *MacOS X* the files are in /Applications/OpenStructure/Examples
+ * on *Linux* and *Windows* PREFIX/share/openstructure/examples, where PREFIX is 
+   the path to the directory containing OpenStructure.
+
+Starting DNG
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The graphical user interface of OpenStructure is called DNG (Dino/DeepView Next 
+Generation). To start it, 
+
+ * on *MacOS X* double click DNG.app in /Applications/OpenStructure
+ * on *Windows* double click dng.bat inside the PREFIX/bin directory
+ * on *Linux* fire up a terminal change into the OpenStructure installation 
+   directory and type 'bin/dng'. If you have the binary directory in the PATH, 
+   typing dng is sufficient.
+
+Interactive Python Shell
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Now we will enter commands in the Python Shell (in the screenshot above, the 
+python shell is located at the bottom of the main window). If you want to get 
+more information on any object, function or class, the python help command may 
+be useful. For example:
+
+  .. code-block:: python
+
+    # get list of methods of EntityView
+    help(mol.EntityView)
+    # get help for method Select
+    help(mol.EntityView.Select)
+    
+Loading and inspecting a protein structure
+--------------------------------------------------------------------------------
+
+OpenStructure has a module that is dedicated to deal with input and output of 
+data, including sequence alignment formats, protein structures and density data 
+and images.  If you are reading this tutorial you most certainly have dealt with 
+protein structures before and you are most certainly aware that they are usually 
+stored in Brookhaven structure files (aka PDB files). The official name for 
+molecules stored in a PDB file is an entity. You will hear this word all the 
+time, but you can replace the word entity with molecule in your head.
+
+
+To load a PDB file, type
+
+  .. code-block:: python
+
+     fragment=io.LoadPDB('/path/to/examples/entity/fragment.pdb')
+
+This will load the fragment from the specified file 'fragment.pdb' and store the result in fragment. For more information on the LoadPDB function, type
+
+  .. code-block:: python
+  
+     help(io.LoadPDB)
+     
+Now let's inspect what we just loaded:
+
+  .. code-block:: python
+  
+     print fragment.chain_count
+     print fragment.residue_count
+     print fragment.atom_count
+
+As you can see, our fragment consists of one peptide chain of 12 amino acids and 
+has 81 atoms in total. Now let's examine our fragment in more detail. Enter the 
+command
+
+  .. code-block:: python
+  
+     for residue in fragment.residues:
+       print residue  
+
+This will print a list of all residues in the fragment. Similarly to get a list 
+of atoms, use:
+
+  .. code-block:: python
+  
+    for atom in fragment.atoms:
+      print atom
+
+Of course, we can also get a list of atoms grouped by residues:
+    
+  .. code-block:: python
+  
+    for residue in fragment.residues:
+      print residue, 'has', residue.atom_count, 'atom(s).'
+      for atom in residue.atoms:
+        print ' ', atom.name, atom.pos
+
+And, for completeness, we will first group them by chain, then by residues.
+
+  .. code-block:: python
+  
+    for chain in fragments.chains:
+      print 'chain', chain.name, 'has', chain.residue_count, 'residue(s)'
+      for residue in chain.residues:
+        print ' ', residue, 'has', residue.atom_count, 'atom(s).'
+        for atom in residue.atoms:
+          print '    ', atom.name, atom.pos
+
+Aah, wait! A protein fragment would not be complete without bonds: Let's see 
+what bonds we have in there:
+
+  .. code-block:: python
+  
+    for bond in fragment.bonds:
+      print bond
+      
+From these short code examples we already see how the entity is structured: On 
+one hand we have a hierarchy of chains, residues and atoms. On the other hand, 
+we have bonds that form a network overlayed on the hierarchy. This is 
+illustrated in the picture on the left. An important feature of entities is that 
+we can always assume that the hierarchy is intact. You will never find an atom 
+without residues, no residue can exist without a parent chain and chains belong 
+always to an entity. 
+
+Let There Be Shiny Graphics
+--------------------------------------------------------------------------------
+
+For visually inspecting the fragment, we now create a graphical representation 
+of the entity:
+
+  .. code-block:: python
+  
+     go=gfx.Entity("Fragment", fragment)
+     scene.Add(go)
+     scene.CenterOn(go)
+
+Now you will see the fragment in the 3D window (left):
+
+![](docs/tut/sel.png)
+
+Use the mouse to rotate, zoom in an shift the camera. Double clicking on an atom will center the camera on that atom. 
+
+Introduction to Views
+--------------------------------------------------------------------------------
+
+Often during processing and visualisation of data, only parts of a protein 
+structure are of interest. This realisation has had a major impact on the design 
+of OpenStructure and is tied very deeply into the core of the framework. 
+Subparts of structure are modeled as so-called :class:`EntityViews 
+<mol.EntityView>`. You can think of them as a selection of chains, residues, 
+atoms and bonds of an entity. A views has almost the same interface as the 
+underlying entity, making it very easy to mix entity views with handles in 
+Python due to the dynamic nature of the language. An algorithm that is written 
+for entities will almost always (with some care) also work for 
+:class:`EntityHandles <mol.EntityHandle>`. This is referred to as `duck-typing 
+<http://en.wikipedia.org/wiki/Duck_typing>`_ (I don' t care if it is a duck as 
+long as it looks like a duck), a concept used all over the place in Python. 
+
+A typical view can be seen in the image on the left. The view consists of one 
+chain, one residue and two atoms. Again the same rule applies: No atom can be 
+part of the view without it's residue. In this example, no bonds are included, 
+since there is at most one atom per bond in the original structure.
+
+To familiarize yourself with the concept of views, we will use the fragment in 
+the 3D window.
+
+We will use several ways to select parts of our fragment:
+ * By using a dedicated query language
+ * By manually constructing a view
+
+The Query Language
+--------------------------------------------------------------------------------
+
+The first way to select parts of a structure is with a dedicated mini-language, 
+called ["the query language”](docs/tut/query.html). In the Python Shell, type
+
+  .. code-block:: python
+  
+    go.selection=fragment.Select('')
+    
+A green halo will be displayed around the selected parts (image in the middle).
+
+As you can see the previous statement created a “full view”, containing all the 
+chains, residues, atoms and bonds. To select lysine residues, type
+
+  .. code-block:: python
+  
+    go.selection=fragment.Select('rname=LYS')
+    
+
+As you can see (image in the middle), the  only lysine residue is now 
+highlighted in the 3D window, because it was the only one matching the predicate 
+"residue name must be equal to LYS". Several such predicates can be combined 
+with boolean operators such as *and* and *or*. To select residues with residue 
+number 1 to 3, the following statement will do the job:
+
+  .. code-block:: python
+  
+    go.selection=fragment.Select('rnum>=1 and rnum<=3')
+    
+but this is very cumbersome. That's why there is a shortcut to this statement. 
+You can specify a range of values.
+
+  .. code-block:: python
+  
+    go.selection=fragment.Select('rnum=1:3')
+
+For a complete description of what you can do with the query language, have a 
+look at the :doc:`../mol/base/query`.
+
+
+Constructing Views Manually
+--------------------------------------------------------------------------------
+
+Sometimes the query language Is Not Enough (TM). For these cases the 
+construction of manual entities becomes neccessary. This is pretty straight 
+forward:
+
+  .. code-block:: python
+  
+    view=fragment.CreateEmptyView()
+    ca=fragment.FindAtom('A', mol.ResNum(1), 'CA')
+    cb=fragment.FindAtom('A', mol.ResNum(1), 'CB')
+    view.AddAtom(ca)
+    view.AddAtom(cb)
+    go.SetSelection(view)
+
+The last step sets our constructed view as the current selection, displaying it 
+in the 3D window. As you can see, C-alpha and C-beta of the first residue are 
+not connected by bonds, even though both atoms are in the view. You have either 
+to add the bond manually with
+
+  .. code-block:: python
+  
+    ca_cb=ca.FindBondToAtom(cb)
+    view.AddBond(ca_cb)
+    
+Or as a very convenient shortcut 'view.AddAllInclusiveBonds()' to add all bonds 
+that have both bonding partners in the view.
+
+Don't forget to call update the selection of the graphics object to see what 
+view you have created.
+
+Saving an Entity
+--------------------------------------------------------------------------------
+
+Saving an entity (or a view) is a breeze:
+
+Type
+
+  .. code-block:: python
+  
+     io.SavePDB(fragment, 'full.pdb')
+
+to save the full view. To save only the backbone atoms, we can first select the 
+backbone atoms and then save it:
+
+  .. code-block:: python
+  
+     io.SavePDB(fragment.Select('aname=CA,C,N,O'), 'backbone.pdb')
+
+
+Loading  images and density maps
+--------------------------------------------------------------------------------
+
+Openstructure features a :mod:`~ost.img` module that is dedicated to the 
+manipulation of 
+images/density maps. The images or density maps can either be one-, two- or 
+three-dimensional. The most common formats used in x-ray and electron 
+crystallography and atomic force microscope are supported in addition to several 
+general purpose image formats. See `supported file formats` for details.
+The :mod:`~ost.img` module was originally developed as part of the Image 
+Processing Library & Toolbox IPLT. More documentation and examples can also be 
+found on the `IPLT website <http://www.iplt.org>`_.
+
+To load a density map, type
+
+  .. code-block:: python
+
+     map=io.LoadImage('/path/to/examples/map/1ppt.map')
+
+This will load the fragment density map from the specified file 'fragment.map' 
+and store the result in fragment_map.
+
+Now let's inspect what we just loaded:
+
+  .. code-block:: python
+  
+    print map.GetPixelSampling()
+    
+We can see that the sampling is set to 1.0 Angstroems in all three dimensions.
+
+Manipulating  images and density maps
+--------------------------------------------------------------------------------
+
+The algorithms used for manipulation of an image are found in the 
+:mod:`~ost.img` module. Therefore before using an algorithm we first have to 
+import the :mod:`~ost.img` module.
+
+  .. code-block:: python
+  
+    from ost import img
+
+
+The :mod:`~ost.img` module provides a wide range of algorithm to manipulate 
+image data. Here for the example we use a LowPassFilter to restrict the 
+resolution of the density map.
+
+  .. code-block:: python
+  
+     map_filtered=map.Apply(img.alg.LowPassFilter(3.0))
+
+The filtered map is stored in a new variable called fragment\_map\_filtered.
+
+
+Displaying images and density maps
+--------------------------------------------------------------------------------
+
+Now that we have a filtered map it's time to have a look at it. There are 
+fundamentally two ways to visualize 3-dimensional density maps. One is by 
+drawing isosurfaces. These are conceputally similar to contour lines used in 
+cartography: every point on an isosurface has the same density value. 
+Isosurfaces are easy to create in OpenStructure:
+
+  .. code-block:: python
+  
+     go=gfx.MapIso("filtered", map_filtered,0.5)
+     scene.Add(go)
+
+The other way to visualize a 3-dimensional map is by showing one 2-dimensional 
+density slice at a time, allowing the user to move through the slices. In 
+OpenStructure this is achieved using a DataViewer docs/tut/imgdataviewer.html). 
+A DataViewer showing the filtered map is created using the following command:
+
+  .. code-block:: python
+  
+    gui.CreateDataViewer(map_filtered)
+
+This command displays a panel showing one slice of the density map lying on a 
+particular (x,y) plane in the coordinate reference system.
+The 'z' and 'x' keys can be used to move to slices lying at a lower or higher 
+coordinate along the 'z' axis, allowing the examination of
+the full 3-dimensional volume.
+
+A more detailed explanation of the :mod:`~ost.img` module can be found in the 
+tutorial section for :mod:`~ost.img`.
diff --git a/modules/doc/newmodule.rst b/modules/doc/newmodule.rst
new file mode 100644
index 000000000..a45283055
--- /dev/null
+++ b/modules/doc/newmodule.rst
@@ -0,0 +1,301 @@
+Creating a New Module
+================================================================================
+
+OpenStructure can be extended by writing additional modules. A module will 
+usually consist of a set of C++ classes and methods, most of which will also be 
+exported to Python. It is also possible to write modules completely in Python.
+
+The build system of OpenStructure is quite simple. The main difference to other 
+projects is the use of a so-called stage  directory. The stage directory 
+replicates the normal layout of a standard Linux directory structure, with an 
+'include' directory for the headers, a 'lib' directory containing the shared 
+library files, a `bin` directory  for the executables and a 'share' directory 
+for the platform-independent data like icons, images and examples.
+
+OpenStructure uses `CMake <http://www.cmake.org>`_ to build the project. The 
+rules for the build-system are defined in `CMakeLists.txt` files. When running 
+`CMake <http://cmake.org>`_, the files are  compiled and copied into stage. The 
+real installation, if necessary, happens at a later stage. This is referred to 
+as staging of the files.
+
+If a new module is written following the guidelines in this page, it will be
+seamlessly included in the build system and will then be available form both
+the DNG python console and the OpenStructure command line as any other native 
+module.
+
+As a first step, a new directory structure must be created to accommodate the 
+new module.
+
+Directory Structure
+--------------------------------------------------------------------------------
+
+For the purpose of this example, let's assume we are creating a new module 
+called 'mod' (for 'modeling'). Let's create a directory named `mod` under the 
+'modules' directory in the OpenStructure development tree, and  populate it with 
+the three subdirectories `src`, `pymod`, and `tests`.  Then we add a 
+`CMakeLists.txt` file in the 'mod' directory, consisting of three lines:
+
+.. code-block:: bash
+
+  add_subdirectory(src)
+  add_subdirectory(pymod)
+  add_subdirectory(tests)
+  
+The Module Code
+--------------------------------------------------------------------------------
+
+In the `src` subdirectory we put the code that implements the functionality of 
+the new module, plus a `config.hh` header file.
+
+Here is a skeleton of one of the files in  the directory , `modeling_new_class.hh`:
+
+.. code-block:: cpp 
+
+  #ifndef OST_MOD_NEW_CLASS_H
+  #define OST_MOD_NEW_CLASS_H
+  
+  #include <ost/mod/module_config.hh>
+  
+  // All other necessary includes go here
+  
+  namespace ost { namespace mod {
+  
+  class DLLEXPORT_OST_MOD NewClass {
+   public:
+     void NewMethod();
+           
+    // All declarations of NewClass go here 
+  
+  };
+  
+  }} // namespaces
+  
+  #endif
+  
+And here is the skeleton of the corresponding `modeling_new_class.cc` file:
+
+.. code-block:: cpp
+
+  #include "modeling_new_class.hh"
+  
+  using namespace ost::mol;
+  using namespace ost::mod;
+  
+  // All other necessary includes and namespace directives
+  // go here
+  
+  void NewClass::NewMethod():
+  {
+    // Implementation     
+  }
+  
+  // Implementation code for NewClass goes here
+  
+Obviously, the `src` directory can contain many files, each implementing classes
+and functions that will end up in the module. In order to build and stage
+the module shared library, a `CMakeLists.txt` file needs to be written for the
+`src` directory:
+
+.. code-block:: bash
+
+  set(OST_MOD_SOURCES 
+  modeling_new_class.cc
+  // All other source files 
+  )
+  
+  set(OST_MOD_HEADERS
+  modeling_new_class.hh
+  // All other header files
+  )
+  
+   module(NAME mod SOURCES "${OST_MOD_SOURCES}"
+          HEADERS ${OST_MOD_HEADERS}
+          DEPENDS_ON mol mol_alg)
+  
+
+The line containing the `DEPENDS_ON` directive lists all the modules on which
+the new module depends (in this case :mod:`mol` and :mod:`ost.mol.alg`).  The 
+`module` macro will take care of staging the headers, in this case into 
+`ost/mod` and compiling, linking and staging of a library with the  name 
+`libost_mod.so` (`libost_gmod.dylib` on MacOS X).
+
+.. note:: 
+
+  Due to a limitation in the built-int install command of CMake, for modules
+  that have their headers in several directories, it is required to group the
+  headers by directory, leading to a call of module like:
+
+.. code-block:: bash
+
+  module(NAME mol SOURCES atom_handle.cc impl/atom_impl.cc
+         HEADERS atom_impl.hh IN_DIR impl
+         atom_handle.hh)   
+
+The `module_config.hh` header is required for each module to setup the 
+environment on Windows: Each public class, method and function needs to marked 
+with `DLLEXPORT` or `DLLIMPORT` to teach the linker where to look for the 
+symbol. The correct use of either `DLLIMPORT` and `DLLEXPORT` is depending on 
+the context: While compiling a header file that is part of the same shared
+library, `DLLEXPORT` must be used. When compiling a header that is part of
+an external shared library, `DLLIMPORT` must be used. A typical module_config
+header looks like this:
+
+.. code-block:: cpp   
+
+  #ifndef OST_MOD_MODULE_CONFIG_HH
+  #define OST_MOD_MODULE_CONFIG_HH
+  
+  #include <ost/base.hh>
+  
+  #if defined(OST_MODULE_OST_MOD)
+  #  define DLLEXPORT_OST_MOD DLLEXPORT
+  #else
+  #  define DLLEXPORT_OST_MOD DLLIMPORT
+  #endif
+  #endif
+      
+The Testing Framework
+--------------------------------------------------------------------------------
+
+The `tests` directory contains code for unit tests. The code is compiled and 
+executed when one invokes compilation using the 'make check' command.  Tests are 
+run by means of the `Boost Unitests Library 
+<http://www.boost.org/doc/libs/1_37_0/libs/test/doc/html/index.html>`_, which is 
+used throughout OpenStructure. Before coding the test routines, the required 
+skeleton needs to be put in place.
+
+The main code is put into 'tests.cc', which will become the test executable:
+    
+.. code-block:: cpp
+
+  #include <boost/test/unit_test.hpp>
+  using boost::unit_test_framework::test_suite;
+  
+  #include "test_modeling.hh"
+  
+  test_suite*
+  unit_unit_test_suite( int argc, char * argv[] ) {
+    std::auto_ptr<test_suite> test(BOOST_TEST_SUITE( "Module Mod Test" ));
+  
+    test->add(CreateModelingTest()); 
+  
+    return test.release(); 
+  }
+  
+        
+The most relevant line adds the test suite for the new module to the global test 
+list. The test suite is created by the factory function CreateModelingTest(), 
+which is declared in the `test_modeling.hh` header file. 
+
+.. code-block:: cpp
+
+  #ifndef OST_MOD_TEST_MODELING_H
+  #define OST_MOD_TEST_MODELING_H
+  
+  #include <boost/test/unit_test.hpp>
+  using boost::unit_test_framework::test_suite;
+  
+  test_suite* CreateModelingTest();
+  
+  #endif
+      
+The definition of the factory function is found in the actual test code,
+which we put in `test_modeling.cc`. Here is a skeleton version of that file:
+
+.. code-block:: cpp
+
+  #include "test_modeling.hh"
+  
+  // additional include statements will go here
+  
+  namespace test_modeling {
+  
+    void test() 
+    {
+      // test code will go here
+    }
+  
+  }
+  
+  test_suite* CreateModelingTest()
+  {
+    using namespace test_modeling;
+    test_suite* ts=BOOST_TEST_SUITE("Modeling Test");
+     ts->add(BOOST_TEST_CASE(&test));
+  
+     return ts;
+  }
+  
+In this file, all the normal Boost Test Library macros and functions can be used. (For example `BOOST_CHECK`, `BOOST_FAIL`, etc.)
+
+Here is finally the build script skeleton that needs to be put into 
+`mod/tests/`:
+
+.. code-block:: bash
+
+  set(OST_MOD_UNIT_TESTS
+  tests.cc
+  test_modeling.cc
+  )
+  
+  ost_unittest(mod "${OST_MOD_UNIT_TESTS}")
+  target_link_libraries(ost_mol ost_mol_alg ost_mod)
+  
+In the last line the call to the 'target\_link\_libraries' function contains the 
+names of the modules on which the 'mod' unit test code depends (in this case, 
+the :mod:`mol` and :mod:`ost.mol.alg` modules), in addition to the `mod` module 
+itself.
+
+The Python Wrapper
+--------------------------------------------------------------------------------
+
+Finally, the module API is exported to Python using the `Boost Python 
+Library <http://www.boost.org/doc/libs/1_37_0/libs/python/doc/index.html>`_.
+In `mod/pymod`, the wrapper code for the classes in the new module is put into a 
+file named `wrap\_mod.cc`:
+
+.. code-block:: cpp
+
+  #include <boost/python.hpp>
+  using namespace boost::python;
+  
+  #include <ost/mod/modeling_new_class.hh>
+  
+  using namespace ost::mol;
+  using namespace ost::mod;
+  
+  // All other necessary includes and namespace directives
+  // go here
+  
+  BOOST_PYTHON_MODULE(_mod)
+  {
+    class_<NewClass>("NewClass", init<>() )
+      .def("NewMethod", &NewClass::NewMethod)
+    ;
+  
+    // All other Boost Python code goes here    
+  }
+
+The `mod/pymod` directory must obviously contain a `CMakeLists.txt` file:
+
+.. code-block:: bash
+
+  set(OST_MOD_PYMOD_SOURCES
+  wrap_mod.cc
+  )
+  
+  pymod(NAME mod OUTPUT_DIR ost/mod 
+        CPP ${OST_MOD_PYMOD_SOURCES} PY __init__.py)
+  
+The directory should also contain an `__init.py__` file with the
+following content:
+
+.. code-block:: python
+  
+  from _mod import *
+    
+In case one wants to implement Python-only functionality for the new module, any
+number of function definitions can be added to the `__init.py__` file.
+
+That's it!. The next time the OpenStructure project is compiled, the new module 
+will be built and made available at both the C++ and the Python level.
diff --git a/modules/geom/doc/composite.rst b/modules/geom/doc/composite.rst
new file mode 100644
index 000000000..0271a206b
--- /dev/null
+++ b/modules/geom/doc/composite.rst
@@ -0,0 +1,529 @@
+Geometric Objects
+================================================================================
+
+.. currentmodule:: ost.geom
+
+Geometrical Objects in Two Dimensions
+--------------------------------------------------------------------------------
+
+.. class:: Line2()
+           Line2(from, to)
+  
+  Parametric line in two dimensions as defined by an origin and a normalized
+  direction vector. The first constructor creates a line with origin (0,0) and 
+  direction along the x axis. The second signature creates a line originating 
+  from `from` and pointing towards `to`.
+  
+  .. method:: At(t)
+    
+    Returns the point on the line at (signed) distance t from origin.
+    
+    :param t: free parameter
+    :type  t: float
+    :rtype:   :class:`Vec2`
+  
+
+  .. method:: GetOrigin()
+  
+    Returns the origin of the line: Also available as :attr:`origin`.
+    
+    :rtype: :class:`Vec2`
+    
+  .. method:: GetDirection()
+  
+    Returns the normalized direction vector. Also available as
+    :attr:`direction`.
+    
+    :rtype: :class:`Vec2`
+    
+  .. attribute:: direction
+  
+  .. attribute:: origin
+
+    
+.. class:: Rectangle2()
+           Rectangle2(top_left, bottom_right)
+  
+  Axis aligned rectangle. The first signature creates a rectangle with top-left 
+  corner (-1, -1) and bottom-right corner (1, 1), wheras the second method 
+  allows to set the top-left and bottom-right corners directly.
+  
+  :type top_left: :class:`Vec2`
+  :param top_left: The top-left corner
+  :param bottom_right: The bottom-right corner  
+  :type bottom_right: :class:`Vec2`  
+
+  .. method:: GetWidth()
+    
+    Returns the width of the rectangle. Also available as :attr:`width`.  
+  
+  .. method:: GetHeight()
+  
+    Returns the height of the rectangle. Also available as :attr:`height`.  
+    
+  .. attribute:: width
+  
+    :type: float
+    
+  .. attribute:: height
+
+    :type: float  
+    
+  .. method:: GetStart()
+  
+    Get top-left corner
+    
+    :rtype: :class:`Vec2`
+    
+  .. method:: GetEnd()
+
+    Get bottom-right corner
+
+    :rtype: :class:`Vec2`    
+  
+  .. method:: SetStart(top_left)
+  
+    Set top-left corner, leaving the bottom-right corner untouched.
+    
+  .. method:: SetEnd(bottom_right)
+  
+    Set the bottom-right corner, leaving the top-left corner untouched.
+
+.. class:: Circle2()
+           Circle2(circle)
+           Circle2(center, radius)
+
+  The first signature creates a circle centered at (0, 0) and radius 1.0. The 
+  second signature creates a circle with the same paramters as `circle`. The 
+  third signature creates a new circle with given center and radius.
+     
+  .. method:: SetCenter(center)
+  
+    Set center of circle
+    
+    :type center: :class:`Vec2`
+    :param center: The new center
+    
+  .. method:: SetRadius(radius)
+  
+    Set radius of circle
+  
+    :type radius: float
+    :param center: The new radius
+    
+  .. method:: GetCenter()
+  
+    Returns the center of the circle
+    
+  .. method:: GetRadius()
+  
+    Returns the radius of the circle
+    
+  .. method:: GetArea()
+  
+    Returns the area of the circle
+    
+  .. method:: GetCircumference()
+  
+    Returns the circumference of the circle
+
+
+.. class:: Ellipse2()
+           Ellipse2(center, a, b, gamma)
+
+  An ellipse is defined by a center, two principal axis and gamma that 
+  defines the angle between the first principal axis an the x-axis.
+  
+  .. method:: At(t)
+  
+    ?
+  
+  .. method:: AtAngle(angle)
+  
+    ?
+  
+  .. method:: GetBoundingBox()
+  
+    Returns the bounding rectangle (axis-aligned) of the ellipse
+    
+    :rtype: :class:`Rectangle2`
+    
+
+  .. method:: GetA()
+  
+    Returns the first principal-axis
+  
+  .. method:: GetB()
+  
+    Returns the second principal-axis
+    
+  .. method:: GetGamma()
+    
+    Returns the angle of the first principal axis to the x-axis
+    
+  .. method:: GetArea()
+  
+    Returns the area of the ellipse
+    
+  .. method:: GetOrigin()
+  
+    Returns the center of the ellipse
+    
+  .. method:: SetA(a)
+  
+    Set the length of the first principal axis
+    
+  .. method:: SetB(b)
+  
+    Set the length of the second principal axis
+    
+  .. method:: SetGamma(gamma)
+  
+    Set the angle of the first principal axis to the x-axis
+    
+  .. method:: SetOrigin(ori)
+  
+    Set the center of the ellipse
+    
+Geometrical Objects in Three Dimensions
+-------------------------------------------------------------------------------
+
+.. class:: Line3()
+           Line3(from, to)
+  
+  Parametric line in three dimensions as defined by an origin and a normalized
+  direction vector. The first constructor creates a line with origin (0,0) and 
+  direction along the x axis. The second signature creates a line originating 
+  from `from` and pointing towards `to`.
+  
+  .. method:: At(t)
+    
+    Returns the point on the line at (signed) distance t from origin.
+    
+    :param t: free parameter
+    :type  t: float
+    :rtype:   :class:`Vec3`
+  
+
+  .. method:: GetOrigin()
+  
+    Returns the origin of the line: Also available as :attr:`origin`.
+    
+    :rtype: :class:`Vec3`
+    
+  .. method:: GetDirection()
+  
+    Returns the normalized direction vector. Also available as
+    :attr:`direction`.
+    
+    :rtype: :class:`Vec3`
+    
+  .. attribute:: direction
+  
+    :type: :class:`Vec3`
+  
+  .. attribute:: origin
+    
+    :type: :class:`Vec3`
+
+.. class:: Plane()
+           Plane(p1, p2, p3)
+           Plane(x, y, z, p)
+           Plane(line, point)
+           Plane(point, normal)
+  
+  A plane in 3d-space. The plane can be constructed by either passing in 3 
+  points (p1, p2, p3), a normal and a point, the four parameters that define the 
+  implicit plane equation (`x`, `y`, `z`, `p`) or a line and a point.
+  
+  .. method:: GetNormal()
+  
+    Returns the normal of the plane. Also available as :attr:`normal`
+    
+    :rtype: :class:`Vec3`
+    
+  .. method:: GetP()
+  
+    Returns the plane offset, i.e. the projection of any point on the plane onto
+    the normal. Also available as :attr:`p`.
+    
+    :rtype: float
+    
+  .. method:: GetOrigin()
+  
+    Get the origin of the plane. Also available as :attr:`origin`.
+    
+    :rtype: :class:`Vec3`
+
+  .. attribute:: origin
+  
+    :type: :class:`Vec3`
+  .. attribute:: normal
+  
+    :type: :class:`Vec3`
+      
+  .. attribute:: p
+  
+    :type: float
+ 
+
+.. class:: Sphere()
+           Sphere(center, radius)
+           
+  Represents a sphere in 3d space. The first constructor creates a sphere with 
+  radius 1, centered at (0, 0, 0), the second allows you to set the radius and 
+  center directly.
+  
+  :param center: The center
+  :type  center: :class:`Vec3`
+  :param radius: The radius
+  :type  radius: float
+  
+  .. attribute:: radius
+    
+    The radius of the sphere. Read-write. Also available as :meth:`GetRadius`, 
+    :meth:`SetRadius`.
+    
+    :type: float
+    
+  .. attribute:: origin
+  
+    The center of the sphere. Read-write. Also available as :meth:`GetOrigin`,
+    :meth:`SetOrigin`.
+    
+    :type: :class:`Vec3`
+
+  .. method:: GetOrigin()  
+  
+    See :attr:`origin`
+    
+  .. method:: SetOrigin(origin)
+    
+    See :attr:`origin`
+    
+  .. method:: GetRadius()
+  
+    See :attr:`radius`
+     
+  .. method:: SetRadius(radius)
+    
+    See :attr:`radius`
+
+.. class:: AlignedCuboid(min, max)
+  
+  Axis aligned cuboid is a cuboid whose axes are aligned to the x-, y-, and z- 
+  axes of the coordinate system. For arbitrarily oriented bounding cuboid 
+  class, see :class:`Cuboid`.
+  
+  .. method:: GetMin()
+  
+    Get minimum coordinate, i.e. the lower bound of x-, y-, and z for 
+    any point in the cuboid
+    
+    :rtype: :class:`Vec3`
+    
+  .. method:: GetMax()
+  
+    Get maximum coordinate, i.e. the upper bound of x-, y-, and z for
+    any point in the cuboid.
+    
+    :rtype: :class:`Vec3`
+
+.. class:: CuboidAxis()
+           CuboidAxis(dir, half_extent)
+  
+  A cuboid axis is defined by a half-extent, and a direction vector. This class 
+  is used in together with the :class:`Cuboid` class.
+  
+  :param dir: Direction vector, will be normalized
+  :type  dir: :class:`Vec3`
+  :param half_extent: The half extent
+  :type half_extent: float
+  
+  .. attribute:: vector
+  
+    The normalized direction vector of the cuboid axis. Also available as 
+    :meth:`GetVector`
+    
+    :type: :class:`Vec3`
+  
+  .. attribute:: half_extent
+  
+    The half extent of the cuboid axis is the magnitude of the cuboid 
+    axis measured from the center to the corner. Also available as
+    :meth:`GetHalfExtent`
+    
+    :type: float
+  
+  .. attribute:: extent
+  
+    The extent of the cuboid axis. This value is always twice the 
+    :attr:`half_extent`. Read-only. Also available as 
+    :meth:`GetExtent`.
+    
+    :type: float
+    
+  .. method:: GetHalfExtent()
+  
+    See :attr:`half_extent`
+  .. method:: GetExtent()
+  
+    See :attr:`extent`
+    
+  .. method:: GetVector()
+  
+    See :attr:`vector`
+    
+.. class:: Cuboid(center, axis_a, axis_b, axis_c)
+  
+  An arbitrarily oriented cuboid defined by a center and 3 axis. The 3 cuboid 
+  axis are stored in the order they are passed to the constructor. This means, 
+  that there is no guarantee that the 3 axes form a right-handed coordinate 
+  system. If a right-handed coordinate system is a requirement, you have to 
+  ensure this on your own:
+  
+  .. code-block:: python
+  
+    center=...
+    axis_a=geom.CuboidAxis(...)
+    axis_b=geom.CuboidAxis(...)
+    axis_c=geom.CuboidAxis(geom.Cross(axis_a.vector, axis_b.vector), ...)
+    
+    cuboid=geom.Cuboid(center, axis_a, axis_b, axis_c)
+  
+  :param center: The center
+  :type  center: :class:`Vec3`
+  :param axis_a: The first axis
+  :type  axis_a: :class:`CuboidAxis`
+  :param axis_b: The second axis
+  :type  axis_b: :class:`CuboidAxis`
+  :param axis_c: The third axis
+  :type  axis_c: :class:`CuboidAxis`
+  
+  .. attribute:: center
+  
+    The center of the cuboid.
+    
+    :type: :class:`Vec3`
+    
+  .. attribute:: axis_a
+  
+    The first cuboid axis
+    
+    :type: :class:`CuboidAxis`
+    
+  .. attribute:: axis_b
+
+    The second cuboid axis
+
+    :type: :class:`CuboidAxis`
+    
+  .. attribute:: axis_c
+
+    The third cuboid axis
+
+    :type: :class:`CuboidAxis`    
+
+Operations on Geometrical Objects
+--------------------------------------------------------------------------------
+
+.. function:: Angle(lhs, rhs)
+
+  Calculate the angle (in radians) between `lhs` and `rhs`. 
+  
+  :param lhs: First object
+  :type  lhs: :class:`Line2`, :class:`Line3`, :class:`Plane`
+  
+  :param rhs: Second object
+  :type  rhs: :class:`Line2`, :class:`Line3`, :class:`Plane`
+  
+  :rtype: float
+
+.. function:: IntersectionPoint(lhs, rhs)
+
+  Calculates and returns the intersection point between `lhs` and `rhs`
+  
+  :param lhs: First object
+  :type  lhs: :class:`Line2`, :class:`Line3`, :class:`Plane`
+  
+  :param rhs: Second object
+  :type  rhs: :class:`Line2`, :class:`Line3`, :class:`Plane`
+  
+  :raises: :exc:`GeomException` when the two objects do not intersect
+  :rtype: :class:`Vec3` (:class:`Vec2` in case of :class:`Line2`)
+
+.. function:: IntersectionLine(plane2, plane2)
+
+  Returns the intersection line between `plane1` and `plane2`.
+  
+  :param plane1: The first plane
+  :type  plane1: :class:`Plane`
+  :param plane2: The second plane
+  :type  plane2: :class:`Plane`  
+  
+  :raises: :exc:GeomException if the two planes are parallel.
+  
+.. function:: Distance(lhs, rhs)
+
+  Returns the minimal distance between `lhs` and `rhs`. 
+  
+  :param lhs: First object
+  :type  lhs: :class:`Line2`, :class:`Line3`, :class:`Plane`
+  
+  :param rhs: Second object
+  :type  rhs: :class:`Line2`, :class:`Line3`, :class:`Plane`
+  
+  :rtype: float
+
+.. function:: IsOnLine(line, point, epsilon=geom.EPSILON)
+
+  Check whether `point` lies on `line` and returns true if point i no further 
+  away than `epsilon`.
+  
+  :rtype: bool
+
+.. function:: IsInPlane(plane, object, epsilon=geom.EPSILON)
+  
+  Check whether `object` lies in `plane` and returns true if the difference is 
+  no bigger than `epsilon`.
+  
+  :param plane: The plane
+  :type  plane: :class:`Plane`
+  :param object: The object
+  :type  object: :class:`Vec3` or :class:`Line3`
+  
+  :rtype: bool
+
+.. function:: AreParallel(lhs, rhs, epsilon=geom.EPSILON)
+
+  Check whether `lhs` and `rhs` are parallel and returns true, if the difference 
+  is below the given treshold `epsilon`.
+  
+  :param lhs: First object
+  :type  lhs: :class:`Line2`, :class:`Line3`, :class:`Plane`
+  
+  :param rhs: Second object
+  :type  rhs: :class:`Line2`, :class:`Line3`, :class:`Plane`
+  
+  :rtype: bool
+
+.. function:: AreIntersecting(line1, line2, epsilon=geom.EPSILON)
+
+  Check whether `line1` and `line2` are intersecting and returns true, if they 
+  intersect below the given threshold `epsilon`.
+  
+  :param lhs: First line
+  :type  lhs: :class:`Line2`, :class:`Line3`
+  
+  :param rhs: Second line
+  :type  rhs: :class:`Line2`, :class:`Line3`
+  
+  :rtype: bool
+  
+
+  
+.. function:: IsInSphere(sphere, point)
+
+  Check whether the `sphere` contains `point`.
+  
+  :rtype: bool
\ No newline at end of file
diff --git a/modules/geom/doc/geom.rst b/modules/geom/doc/geom.rst
index 27accb014..d0412a134 100644
--- a/modules/geom/doc/geom.rst
+++ b/modules/geom/doc/geom.rst
@@ -1,15 +1,16 @@
-:mod:`geom` -- vectors, matrices and geometrical objects
+:mod:`~ost.geom` -- vectors, matrices and geometrical objects
 ================================================================================
 
-.. module:: geom
+.. module:: ost.geom
    :synopsis: Functions and classes for vectors, matrices and geometrical
               objects in 2, 3 and four dimensions
 
-The geom modules contains functions and classes for vectors, matrices and other geometrical objects in 2, 3 and four dimensions.
+The geom modules contains functions and classes for vectors, matrices and other 
+geometrical objects in 2, 3 and four dimensions.
 
 
 .. toctree::
 
   vec
-              
-              
\ No newline at end of file
+  mat
+  composite
\ No newline at end of file
diff --git a/modules/geom/doc/mat.rst b/modules/geom/doc/mat.rst
new file mode 100644
index 000000000..c8736733a
--- /dev/null
+++ b/modules/geom/doc/mat.rst
@@ -0,0 +1,167 @@
+Matrices
+================================================================================
+
+.. currentmodule:: ost.geom
+
+The :mod:`~ost.geom` module defines matrices in two, three and four dimensions. 
+All matrices store the values in row-major order, meaning that, the matrix ((1, 
+2), (3,4)) stores the values as (1, 2, 3, 4). This is illustrated in 
+the following code examples:
+
+.. code-block:: python
+
+  m=geom.Mat2(1, 2, 3, 4)
+  print m # will print {{1,2},{3,4}}
+  print m[(0,0)], m[(0,1)], m[(1,0)], m[(1,1)] # will print 1, 2, 3, 4
+
+Matrices support arithmetic via overloaded operators. The following operations are 
+supported:
+
+  * adding and subtracting two matrices
+  * negation
+  * multiplication of matrices
+  * multiplying and dividing by scalar value
+
+The Matrix Classes
+--------------------------------------------------------------------------------
+
+.. class:: Mat2()
+           Mat2(d00, d01, d10, d11)
+
+  2x2 real-valued matrix. The first signature creates a new identity matrix. The 
+  second signature initializes the matrix in row-major order. 
+
+  .. staticmethod:: Identity()
+  
+    Returns the 2x2 identity matrix
+  
+  
+.. class:: Mat3()
+           Mat3(d00, d01, d02, d10, d11, d12, d20, d21, d22)
+
+  3x3 real-valued matrix. The first signature creates a new identity matrix. The 
+  second signature initializes the matrix in row-major order.
+  
+  .. staticmethod:: Identity()
+  
+    Returns the 3x3 identity matrix
+    
+.. class:: Mat4()
+           Mat4(d00, d01, d02, d03, d10, d11, d12, d13, d20, d21, d22, d23, d30, d31, d32, d33)
+
+  4x4 real-valued matrix. The first signature creates a new identity matrix. The 
+  second signature initializes the matrix in row-major order.
+  
+  .. method:: ExtractRotation()
+    
+    Returns the 3x3 submatrix
+    
+  .. method:: PasteRotation(mat)
+  
+    Set the 3x3 submatrix of the top-left corner to `mat`
+    
+  .. method:: ExtractTranslation()
+  
+    Extract translation component from matrix. Only meaningful when matrix 
+    is a combination of rotation and translation matrices, otherwise the result 
+    is undefined.
+    
+  .. PasteTranslation(trans)
+  
+    Set the translation component of the matrix to `trans`
+    
+    :param trans: The translation
+    :type  trans: :class:`Vec3`
+    
+  .. staticmethod:: Identity()
+  
+    Returns the 4x4 identity matrix
+
+Functions Operating on Matrices
+--------------------------------------------------------------------------------
+.. function:: Equal(lhs, rhs, epsilon=geom.EPSILON)
+
+  Compares the two matrices `lhs` and `rhs` and returns True, if all 
+  of the element-wise differences are smaller than epsilon. `lhs` 
+  and `rhs` must be matrices of the same dimension.
+  
+  :param lhs: First matrix
+  :type  lhs: :class:`Mat2`, :class:`Mat3` or :class:`Mat4`
+  :param rhs: Second matrix
+  :type  rhs: :class:`Mat2`, :class:`Mat3` or :class:`Mat4`
+
+.. function:: Transpose(mat)
+
+  Returns the transpose of `mat`
+  
+  :param mat: The matrix to be transposed
+  :type  lhs: :class:`Mat2`, :class:`Mat3` or :class:`Mat4`
+
+.. function:: Invert(mat)
+
+  Returns the inverse of `mat`
+  
+  :param mat: The matrix to be inverted
+  :type  mat: :class:`Mat2`, :class:`Mat3` or :class:`Mat4`
+  
+  What happens when determinant is 0?
+  
+.. function:: CompMultiply(lhs, rhs)
+
+  Returns the component-wise product of `lhs` and `rhs`. `lhs` and 
+  `rhs` must be vectors of the same dimension.
+  
+  :param lhs: The lefthand-side vector
+  :type  lhs: :class:`~Vec2`, :class:`~Vec3` or 
+              :class:`~Vec4`
+  :param rhs: The righthand-side vector
+  :type  rhs: :class:`~Vec2`, :class:`~Vec3` or 
+              :class:`~Vec4`
+              
+.. function:: CompDivide(lhs, rhs)
+
+  Returns the component-wise quotient of `lhs` divided by `rhs`. `lhs` 
+  and `rhs` must be vectors of the same dimension.
+
+  :param lhs: The lefthand-side vector
+  :type  lhs: :class:`~Vec2`, :class:`~Vec3` or 
+              :class:`~Vec4`
+  :param rhs: The righthand-side vector
+  :type  rhs: :class:`~Vec2`, :class:`~Vec3` or 
+              :class:`~Vec4`
+
+.. function:: Det(mat)
+
+  Returns the determinant of `mat`
+  :param mat: A matrix
+  :type  mat: :class:`~Mat2`, :class:`~Mat3` or :class:`~Mat4`
+
+.. function:: Minor(mat, i, j)
+  
+  Returns the determinant of the 2x2 matrix generated from `mat`  by 
+  removing the ith row and jth column.
+
+.. function:: EulerTransformation(phi, theta, xi)
+  
+  Returns a rotation matrix for the 3 euler angles `phi`, `theta`, and
+  `xi`. The 3 angles are given in radians.
+  
+  
+.. function:: AxisRotation(axis, angle)
+
+  Returns a rotation matrix that represents a rotation of `angle` 
+  around the `axis`. 
+  
+  :param axis: The rotation axis. Will be normalized
+  :type  axis: :class:`Vec3`
+  :param angle: Rotation angle (radians) in clockwise direction when 
+      looking down the axis.
+  
+.. function:: OrthogonalVector(vec)
+
+  Get arbitrary vector orthogonal to `vec`. The returned vector is of length 
+  1, except when `vec` is a zero vector. In that case, the returned vector is 
+  (0, 0, 0).
+  
+  :param vec: A vector of arbitrary length
+  :type vec: :class:`Vec3`
\ No newline at end of file
diff --git a/modules/geom/doc/vec.rst b/modules/geom/doc/vec.rst
index b3da8088b..d3876bcb1 100644
--- a/modules/geom/doc/vec.rst
+++ b/modules/geom/doc/vec.rst
@@ -1,9 +1,11 @@
 Vectors
 ================================================================================
-.. currentmodule:: geom
+.. currentmodule:: ost.geom
 
 
-The :class:`Vec2`, :class:`Vec3`, :class:`Vec4` classes implement vectors in 2, 3 and four dimensions. They support basic arithmetic via overloaded operators. Essentially, the following basic operations are available:
+The :class:`Vec2`, :class:`Vec3`, :class:`Vec4` classes implement vectors in 2, 
+3 and four dimensions. They support basic arithmetic via overloaded operators. 
+Essentially, the following basic operations are available:
 
  * adding and subtracting two vectors
  * negation
@@ -19,7 +21,8 @@ This is shown in the following example:
    print vec_a+vec_b
    print vec_a*3-vec_b
 
-The standard vector operations are implemented as :ref:`free standing functions <vector-functions>`:
+The standard vector operations are implemented as :ref:`free standing functions 
+<vector-functions>`:
 
 
 .. code-block:: python
diff --git a/modules/geom/pymod/export_composite2.cc b/modules/geom/pymod/export_composite2.cc
index f9e793ee1..96f42ab26 100644
--- a/modules/geom/pymod/export_composite2.cc
+++ b/modules/geom/pymod/export_composite2.cc
@@ -42,6 +42,8 @@ void export_Composite2()
     .def("At",&Line2::At)
     .def("GetOrigin",&Line2::GetOrigin)
     .def("GetDirection",&Line2::GetDirection)
+    .add_property("direction", &Line2::GetDirection)
+    .add_property("origin", &Line2::GetOrigin)
   ;
 
   class_<Polygon2>("Polygon2",init<>())
diff --git a/modules/geom/pymod/export_composite3.cc b/modules/geom/pymod/export_composite3.cc
index 8468578df..bf269d552 100644
--- a/modules/geom/pymod/export_composite3.cc
+++ b/modules/geom/pymod/export_composite3.cc
@@ -18,10 +18,9 @@
 //------------------------------------------------------------------------------
 #include <boost/python.hpp>
 #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
-using namespace boost::python;
-
 #include <ost/geom/geom.hh>
 
+using namespace boost::python;
 void export_Composite3()
 {
   using namespace geom;
@@ -32,6 +31,8 @@ void export_Composite3()
     .def("At",&Line3::At)
     .def("GetOrigin",&Line3::GetOrigin)
     .def("GetDirection",&Line3::GetDirection)
+    .add_property("origin", &Line3::GetOrigin)
+    .add_property("direction", &Line3::GetDirection)
   ;
 
 { // scope
@@ -49,6 +50,7 @@ scope PlaneScope =
     .def("GetNormal",&Plane::GetNormal)
     .add_property("normal", &Plane::GetNormal)
     .add_property("origin", &Plane::GetOrigin)
+    .add_property("p", &Plane::GetP)
     .def("GetP",&Plane::GetP)
   ;
 
@@ -105,6 +107,8 @@ scope PlaneScope =
     .def(init<const Vec3&,Real>())
     .def("GetOrigin",&Sphere::GetOrigin)
     .def("GetRadius",&Sphere::GetRadius)
+    .add_property("origin", &Sphere::GetOrigin, &Sphere::SetOrigin)
+    .add_property("radius", &Sphere::GetRadius, &Sphere::SetRadius)
   ;
   
   class_<CuboidAxis>("CuboidAxis", init<>())
@@ -113,29 +117,50 @@ scope PlaneScope =
     .def("GetVector", &CuboidAxis::GetVector,
          return_value_policy<copy_const_reference>())
     .def("GetExtent", &CuboidAxis::GetExtent)
+    
+    .add_property("vector", make_function(&CuboidAxis::GetVector,
+                  return_value_policy<copy_const_reference>()))
+    .add_property("half_extent", &CuboidAxis::GetHalfExtent)
+    .add_property("extent", &CuboidAxis::GetExtent)
   ;
   
   class_<Cuboid>("Cuboid", init<>())
     .def(init<const geom::Vec3&, const CuboidAxis&,const CuboidAxis&, 
               const CuboidAxis&>())
     .def("GetCenter",&Cuboid::GetCenter)
+    .add_property("center", &Cuboid::GetCenter)
     .def("GetVecA", &Cuboid::GetVecA,
          return_value_policy<copy_const_reference>())
+    .add_property("vec_a", make_function(&Cuboid::GetVecA,
+              return_value_policy<copy_const_reference>()))
     .def("GetVecB", &Cuboid::GetVecB,
          return_value_policy<copy_const_reference>())
+   .add_property("vec_b", make_function(&Cuboid::GetVecB,
+             return_value_policy<copy_const_reference>()))         
     .def("GetVecC", &Cuboid::GetVecC,
          return_value_policy<copy_const_reference>())
+    .add_property("vec_c", make_function(&Cuboid::GetVecC,
+                  return_value_policy<copy_const_reference>()))         
     .def("GetAxisA", &Cuboid::GetAxisA, 
          return_value_policy<copy_const_reference>())
+    .add_property("axis_a", make_function(&Cuboid::GetAxisA,
+                 return_value_policy<copy_const_reference>()))
     .def("GetAxisB", &Cuboid::GetAxisB, 
          return_value_policy<copy_const_reference>())
+    .add_property("axis_b", make_function(&Cuboid::GetAxisB,
+                  return_value_policy<copy_const_reference>()))
     .def("GetAxisC", &Cuboid::GetAxisC, 
-         return_value_policy<copy_const_reference>())                  
+         return_value_policy<copy_const_reference>())              
+    .add_property("axis_c", make_function(&Cuboid::GetAxisC,
+                  return_value_policy<copy_const_reference>()))             
     .def("GetHalfExtents", &Cuboid::GetHalfExtents)
+    .add_property("half_extents", &Cuboid::GetHalfExtents)
   ;
   class_<AlignedCuboid>("AlignedCuboid", init<geom::Vec3, geom::Vec3>())
-    .def("GetMin", &AlignedCuboid::GetMin, return_value_policy<copy_const_reference>())
-    .def("GetMax", &AlignedCuboid::GetMax, return_value_policy<copy_const_reference>())
+    .def("GetMin", &AlignedCuboid::GetMin, 
+         return_value_policy<copy_const_reference>())
+    .def("GetMax", &AlignedCuboid::GetMax, 
+         return_value_policy<copy_const_reference>())
   ;
 }
 
diff --git a/modules/geom/pymod/export_vec2.cc b/modules/geom/pymod/export_vec2.cc
index 6c0722ffc..d32c72ad9 100644
--- a/modules/geom/pymod/export_vec2.cc
+++ b/modules/geom/pymod/export_vec2.cc
@@ -30,6 +30,7 @@ void export_Vec2()
 
   class_<Vec2>("Vec2",init<>())
     .def(init<Real,Real>())
+    .def(init<const Vec2&>())
     .def(init<const Vec3&>())
     .def(init<const Vec4&>())
     .def(self *= Real())
diff --git a/modules/geom/pymod/export_vec3.cc b/modules/geom/pymod/export_vec3.cc
index f822214b2..b9bf4edea 100644
--- a/modules/geom/pymod/export_vec3.cc
+++ b/modules/geom/pymod/export_vec3.cc
@@ -38,6 +38,7 @@ void export_Vec3()
     .def(init<Real,Real,Real>())
     .def(init<const Vec2&>())
     .def(init<const Vec4&>())
+    .def(init<const Vec3&>())
     .def(self *= Real())
     .def(self /= Real())
     .def(self += Real())
diff --git a/modules/geom/pymod/export_vec4.cc b/modules/geom/pymod/export_vec4.cc
index 8a4f9e2f3..9bb393654 100644
--- a/modules/geom/pymod/export_vec4.cc
+++ b/modules/geom/pymod/export_vec4.cc
@@ -35,6 +35,7 @@ void export_Vec4()
     .def(init<Real,Real,Real,Real>())
     .def(init<const Vec2&>())
     .def(init<const Vec3&>())
+    .def(init<const Vec4&>())
     .def(self *= Real())
     .def(self /= Real())
     .def(self += Real())
diff --git a/modules/geom/pymod/export_vecmat3_op.cc b/modules/geom/pymod/export_vecmat3_op.cc
index 6500b4283..cdafc821c 100644
--- a/modules/geom/pymod/export_vecmat3_op.cc
+++ b/modules/geom/pymod/export_vecmat3_op.cc
@@ -58,4 +58,5 @@ void export_VecMat3_op()
   def("Minor",Mat3Minor);
   def("EulerTransformation",EulerTransformation);
   def("AxisRotation",AxisRotation);
+  def("OrthogonalVector",OrthogonalVector);
 }
diff --git a/modules/geom/src/vecmat3_op.hh b/modules/geom/src/vecmat3_op.hh
index 43961e798..44c835768 100644
--- a/modules/geom/src/vecmat3_op.hh
+++ b/modules/geom/src/vecmat3_op.hh
@@ -36,10 +36,12 @@ Real DLLEXPORT_OST_GEOM Length(const Vec3& v);
 Real DLLEXPORT_OST_GEOM Length2(const Vec3& v);
 
 //! return true if components differ not more than ephilon
-bool DLLEXPORT_OST_GEOM Equal(const Vec3& v1, const Vec3& v2, Real ephilon=EPSILON);
+bool DLLEXPORT_OST_GEOM Equal(const Vec3& v1, const Vec3& v2, 
+                              Real ephilon=EPSILON);
 
 //! return true if components differ not more than ephilon
-bool DLLEXPORT_OST_GEOM Equal(const Mat3& m1, const Mat3& m2, Real ephilon=EPSILON);
+bool DLLEXPORT_OST_GEOM Equal(const Mat3& m1, const Mat3& m2, 
+                              Real ephilon=EPSILON);
 
 //! vector dot product
 Real DLLEXPORT_OST_GEOM Dot(const Vec3& v1, const Vec3& v2);
diff --git a/modules/gfx/pymod/export_entity.cc b/modules/gfx/pymod/export_entity.cc
index 23e341b04..a81f8299e 100644
--- a/modules/gfx/pymod/export_entity.cc
+++ b/modules/gfx/pymod/export_entity.cc
@@ -23,7 +23,7 @@ using namespace boost::python;
 #include <ost/gfx/entity.hh>
 using namespace ost;
 using namespace ost::gfx;
-
+#include <ost/export_helper/pair_to_tuple_conv.hh>
 #include "color_by_def.hh"
 
 namespace {
@@ -177,14 +177,6 @@ void ent_apply_62(Entity* e, MapHandleColorOp& mhco){
 }
 #endif //OST_IMG_ENABLED
 
-template<class T1, class T2>
-struct PairToTupleConverter {
-  static PyObject* convert(const std::pair<T1, T2>& pair) {
-    tuple t=boost::python::make_tuple<T1,T2>(pair.first,pair.second);
-    return incref(t.ptr());
-  }
-};
-
 
 RenderOptionsPtr ent_sline_opts(Entity* ent)
 {
diff --git a/modules/gfx/pymod/export_map.cc b/modules/gfx/pymod/export_map.cc
index cd88c771b..7ba389b90 100644
--- a/modules/gfx/pymod/export_map.cc
+++ b/modules/gfx/pymod/export_map.cc
@@ -17,6 +17,7 @@
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
 #include <boost/python.hpp>
+#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
 using namespace boost::python;
 
 #include <ost/gfx/map_iso.hh>
@@ -50,13 +51,32 @@ void ms_color_by_04(MapSlab *s, const Color& c1, const Color& c2)
 
 void export_Map()
 {
+
+  enum_<MapIsoType>("MapIsoType")
+    .value("ORIGINAL_MAP", ORIGINAL_MAP)
+    .value("DOWNSAMPLED_MAP", DOWNSAMPLED_MAP)
+  ;
+
   class_<MapIso, bases<GfxObj>, boost::shared_ptr<MapIso>,
          boost::noncopyable>("MapIso", init<const String&, const ::img::MapHandle&, float, optional<uint> >())
     .def("SetLevel",&MapIso::SetLevel)
     .def("GetLevel",&MapIso::GetLevel)
+    .def("GetMinLevel",&MapIso::GetMinLevel)
+    .def("GetMaxLevel",&MapIso::GetMaxLevel)
     .def("GetMean", &MapIso::GetMean)
+    .def("GetHistogram",&MapIso::GetHistogram)
+    .def("SetHistogramBinCount",&MapIso::SetHistogramBinCount)
+    .def("GetHistogramBinCount",&MapIso::GetHistogramBinCount)
+
     .def("GetMap", &MapIso::GetMap,return_value_policy<reference_existing_object>())
     .def("GetOriginalMap", &MapIso::GetOriginalMap,return_value_policy<reference_existing_object>())
+    .def("GetDownsampledMap", &MapIso::GetDownsampledMap,return_value_policy<reference_existing_object>())
+    .def("ShowDownsampledMap", &MapIso::ShowDownsampledMap)
+    .def("ShowOriginalMap", &MapIso::ShowOriginalMap)
+    .def("IsDownsampledMapAvailable", &MapIso::IsDownsampledMapAvailable)
+    .def("GetShownMapType", &MapIso::GetShownMapType)
+    .def("MakeOctreeDirty", &MapIso::MakeOctreeDirty)
+    .def("IfOctreeDirty", &MapIso::IfOctreeDirty)
     .def("Rebuild", &MapIso::Rebuild)
     .def("SetNSF",&MapIso::SetNSF)
     .def("SetColor", &MapIso::SetColor)
diff --git a/modules/gfx/pymod/export_surface.cc b/modules/gfx/pymod/export_surface.cc
index a2f8a560a..4a4ebc882 100644
--- a/modules/gfx/pymod/export_surface.cc
+++ b/modules/gfx/pymod/export_surface.cc
@@ -122,8 +122,4 @@ void export_Surface()
     .def("CleanColorOps", &Surface::CleanColorOps)
     .def("ReapplyColorOps", &Surface::ReapplyColorOps)
     ;
-
-  class_<RSurface, bases<GfxObj>, RSurfaceP, boost::noncopyable>("RSurface", init<const String&, const mol::rsurf::RSurfP&>())
-    ;
-
 }
diff --git a/modules/gfx/src/entity.cc b/modules/gfx/src/entity.cc
index f7b924c13..8d639a336 100644
--- a/modules/gfx/src/entity.cc
+++ b/modules/gfx/src/entity.cc
@@ -249,7 +249,7 @@ void Entity::ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc,
     maxc = geom::Max(maxc, geom::Max(t1, geom::Max(t2, geom::Max(t3, 
                      geom::Max(t4, geom::Max(t5, geom::Max(t6,
                      geom::Max(t7, t8))))))));
-  } catch(Error& e) {
+  } catch(Error&) {
     // in case the object is empty...
   }
 } 
diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc
index 0a28a7e6e..c0d24ff0e 100644
--- a/modules/gfx/src/gfx_object.cc
+++ b/modules/gfx/src/gfx_object.cc
@@ -114,7 +114,7 @@ void GfxObj::ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc,
     maxc = geom::Max(maxc, geom::Max(t1, geom::Max(t2, geom::Max(t3, 
                      geom::Max(t4, geom::Max(t5, geom::Max(t6,
                      geom::Max(t7, t8))))))));
-  } catch(Error& e) {
+  } catch(Error&) {
     // in case the object is empty...
   }
 }
diff --git a/modules/gfx/src/impl/entity_detail.cc b/modules/gfx/src/impl/entity_detail.cc
index ccc160078..572de5bb7 100644
--- a/modules/gfx/src/impl/entity_detail.cc
+++ b/modules/gfx/src/impl/entity_detail.cc
@@ -43,9 +43,9 @@ void GfxView::AddAtom(const AtomView& av)
   AtomEntry ae(a,default_radius,
                a.GetRadius(),
                GfxObj::Ele2Color(a.GetElement()));
-  atom_map[a.GetHashCode()]=ae;
+  atom_map[a.GetHandle().GetHashCode()]=ae;
   if(av.GetBondCount()==0) {
-    orphan_atom_list.push_back(a.GetHashCode());
+    orphan_atom_list.push_back(a.GetHandle().GetHashCode());
   }
 }
 
@@ -297,7 +297,7 @@ SplineEntryList Spline::Generate(int nsub) const
       float psum=0.0;
       float qsum=0.0;
       ++c;
-      while(sublist[c].type==1 && c<nsub*size) {
+      while(c<nsub*size && sublist[c].type==1) {
         n = geom::Normalize(geom::Cross(sublist[c].normal,
                                         sublist[c].direction));
         geom::Vec3 p1 = sublist[c].position+n;
diff --git a/modules/gfx/src/impl/map_octree.cc b/modules/gfx/src/impl/map_octree.cc
index 33bd93d71..a130b6552 100644
--- a/modules/gfx/src/impl/map_octree.cc
+++ b/modules/gfx/src/impl/map_octree.cc
@@ -25,12 +25,34 @@
 
 namespace ost { namespace gfx { namespace impl {
 
-MapOctree::MapOctree(const img::ImageHandle& map):
-  map_(map)
+MapOctree::MapOctree(const img::ImageHandle& ih):
+  map_(ih),
+  built_(false)
+{}
+
+void MapOctree::Initialize()
 {
+  built_=false;
+  levels_.clear();
   this->BuildOctree();
 }
 
+
+void MapOctree::SetNewMap(const img::ImageHandle& ih)
+{
+  map_=ih;
+}
+
+bool MapOctree::IsMapManageable (const img::ImageHandle ih)
+{
+ bool manageable = true;
+ if (ih.GetExtent().GetWidth() > 256 ||
+     ih.GetExtent().GetHeight() > 256 ||
+     ih.GetExtent().GetDepth() > 256 ) manageable=false;
+ return manageable;
+}
+
+
 uint32_t MapOctree::GetNumNodesForLevel(uint8_t level) const
 {
   img::Size size=map_.GetExtent().GetSize();
@@ -52,7 +74,9 @@ void MapOctree::BuildOctree()
   assert(p && "Octree only supports real spatial images");
   OctreeNode dummy;
   this->BuildOctreeRec(range_vec, 0, p, map_.GetExtent(), dummy);
+  built_=true;
 }
+
 std::pair<float,float> MapOctree::BuildOctreeRec(const OcRangeVector& range_vec,
                                                  uint16_t level,
                                                  img::RealSpatialImageState* map,
@@ -100,9 +124,9 @@ std::pair<float,float> MapOctree::BuildOctreeRec(const OcRangeVector& range_vec,
   }  
   // determine branch pattern
   uint16_t highest_order_mask=1 << highest_order_bit;
-  bool branch_x=range_vec.x & highest_order_mask;
-  bool branch_y=range_vec.y & highest_order_mask;
-  bool branch_z=range_vec.z & highest_order_mask;
+  bool branch_x=(range_vec.x & highest_order_mask)!= 0;
+  bool branch_y=(range_vec.y & highest_order_mask)!= 0;
+  bool branch_z=(range_vec.z & highest_order_mask)!= 0;
   int range_x[2][2];
   int range_y[2][2];
   int range_z[2][2];
diff --git a/modules/gfx/src/impl/map_octree.hh b/modules/gfx/src/impl/map_octree.hh
index 999219e83..4c73f54bd 100644
--- a/modules/gfx/src/impl/map_octree.hh
+++ b/modules/gfx/src/impl/map_octree.hh
@@ -109,8 +109,11 @@ typedef std::vector<OctreeNode> OcNodeEntryList;
 class DLLEXPORT_OST_GFX MapOctree {
 public:
   MapOctree(const img::ImageHandle& map);
+  void Initialize();
   uint32_t GetNumNodesForLevel(uint8_t level) const;
-  
+  void SetNewMap(const img::ImageHandle& ih);
+  static bool IsMapManageable (const img::ImageHandle ih);
+
   /// \brief depth-first visit of octree nodes
   template <typename F>
   void VisitDF(F& f) const
@@ -216,6 +219,7 @@ private:
 
   img::ImageHandle            map_;
   std::vector<OcNodeEntryList>      levels_;
+  bool                        built_;
 };
 
 }}}
diff --git a/modules/gfx/src/map_iso.cc b/modules/gfx/src/map_iso.cc
index 20736f6c9..06183729a 100644
--- a/modules/gfx/src/map_iso.cc
+++ b/modules/gfx/src/map_iso.cc
@@ -24,8 +24,8 @@
 #include <ost/profile.hh>
 #include <ost/profile.hh>
 #include <ost/base.hh>
-#include <ost/img/alg/stat.hh>
 #include <ost/img/alg/discrete_shrink.hh>
+#include <ost/img/alg/histogram.hh>
 
 #include "gl_helper.hh"
 #include "glext_include.hh"
@@ -62,9 +62,12 @@ namespace gfx {
 MapIso::MapIso(const String& name, const img::MapHandle& mh, float level):
   GfxObj(name),
   original_mh_(mh),
-  downsampled_mh_(MapIso::DownsampleMap(mh)),
-  mh_(downsampled_mh_),
+  downsampled_mh_(),
+  mh_(MapIso::DownsampleMap(mh)),
   octree_(mh_),
+  stat_calculated_(false),
+  histogram_calculated_(false),
+  histogram_bin_count_(100),
   level_(level),
   normals_calculated_(false),
   alg_(0),
@@ -72,6 +75,11 @@ MapIso::MapIso(const String& name, const img::MapHandle& mh, float level):
   debug_octree_(false),
   color_(Color::GREY)
 {
+  // TODO replace with def mat for this gfx obj type
+  if (mh_ != original_mh_) {
+    downsampled_mh_ = mh_;
+  }
+  octree_.Initialize();
   SetMatAmb(Color(0,0,0));
   SetMatDiff(Color(1,1,1));
   SetMatSpec(Color(0.1,0.1,0.1));
@@ -87,16 +95,23 @@ MapIso::MapIso(const String& name, const img::MapHandle& mh,
                float level, uint a):
   GfxObj(name),
   original_mh_(mh),
-  downsampled_mh_(MapIso::DownsampleMap(mh)),
-  mh_(downsampled_mh_),
+  downsampled_mh_(),
+  mh_(MapIso::DownsampleMap(mh)),
   octree_(mh_),
+  stat_calculated_(false),
+  histogram_calculated_(false),
+  histogram_bin_count_(100),
   level_(level),
   normals_calculated_(false),
   alg_(a),
   debug_octree_(false),
-  color_(Color::GREY)
+  color_(Color::GREY)  
 {
   // TODO replace with def mat for this gfx obj type
+  if (mh_ != original_mh_) {
+    downsampled_mh_ = mh_;
+  }
+  octree_.Initialize();
   SetMatAmb(Color(0,0,0));
   SetMatDiff(Color(1,1,1));
   SetMatSpec(Color(0.1,0.1,0.1));
@@ -261,6 +276,16 @@ void MapIso::OnInput(const InputEvent& e)
 
 void MapIso::Rebuild()
 {
+  if (mh_.IsFrequency() == true){
+    throw Error("Error: Map not in real space. Cannot create of this map");
+  }
+  if (octree_.IsMapManageable(mh_) == false) {
+    throw Error("Error: Map is too big for visualization");
+  }
+  if (IfOctreeDirty()==true) {
+    octree_.SetNewMap(mh_);
+    octree_.Initialize();
+  }
   va_.Clear();
   va_.SetMode(0x2);
   normals_calculated_=false;
@@ -273,7 +298,7 @@ void MapIso::Rebuild()
   va_.CalcNormals(1.0);
   va_.DrawNormals(true);
 #endif  
-  OnRenderModeChange();
+  OnRenderModeChange();  
 }
 
 void MapIso::SetLevel(float l)
@@ -283,6 +308,31 @@ void MapIso::SetLevel(float l)
   Scene::Instance().RequestRedraw();
 }
 
+void MapIso::CalculateStat() const
+{
+  mh_.ApplyIP(stat_);
+  stat_calculated_=true;
+}
+
+void MapIso::CalculateHistogram() const
+{
+  histogram_ = img::alg::HistogramBase(histogram_bin_count_, this->GetMinLevel(), this->GetMaxLevel());
+  mh_.ApplyIP(histogram_);
+  histogram_calculated_=true;
+}
+
+float MapIso::GetMinLevel() const
+{
+  if(!stat_calculated_)CalculateStat();
+  return stat_.GetMinimum();
+}
+
+float MapIso::GetMaxLevel() const
+{
+  if(!stat_calculated_)CalculateStat();
+  return stat_.GetMaximum();
+}
+
 float MapIso::GetLevel() const
 {
   return level_;
@@ -290,9 +340,27 @@ float MapIso::GetLevel() const
 
 float MapIso::GetStdDev() const
 {
-  img::alg::Stat stat;
-  mh_.Apply(stat);
-  return stat.GetStandardDeviation();
+  if(!stat_calculated_)CalculateStat();
+  return stat_.GetStandardDeviation();
+}
+
+void MapIso::SetHistogramBinCount(int count)
+{
+  if (count > 0){
+    histogram_bin_count_ = count;
+    histogram_calculated_ = false;
+  }
+}
+
+int MapIso::GetHistogramBinCount() const
+{
+  return histogram_bin_count_;
+}
+
+std::vector<int> MapIso::GetHistogram() const
+{
+  if(!histogram_calculated_)CalculateHistogram();
+  return histogram_.GetBins();
 }
 
 img::ImageHandle& MapIso::GetMap()
@@ -305,11 +373,15 @@ img::ImageHandle& MapIso::GetOriginalMap()
   return original_mh_;
 }
 
+img::ImageHandle& MapIso::GetDownsampledMap()
+{
+  return downsampled_mh_;
+}
+
 float MapIso::GetMean() const
 {
-  img::alg::Stat stat;
-  mh_.Apply(stat);
-  return static_cast<float>(stat.GetMean());
+  if(!stat_calculated_)CalculateStat();
+  return static_cast<float>(stat_.GetMean());
 }
 
 void MapIso::SetNSF(float nsf)
@@ -319,11 +391,60 @@ void MapIso::SetNSF(float nsf)
   Scene::Instance().RequestRedraw();
 }
 
+/// \brief sets the donsampled map to active
+void MapIso::ShowDownsampledMap()
+{
+  if (downsampled_mh_.IsValid()) mh_ = downsampled_mh_;
+  MakeOctreeDirty();
+  stat_calculated_ = false;
+  histogram_calculated_ = false;
+  Rebuild();
+  Scene::Instance().RequestRedraw();
+}
+
+/// \brief sets the original map to active
+void MapIso::ShowOriginalMap()
+{
+  if (original_mh_.IsValid()) mh_ = original_mh_;
+  MakeOctreeDirty();
+  stat_calculated_ = false;
+  histogram_calculated_ = false;
+  Rebuild();
+  Scene::Instance().RequestRedraw();
+}
+
+
+void MapIso::MakeOctreeDirty()
+{
+  dirty_octree_=true;
+}
+
+MapIsoType MapIso::GetShownMapType() const
+{
+   MapIsoType ret = ORIGINAL_MAP;
+   if (mh_ == downsampled_mh_) {
+     ret = DOWNSAMPLED_MAP;
+   }
+   return ret;
+}
+
+bool MapIso::IfOctreeDirty() const
+{
+  return dirty_octree_;
+}
+
+/// \brief checks if the downsampled map is available
+bool MapIso::IsDownsampledMapAvailable() const
+{
+  return !(downsampled_mh_==img::ImageHandle());
+}
+
 img::ImageHandle MapIso::DownsampleMap(const img::ImageHandle& mh)
 {
   uint downsampling_fact = compute_downsampling_fact(mh);
   img:: ImageHandle ret_mh = mh;
   if (downsampling_fact != 1) {
+    LOG_MESSAGE("Downsampling map for more comfortable visualization")
     img::alg::DiscreteShrink shrink_alg(img::Size(downsampling_fact,downsampling_fact,downsampling_fact));
     ret_mh = mh.Apply(shrink_alg);
   }
diff --git a/modules/gfx/src/map_iso.hh b/modules/gfx/src/map_iso.hh
index 87eda29a9..9ed928632 100644
--- a/modules/gfx/src/map_iso.hh
+++ b/modules/gfx/src/map_iso.hh
@@ -26,12 +26,20 @@
 #include <boost/shared_ptr.hpp>
 
 #include <ost/img/map.hh>
+#include <ost/img/alg/stat.hh>
+#include <ost/img/alg/histogram.hh>
+
 #include <ost/gfx/impl/map_octree.hh>
 #include "gfx_object.hh"
 #include "map_iso_prop.hh"
 
 namespace ost { namespace gfx {
 
+enum MapIsoType {
+  ORIGINAL_MAP,
+  DOWNSAMPLED_MAP
+};
+
 class MapIso;
 typedef boost::shared_ptr<MapIso> MapIsoP;
 
@@ -67,6 +75,9 @@ public:
   /// Will force rebuild of the vertex buffers/indices
   void SetLevel(float l);
   
+  float GetMinLevel() const;
+  float GetMaxLevel() const;
+
   /// \brief get current isocontouring level
   float GetLevel() const;
 
@@ -76,6 +87,16 @@ public:
   /// \brief get std dev of map.
   float GetStdDev() const;
   
+
+  /// \brief get histogram
+  std::vector<int> GetHistogram() const;
+
+  /// \brief set Histogram bin count
+  void SetHistogramBinCount(int count);
+
+  /// \brief get Histogram bin count
+  int GetHistogramBinCount() const;
+
   /// \brief get the map handle of the currently displayed map
   // The following is a hack. For the DataViewer I need to pass a reference to an ImagHandle
   // that never goes out of scope, so I get a reference from here
@@ -86,6 +107,23 @@ public:
   // that never goes out of scope, so I get a reference from here
   img::ImageHandle& GetOriginalMap();
 
+  /// \brief get the map handle of the downsampled map
+  // The following is a hack. For the DataViewer I need to pass a reference to an ImagHandle
+  // that never goes out of scope, so I get a reference from here
+  img::ImageHandle& GetDownsampledMap();
+
+  /// \brief sets the donwsampled map to active
+  void ShowDownsampledMap();
+
+  /// \brief sets the original map to active
+  void ShowOriginalMap();
+
+  /// \brief checks if the downsampled map is available
+  bool IsDownsampledMapAvailable() const ;
+
+  /// \brief returns the type of map currently being show
+  MapIsoType GetShownMapType() const;
+
   /// \brief set  color
   /// 
   /// By default, the color is white.
@@ -100,25 +138,40 @@ public:
   const Color& GetColor() const { return color_; }
   void SetNSF(float smoothf);
   void SetDebugOctree(bool flag) { debug_octree_=flag; }
+
+  /// \brief flags the octree to be rebuilt
+  void MakeOctreeDirty();
+
+  /// \brief checks is the octree needs to be rebuilt
+  bool IfOctreeDirty() const;
+
 protected:
+  void CalculateStat() const;
+  void CalculateHistogram() const;
   virtual void CustomPreRenderGL(bool flag);
   static img::ImageHandle DownsampleMap(const img::ImageHandle& mh);
 
 private:
-  img::MapHandle   original_mh_;
-  img::MapHandle   downsampled_mh_;
-  img::MapHandle   mh_;
-  impl::MapOctree  octree_;
-  float            level_;
-  bool             normals_calculated_;
-  uint             alg_;
-  float            smoothf_;
-  float            min_;
-  float            max_;
-  float            std_dev_;
-  float            min_max_;
-  bool             debug_octree_;
-  Color            color_; 
+  img::MapHandle           original_mh_;
+  img::MapHandle           downsampled_mh_;
+  img::MapHandle           mh_;
+  impl::MapOctree          octree_;
+  mutable img::alg::Stat   stat_;
+  mutable bool             stat_calculated_;
+  mutable img::alg::Histogram   histogram_;
+  mutable bool             histogram_calculated_;
+  int                      histogram_bin_count_;
+  float                    level_;
+  bool                     normals_calculated_;
+  uint                     alg_;
+  float                    smoothf_;
+  float                    min_;
+  float                    max_;
+  float                    std_dev_;
+  float                    min_max_;
+  bool                     debug_octree_;
+  Color                    color_;
+  bool                     dirty_octree_;
 };
 
 }}
diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc
index c85abc13d..46af47626 100644
--- a/modules/gfx/src/scene.cc
+++ b/modules/gfx/src/scene.cc
@@ -604,6 +604,7 @@ void Scene::Remove(const GfxNodeP& go)
   if(!go) return;
   root_node_->Remove(go);
   this->NotifyObservers(bind(&SceneObserver::NodeRemoved, _1,go));
+  this->RequestRedraw();
 }
 
 void Scene::Remove(const String& name)
@@ -614,6 +615,7 @@ void Scene::Remove(const String& name)
     root_node_->Remove(name);
     if(GfxObjP go = dyn_cast<GfxObj>(fn.node)) {
       this->NotifyObservers(bind(&SceneObserver::NodeRemoved, _1,go));
+      this->RequestRedraw();
     }
   }
 }
diff --git a/modules/gfx/src/surface.cc b/modules/gfx/src/surface.cc
index e0d08cdc1..dbf740077 100644
--- a/modules/gfx/src/surface.cc
+++ b/modules/gfx/src/surface.cc
@@ -360,169 +360,4 @@ void Surface::ReapplyColorOps(){
   GfxObj::ReapplyColorOps();
 }
 
-// rsurf stuff
-using namespace mol::rsurf;
-
-RSurface::RSurface(const String& name, const RSurfP& rs):
-  GfxObj(name),
-  rs_(rs)
-{
-  ArcList alist = rs->GetArcList();
-  TetList tlist = rs->GetTetList();
-  SphereList slist = rs->GetSphereList();
-
-
-#if 0
-  for(TetList::const_iterator it=tlist.begin();it!=tlist.end();++it) {
-    VertexID id1 = va_.Add((*it)->A->pos,Vec3(),Color(1,1,1));
-    VertexID id2 = va_.Add((*it)->B->pos,Vec3(),Color(1,1,1));
-    VertexID id3 = va_.Add((*it)->C->pos,Vec3(),Color(1,1,1));
-    VertexID id4 = va_.Add((*it)->cA,Vec3(),Color(0,1,0));
-    VertexID id5 = va_.Add((*it)->cB,Vec3(),Color(0,1,0));
-    VertexID id6 = va_.Add((*it)->cC,Vec3(),Color(0,1,0));
-    va_.AddLine(id1,id4);
-    va_.AddLine(id2,id5);
-    va_.AddLine(id3,id6);
-    va_.AddLine(id4,id5);
-    va_.AddLine(id5,id6);
-    va_.AddLine(id6,id4);
-  }
-#endif
-
-#if 0
-  for(ArcList::const_iterator it=alist.begin();it!=alist.end();++it) {
-    Arc& arc= *(*it);
-    if(arc.S && arc.T) {
-      VertexID id0 = va_.Add(arc.S->pos,Vec3(),Color(1,0,0));
-      VertexID id1 = va_.Add(arc.mid,Vec3(),Color(1,1,1));
-      VertexID id2 = va_.Add(arc.T->pos,Vec3(),Color(1,0,1));
-      VertexID id3 = va_.Add(arc.H->pos,Vec3(),Color(1,1,1));
-      VertexID id4 = va_.Add(arc.K->pos,Vec3(),Color(1,1,1));
-      va_.AddLine(id0,id1);
-      va_.AddLine(id1,id2);
-      va_.AddLine(id1,id3);
-      va_.AddLine(id1,id4);
-    }
-  }
-#endif
-
-
-  for(SphereList::const_iterator it=slist.begin();it!=slist.end();++it) {
-    for(uint l=0;l<(*it)->arc_list_list.size();++l) {
-      const Sphere& sp = *(*it);
-      const ArcDirDeque& alist=sp.arc_list_list[l];
-      if(alist.empty()) continue; 
-
-      if(alist.size()<4) continue;
-      Vec3 a0 = alist[0].inv_arc ? -alist[0].arc->axis : alist[0].arc->axis;
-      Vec3 a1 = alist[1].inv_arc ? -alist[1].arc->axis : alist[1].arc->axis;
-      Vec3 s0 = alist[0].inv_arc ? alist[0].arc->T->pos : alist[0].arc->S->pos;
-      Vec3 s1 = alist[1].inv_arc ? alist[1].arc->T->pos : alist[1].arc->S->pos;
-      Vec3 p0 = sp.pos+sp.rad*(s0-sp.pos)/((sp.rad+alist[0].arc->S->rad));
-      Vec3 p1 = sp.pos+sp.rad*(s1-sp.pos)/((sp.rad+alist[1].arc->S->rad));
-
-      VertexID id00 = va_.Add(p0,Vec3(),Color(1,1,1));
-      VertexID id10 = va_.Add(p1,Vec3(),Color(1,1,1));
-      VertexID id20 = id00;
-
-      for(float c=0.0;c<=1.0;c+=0.1) {
-        Mat3 r0 = AxisRotation(a0,c*alist[0].arc->phi);
-        Mat3 r1 = AxisRotation(a1,c*alist[1].arc->phi);
-        Vec3 v0 = r0*(p0-alist[0].arc->fixpoint)+alist[0].arc->fixpoint;
-        Vec3 v1 = r1*(p1-alist[1].arc->fixpoint)+alist[1].arc->fixpoint;
-        Vec3 v2 = r1*(v0-alist[1].arc->fixpoint)+alist[1].arc->fixpoint;
-        VertexID id01 = va_.Add(v0,Vec3(),Color(1,1,1));
-        VertexID id11 = va_.Add(v1,Vec3(),Color(1,1,1));
-        VertexID id21 = va_.Add(v2,Vec3(),Color(1,c,0));
-        va_.AddLine(id00,id01);
-        va_.AddLine(id10,id11);
-        va_.AddLine(id20,id21);
-        id00=id01;
-        id10=id11;
-        id20=id21;
-      }
-
-#if 0
-      Vec3 sum1;
-      Vec3 sum2;
-      Vec3 sum3;
-      Vec3 prev;
-      float plan=0.0;
-      for(uint i=0;i<alist.size();++i) {
-        uint j = (i-1+alist.size())%alist.size();
-        uint k = (i+1)%alist.size();
-        sum1+=(alist[i].arc->mid-sp.pos)*alist[i].arc->phi;
-        Vec3 d0 = alist[i].arc->S->pos-sp.pos;
-        Vec3 d1 = alist[i].arc->mid-sp.pos;
-        Vec3 d2 = alist[i].arc->T->pos-sp.pos;
-
-        Vec3 p0 = sp.pos+sp.rad*(d0)/(sp.rad+alist[i].arc->S->rad);
-        Vec3 p1 = sp.pos+sp.rad*(d1)/(sp.rad+alist[i].arc->S->rad);
-        Vec3 p2 = sp.pos+sp.rad*(d2)/(sp.rad+alist[i].arc->S->rad);
-        Vec3 c0 = Normalize(Cross(Normalize(alist[i].w.pos-alist[i].v.pos),
-                                  Normalize(alist[k].w.pos-alist[k].v.pos))+
-                            Cross(Normalize(alist[j].w.pos-alist[j].v.pos),
-                                  Normalize(alist[i].w.pos-alist[i].v.pos)));
-        Vec3 c1 = Normalize(Cross(Normalize(p0-p1),Normalize(p2-p1)));
-
-        if(i>0) {
-          plan+=Dot(prev,Normalize(d1));
-        }
-        prev=Normalize(d1);
-        sum2+=c0*alist[i].arc->phi;
-
-        VertexID id0 = va_.Add(p0,Vec3(),Color(1,1,0));
-        VertexID id1 = va_.Add(p1,Vec3(),Color(1,1,1));
-        VertexID id2 = va_.Add(p2,Vec3(),Color(1,1,0));
-        VertexID id3 = va_.Add(sp.pos,Vec3(),Color(1,1,1));
-        va_.AddLine(id0,id1);
-        va_.AddLine(id1,id2);
-        //va_.AddLine(id1,id3);
-      }
-      float f = plan/static_cast<float>(alist.size());
-      VertexID id8 = va_.Add(sp.pos,Vec3(),Color(1,1,1));
-      VertexID id9 = va_.Add(sp.pos+1.1*sp.rad*Normalize(sum1),Vec3(),Color(0,0,1));
-      VertexID idA = va_.Add(sp.pos+1.1*sp.rad*Normalize(sum2),Vec3(),Color(1,0,0));
-      VertexID idB = va_.Add(sp.pos+1.1*sp.rad*Normalize(f*sum1+(1.0-f)*sum2),Vec3(),Color(0,1,0));
-      va_.AddLine(id8,id9);
-      va_.AddLine(id8,idA);
-      va_.AddLine(id8,idB);
-#endif
-#if 0
-      VertexID id0 = va_.Add(sp.pos,Vec3(),Color(1,1,1));
-      VertexID id1 = va_.Add(sp.top_list[l],Vec3(),Color(1,1,0));
-      va_.AddLine(id0,id1);
-#endif
-    }
-  }
-
-  va_.SetMode(0x2);
-  va_.SetLighting(false);
-  va_.SetCullFace(false);
-  va_.SetColorMaterial(true);
-
-}
-
-Vec3 RSurface::GetCenter() const
-{
-  return Vec3(0,0,0);
-}
-
-void RSurface::CustomRenderGL(RenderPass pass)
-{
-  if (!(pass==STANDARD_RENDER_PASS || pass==OPAQUE_RENDER_PASS)) 
-    return;
-  va_.RenderGL();
-}
-
-geom::AlignedCuboid RSurface::GetBoundingBox() const
-{
-  return geom::AlignedCuboid(Vec3(-1,-1,-1), Vec3(1,1,1));
-}
-
-void RSurface::ProcessLimits(Vec3& minc, Vec3& maxc, const mol::Transform& tf) const
-{
-  // nop
-}
-
 }} // ns
diff --git a/modules/gfx/src/surface.hh b/modules/gfx/src/surface.hh
index 186d41dc2..c8fc12834 100644
--- a/modules/gfx/src/surface.hh
+++ b/modules/gfx/src/surface.hh
@@ -123,24 +123,6 @@ private:
   boost::ptr_vector<gfx::ColorOp> c_ops_;
 };
 
-// temporary debug 
-class RSurface;
-typedef boost::shared_ptr<RSurface> RSurfaceP;
-
-class DLLEXPORT_OST_GFX RSurface: public GfxObj {
-public:
-  RSurface(const String& name, const mol::rsurf::RSurfP& rs);
-  virtual geom::Vec3 GetCenter() const;
-  virtual void CustomRenderGL(RenderPass pass);
-  
-  virtual geom::AlignedCuboid GetBoundingBox() const;
-
-  virtual void ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc, const mol::Transform& tf) const;
-
-private:
-  mol::rsurf::RSurfP rs_;
-};
-
 }} // ns
 
 #endif
diff --git a/modules/gfx/tests/CMakeLists.txt b/modules/gfx/tests/CMakeLists.txt
index a055e099e..fe6a3d670 100644
--- a/modules/gfx/tests/CMakeLists.txt
+++ b/modules/gfx/tests/CMakeLists.txt
@@ -4,10 +4,8 @@ set(OST_GFX_UNIT_TESTS
 )
 if (ENABLE_IMG)
   list(APPEND OST_GFX_UNIT_TESTS test_map_octree.cc)
-
-	ost_unittest(gfx "${OST_GFX_UNIT_TESTS}")
-
-	target_link_libraries(gfx_tests ost_io)
 endif()
 
+ost_unittest(gfx "${OST_GFX_UNIT_TESTS}")
 
+target_link_libraries(gfx_tests ost_io)
diff --git a/modules/gfx/tests/test_ent_pov_export.cc b/modules/gfx/tests/test_ent_pov_export.cc
index 450051dc7..2d1717eac 100644
--- a/modules/gfx/tests/test_ent_pov_export.cc
+++ b/modules/gfx/tests/test_ent_pov_export.cc
@@ -22,12 +22,17 @@
  */
 
 #include <fstream>
-#include <boost/test/unit_test.hpp>
 #include <ost/io/load_entity.hh>
 #include <ost/gfx/scene.hh>
 #include <ost/gfx/entity.hh>
 
+#include <ost/test_utils/compare_files.hh>
+
+#define BOOST_TEST_DYN_LINK
+#include <boost/test/unit_test.hpp>
+
 using boost::unit_test_framework::test_suite;
+
 using namespace ost;
 using namespace ost::gfx;
 
@@ -42,36 +47,6 @@ boost::shared_ptr<Entity> prepare_object(gfx::RenderMode::Type mode)
   return gfx_ent;
 }
 
-bool compare_files(const String& test, const String& gold_standard)
-{
-  std::ifstream test_stream(test.c_str());
-  std::ifstream gold_stream(gold_standard.c_str());
-  String test_line, gold_line;
-  while (true) {
-    bool test_end=std::getline(test_stream, test_line);
-    bool gold_end=std::getline(gold_stream, gold_line);
-    if (!(test_end || gold_end)) {
-      return true;
-    }
-    if (!test_end) {
-      std::cerr << gold_standard << " contains additional line(s):"
-                << std::endl << gold_line;
-      return false;
-    }
-    if (!gold_end) {
-      std::cerr << test << " contains additional line(s):"
-                << std::endl << test_line;
-      return false;
-    }
-    if (gold_line!=test_line) {
-      std::cerr << "line mismatch:" << std::endl << "test: " << test_line 
-                << std::endl << "gold: " << gold_line;
-      return false;
-    }
-  }
-  return true;
-}
-
 // The GfxView uses a std::map for efficient access to atoms. This however has 
 // implications for the POV export. In general we can't assume that the atoms 
 // are written in any particular order. That's why we first filter out all 
@@ -129,6 +104,7 @@ bool compare_sphere_cyl_entries(const String& test,
 }
 
 }
+
 BOOST_AUTO_TEST_SUITE(gfx)
 
 BOOST_AUTO_TEST_CASE(pov_export_simple)
@@ -156,7 +132,7 @@ BOOST_AUTO_TEST_CASE(pov_export_cartoon)
   Scene::Instance().SetOffscreenMode();
   boost::shared_ptr<Entity> obj=prepare_object(RenderMode::HSC);
   Scene::Instance().ExportPov("pov_cartoon_test", ".");
-  BOOST_CHECK(compare_files("pov_cartoon_test.inc", 
+  BOOST_CHECK(ost::compare_files("pov_cartoon_test.inc", 
                             "testfiles/pov_cartoon_std.inc"));
   Scene::Instance().Remove(obj);
 }
@@ -176,7 +152,7 @@ BOOST_AUTO_TEST_CASE(pov_export_trace)
   Scene::Instance().SetOffscreenMode();
   boost::shared_ptr<Entity> obj=prepare_object(RenderMode::TRACE);
   Scene::Instance().ExportPov("pov_trace_test", ".");
-  BOOST_CHECK(compare_files("pov_trace_test.inc", 
+  BOOST_CHECK(ost::compare_files("pov_trace_test.inc", 
                             "testfiles/pov_trace_std.inc"));
   Scene::Instance().Remove(obj);
 }
@@ -186,7 +162,7 @@ BOOST_AUTO_TEST_CASE(pov_export_line_trace)
   Scene::Instance().SetOffscreenMode();
   boost::shared_ptr<Entity> obj=prepare_object(RenderMode::LINE_TRACE);
   Scene::Instance().ExportPov("pov_line_trace_test", ".");
-  BOOST_CHECK(compare_files("pov_line_trace_test.inc", 
+  BOOST_CHECK(ost::compare_files("pov_line_trace_test.inc", 
                             "testfiles/pov_line_trace_std.inc"));
   Scene::Instance().Remove(obj);
 }
@@ -196,7 +172,7 @@ BOOST_AUTO_TEST_CASE(pov_export_sline)
   Scene::Instance().SetOffscreenMode();
   boost::shared_ptr<Entity> obj=prepare_object(RenderMode::SLINE);
   Scene::Instance().ExportPov("pov_sline_test", ".");
-  BOOST_CHECK(compare_files("pov_sline_test.inc", 
+  BOOST_CHECK(ost::compare_files("pov_sline_test.inc", 
                             "testfiles/pov_sline_std.inc"));
   Scene::Instance().Remove(obj);
 }
diff --git a/modules/gfx/tests/test_map_octree.cc b/modules/gfx/tests/test_map_octree.cc
index 819b38618..31dd637f7 100644
--- a/modules/gfx/tests/test_map_octree.cc
+++ b/modules/gfx/tests/test_map_octree.cc
@@ -21,10 +21,14 @@
   Author: Marco Biasini
  */
 
-#include <boost/test/unit_test.hpp>
+#include <ost/gfx/impl/map_octree.hh>
+
 #include <ost/img/image_handle.hh>
 #include <ost/img/image_factory.hh>
-#include <ost/gfx/impl/map_octree.hh>
+
+#define BOOST_TEST_DYN_LINK
+#include <boost/test/unit_test.hpp>
+
 
 using boost::unit_test_framework::test_suite;
 using namespace ost;
@@ -174,6 +178,7 @@ BOOST_AUTO_TEST_CASE(octree_power_of_two)
   img.SetReal(img::Point(0, 0, 1), 0.5f);
   Pow2Vis v;
   MapOctree octree(img);
+  octree.Initialize();
   octree.VisitDF(v);  
   BOOST_CHECK_EQUAL(v.leaf_count, 8);
   BOOST_CHECK_EQUAL(v.node_count, 1);
@@ -192,6 +197,7 @@ BOOST_AUTO_TEST_CASE(octree_non_power_of_two)
   img.SetReal(img::Point(0, 0, 1), 0.5f);
   NonPow2Vis v;
   MapOctree octree(img);
+  octree.Initialize();
   octree.VisitDF(v);  
 }
 
diff --git a/modules/gui/pymod/CMakeLists.txt b/modules/gui/pymod/CMakeLists.txt
index 200515b96..9b1353330 100644
--- a/modules/gui/pymod/CMakeLists.txt
+++ b/modules/gui/pymod/CMakeLists.txt
@@ -9,7 +9,6 @@ set(OST_GUI_PYMOD_SOURCES
   export_remote_site_loader.cc
   export_scene_win.cc
   export_sequence_viewer.cc
-  export_sequence_viewerV2.cc
   export_perspective.cc
   export_sip_handler.cc
   export_scene_selection.cc
@@ -35,6 +34,7 @@ immutable_gradient_info_handler.py
 immutable_preset_info_handler.py
 init_inspector.py
 inspector_widget.py
+map_level_widget.py
 preset.py
 preset_editor_list_model.py
 preset_editor_widget.py
@@ -45,6 +45,7 @@ render_mode_widget.py
 render_op.py
 render_options_widget.py
 scene_observer_impl.py
+scene_selection_helper.py
 simple_widget.py
 sline_widget.py
 toolbar_options_widget.py
@@ -58,6 +59,7 @@ loader_list_model.py
 loader_manager_widget.py
 immutable_loader_info_handler.py
 line_trace_widget.py
+wireframe_widget.py
 )
 if (ENABLE_IMG)
   list(APPEND OST_GUI_PYMOD_SOURCES
diff --git a/modules/gui/pymod/export_gosty.cc b/modules/gui/pymod/export_gosty.cc
index 9cd97b7fd..0f32ef31e 100644
--- a/modules/gui/pymod/export_gosty.cc
+++ b/modules/gui/pymod/export_gosty.cc
@@ -27,7 +27,6 @@ using namespace boost::python;
 #include <ost/gui/perspective.hh>
 #include <ost/gui/python_shell/python_shell.hh>
 #include <ost/gui/scene_win/scene_win.hh>
-#include <ost/gui/sequence_viewer/sequence_viewer.hh>
 #include <ost/gui/tools/tool_options_win.hh>
 
 #include "transfer_ownership.hh"
@@ -96,10 +95,6 @@ void export_Gosty()
         return_value_policy<reference_existing_object>())
     .add_property("seq_viewer", make_function(&GostyApp::GetSequenceViewer,
         return_value_policy<reference_existing_object>()))
-    .def("GetSequenceViewerV2", &GostyApp::GetSequenceViewerV2,
-        return_value_policy<reference_existing_object>())
-    .add_property("seq_viewer_v2", make_function(&GostyApp::GetSequenceViewerV2,
-        return_value_policy<reference_existing_object>()))
     .def("GetToolOptionsWin", &GostyApp::GetToolOptionsWin,
         return_value_policy<reference_existing_object>())
     .add_property("tool_options_win", make_function(&GostyApp::GetToolOptionsWin,
diff --git a/modules/gui/pymod/export_overlay.cc b/modules/gui/pymod/export_overlay.cc
index d5293ddd0..4a19bceeb 100644
--- a/modules/gui/pymod/export_overlay.cc
+++ b/modules/gui/pymod/export_overlay.cc
@@ -118,8 +118,8 @@ void export_overlay()
     .def("ClearMask",&MaskOverlay::ClearMask)
     .def("GetShift",&MaskOverlay::GetShift)
     .def("ClearShift",&MaskOverlay::ClearShift)
-   // .def("SetShift",&MaskOverlay::SetShift)
-   // .def("ApplyShiftToMask",&MaskOverlay::ApplyShiftToMask)
+    .def("SetShift",&MaskOverlay::SetShift)
+    .def("ApplyShiftToMask",&MaskOverlay::ApplyShiftToMask)
     ;
 
 /*  class_<Gauss2DOverlay,bases<Overlay>,boost::noncopyable>("Gauss2DOverlay",init<const alg::ParamsGauss2D&>())
diff --git a/modules/gui/pymod/export_sequence_viewer.cc b/modules/gui/pymod/export_sequence_viewer.cc
index e6127166c..32e79ed48 100644
--- a/modules/gui/pymod/export_sequence_viewer.cc
+++ b/modules/gui/pymod/export_sequence_viewer.cc
@@ -16,7 +16,10 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
+#include <vector>
+
 #include <boost/python.hpp>
+#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
 
 #include <ost/gui/sequence_viewer/sequence_viewer.hh>
 
@@ -26,12 +29,88 @@ using namespace boost::python;
 using namespace ost;
 using namespace ost::gui;
 
+namespace {
+
+void change_display_mode_a(SequenceViewer* seq_viewer, const QString& mode)
+{
+  seq_viewer->ChangeDisplayMode(mode);
+}
+
+void change_display_mode_b(SequenceViewer* seq_viewer, const gfx::EntityP& entity, const QString& mode)
+{
+  seq_viewer->ChangeDisplayMode(entity, mode);
+}
+
+void change_display_mode_c(SequenceViewer* seq_viewer, const seq::AlignmentHandle& alignment, const QString& mode)
+{
+  seq_viewer->ChangeDisplayMode(alignment, mode);
+}
+
+String get_current_display_mode_a(SequenceViewer* seq_viewer)
+{
+  return seq_viewer->GetCurrentDisplayMode().toStdString();
+}
+
+String get_current_display_mode_b(SequenceViewer* seq_viewer, const gfx::EntityP& entity)
+{
+  return seq_viewer->GetCurrentDisplayMode(entity).toStdString();
+}
+
+String get_current_display_mode_c(SequenceViewer* seq_viewer, const seq::AlignmentHandle& alignment)
+{
+  return seq_viewer->GetCurrentDisplayMode(alignment).toStdString();
+}
+
+std::vector<String> get_display_modes_a(SequenceViewer* seq_viewer)
+{
+  std::vector<String> modes;
+  const QStringList& list = seq_viewer->GetDisplayModes();
+  for (int i=0; i<list.size(); i++){
+    modes.push_back(list.at(i).toStdString());
+  }
+  return modes;
+}
+
+std::vector<String> get_display_modes_b(SequenceViewer* seq_viewer, const gfx::EntityP& entity)
+{
+  std::vector<String> modes;
+  const QStringList& list = seq_viewer->GetDisplayModes(entity);
+  for (int i=0; i<list.size(); i++){
+    modes.push_back(list.at(i).toStdString());
+  }
+  return modes;
+}
+
+std::vector<String> get_display_modes_c(SequenceViewer* seq_viewer, const seq::AlignmentHandle& alignment)
+{
+  std::vector<String> modes;
+  const QStringList& list = seq_viewer->GetDisplayModes(alignment);
+  for (int i=0; i<list.size(); i++){
+    modes.push_back(list.at(i).toStdString());
+  }
+  return modes;
+}
+
+}
+
 
 void export_SequenceViewer()
 {
-  class_<SequenceViewer, boost::noncopyable >("SequenceViewer", no_init)
+  class_<SequenceViewer, boost::noncopyable >("SequenceViewer",init<>())
+    .def(init<bool, optional<QWidget*> >())
     .def("Show", &SequenceViewer::show)
     .def("Hide", &SequenceViewer::hide)
+    .def("AddAlignment", &SequenceViewer::AddAlignment)
+    .def("RemoveAlignment", &SequenceViewer::RemoveAlignment)
+    .def("GetDisplayModes", &get_display_modes_a)
+    .def("GetDisplayModes", &get_display_modes_b)
+    .def("GetDisplayModes", &get_display_modes_c)
+    .def("GetCurrentDisplayMode", &get_current_display_mode_a)
+    .def("GetCurrentDisplayMode", &get_current_display_mode_b)
+    .def("GetCurrentDisplayMode", &get_current_display_mode_c)
+    .def("ChangeDisplayMode",&change_display_mode_a)
+    .def("ChangeDisplayMode",&change_display_mode_b)
+    .def("ChangeDisplayMode",&change_display_mode_c)
     .def("GetQObject",&get_py_qobject<SequenceViewer>)
     .add_property("qobject", &get_py_qobject<SequenceViewer>)
   ;
diff --git a/modules/gui/pymod/export_tool.cc b/modules/gui/pymod/export_tool.cc
index 730673364..946340659 100644
--- a/modules/gui/pymod/export_tool.cc
+++ b/modules/gui/pymod/export_tool.cc
@@ -45,7 +45,7 @@ struct WrappedTool : public Tool
     {
       try {
         return call_method<void, MouseEvent>(self, "Click", event);
-      } catch(error_already_set& e) {
+      } catch(error_already_set& ) {
         PyErr_Print();
       }
     }
@@ -58,7 +58,7 @@ struct WrappedTool : public Tool
     {
       try {
         return call_method< bool, gfx::NodePtrList >(self, "CanOperateOn", nodes);
-      } catch(error_already_set& e) {
+      } catch(error_already_set& ) {
         PyErr_Print();
       }
       return false;
@@ -71,7 +71,7 @@ struct WrappedTool : public Tool
         String loc = call_method<String>(self, "GetIconPath");
         QIcon icon = QIcon(loc.c_str());
         return icon;
-      } catch(error_already_set& e) {
+      } catch(error_already_set& ) {
         PyErr_Print();
       }
       QIcon icon = QIcon();
diff --git a/modules/gui/pymod/scene/color_options_widget.py b/modules/gui/pymod/scene/color_options_widget.py
index 2683a745d..7ec80e1a5 100644
--- a/modules/gui/pymod/scene/color_options_widget.py
+++ b/modules/gui/pymod/scene/color_options_widget.py
@@ -22,7 +22,15 @@ import sys
 from ost import mol
 from ost import gui
 from ost import gfx
+try: 
+  from ost import img
+  _img_present=True
+except ImportError:
+  _img_present=False
+  pass
+
 from PyQt4 import QtCore, QtGui
+from scene_selection_helper import SelHelper
 from gradient_editor_widget import GradientEditor
 from uniform_color_widget import UniformColorWidget
 from combo_options_widget import ComboOptionsWidget
@@ -35,11 +43,15 @@ class ColorOptionsWidget(ComboOptionsWidget):
     self.text_ = "Color Options"
     
     #Add options to menu
-    self.AddWidget("Color by Element", ByElementWidget("Color by Element"))
-    self.AddWidget("Color by Chain", ByChainWidget("Color by Chain"))
-    self.AddWidget("Color by Property", GradientEditor(self))
-    self.AddWidget("Uniform",UniformColorWidget(self))
+    self.entity_widgets_ = list()
+    self.entity_widgets_.append(["Color by Element", ByElementWidget("Color by Element")])
+    self.entity_widgets_.append(["Color by Chain", ByChainWidget("Color by Chain")])
+    self.entity_widgets_.append(["Color by Property", GradientEditor()])
+    self.entity_widgets_.append(["Uniform",UniformColorWidget()])
   
+    self.img_widgets_ = list()
+    self.img_widgets_.append(["Uniform",UniformColorWidget()])
+
     self.setMinimumSize(250,200)
     
   def DoSomething(self, item):
@@ -57,19 +69,31 @@ class ColorOptionsWidget(ComboOptionsWidget):
     
     
   def Update(self):
+    
     ComboOptionsWidget.setEnabled(self,True)
-    scene_selection = gui.SceneSelection.Instance()
     
-    if scene_selection.GetActiveNodeCount() == 0 and scene_selection.GetActiveViewCount() == 0:
+    if SelHelper().CheckAllFlags(SelHelper.NO_SELECTION):
       ComboOptionsWidget.setEnabled(self,False)
       return
-        
-    for i in range(0,scene_selection.GetActiveNodeCount()):
-      node = scene_selection.GetActiveNode(i)
-      if not (isinstance(node, gfx.Entity) or isinstance(node, gfx.Surface)):
-        ComboOptionsWidget.setEnabled(self,False)
-        return
-
+    
+    for w in self.entity_widgets_:
+      self.RemoveWidget(w[0])
+    for w in self.img_widgets_:
+      self.RemoveWidget(w[0])
+    
+    
+    if SelHelper().CheckFlags(SelHelper.HAS_IMG | SelHelper.IS_ONE_TYPE):
+      for w in self.img_widgets_:
+        self.AddWidget(w[0], w[1])
+    elif SelHelper().CheckMinOneFlag(SelHelper.HAS_ENTITY| SelHelper.HAS_VIEW| SelHelper.HAS_SURFACE) and SelHelper().CheckNotFlags(SelHelper.HAS_IMG):
+      for w in self.entity_widgets_:
+        self.AddWidget(w[0], w[1])
+    else:
+      ComboOptionsWidget.setEnabled(self,False)
+      return
+    
+    self.GetCurrentWidget().Update()
+    
   def GetText(self):
     return self.text_
   
diff --git a/modules/gui/pymod/scene/color_select_widget.py b/modules/gui/pymod/scene/color_select_widget.py
index a02986b7b..b8de8bf04 100644
--- a/modules/gui/pymod/scene/color_select_widget.py
+++ b/modules/gui/pymod/scene/color_select_widget.py
@@ -59,11 +59,19 @@ class ColorSelectWidget(QtGui.QWidget):
   def GetColor(self):
     return self.color_
   
+  def GetGfxColor(self):
+    color = self.GetColor()
+    return gfx.Color(color.redF(), color.greenF(), color.blueF())
+  
   def SetColor(self, color):
     if(self.color_ != color):
       self.color_ = color
       self.emit(QtCore.SIGNAL("colorChanged"))
       self.update()
+  
+  def SetGfxColor(self, color):
+    qcolor= QtGui.QColor(color.Red()*255,color.Green()*255,color.Blue()*255,color.Alpha()*255)
+    self.SetColor(qcolor)
             
   def paintEvent(self, event):
     if self.isEnabled():
diff --git a/modules/gui/pymod/scene/combo_options_widget.py b/modules/gui/pymod/scene/combo_options_widget.py
index dea16f037..b84630cc1 100644
--- a/modules/gui/pymod/scene/combo_options_widget.py
+++ b/modules/gui/pymod/scene/combo_options_widget.py
@@ -81,7 +81,7 @@ class ComboOptionsWidget(QtGui.QWidget):
   def RemoveWidget(self,ident):
     index = self.__GetIndex(ident)
     if(index >= 0):
-      self.stacked_widget_.removeWidget(self.combo_box_.itemData().toPyObject()[1])
+      self.stacked_widget_.removeWidget(self.combo_box_.itemData(index).toPyObject()[1])
       self.combo_box_.removeItem(index)
   
   def DoSomething(self, item):
@@ -103,7 +103,9 @@ class ComboOptionsWidget(QtGui.QWidget):
       self.__UpdateView(None)
   
   def GetCurrentWidget(self):
-    return self.__GetCurrentPair()[1]
+    if(self.combo_box_.currentIndex() >= 0):
+      return self.__GetCurrentPair()[1]
+    return None
   
   def DoResize(self):
     item = self.GetCurrentWidget()
@@ -127,7 +129,7 @@ class ComboOptionsWidget(QtGui.QWidget):
   def __GetIndex(self, ident):
     for i in range(self.combo_box_.count()):
       pair = self.combo_box_.itemData(i).toPyObject()
-      if ident == pair[0] and i != self.combo_box_.currentIndex():
+      if ident == pair[0]:
         return i
     return -1
   
diff --git a/modules/gui/pymod/scene/inspector_widget.py b/modules/gui/pymod/scene/inspector_widget.py
index 4e7e7f761..25082a267 100644
--- a/modules/gui/pymod/scene/inspector_widget.py
+++ b/modules/gui/pymod/scene/inspector_widget.py
@@ -28,7 +28,8 @@ from toolbar_options_widget import ToolBarOptionsWidget
 from render_options_widget import RenderOptionsWidget
 from color_options_widget import ColorOptionsWidget
 from ost.gui.scene.scene_observer_impl import SceneObserverImpl
-from preset_widget import PresetWidget
+from map_level_widget import AdditionalSettingsWidget
+from scene_selection_helper import SelHelper
 
 class InspectorWidget(ToolBarOptionsWidget):
   ICONS_PATH = os.path.join(ost.GetSharedDataPath(), "scene", "icons/")
@@ -38,7 +39,7 @@ class InspectorWidget(ToolBarOptionsWidget):
     options = [
                 [InspectorWidget.ICONS_PATH+"render_icon.png",RenderOptionsWidget(self),None], 
                 [InspectorWidget.ICONS_PATH+"color_icon.png",ColorOptionsWidget(self),None],
-                [InspectorWidget.ICONS_PATH+"preset_icon.png", PresetWidget(self),None],
+                [InspectorWidget.ICONS_PATH+"preset_icon.png", AdditionalSettingsWidget(self),"Additional Node Settings"],
                 [InspectorWidget.ICONS_PATH+"tool_icon.png",app.tool_options_win.qobject,"Tool Options"]
               ]
     for o in options:
@@ -46,8 +47,7 @@ class InspectorWidget(ToolBarOptionsWidget):
     
     self.obs = SceneObserverImpl()
     self.obs.AttachObserver(self)
-    ost.scene.AttachObserver(self.obs)    
-    self.scene_selection_ = gui.SceneSelection.Instance()
+    ost.scene.AttachObserver(self.obs)
     QtCore.QObject.connect(app.scene_win.qobject,QtCore.SIGNAL("ActiveNodesChanged()"),
                            self.ActiveNodesChanged)     
     
@@ -58,15 +58,19 @@ class InspectorWidget(ToolBarOptionsWidget):
         
   #Observer Methods    
   def NodeRemoved(self, node):
+    SelHelper().Update()
     ToolBarOptionsWidget.Update(self)  
   
   def RenderModeChanged(self, node):
+    SelHelper().Update()
     ToolBarOptionsWidget.Update(self)
    
   def NodeChanged(self, node):
+    SelHelper().Update()
     ToolBarOptionsWidget.Update(self)
 
   def ActiveNodesChanged(self):
+    SelHelper().Update()
     ToolBarOptionsWidget.Update(self)
 
 class InspectorDialog(QtGui.QDialog):
diff --git a/modules/gui/pymod/scene/map_level_widget.py b/modules/gui/pymod/scene/map_level_widget.py
new file mode 100644
index 000000000..fd4f4d15a
--- /dev/null
+++ b/modules/gui/pymod/scene/map_level_widget.py
@@ -0,0 +1,246 @@
+#------------------------------------------------------------------------------
+# This file is part of the OpenStructure project <www.openstructure.org>
+#
+# Copyright (C) 2008-2010 by the OpenStructure authors
+#
+# This library is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3.0 of the License, or (at your option)
+# any later version.
+# This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+#------------------------------------------------------------------------------
+# -*- coding: utf-8 -*-
+import math
+from ost import gui
+from ost import gfx
+try: 
+  from ost import img
+  _img_present=True
+except ImportError:
+  _img_present=False
+  pass
+from PyQt4 import QtCore, QtGui
+
+from preset_widget import PresetWidget
+
+class AdditionalSettingsWidget(QtGui.QStackedWidget):
+  def __init__(self, parent=None):
+    QtGui.QStackedWidget.__init__(self, parent)
+    self.map_widget_ = MapLevelWidget(self)
+    self.preset_widget_ = PresetWidget(self)
+    self.addWidget(self.preset_widget_);
+    self.addWidget(self.map_widget_);
+    self.setContentsMargins(0,0,0,0)
+    self.setMinimumSize(self.preset_widget_.minimumSize())
+    
+  def Update(self):
+    self.setEnabled(True)
+    scene_selection = gui.SceneSelection.Instance()
+    all_img = True
+    all_entity = True
+    for i in range(0,scene_selection.GetActiveNodeCount()):
+      node = scene_selection.GetActiveNode(i)
+      if not (isinstance(node, gfx.Entity) or isinstance(node, gfx.Surface)):
+        all_entity = False
+      if (not _img_present) or (not isinstance(node, gfx.MapIso)):
+        all_img = False
+    if all_img:
+      self.map_widget_.Update()
+      self.setMinimumSize(self.map_widget_.minimumSize())
+      self.resize(self.map_widget_.minimumSize())
+      self.setMinimumSize(self.map_widget_.minimumSize())
+      self.setCurrentWidget(self.map_widget_)
+    elif all_entity:
+      self.preset_widget_.Update()
+      self.setMinimumSize(self.preset_widget_.minimumSize())
+      self.resize(self.preset_widget_.minimumSize())
+      self.setMinimumSize(self.preset_widget_.minimumSize())
+      self.setCurrentWidget(self.preset_widget_)
+    else:
+      self.setEnabled(False)
+    
+#Map Level Widget
+class MapLevelWidget(QtGui.QWidget):
+  def __init__(self, parent=None):
+    QtGui.QWidget.__init__(self, parent)
+    
+    #Create Ui elements
+    map_level_label = QtGui.QLabel("Map Contour Level")
+    font = map_level_label.font()
+    font.setBold(True)
+    
+    self.level_preview_ = LevelPreview()
+    
+    self.level_spinbox_ = QtGui.QDoubleSpinBox()
+    self.level_spinbox_.setDecimals(3)
+    self.level_spinbox_.setSingleStep(0.05)
+    
+    grid = QtGui.QGridLayout()
+    grid.setContentsMargins(0,5,0,0)
+    grid.addWidget(self.level_preview_, 0, 0, 1, 4)
+    grid.addWidget(map_level_label, 1, 0, 1, 3)
+    grid.addWidget(self.level_spinbox_,1,3,1,1)
+    grid.setRowStretch(3, 1)
+    self.setLayout(grid)
+    
+    QtCore.QObject.connect(self.level_preview_, QtCore.SIGNAL("levelUpdated"), self.UpdateLevel)
+    QtCore.QObject.connect(self.level_preview_, QtCore.SIGNAL("levelModified"), self.ModifySpinBox)
+    QtCore.QObject.connect(self.level_spinbox_, QtCore.SIGNAL("valueChanged(double)"), self.UpdateLevel)
+
+    self.setMinimumSize(250,200)
+        
+  def Update(self):
+    scene_selection = gui.SceneSelection.Instance()
+    if(scene_selection.GetActiveNodeCount()==1):
+      node = scene_selection.GetActiveNode(0)
+      if _img_present and isinstance(node, gfx.MapIso):
+        self.level_preview_.SetBins(node.GetHistogram())
+        self.level_preview_.SetMinimum(node.GetMinLevel())
+        self.level_spinbox_.setMinimum(node.GetMinLevel())
+        self.level_preview_.SetMaximum(node.GetMaxLevel())
+        self.level_spinbox_.setMaximum(node.GetMaxLevel())
+        self.level_preview_.SetLevel(node.GetLevel())
+        self.setEnabled(True)
+      else:
+        self.setEnabled(False)
+    else:
+      self.setEnabled(False)
+        
+  def UpdateLevel(self, level):
+    scene_selection = gui.SceneSelection.Instance()
+    if(scene_selection.GetActiveNodeCount()==1):
+      node = scene_selection.GetActiveNode(0)
+      node.SetLevel(level)
+      
+  def ModifySpinBox(self, level):
+    QtCore.QObject.disconnect(self.level_spinbox_, QtCore.SIGNAL("valueChanged(double)"), self.UpdateLevel)
+    self.level_spinbox_.setValue(level)
+    QtCore.QObject.connect(self.level_spinbox_, QtCore.SIGNAL("valueChanged(double)"), self.UpdateLevel)
+        
+#Level Preview
+class LevelPreview(QtGui.QWidget):
+  def __init__(self, parent=None):
+    QtGui.QWidget.__init__(self, parent)
+    
+    #Defaults
+    self.border_offset_ = 3
+    self.preview_height_ = 150
+    QtGui.QWidget.__init__(self, parent)
+    
+    #Ui
+    self.setMinimumSize(0, self.preview_height_ + 4)
+
+    self.bins_ = None
+    self.level_ = 0
+    self.minimum_ = 0
+    self.maximum_ = 0
+    
+    self.paint_mouse_=False
+    
+  def SetBins(self, bins):
+    self.bins_ = bins
+    self.update()
+
+  def SetMaximum(self, max):
+    self.maximum_ = max
+
+  def SetMinimum(self, min):
+    self.minimum_ = min
+    
+  def SetLevel(self, level):
+    self.level_ = level
+
+  def GetLevel(self):
+    return self.level_
+    
+  def paintEvent(self, event):   
+    if self.isEnabled() and self.bins_ is not None:
+      painter = QtGui.QPainter()
+      if painter.begin(self):
+        self.PaintBackground(painter)
+        self.PaintBins(painter)
+        self.PaintLevel(painter)
+        if(self.paint_mouse_):
+          self.PaintMouse(painter)
+      painter.end()
+
+  def PaintBackground(self,painter):
+    size = self.size()
+    painter.setBrush(QtCore.Qt.white)
+    painter.setPen(QtCore.Qt.white)
+    painter.drawRect(self.border_offset_,
+                   self.border_offset_,
+                   size.width() - 2 * self.border_offset_,
+                   self.preview_height_)
+
+  def PaintBins(self,painter):
+    size = self.size()
+    bin_cnt = len(self.bins_)
+    bin_width = (size.width()-2* self.border_offset_) / float(bin_cnt)
+    max=0
+    for b in self.bins_:
+      if(b>max):
+        max = b
+    max = math.log(max)
+    if(max > 0):
+      painter.setBrush(QtCore.Qt.black)
+      painter.setPen(QtCore.Qt.black)
+      for i in range(0,bin_cnt):
+        bin_height = self.bins_[i]
+        if(bin_height>0):
+          bin_height = math.floor((math.log(bin_height)/max)*(self.preview_height_-2*(self.border_offset_)))
+          painter.drawRect(self.border_offset_ + (i*bin_width),
+                         self.preview_height_ - bin_height,
+                         bin_width,
+                         bin_height)
+
+  def PaintLevel(self,painter):
+    size = self.size()
+    width = size.width()-(2* self.border_offset_)
+    tot_len = self.maximum_-self.minimum_
+    if(tot_len>0):
+      cur_len = self.level_-self.minimum_
+      painter.setBrush(QtCore.Qt.red)
+      painter.setPen(QtCore.Qt.red)
+      painter.drawRect((width / tot_len) * cur_len,
+                     self.border_offset_,
+                     1,
+                     self.preview_height_)
+
+  def PaintMouse(self,painter):
+    size = self.size()
+    width = size.width()-(2* self.border_offset_)
+    painter.setBrush(QtCore.Qt.gray)
+    painter.setPen(QtCore.Qt.gray)
+    pos=self.mapFromGlobal(QtGui.QCursor.pos())
+    painter.drawRect(pos.x(),
+                   self.border_offset_,
+                   1,
+                   self.preview_height_)
+
+  def mouseReleaseEvent(self, event):
+    self.paint_mouse_=False
+    size = self.size()
+    width = size.width()-(2* self.border_offset_)
+    tot_len = self.maximum_-self.minimum_
+    self.level_ = self.minimum_ + float(event.x())/width * tot_len
+    self.update()
+    self.emit(QtCore.SIGNAL("levelUpdated"),(self.level_))
+  
+  def mousePressEvent(self,event):
+    self.paint_mouse_=True
+    
+  def mouseMoveEvent(self, event):
+    size = self.size()
+    width = size.width()-(2* self.border_offset_)
+    tot_len = self.maximum_-self.minimum_
+    level = self.minimum_ + float(event.x())/width * tot_len
+    self.emit(QtCore.SIGNAL("levelModified"),(level))
+    self.update()
\ No newline at end of file
diff --git a/modules/gui/pymod/scene/preset_widget.py b/modules/gui/pymod/scene/preset_widget.py
index d581a38ea..dc97b10f7 100644
--- a/modules/gui/pymod/scene/preset_widget.py
+++ b/modules/gui/pymod/scene/preset_widget.py
@@ -23,6 +23,7 @@ import ost
 import os
 from datetime import datetime
 from PyQt4 import QtCore, QtGui
+from scene_selection_helper import SelHelper
 from preset_list_model import PresetListModel
 from preset_editor_widget import PresetEditor
 from preset import Preset
@@ -67,7 +68,7 @@ class PresetWidget(QtGui.QWidget):
   
     QtCore.QObject.connect(self.list_view_, QtCore.SIGNAL("doubleClicked(const QModelIndex)"), self.Load)
     
-    self.setMinimumSize(250,150)
+    self.setMinimumSize(250,200)
     
   def CreateImmutableContextMenu(self):  
     self.immucontext_menu_ = QtGui.QMenu("Context menu", self)
@@ -145,16 +146,13 @@ class PresetWidget(QtGui.QWidget):
   
   def Update(self):
     self.setEnabled(True)
-    scene_selection = gui.SceneSelection.Instance()
-    if scene_selection.GetActiveNodeCount() == 0:
+    if SelHelper().CheckAllFlags(SelHelper.NO_SELECTION):
       self.setEnabled(False)
       return
     
-    for i in range(0,scene_selection.GetActiveNodeCount()):
-      entity = scene_selection.GetActiveNode(i)
-      if not isinstance(scene_selection.GetActiveNode(i), gfx.Entity):
-        self.setEnabled(False)
-        return
+    if SelHelper().CheckNotFlags(SelHelper.HAS_ENTITY | SelHelper.IS_ONE_TYPE):
+      self.setEnabled(False)
+      return
 
   def Rename(self):
     if(self.list_view_.currentIndex().isValid()):
diff --git a/modules/gui/pymod/scene/render_mode_widget.py b/modules/gui/pymod/scene/render_mode_widget.py
index 68150543a..271ae6699 100644
--- a/modules/gui/pymod/scene/render_mode_widget.py
+++ b/modules/gui/pymod/scene/render_mode_widget.py
@@ -44,7 +44,7 @@ class RenderModeWidget(QtGui.QWidget):
     
     scene_selection = gui.SceneSelection.Instance()
     if scene_selection.GetActiveNodeCount() == 0 and scene_selection.GetActiveViewCount() == 0:
-      ComboOptionsWidget.setEnabled(self,False)
+      self.setEnabled(False)
       return
     
     if scene_selection.GetActiveNodeCount() > 0 :
@@ -53,7 +53,7 @@ class RenderModeWidget(QtGui.QWidget):
         if isinstance(entity, gfx.Entity):
           self.entities_.add(entity)
         else:
-          ComboOptionsWidget.setEnabled(self,False)
+          self.setEnabled(False)
           return
 
     if scene_selection.GetActiveViewCount() > 0 :
diff --git a/modules/gui/pymod/scene/render_options_widget.py b/modules/gui/pymod/scene/render_options_widget.py
index 4b61a1216..cc22f3cc1 100644
--- a/modules/gui/pymod/scene/render_options_widget.py
+++ b/modules/gui/pymod/scene/render_options_widget.py
@@ -21,7 +21,15 @@
 import sys
 from ost import gui
 from ost import gfx
+try: 
+  from ost import img
+  from wireframe_widget import WireframeWidget
+  _img_present=True
+except ImportError:
+  _img_present=False
+  pass
 from PyQt4 import QtCore, QtGui
+from scene_selection_helper import SelHelper
 from combo_options_widget import ComboOptionsWidget
 from custom_widget import CustomWidget
 from cpk_widget import CPKWidget
@@ -50,34 +58,41 @@ class RenderOptionsWidget(ComboOptionsWidget):
     self.grid_layout_.addWidget(self.stacked_widget_, 1, 0, 1, 2)
     
     #Add options to menu    
-    ComboOptionsWidget.AddWidget(self, "", EmptyMode())
-    ComboOptionsWidget.AddWidget(self, gfx.RenderMode.SIMPLE, SimpleWidget(self))
-    ComboOptionsWidget.AddWidget(self, gfx.RenderMode.CUSTOM, CustomWidget(self))
-    ComboOptionsWidget.AddWidget(self, gfx.RenderMode.CPK, CPKWidget(self))
-    ComboOptionsWidget.AddWidget(self, gfx.RenderMode.LINE_TRACE, LineTraceWidget(self))    
-    ComboOptionsWidget.AddWidget(self, gfx.RenderMode.TRACE, TraceWidget(self))
-    ComboOptionsWidget.AddWidget(self, gfx.RenderMode.SLINE, SlineWidget(self))
-    ComboOptionsWidget.AddWidget(self, gfx.RenderMode.TUBE, TubeWidget(self))
-    ComboOptionsWidget.AddWidget(self, gfx.RenderMode.HSC, HSCWidget(self))
+    self.entity_widgets_ = list()
+    self.entity_widgets_.append(["", EmptyMode()])
+    self.entity_widgets_.append([gfx.RenderMode.SIMPLE, SimpleWidget()])
+    self.entity_widgets_.append([gfx.RenderMode.CUSTOM, CustomWidget()])
+    self.entity_widgets_.append([gfx.RenderMode.CPK, CPKWidget()])
+    self.entity_widgets_.append([gfx.RenderMode.LINE_TRACE, LineTraceWidget()])
+    self.entity_widgets_.append([gfx.RenderMode.TRACE, TraceWidget()])
+    self.entity_widgets_.append([gfx.RenderMode.SLINE, SlineWidget()])
+    self.entity_widgets_.append([gfx.RenderMode.TUBE, TubeWidget()])
+    self.entity_widgets_.append([gfx.RenderMode.HSC, HSCWidget()])
 
+    self.img_widgets_ = list()
+    if _img_present:
+      self.img_widgets_.append(["", EmptyMode()])
+      self.img_widgets_.append([gfx.RenderMode.SIMPLE, WireframeWidget()])
+      self.img_widgets_.append([gfx.RenderMode.FILL, EmptyMode("Fill",gfx.RenderMode.FILL)])
+
+    self._in_view_method = False
     self.setMinimumSize(250,200)
     
   def DoSomething(self, item):
     scene_selection = gui.SceneSelection.Instance()
     for i in range(0,scene_selection.GetActiveNodeCount()):
       node = scene_selection.GetActiveNode(i)
-      if isinstance(node, gfx.Entity):
+      if isinstance(node, gfx.Entity) or (_img_present and isinstance(node, gfx.MapIso)):
         render_mode = item.GetRenderMode()
         if render_mode is not None:
           node.SetRenderMode(render_mode)     
     
     if(scene_selection.GetActiveViewCount() > 0):
       entity = scene_selection.GetViewEntity()
-      for i in range(0,scene_selection.GetActiveViewCount()):
-        view = scene_selection.GetActiveView(i)
-        render_mode = item.GetRenderMode()
-        if render_mode is not None:
-          entity.SetRenderMode(item.GetRenderMode(),view,self.keep_action_.isChecked())
+      view = scene_selection.GetViewUnion()        
+      render_mode = item.GetRenderMode()
+      if render_mode is not None:
+        entity.SetRenderMode(item.GetRenderMode(),view,self.keep_action_.isChecked())
         
     item.Update()
     self.DoResize()
@@ -85,49 +100,85 @@ class RenderOptionsWidget(ComboOptionsWidget):
   def Update(self):
     if hasattr(self, "keep_button_"):
       self.keep_button_.setEnabled(True)
-    scene_selection = gui.SceneSelection.Instance()
-    if scene_selection.GetActiveNodeCount() == 0 and scene_selection.GetActiveViewCount() == 0:
+    
+    ComboOptionsWidget.setEnabled(self,True)
+    
+    cur_widget = self.GetCurrentWidget()
+    new_render_mode = None
+    if cur_widget is not None:
+      new_render_mode = cur_widget.GetRenderMode()
+    
+    if SelHelper().CheckAllFlags(SelHelper.NO_SELECTION):
       ComboOptionsWidget.setEnabled(self,False)
       return
     
+    if not self._in_view_method:
+      for w in self.entity_widgets_:
+        self.RemoveWidget(w[0])
+      for w in self.img_widgets_:
+        self.RemoveWidget(w[0])
+
+    scene_selection = gui.SceneSelection.Instance()        
     if scene_selection.GetActiveNodeCount() > 0 :
       if hasattr(self, "keep_button_"):
         self.keep_button_.setEnabled(False)
       render_mode_valid = True
       render_mode = None
       for i in range(0,scene_selection.GetActiveNodeCount()):
-        entity = scene_selection.GetActiveNode(i)
-        if isinstance(scene_selection.GetActiveNode(i), gfx.Entity):
+        node = scene_selection.GetActiveNode(i)
+        if isinstance(scene_selection.GetActiveNode(i), gfx.GfxObj):
           if render_mode is None:
-            render_mode = entity.GetRenderMode()
-          elif render_mode != entity.GetRenderMode():
+            render_mode = node.GetRenderMode()
+          elif render_mode != node.GetRenderMode():
             render_mode_valid = False
-            break
-        else:
-          ComboOptionsWidget.setEnabled(self,False)
-          return
+ 
+    if SelHelper().CheckFlags(SelHelper.HAS_IMG | SelHelper.IS_ONE_TYPE):
+      for w in self.img_widgets_:
+        self.AddWidget(w[0], w[1])
+    elif SelHelper().CheckMinOneFlag(SelHelper.HAS_ENTITY| SelHelper.HAS_VIEW) and SelHelper().CheckNotFlags(SelHelper.HAS_IMG):
+      if not self._in_view_method:
+        for w in self.entity_widgets_:
+          self.AddWidget(w[0], w[1])
+    else:
+      ComboOptionsWidget.setEnabled(self,False)
+      return
+    
+    if SelHelper().CheckMinOneFlag(SelHelper.HAS_ENTITY| SelHelper.HAS_IMG) and SelHelper().CheckNotFlags(SelHelper.HAS_VIEW):
       if(render_mode_valid):
         ComboOptionsWidget.ChangeSelectedItem(self,render_mode)
       else:
         ComboOptionsWidget.ChangeSelectedItem(self,"")
-    
+    else:
+      if not self._in_view_method:
+        self._in_view_method = True
+      ComboOptionsWidget.ChangeSelectedItem(self,new_render_mode)
     self.GetCurrentWidget().Update()
-    
-    ComboOptionsWidget.setEnabled(self,True)
-  
+      
   def GetText(self):
     return self.text_
         
 class EmptyMode(QtGui.QWidget):
-  def __init__(self, parent=None):
+  def __init__(self, text="", render_mode=None, parent=None):
     QtGui.QLabel.__init__(self, parent)
     self.setMinimumSize(250,30)
-  
+    self.text = text
+    self.render_mode = render_mode
+    if(render_mode):
+      text_label = QtGui.QLabel(text)
+      font = text_label.font()
+      font.setBold(True)
+      grid = QtGui.QGridLayout()
+      grid.addWidget(text_label,0,0,1,1)
+      grid.addWidget(QtGui.QLabel("No Settings available"), 1, 0, 1, 3)
+      grid.setRowStretch(2,1)
+      self.setLayout(grid)
+      self.setMinimumSize(250,60)
+      
   def Update(self):
    True #Do Nothing
 
   def GetText(self):
-    return ""
+    return self.text
 
   def GetRenderMode(self):
-    return None
+    return self.render_mode
diff --git a/modules/gui/pymod/scene/scene_selection_helper.py b/modules/gui/pymod/scene/scene_selection_helper.py
new file mode 100644
index 000000000..0dc43312c
--- /dev/null
+++ b/modules/gui/pymod/scene/scene_selection_helper.py
@@ -0,0 +1,106 @@
+#------------------------------------------------------------------------------
+# This file is part of the OpenStructure project <www.openstructure.org>
+#
+# Copyright (C) 2008-2010 by the OpenStructure authors
+#
+# This library is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3.0 of the License, or (at your option)
+# any later version.
+# This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+#------------------------------------------------------------------------------
+
+import sys
+from ost import gui
+import sip
+from ost import gfx
+import ost
+import os
+try: 
+  from ost import img
+  _img_present=True
+except ImportError:
+  _img_present=False
+  pass
+
+class SelHelper():
+  __shared_state = {}
+  
+  NO_SELECTION = 0
+  HAS_ENTITY = 1
+  HAS_VIEW = 2
+  HAS_IMG = 4
+  HAS_SURFACE = 8
+  IS_ONE_TYPE = 16
+  IS_MULTI_TYPE = 32
+  SINGLE_SELECTION = 64
+  MULTI_SELECTION = 128
+    
+  def __init__(self):
+    self.__dict__ = self.__shared_state
+    if not '_ready' in dir(self):
+      self.scene_sel_ = gui.SceneSelection.Instance()
+      self.current_flags_ = 0
+      self._ready = True
+
+  def Update(self):
+    self.current_flags_ = 0
+    if self.scene_sel_.GetActiveNodeCount() == 0 and self.scene_sel_.GetActiveViewCount() == 0:
+      return
+    
+    for i in range(0,self.scene_sel_.GetActiveNodeCount()):
+      node = self.scene_sel_.GetActiveNode(i)
+      if isinstance(node, gfx.Entity):
+        self.current_flags_ = self.current_flags_ | SelHelper.HAS_ENTITY 
+      if isinstance(node, gfx.Surface):
+        self.current_flags_ = self.current_flags_ | SelHelper.HAS_SURFACE
+      if (_img_present) and isinstance(node, gfx.MapIso):
+        self.current_flags_ = self.current_flags_ | SelHelper.HAS_IMG
+    
+    if self.scene_sel_.GetActiveViewCount() > 0:
+      self.current_flags_ = self.current_flags_ | SelHelper.HAS_VIEW
+    
+    cnt = 0
+    if self.current_flags_ & SelHelper.HAS_ENTITY:
+      cnt += 1
+    if self.current_flags_ & SelHelper.HAS_SURFACE:
+      cnt += 1
+    if self.current_flags_ & SelHelper.HAS_IMG:
+      cnt += 1
+    if self.current_flags_ & SelHelper.HAS_VIEW:
+      cnt += 1
+    
+    if cnt == 1:
+      self.current_flags_ = self.current_flags_ | SelHelper.IS_ONE_TYPE
+    elif cnt > 1:
+      self.current_flags_ = self.current_flags_ | SelHelper.IS_MULTI_TYPE
+    
+    if self.scene_sel_.GetActiveNodeCount()==1:
+      self.current_flags_ = self.current_flags_ | SelHelper.SINGLE_SELECTION
+    elif self.scene_sel_.GetActiveNodeCount()>1:
+      self.current_flags_ = self.current_flags_ | SelHelper.MULTI_SELECTION
+    
+  def CheckAllFlags(self, flags):
+    if(flags == self.current_flags_ & flags) and (flags == self.current_flags_ | flags):
+      return True
+    return False
+  
+  def CheckNotFlags(self, flags):
+    return not self.CheckFlags(flags)
+    
+  def CheckFlags(self, flags):
+    if(flags == self.current_flags_ & flags):
+      return True
+    return False
+  
+  def CheckMinOneFlag(self, flags):
+    if((self.current_flags_ - (self.current_flags_ & flags)) < self.current_flags_):
+      return True
+    return False
diff --git a/modules/gui/pymod/scene/toolbar_options_widget.py b/modules/gui/pymod/scene/toolbar_options_widget.py
index 006c09b16..d331b62b4 100644
--- a/modules/gui/pymod/scene/toolbar_options_widget.py
+++ b/modules/gui/pymod/scene/toolbar_options_widget.py
@@ -126,13 +126,13 @@ class ToolBarOptionsWidget(QtGui.QWidget):
        self.current_action_ = action
     widget = action.data().toPyObject()[1]
     self.stackedWidget.setCurrentWidget(widget)
-    self.DoSomething(widget)
     if hasattr(widget, "Update"): 
       widget.Update()
     if(self.current_action_ == action):
       self.current_action_.setChecked(True)
     else:
       self.current_action_=action
+    self.DoSomething(widget)
   #Private Methods
   def __GetCurrentWidget(self):
       return self.stackedWidget.currentWidget();
diff --git a/modules/gui/pymod/scene/uniform_color_widget.py b/modules/gui/pymod/scene/uniform_color_widget.py
index ff2cdc2dd..b5c074c9c 100644
--- a/modules/gui/pymod/scene/uniform_color_widget.py
+++ b/modules/gui/pymod/scene/uniform_color_widget.py
@@ -21,6 +21,12 @@
 from ost import gui
 from ost import gfx
 from ost import mol
+try: 
+  from ost import img
+  _img_present=True
+except ImportError:
+  _img_present=False
+  pass
 from PyQt4 import QtCore, QtGui
 from color_select_widget import ColorSelectWidget
 
@@ -52,37 +58,45 @@ class UniformColorWidget(QtGui.QWidget):
     top_layout.addLayout(grid)
     self.setLayout(top_layout)
     
-    QtCore.QObject.connect(self.color_select_widget_, QtCore.SIGNAL("colorChanged"), self.Update)
+    QtCore.QObject.connect(self.color_select_widget_, QtCore.SIGNAL("colorChanged"), self.ChangeColors)
     
     self.setMinimumSize(250,150)
 
   def Update(self):
+    scene_selection = gui.SceneSelection.Instance()
+    for i in range(0,scene_selection.GetActiveNodeCount()):
+      node = scene_selection.GetActiveNode(i)
+      if _img_present and isinstance(node, gfx.MapIso):
+        if self.color_select_widget_.GetGfxColor() != node.GetColor():
+          self.color_select_widget_.SetGfxColor(node.GetColor())
+      else:
+        self.ChangeColors()
+        
+  def ChangeColors(self):
     scene_selection = gui.SceneSelection.Instance()
     for i in range(0,scene_selection.GetActiveNodeCount()):
       node = scene_selection.GetActiveNode(i)
       self.ChangeColor(node)
-      
+    
     if(scene_selection.GetActiveViewCount() > 0):
       entity = scene_selection.GetViewEntity()
       view = scene_selection.GetViewUnion()
       self.ChangeViewColor(entity,view)
-        
+  
   def ChangeColor(self, node):
+    gfx_color = self.color_select_widget_.GetGfxColor()
     if isinstance(node, gfx.Entity) or isinstance(node, gfx.Surface):
-      gfx_color = self.GetGfxColor()
-      node.CleanColorOps()
-      node.SetColor(gfx_color,"")
+        node.CleanColorOps()
+        node.SetColor(gfx_color,"")
+    elif _img_present and isinstance(node, gfx.MapIso):
+        node.SetColor(gfx_color)
   
   def ChangeViewColor(self, entity, view):
     if isinstance(entity, gfx.Entity) and isinstance(view, mol.EntityView):
-      gfx_color = self.GetGfxColor()
+      gfx_color = self.color_select_widget_.GetGfxColor()
       ufco=gfx.UniformColorOp(mol.QueryViewWrapper(view),gfx_color)
       entity.Apply(ufco)
-  
-  def GetGfxColor(self):
-    color = self.color_select_widget_.GetColor()
-    return gfx.Color(color.redF(), color.greenF(), color.blueF())
-  
+    
   def resizeEvent(self, event):
     self.color_select_widget_.SetSize(self.width()/2,self.height()/2)
     
diff --git a/modules/gui/pymod/scene/wireframe_widget.py b/modules/gui/pymod/scene/wireframe_widget.py
new file mode 100644
index 000000000..997003743
--- /dev/null
+++ b/modules/gui/pymod/scene/wireframe_widget.py
@@ -0,0 +1,103 @@
+#------------------------------------------------------------------------------
+# This file is part of the OpenStructure project <www.openstructure.org>
+#
+# Copyright (C) 2008-2010 by the OpenStructure authors
+#
+# This library is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3.0 of the License, or (at your option)
+# any later version.
+# This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+#------------------------------------------------------------------------------
+# -*- coding: utf-8 -*-
+
+from ost import gui
+from ost import gfx
+from PyQt4 import QtCore, QtGui
+try: 
+  from ost import img
+  _img_present=True
+except ImportError:
+  _img_present=False
+  pass
+from scene_selection_helper import SelHelper
+
+#Wireframe Options
+class WireframeWidget(QtGui.QWidget):
+  def __init__(self, parent=None):
+    QtGui.QWidget.__init__(self, parent)
+    
+    #Title
+    self.text_ = "Wireframe"
+        
+    #Defaults
+    min_line_width = 0.01
+    max_line_width = 20
+    
+    #Set Render Mode
+    self.mode_ = gfx.RenderMode.SIMPLE
+        
+    #Create Ui elements
+    self.aa_rendering_cb_ = QtGui.QCheckBox()
+  
+    self.radius_spinbox_ = QtGui.QDoubleSpinBox()
+    self.radius_spinbox_.setRange(min_line_width, max_line_width)
+    self.radius_spinbox_.setDecimals(2)
+    self.radius_spinbox_.setSingleStep(0.1)
+
+    simple_label = QtGui.QLabel("Wireframe Settings")
+    font = simple_label.font()
+    font.setBold(True)
+    
+    radius_label = QtGui.QLabel("Line Width")
+    aa_label = QtGui.QLabel("AA-Lines")
+
+    grid = QtGui.QGridLayout()
+    grid.addWidget(simple_label,0,0,1,3)
+    grid.addWidget(aa_label, 1, 0, 1, 3)
+    grid.addWidget(self.aa_rendering_cb_, 1, 2, 1, 1)
+    grid.addWidget(radius_label,2,0,1,3)
+    grid.addWidget(self.radius_spinbox_,2,2,1,1)
+    grid.setRowStretch(5,1)
+    self.setLayout(grid)
+    
+    QtCore.QObject.connect(self.radius_spinbox_, QtCore.SIGNAL("valueChanged(double)"), self.UpdateLineWidth)
+    QtCore.QObject.connect(self.aa_rendering_cb_, QtCore.SIGNAL("stateChanged(int)"), self.UpdateAA)  
+    
+    self.setMinimumSize(250,100)
+    
+  def UpdateAA(self, value):
+    scene_selection = gui.SceneSelection.Instance()
+    for i in range(0,scene_selection.GetActiveNodeCount()):
+      node = scene_selection.GetActiveNode(i)
+      node.SetAALines(value)
+          
+  def UpdateLineWidth(self, value):
+    scene_selection = gui.SceneSelection.Instance()
+    for i in range(0,scene_selection.GetActiveNodeCount()):
+      node = scene_selection.GetActiveNode(i)
+      node.SetLineWidth(value)
+
+  def UpdateGui(self):
+    scene_selection = gui.SceneSelection.Instance()
+    node = scene_selection.GetActiveNode(0)
+    self.radius_spinbox_.setValue(node.GetLineWidth())
+
+  def Update(self):
+    self.setEnabled(True)
+    self.UpdateGui()
+    if SelHelper().CheckNotFlags(SelHelper.HAS_IMG | SelHelper.IS_ONE_TYPE):
+      self.setEnabled(False)          
+
+  def GetText(self):
+    return self.text_
+
+  def GetRenderMode(self):
+    return self.mode_
\ No newline at end of file
diff --git a/modules/gui/pymod/wrap_gui.cc b/modules/gui/pymod/wrap_gui.cc
index 149c7885f..4034dfe1c 100644
--- a/modules/gui/pymod/wrap_gui.cc
+++ b/modules/gui/pymod/wrap_gui.cc
@@ -33,7 +33,6 @@ void export_Gosty();
 void export_PyShell();
 void export_SceneWin();
 void export_SequenceViewer();
-void export_SequenceViewerV2();
 void export_PanelBar();
 void export_Perspective();
 void export_SipHandler();
@@ -117,7 +116,6 @@ BOOST_PYTHON_MODULE(_gui)
   export_SceneWin();
   export_SceneSelection();
   export_SequenceViewer();
-  export_SequenceViewerV2();
   export_RemoteSiteLoader();
   export_FileLoader();
   export_Widget();
diff --git a/modules/gui/share/CMakeLists.txt b/modules/gui/share/CMakeLists.txt
index d755bcd3a..6b0848768 100644
--- a/modules/gui/share/CMakeLists.txt
+++ b/modules/gui/share/CMakeLists.txt
@@ -3,7 +3,9 @@ set(GUI_ICONS
   icons/add_icon.png
   icons/close_icon.png
   icons/distance_icon.png
+  icons/find_icon.png
   icons/map_icon.png
+  icons/menubar_icon.png
   icons/rigid_body_manipulator_icon.png
   icons/selection_icon.png
   icons/show_sidebar_icon.png
diff --git a/modules/gui/share/icons/find_icon.png b/modules/gui/share/icons/find_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..39f6331715ea8fce80451c6314e9eac45193dabe
GIT binary patch
literal 488
zcmeAS@N?(olHy`uVBq!ia0y~yU=Rag4mJh`h9g^YtQi;>7>k44ofy`glX=O&z`&N|
z?e4<x9|RZdT|SwCfq}EYBeIx*fm;}a85w5Hkzin8U@!6Xb!ETB#>gilc<xGgCj$dx
zhNp{Th{frpQ#bk@HV|mDS5ItKe-R+2^}uk3&=gU%3YJqXH*RXFaphl_Xel5jw}78v
zMMq;JyF*e*)->*j&dEE@dR|lAcl!PPZ}s9IwpjFaKE7ctdzEEV*VD?l+1$UH%8a%#
zls9TCFq$>0eqg-A7##mB^qBDjQ4669M(ON37<=>|A4r<bsD8lQfNfhN@5khs$Hi@g
z>NOs7TQG=)ol`I1wqZPfz~MlsdUAr&zeP-0x1AonI~{b2bC3SNjmho3g~>dbv&>Gf
z?ay5M|BC2|!`(+F_2moS*V2`Y@7mAi#`{yb^Y=+#m%j?h3}+gR6Es#yp86g0=&ez=
z(kGksq4#{Y><L@Xd3b`(={eKOx!y2-KhS?hx3T=e9aXmIJlDWK@~w+s?qNKBV44Bf
z)0*YHu8Cedck1<*ZoeP$Y?b?LlicoYM%%VO@7QV-9@`t2?JMHCm38gC1TEXh%Bdxy
mA=$CH7OTSLBfh5p;(i{Sobri#q74HB1B0ilpUXO@geCwYB*Mi2

literal 0
HcmV?d00001

diff --git a/modules/gui/share/icons/menubar_icon.png b/modules/gui/share/icons/menubar_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..3e8d988cce14a8ea5f124e7651dbbcfd2b8026fd
GIT binary patch
literal 301
zcmeAS@N?(olHy`uVBq!ia0y~yU=Rag4mJh`h9g^YtQi;>7>k44ofy`glX=O&z`&N|
z?e4<x9|RZdT|SwCfq}EYBeIx*fm;}a85w5Hkzin8U@!6Xb!ETB#>i)+RdQo{BLf4&
zT2B|p5R21iLml~86gilm7RuDDW0zZ=m~XsJxld)5&-rB@3t1Bc&+wet^GoJ}(nklE
zoJVaw>aC?uH!Cq6{Al>KM9^<S+*&@9Q1AbahBBG54+OReDnF7;3T>ToNmA2G^ZK3(
z5_hgRT>H@H@liqUW?|x09|6INx!=1al%LG`zCL>G*J+1lr))0GW`6to-0R2YXUewZ
z=7;b4yR)-HuIk&(3+gge=P#|eaC_#hDxdn*OYGTNB{ViNFfcH9y85}Sb4q9e0Ol=n
AegFUf

literal 0
HcmV?d00001

diff --git a/modules/gui/src/CMakeLists.txt b/modules/gui/src/CMakeLists.txt
index 7bee5c277..651079e49 100644
--- a/modules/gui/src/CMakeLists.txt
+++ b/modules/gui/src/CMakeLists.txt
@@ -12,16 +12,12 @@ side_bar.hh
 splitter_panel_bar.hh
 tabbed_panel_bar.hh
 )
-set(OST_GUI_SEQUENCE_VIEWER_HEADERS
-sequence_item.hh
-sequence_viewer_base.hh
-sequence_viewer.hh
-sequence_scene.hh
-sequence_search_bar.hh
-)
 
-set(OST_GUI_SEQUENCE_VIEW_HEADERS
+set(OST_GUI_SEQUENCE_VIEWER_HEADERS
+align_properties_painter.hh
 base_row.hh
+background_painter.hh
+conservation_painter.hh
 painter.hh
 secstr_row.hh
 seq_secstr_painter.hh
@@ -30,11 +26,14 @@ seq_text_painter.hh
 sequence_delegate.hh
 sequence_model.hh
 sequence_row.hh
+sequence_search_bar.hh
 sequence_table_view.hh
 sequence_viewer.hh
 tick_painter.hh
 title_row.hh
-view_object.hh
+alignment_view_object.hh
+base_view_object.hh
+sequence_view_object.hh
 )
 
 set(OST_GUI_TOOLS_HEADERS
@@ -209,24 +208,25 @@ scene_menu.cc
 widget.cc
 widget_pool.cc
 remote_site_loader.cc
-sequence_viewer/sequence_item.cc
-sequence_viewer/sequence_viewer_base.cc
-sequence_viewer/sequence_viewer.cc
-sequence_viewer/sequence_scene.cc
+sequence_viewer/align_properties_painter.cc
+sequence_viewer/base_row.cc
+sequence_viewer/background_painter.cc
+sequence_viewer/conservation_painter.cc
+sequence_viewer/secstr_row.cc
+sequence_viewer/seq_secstr_painter.cc
+sequence_viewer/seq_selection_painter.cc
+sequence_viewer/seq_text_painter.cc
+sequence_viewer/sequence_delegate.cc
+sequence_viewer/sequence_model.cc
+sequence_viewer/sequence_row.cc
 sequence_viewer/sequence_search_bar.cc
-sequence/base_row.cc
-sequence/secstr_row.cc
-sequence/seq_secstr_painter.cc
-sequence/seq_selection_painter.cc
-sequence/seq_text_painter.cc
-sequence/sequence_delegate.cc
-sequence/sequence_model.cc
-sequence/sequence_row.cc
-sequence/sequence_table_view.cc
-sequence/sequence_viewer.cc
-sequence/tick_painter.cc
-sequence/title_row.cc
-sequence/view_object.cc
+sequence_viewer/sequence_table_view.cc
+sequence_viewer/sequence_viewer.cc
+sequence_viewer/tick_painter.cc
+sequence_viewer/title_row.cc
+sequence_viewer/alignment_view_object.cc
+sequence_viewer/base_view_object.cc
+sequence_viewer/sequence_view_object.cc
 gosty_app.cc
 change_process_name.cc
 main_area.cc
@@ -342,25 +342,26 @@ scene_selection.hh
 widget.hh
 widget_geom_handler.hh
 widget_pool.hh
-sequence_viewer/sequence_item.hh
-sequence_viewer/sequence_viewer_base.hh
-sequence_viewer/sequence_viewer.hh
-sequence_viewer/sequence_scene.hh
+sequence_viewer/align_properties_painter.hh
+sequence_viewer/background_painter.hh
+sequence_viewer/base_row.hh
+sequence_viewer/conservation_painter.hh
+sequence_viewer/painter.hh
+sequence_viewer/secstr_row.hh
+sequence_viewer/seq_secstr_painter.hh
+sequence_viewer/seq_selection_painter.hh
+sequence_viewer/seq_text_painter.hh
+sequence_viewer/sequence_delegate.hh
+sequence_viewer/sequence_model.hh
+sequence_viewer/sequence_row.hh
 sequence_viewer/sequence_search_bar.hh
-sequence/base_row.hh
-sequence/painter.hh
-sequence/secstr_row.hh
-sequence/seq_secstr_painter.hh
-sequence/seq_selection_painter.hh
-sequence/seq_text_painter.hh
-sequence/sequence_delegate.hh
-sequence/sequence_model.hh
-sequence/sequence_row.hh
-sequence/sequence_table_view.hh
-sequence/sequence_viewer.hh
-sequence/tick_painter.hh
-sequence/title_row.hh
-sequence/view_object.hh
+sequence_viewer/sequence_table_view.hh
+sequence_viewer/sequence_viewer.hh
+sequence_viewer/tick_painter.hh
+sequence_viewer/title_row.hh
+sequence_viewer/alignment_view_object.hh
+sequence_viewer/base_view_object.hh
+sequence_viewer/sequence_view_object.hh
 plot_viewer/plot_axis_base.hh
 plot_viewer/plot_data_graphics_item_base.hh
 plot_viewer/plot_function_info.hh
@@ -470,14 +471,13 @@ module(NAME gui SOURCES ${OST_GUI_MOCS} ${OST_GUI_SOURCES}
        HEADERS ${OST_GUI_TOOLS_HEADERS} IN_DIR tools
                ${OST_GUI_PLOT_VIEWER_HEADERS} IN_DIR plot_viewer
                ${OST_GUI_SEQUENCE_VIEWER_HEADERS} IN_DIR sequence_viewer
-               ${OST_GUI_SEQUENCE_VIEW_HEADERS} IN_DIR sequence
                ${OST_GUI_PYTHON_SHELL_HEADERS} IN_DIR python_shell
                ${OST_GUI_PANEL_BAR_HEADERS} IN_DIR panel_bar
                ${OST_GUI_SCENE_WIN_HEADERS} IN_DIR scene_win
                ${OST_GUI_INPUT_HEADERS}
                ${OST_GUI_DATA_VIEWER_HEADERS}
                ${OST_GUI_HEADERS}
-       DEPENDS_ON gfx io mol_alg
+       DEPENDS_ON gfx io mol_alg seq_alg
        LINK ${QT_LIBRARIES} ${PYTHON_LIBRARIES} ${BOOST_PYTHON_LIBRARIES} ${SPNAV_LIBRARIES})
 include_directories(${PYTHON_INCLUDE_PATH})
 qt4_add_resources(OST_QT_RESOURCE dngr.qrc)
diff --git a/modules/gui/src/data_viewer/mask_overlay.cc b/modules/gui/src/data_viewer/mask_overlay.cc
index a10082a34..6e1ae0990 100644
--- a/modules/gui/src/data_viewer/mask_overlay.cc
+++ b/modules/gui/src/data_viewer/mask_overlay.cc
@@ -214,5 +214,19 @@ void MaskOverlay::ClearMask()
   add_mode_=false;
 }
 
+void MaskOverlay::SetShift(geom::Vec2 shift)
+{
+  shift_=shift;
+}
+
+void MaskOverlay::ApplyShiftToMask()
+{
+  for(std::vector<geom::Polygon2>::iterator it=polygons_.begin();it!=polygons_.end();++it){
+    (*it)=(*it)+shift_;
+  }
+  new_poly_=new_poly_+shift_;
+  shift_=geom::Vec2(0.0,0.0);
+}
+
 
 }}}  //ns
diff --git a/modules/gui/src/data_viewer/mask_overlay.hh b/modules/gui/src/data_viewer/mask_overlay.hh
index e274f3157..36feb893d 100644
--- a/modules/gui/src/data_viewer/mask_overlay.hh
+++ b/modules/gui/src/data_viewer/mask_overlay.hh
@@ -56,6 +56,8 @@ public:
   void ClearMask();
   void ClearShift(){shift_=geom::Vec2();}
   geom::Vec2 GetShift(){return shift_;}
+  void SetShift(geom::Vec2 shift);
+  void ApplyShiftToMask();
 
 protected:
   std::vector<geom::Polygon2> polygons_;
diff --git a/modules/gui/src/file_browser.cc b/modules/gui/src/file_browser.cc
index c854be414..c7919c7ec 100644
--- a/modules/gui/src/file_browser.cc
+++ b/modules/gui/src/file_browser.cc
@@ -16,12 +16,15 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
+#include <QCursor>
 #include <QVBoxLayout>
+#include <QDesktopServices>
 #include <QDir>
 #include <QHeaderView>
 #include <QFileInfo>
 #include <QMessageBox>
 #include <QApplication>
+#include <QUrl>
 
 #include <ost/platform.hh>
 #include <ost/config.hh>
@@ -91,6 +94,8 @@ void FileBrowser::Init(const QString& path)
   view_->setModel(model_);
   view_->setRootIndex(model_->index(path));
   view_->setAttribute(Qt::WA_MacShowFocusRect, false);
+  view_->setContextMenuPolicy(Qt::CustomContextMenu);
+  connect(view_,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(ShowContextMenu(const QPoint&)));
   menu_= new QComboBox(this);
   UpdateMenu(path);
 
@@ -137,13 +142,7 @@ bool FileBrowser::Restore(const QString& prefix)
 
 void FileBrowser::DoubleClicked(const QModelIndex& index)
 {
-  if(model_->isDir(index)){
-    view_->setRootIndex(index);
-    UpdateMenu(model_->filePath(index));
-  }
-  else{
-    LoadObject(index);
-  }
+  LoadObject(index);
 }
 
 void FileBrowser::ChangeToParentDirectory(int index){
@@ -193,10 +192,15 @@ void FileBrowser::AddItem(const QDir& directory, const QString& mypath){
 }
 
 void FileBrowser::LoadObject(const QModelIndex& index){
-  gfx::GfxObjP obj;
   if (index.isValid()) {
-    QString file_name=model_->filePath(index);
-    FileLoader::LoadObject(file_name);
+    if(model_->isDir(index)){
+      view_->setRootIndex(index);
+      UpdateMenu(model_->filePath(index));
+    }
+    else{
+      QString file_name=model_->filePath(index);
+      FileLoader::LoadObject(file_name);
+    }
   }
 }
 
@@ -206,6 +210,43 @@ void FileBrowser::keyPressEvent(QKeyEvent* event){
   }
 }
 
+void FileBrowser::ShowContextMenu(const QPoint& pos){
+
+  QModelIndex index = view_->selectionModel()->currentIndex();
+  QMenu* menu = new QMenu(this);
+  if(model_->isDir(index)){
+    QAction* open_action = new QAction(menu);
+    open_action->setText("Open");
+    connect(open_action,SIGNAL(triggered(bool)),this,SLOT(LoadCurrentObject()));
+    menu->addAction(open_action);
+  }
+  if(!model_->isDir(index)){
+    QAction* load_action = new QAction(menu);
+    load_action->setText("Load");
+    connect(load_action,SIGNAL(triggered(bool)),this,SLOT(LoadCurrentObject()));
+    menu->addAction(load_action);
+    QAction* system_open_action = new QAction(menu);
+    system_open_action->setText("Open with system editor");
+    connect(system_open_action,SIGNAL(triggered(bool)),this,SLOT(LoadWithSystemEditor()));
+    menu->addAction(system_open_action);
+  }
+  if(menu->actions().size()>0){
+    menu->exec(QCursor::pos());
+  }
+}
+
+void FileBrowser::LoadCurrentObject(){
+  QModelIndex index = view_->selectionModel()->currentIndex();
+  this->LoadObject(index);
+}
+
+void FileBrowser::LoadWithSystemEditor(){
+  QModelIndex index = view_->selectionModel()->currentIndex();
+  QString file_name=model_->filePath(index);
+  QDesktopServices::openUrl(QUrl::fromLocalFile(file_name));
+}
+
+
 OST_REGISTER_WIDGET_WITH_DEFAULT_FACTORY(ost::gui, FileBrowser, "File Browser");  
 
 
diff --git a/modules/gui/src/file_browser.hh b/modules/gui/src/file_browser.hh
index 78ad1acf7..3f04a0b8e 100644
--- a/modules/gui/src/file_browser.hh
+++ b/modules/gui/src/file_browser.hh
@@ -51,6 +51,9 @@ private slots:
   void DoubleClicked(const QModelIndex& index);
   void ChangeToParentDirectory(int index);
   void Split();
+  void ShowContextMenu(const QPoint& pos);
+  void LoadCurrentObject();
+  void LoadWithSystemEditor();
 private:
   void LoadObject(const QModelIndex& index);
   void UpdateMenu(const QString& path);
diff --git a/modules/gui/src/file_loader.cc b/modules/gui/src/file_loader.cc
index 892278c56..31636340e 100644
--- a/modules/gui/src/file_loader.cc
+++ b/modules/gui/src/file_loader.cc
@@ -38,6 +38,9 @@
 
 #include <ost/conop/conop.hh>
 
+#include <ost/seq/sequence_list.hh>
+#include <ost/seq/alignment_handle.hh>
+
 #include <ost/gfx/entity.hh>
 #include <ost/gfx/surface.hh>
 #include <ost/gfx/scene.hh>
@@ -47,6 +50,7 @@
 #include <ost/gui/python_shell/python_interpreter.hh>
 #include <ost/gui/main_area.hh>
 #include <ost/gui/file_type_dialog.hh>
+#include <ost/gui/sequence_viewer/sequence_viewer.hh>
 
 #if OST_IMG_ENABLED
   #include <ost/io/img/load_map.hh>
@@ -88,11 +92,22 @@ void FileLoader::LoadObject(const QString& filename, const QString& selection)
         }
       }
   #endif
+      if (!obj)  {
+        try{
+          obj=FileLoader::TryLoadAlignment(filename);
+        } catch (io::IOFileAlreadyLoadedException&) {
+          return;
+        }
+      }
       if (!obj) {
         obj=FileLoader::TryLoadSurface(filename);
       }
       if (!obj) {
-        obj=FileLoader::NoHandlerFound(filename);
+        try{
+          obj=FileLoader::NoHandlerFound(filename);
+        } catch (io::IOFileAlreadyLoadedException&) {
+          return;
+        }
       }
       if (!obj){
         return;
@@ -124,6 +139,9 @@ gfx::GfxObjP FileLoader::NoHandlerFound(const QString& filename)
     if(dialog.GetEntityHandler()){
       return TryLoadEntity(filename, dialog.GetEntityHandler());
     }
+    if(dialog.GetSequenceHandler()){
+      return TryLoadAlignment(filename, dialog.GetSequenceHandler());
+    }
     if(dialog.GetSurfaceHandler()){
       return TryLoadSurface(filename,dialog.GetSurfaceHandler());
     }
@@ -199,9 +217,15 @@ void FileLoader::HandleError(Message m, ErrorType type, const QString& filename,
       break;
     }
   }
+  else if(type==INFO){
+    QMessageBox message_box(QMessageBox::Information,
+        "Information", m._mesg.c_str());
+    message_box.setStandardButtons( QMessageBox::Ok);
+    message_box.exec();
+  }
 }
 
-gfx::GfxObjP FileLoader::TryLoadEntity(const QString& filename, io::EntityIOHandlerP handler, const QString& selection) throw (io::IOException)
+gfx::GfxObjP FileLoader::TryLoadEntity(const QString& filename, io::EntityIOHandlerP handler, const QString& selection)
 {
   if(!handler){
     try{
@@ -232,7 +256,7 @@ gfx::GfxObjP FileLoader::TryLoadEntity(const QString& filename, io::EntityIOHand
 }
 
 #if OST_IMG_ENABLED
-gfx::GfxObjP FileLoader::TryLoadMap(const QString& filename, io::MapIOHandlerPtr handler) throw(io::IOException, io::IOFileAlreadyLoadedException)
+gfx::GfxObjP FileLoader::TryLoadMap(const QString& filename, io::MapIOHandlerPtr handler)
 {
   if(!handler){
     try{
@@ -266,7 +290,7 @@ gfx::GfxObjP FileLoader::TryLoadMap(const QString& filename, io::MapIOHandlerPtr
 }
 #endif
 
-gfx::GfxObjP FileLoader::TryLoadSurface(const QString& filename, io::SurfaceIOHandlerPtr handler) throw(io::IOException)
+gfx::GfxObjP FileLoader::TryLoadSurface(const QString& filename, io::SurfaceIOHandlerPtr handler)
 {
   if(!handler){
     try{
@@ -296,6 +320,29 @@ gfx::GfxObjP FileLoader::TryLoadSurface(const QString& filename, io::SurfaceIOHa
   return gfx::GfxObjP();
 }
 
+gfx::GfxObjP FileLoader::TryLoadAlignment(const QString& filename, io::SequenceIOHandlerPtr handler)
+{
+  if(!handler){
+    try{
+      handler = io::IOManager::Instance().FindAlignmentImportHandler(filename.toStdString(),"auto");
+    }
+    catch(io::IOUnknownFormatException e){
+      handler = io::SequenceIOHandlerPtr();
+    }
+  }
+  if(handler){
+    seq::SequenceList seq_list = seq::CreateSequenceList();
+    handler->Import(seq_list,filename.toStdString());
+    seq::AlignmentHandle alignment = seq::AlignmentFromSequenceList(seq_list);
+    gui::MainArea* main_area = gui::GostyApp::Instance()->GetPerspective()->GetMainArea();
+    SequenceViewer* viewer = new SequenceViewer(true,main_area);
+    viewer->AddAlignment(alignment);
+    main_area->AddWidget(filename,viewer);
+    throw io::IOFileAlreadyLoadedException("Loaded in DataViewer");
+  }
+  return gfx::GfxObjP();
+}
+
 void FileLoader::RunScript(const QString& filename)
 {
   PythonInterpreter& pi = PythonInterpreter::Instance();
@@ -320,9 +367,11 @@ void FileLoader::LoadPDB(const QString& filename, const QString& selection)
     conop::Conopology::Instance().ConnectAll(builder,ent,0);
     entities.append(ent);
   }
-
   QFileInfo file_info(filename);
-  if(entities.size()==1){
+  if(entities.empty()){
+    FileLoader::HandleError(Message(QString("No entities found in file: "+ filename).toStdString()),INFO,filename);
+  }
+  else if(entities.size()==1){
     gfx::EntityP gfx_ent(new gfx::Entity(file_info.baseName().toStdString(),entities.first(),mol::Query(selection.toStdString())));
     try{
       gfx::Scene::Instance().Add(gfx_ent);
diff --git a/modules/gui/src/file_loader.hh b/modules/gui/src/file_loader.hh
index b102e17f6..ea2d63e2d 100644
--- a/modules/gui/src/file_loader.hh
+++ b/modules/gui/src/file_loader.hh
@@ -32,6 +32,7 @@
 
 #include <ost/io/io_exception.hh>
 #include <ost/io/entity_io_handler.hh>
+#include <ost/io/sequence_io_handler.hh>
 #include <ost/io/surface_io_handler.hh>
 #if OST_IMG_ENABLED
 #include <ost/io/map_io_handler.hh>
@@ -45,14 +46,16 @@ private:
   enum ErrorType { DEFAULT = 0,
     IO_LOADING,
     GFX_ADD,
-    GFX_MULTIPLE_ADD
+    GFX_MULTIPLE_ADD,
+    INFO
   };
 
   FileLoader();
-  static gfx::GfxObjP TryLoadEntity(const QString& filename, io::EntityIOHandlerP handler=io::EntityIOHandlerP(), const QString& selection=QString()) throw (io::IOException);
-  static gfx::GfxObjP TryLoadSurface(const QString& filename, io::SurfaceIOHandlerPtr handler=io::SurfaceIOHandlerPtr()) throw (io::IOException);
+  static gfx::GfxObjP TryLoadEntity(const QString& filename, io::EntityIOHandlerP handler=io::EntityIOHandlerP(), const QString& selection=QString());
+  static gfx::GfxObjP TryLoadSurface(const QString& filename, io::SurfaceIOHandlerPtr handler=io::SurfaceIOHandlerPtr());
+  static gfx::GfxObjP TryLoadAlignment(const QString& filename, io::SequenceIOHandlerPtr handler=io::SequenceIOHandlerPtr());
 #if OST_IMG_ENABLED
-  static gfx::GfxObjP TryLoadMap(const QString& filename, io::MapIOHandlerPtr handler=io::MapIOHandlerPtr()) throw (io::IOException, io::IOFileAlreadyLoadedException);
+  static gfx::GfxObjP TryLoadMap(const QString& filename, io::MapIOHandlerPtr handler=io::MapIOHandlerPtr());
 #endif
   static void RunScript(const QString& filename);
   static void LoadPDB(const QString& filename, const QString& selection=QString());
diff --git a/modules/gui/src/file_type_dialog.cc b/modules/gui/src/file_type_dialog.cc
index cba2cba95..ac9dd54ab 100644
--- a/modules/gui/src/file_type_dialog.cc
+++ b/modules/gui/src/file_type_dialog.cc
@@ -30,7 +30,7 @@
 namespace ost { namespace gui {
 
 FileTypeDialog::FileTypeDialog(const QString& file_name, QWidget* parent):
-  QDialog(parent),entity_handler_(), surf_handler_()
+  QDialog(parent),entity_handler_(),seq_handler_(), surf_handler_()
 #if OST_IMG_ENABLED
       ,map_handler_()
 #endif
@@ -66,6 +66,13 @@ FileTypeDialog::FileTypeDialog(const QString& file_name, QWidget* parent):
     this->AddRow(list_->rowCount(),entity_handler[i]->GetFormatName().c_str(),entity_handler[i]->GetFormatDescription().c_str(),handler);
   }
 
+  io::AlignmentIOFList alignment_handler = io::IOManager::Instance().GetAvailableAlignmentHandler();
+  for(unsigned int i = 0 ; i < alignment_handler.size() ; i++){
+    QVariant handler = QVariant();
+    handler.setValue(alignment_handler[i]);
+    this->AddRow(list_->rowCount(),alignment_handler[i]->GetFormatName().c_str(),alignment_handler[i]->GetFormatDescription().c_str(),handler);
+  }
+
 #if OST_IMG_ENABLED
   io::MapIOFList map_handler = io::IOManager::Instance().GetAvailableMapHandler();
   for(unsigned int i = 0 ; i < map_handler.size() ; i++){
@@ -106,6 +113,11 @@ void FileTypeDialog::accept(){
         entity_handler_ = ent_handler_fac->Create();
         break;
       }
+      io::SequenceIOHandlerFactoryBasePtr seq_handler_fac = variant.value<io::SequenceIOHandlerFactoryBasePtr>();
+      if(seq_handler_fac){
+        seq_handler_ = seq_handler_fac->Create();
+        break;
+      }
       io::SurfaceIOHandlerFactoryBasePtr surf_handler_fac = variant.value<io::SurfaceIOHandlerFactoryBasePtr>();
       if(surf_handler_fac){
         surf_handler_ = surf_handler_fac->Create();
@@ -127,6 +139,9 @@ io::EntityIOHandlerP FileTypeDialog::GetEntityHandler(){
  return entity_handler_;
 }
 
+io::SequenceIOHandlerPtr FileTypeDialog::GetSequenceHandler(){
+ return seq_handler_;
+}
 
 io::SurfaceIOHandlerPtr FileTypeDialog::GetSurfaceHandler(){
   return surf_handler_;
diff --git a/modules/gui/src/file_type_dialog.hh b/modules/gui/src/file_type_dialog.hh
index 3efee2c53..b0d6e4433 100644
--- a/modules/gui/src/file_type_dialog.hh
+++ b/modules/gui/src/file_type_dialog.hh
@@ -31,6 +31,7 @@
 #include <QLabel>
 
 #include <ost/io/entity_io_handler.hh>
+#include <ost/io/sequence_io_handler.hh>
 #include <ost/io/surface_io_handler.hh>
 #if OST_IMG_ENABLED
 #include <ost/io/map_io_handler.hh>
@@ -44,6 +45,7 @@ class DLLEXPORT_OST_GUI FileTypeDialog : public QDialog {
 public:
   FileTypeDialog(const QString& file_name, QWidget* parent=NULL);
   io::EntityIOHandlerP GetEntityHandler();
+  io::SequenceIOHandlerPtr GetSequenceHandler();
   io::SurfaceIOHandlerPtr GetSurfaceHandler();
 #if OST_IMG_ENABLED
   io::MapIOHandlerPtr GetMapHandler();
@@ -59,6 +61,7 @@ private:
   QTableWidget* list_;
   QLabel* label_;
   io::EntityIOHandlerP entity_handler_;
+  io::SequenceIOHandlerPtr seq_handler_;
   io::SurfaceIOHandlerPtr surf_handler_;
 #if OST_IMG_ENABLED
   io::MapIOHandlerPtr map_handler_;
@@ -69,6 +72,7 @@ private:
 }}
 
 Q_DECLARE_METATYPE(ost::io::EntityIOHandlerFactoryBaseP);
+Q_DECLARE_METATYPE(ost::io::SequenceIOHandlerFactoryBasePtr);
 Q_DECLARE_METATYPE(ost::io::SurfaceIOHandlerFactoryBasePtr);
 #if OST_IMG_ENABLED
 Q_DECLARE_METATYPE(ost::io::MapIOHandlerFactoryBasePtr);
diff --git a/modules/gui/src/gosty_app.cc b/modules/gui/src/gosty_app.cc
index b78c4f794..7090e7449 100644
--- a/modules/gui/src/gosty_app.cc
+++ b/modules/gui/src/gosty_app.cc
@@ -46,7 +46,7 @@ GostyApp* GostyApp::app_=NULL;
 
 GostyApp::GostyApp():
   py_shell_(NULL), w_py_shell_(NULL), gl_win_(NULL), w_gl_win_(NULL),
-  scene_win_(NULL), w_scene_win_(NULL), seq_viewer_(NULL), seq_viewer_v2_(NULL), tool_options_win_(NULL),
+  scene_win_(NULL), w_scene_win_(NULL), seq_viewer_(NULL), tool_options_win_(NULL),
   w_tool_options_(NULL), main_(new GostyMainWindow), 
   perspective_(NULL), external_widgets_(QMap<QString,WidgetGeomHandler *>())
 {
@@ -98,21 +98,12 @@ SceneWin* GostyApp::GetSceneWin()
 SequenceViewer* GostyApp::GetSequenceViewer()
 {
   if (seq_viewer_==NULL) {
-  seq_viewer_=new SequenceViewer;
-  seq_viewer_->SetDestroyOnClose(false);
+    seq_viewer_=new SequenceViewer(false);
+    seq_viewer_->SetDestroyOnClose(false);
   }
   return seq_viewer_;
 }
 
-SequenceViewerV2* GostyApp::GetSequenceViewerV2()
-{
-  if (seq_viewer_v2_==NULL) {
-    seq_viewer_v2_=new SequenceViewerV2;
-    seq_viewer_v2_->SetDestroyOnClose(false);
-  }
-  return seq_viewer_v2_;
-}
-
 #if OST_IMG_ENABLED
 ost::img::gui::DataViewer* GostyApp::CreateDataViewer(const ost::img::Data& d, const QString& name)
 {
diff --git a/modules/gui/src/gosty_app.hh b/modules/gui/src/gosty_app.hh
index 46381ff16..f9ce1d851 100644
--- a/modules/gui/src/gosty_app.hh
+++ b/modules/gui/src/gosty_app.hh
@@ -31,7 +31,6 @@
 #include <ost/gui/module_config.hh>
 #include <ost/gui/scene_win/scene_win.hh>
 #include <ost/gui/sequence_viewer/sequence_viewer.hh>
-#include <ost/gui/sequence/sequence_viewer.hh>
 #include <ost/gui/main.hh>
 #include <ost/gui/widget_geom_handler.hh>
 #if OST_IMG_ENABLED
@@ -93,7 +92,6 @@ public:
   /// The sequence viewer is initialized when this method is first called. All
   /// subsequent calls will return the same SequenceViewer instance.
   SequenceViewer* GetSequenceViewer();
-  SequenceViewerV2* GetSequenceViewerV2();
   
   /// \brief get tool options window
   /// 
@@ -156,8 +154,7 @@ private:
   SceneWin*         scene_win_;
   QWidget*          w_scene_win_;
 
-  SequenceViewer*   seq_viewer_;
-  SequenceViewerV2* seq_viewer_v2_;
+  SequenceViewer* seq_viewer_;
 
   ToolOptionsWin*   tool_options_win_;
   QWidget*          w_tool_options_;  
diff --git a/modules/gui/src/main.cc b/modules/gui/src/main.cc
index 9836c6e90..9abeac746 100644
--- a/modules/gui/src/main.cc
+++ b/modules/gui/src/main.cc
@@ -43,7 +43,6 @@
 #include "gl_win.hh"
 //#include "entity_explorer/entity_explorer.hh"
 #include "mdi_sub_window.hh"
-#include "sequence_viewer/sequence_viewer.hh"
 #include "tools/tool_options_win.hh"
 #include "plot_viewer/plot_viewer_proxy.hh"
 #include "plot_viewer/plot_viewer.hh"
diff --git a/modules/gui/src/plot_viewer/plot_viewer_panel.cc b/modules/gui/src/plot_viewer/plot_viewer_panel.cc
index 07ec70d9d..a440c0680 100644
--- a/modules/gui/src/plot_viewer/plot_viewer_panel.cc
+++ b/modules/gui/src/plot_viewer/plot_viewer_panel.cc
@@ -138,7 +138,7 @@ void PlotViewerPanel::wheelEvent ( QWheelEvent * e )
 }
 void PlotViewerPanel::OnZoomX(int delta,QPoint pos)
 {
-  QPointF cursorpos=mapToScene(pos+QPoint(-PlotAxisBase::AXISWIDTH,0));
+  QPointF cursorpos=mapToScene(pos+QPoint(-int(PlotAxisBase::AXISWIDTH),0));
   Real scalefactor=exp(delta/1000.0);
   QRectF scenerect;
   scenerect.setCoords(cursorpos.x()-(cursorpos.x()-GetMinimumX())/scalefactor,
diff --git a/modules/gui/src/python_shell/dir_model.cc b/modules/gui/src/python_shell/dir_model.cc
index 96c57f61a..e4d2c049b 100644
--- a/modules/gui/src/python_shell/dir_model.cc
+++ b/modules/gui/src/python_shell/dir_model.cc
@@ -20,7 +20,6 @@
   Author: Andreas Schenk
  */
 
-
 #include "dir_model.hh"
 
 
diff --git a/modules/gui/src/scene_selection.cc b/modules/gui/src/scene_selection.cc
index eb92c848e..7beeadc58 100644
--- a/modules/gui/src/scene_selection.cc
+++ b/modules/gui/src/scene_selection.cc
@@ -152,6 +152,23 @@ void SceneSelection::ViewDensitySlices() {
   }
 }
 
+void SceneSelection::ShowDownsampledMap()
+{
+  gfx::MapIsoP obj = dyn_cast<gfx::MapIso> (nodes_[0]);
+  if (obj) {
+    obj->ShowDownsampledMap();
+  }
+}
+
+
+void SceneSelection::ShowOriginalMap()
+{
+  gfx::MapIsoP obj = dyn_cast<gfx::MapIso> (nodes_[0]);
+  if (obj) {
+    obj->ShowOriginalMap();
+  }
+}
+
 #endif // OST_IMG_ENABLED
 
 void SceneSelection::Select() {
diff --git a/modules/gui/src/scene_selection.hh b/modules/gui/src/scene_selection.hh
index 3b5bebabb..7bbcb2e38 100644
--- a/modules/gui/src/scene_selection.hh
+++ b/modules/gui/src/scene_selection.hh
@@ -46,6 +46,8 @@ public slots:
   void Delete();
 #if OST_IMG_ENABLED
   void ViewDensitySlices();
+  void ShowDownsampledMap();
+  void ShowOriginalMap();  
 #endif // OST_IMG_ENABLED
   void CopyViews();
   void Select();
@@ -61,6 +63,7 @@ public slots:
   void HideExclusive();
   mol::EntityView GetViewUnion();
 
+
 private slots:
   void SetActiveNodes(gfx::NodePtrList nodes, gfx::EntityP entity, mol::QueryViewWrapperList views);
 
diff --git a/modules/gui/src/scene_win/context_menu.cc b/modules/gui/src/scene_win/context_menu.cc
index d873c99f5..afce21203 100644
--- a/modules/gui/src/scene_win/context_menu.cc
+++ b/modules/gui/src/scene_win/context_menu.cc
@@ -26,6 +26,8 @@
 #include <QItemSelection>
 #include <QItemSelectionModel>
 
+#include <ost/dyn_cast.hh>
+
 #include <ost/gui/scene_selection.hh>
 #include <ost/gui/query_dialog.hh>
 
@@ -114,6 +116,14 @@ ContextMenu::ContextMenu(QTreeView* view, SceneWinModel* model):
   action = new QAction("View Density Slices",this);
   connect(action, SIGNAL(triggered()), SceneSelection::Instance(), SLOT(ViewDensitySlices()));
   this->AddAction(action, MAP);
+
+  action = new QAction("Show Original Map",this);
+  connect(action, SIGNAL(triggered()), SceneSelection::Instance(), SLOT(ShowOriginalMap()));
+  this->AddAction(action, MAP | SINGLE | MAP_DOWNSAMPLED);
+
+  action = new QAction("Show Downsampled Map",this);
+  connect(action, SIGNAL(triggered()), SceneSelection::Instance(), SLOT(ShowDownsampledMap()));
+  this->AddAction(action, MAP | SINGLE | MAP_ORIGINAL | MAP_DSAMPLED_AVAIL);
 #endif // OST_IMG_ENABLED
 
 }
@@ -139,10 +149,28 @@ void ContextMenu::ShowMenu(const QPoint& pos)
             flags &= ~NOT_VISIBLE;
           }
           if(gfx_node->GetType()==0){flags &= ~NOT_SCENE;}
-          if(!dynamic_cast<gfx::GfxObj*> (gfx_node.get())){flags &= ~GFX_OBJECT;}
-          if(!dynamic_cast<gfx::Entity*> (gfx_node.get())){flags &= ~ENTITY;}
+          if(!dyn_cast<gfx::GfxObj> (gfx_node)){flags &= ~GFX_OBJECT;}
+          if(!dyn_cast<gfx::Entity> (gfx_node)){flags &= ~ENTITY;}
 #if OST_IMG_ENABLED
-          if(!dynamic_cast<gfx::MapIso*> (gfx_node.get())){flags &= ~MAP;}
+          if(!dyn_cast<gfx::MapIso>(gfx_node))
+          {
+            flags &= ~MAP;
+          } else {
+            gfx::MapIsoP mapisop = dyn_cast<gfx::MapIso> (gfx_node);
+            if (mapisop->GetShownMapType() == gfx::ORIGINAL_MAP){
+              flags &= ~MAP_DOWNSAMPLED;
+            } else {
+              flags &= ~MAP_ORIGINAL;
+            }
+            if (mapisop->IsDownsampledMapAvailable() == false){
+              flags &= ~MAP_DSAMPLED_AVAIL;
+            }
+          }
+          if(!dyn_cast<gfx::MapIso> (gfx_node)){
+          flags &= ~MAP;
+
+          }
+          if(!dyn_cast<gfx::MapIso> (gfx_node)){flags &= ~MAP;}
 #endif // OST_IMG_ENABLED
         }
         else{
diff --git a/modules/gui/src/scene_win/context_menu.hh b/modules/gui/src/scene_win/context_menu.hh
index bc2f8e9d1..1a2501da8 100644
--- a/modules/gui/src/scene_win/context_menu.hh
+++ b/modules/gui/src/scene_win/context_menu.hh
@@ -45,7 +45,10 @@ enum ContextActionType
   SINGLE=0x80,
   MULTI=0x100
 #if OST_IMG_ENABLED
-  ,MAP=0x200
+  ,MAP=0x200,
+  MAP_ORIGINAL=0x400,
+  MAP_DOWNSAMPLED=0x800,
+  MAP_DSAMPLED_AVAIL=0x1000
 #endif
 };
 Q_DECLARE_FLAGS(ContextActionTypes, ContextActionType)
diff --git a/modules/gui/src/scene_win/gfx_scene_node.cc b/modules/gui/src/scene_win/gfx_scene_node.cc
index 9b8828779..f8632e901 100644
--- a/modules/gui/src/scene_win/gfx_scene_node.cc
+++ b/modules/gui/src/scene_win/gfx_scene_node.cc
@@ -71,10 +71,10 @@ bool GfxSceneNode::SetData(int column, const QVariant& value, int role){
 
 Qt::ItemFlags GfxSceneNode::Flags(int column) const{
   if(column==0){
-    return Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled;
+    return Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsDragEnabled;
   }
   else if(column==1){
-    return Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable;
+    return Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsDragEnabled;
   }
   return Qt::NoItemFlags;
 }
diff --git a/modules/gui/src/scene_win/render_mode_node.cc b/modules/gui/src/scene_win/render_mode_node.cc
index 63789cd37..52836c043 100644
--- a/modules/gui/src/scene_win/render_mode_node.cc
+++ b/modules/gui/src/scene_win/render_mode_node.cc
@@ -77,9 +77,9 @@ gfx::RenderMode::Type RenderModeNode::GetRenderMode() const {
   return render_mode_;
 }
 
-void RenderModeNode::SetQueryView(mol::QueryViewWrapper part)
+void RenderModeNode::Update()
 {
-  //Do Nothing
+  this->SetQueryView(mol::QueryViewWrapper(entity_->GetRenderView(this->GetRenderMode())));
 }
 
 }}
diff --git a/modules/gui/src/scene_win/render_mode_node.hh b/modules/gui/src/scene_win/render_mode_node.hh
index 68bf5300e..f5de2d084 100644
--- a/modules/gui/src/scene_win/render_mode_node.hh
+++ b/modules/gui/src/scene_win/render_mode_node.hh
@@ -54,8 +54,7 @@ public:
 
   gfx::RenderMode::Type GetRenderMode() const;
 
-  virtual void SetQueryView(mol::QueryViewWrapper part);
-
+  virtual void Update();
 private:
   gfx::EntityP entity_;
   gfx::RenderMode::Type render_mode_;
diff --git a/modules/gui/src/scene_win/render_modes_node.cc b/modules/gui/src/scene_win/render_modes_node.cc
index 0e46a1a03..4c551f6b7 100644
--- a/modules/gui/src/scene_win/render_modes_node.cc
+++ b/modules/gui/src/scene_win/render_modes_node.cc
@@ -54,6 +54,9 @@ void RenderModesNode::Update(){
       model->AddNode(this, node);
       render_types_.insert(render_modes[i],node);
     }
+    else{
+      render_types_[render_modes[i]]->Update();
+    }
   }
   QSet<gfx::RenderMode::Type> types_to_delete;
   QMap<gfx::RenderMode::Type,RenderModeNode*>::iterator type;
diff --git a/modules/gui/src/scene_win/scene_win.cc b/modules/gui/src/scene_win/scene_win.cc
index 213582ff6..0b2e75bd3 100644
--- a/modules/gui/src/scene_win/scene_win.cc
+++ b/modules/gui/src/scene_win/scene_win.cc
@@ -52,12 +52,14 @@ SceneWin::SceneWin(QWidget* parent) :
   view_ = new QTreeView(this);
   context_menu_ = new ContextMenu(view_,model_);
   view_->setAttribute(Qt::WA_MacShowFocusRect, false);
+  view_->setAttribute(Qt::WA_MacSmallSize, true);
   view_->header()->hide();
   view_->setContextMenuPolicy(Qt::CustomContextMenu);
   view_->setModel(model_);
   view_->setSelectionBehavior(QAbstractItemView::SelectRows);
   view_->setSelectionMode(QAbstractItemView::ExtendedSelection);
   view_->setEditTriggers(QAbstractItemView::EditKeyPressed);
+  view_->setDragEnabled(true);
   view_->expandAll();
 
   layout->addWidget(view_);
diff --git a/modules/gui/src/scene_win/scene_win_model.cc b/modules/gui/src/scene_win/scene_win_model.cc
index 12df1534d..9e7542b08 100644
--- a/modules/gui/src/scene_win/scene_win_model.cc
+++ b/modules/gui/src/scene_win/scene_win_model.cc
@@ -198,6 +198,36 @@ bool SceneWinModel::setData(const QModelIndex& index,
   return false;
 }
 
+QStringList SceneWinModel::mimeTypes() const
+{
+    QStringList types;
+    types << "text/plain";
+    return types;
+}
+
+Qt::DropActions SceneWinModel::supportedDragActions() const
+{
+    return Qt::MoveAction;
+}
+
+QMimeData* SceneWinModel::mimeData(const QModelIndexList &indexes) const
+{
+  QMimeData *mimeData = new QMimeData();
+  QByteArray encoded_data;
+
+  QDataStream stream(&encoded_data, QIODevice::WriteOnly);
+
+
+  foreach (QModelIndex index, indexes) {
+    if (index.isValid() && index.column()==1) {
+      QString text = "scene['"+data(index, Qt::DisplayRole).toString()+"']";
+      encoded_data.append(text);
+    }
+  }
+  mimeData->setData("text/plain", encoded_data);
+  return mimeData;
+}
+
 void SceneWinModel::NodeAdded(const gfx::GfxNodeP& node)
 {
   gfx::EntityP e=boost::dynamic_pointer_cast<gfx::Entity>(node);
diff --git a/modules/gui/src/scene_win/scene_win_model.hh b/modules/gui/src/scene_win/scene_win_model.hh
index 996f7b640..c65af6677 100644
--- a/modules/gui/src/scene_win/scene_win_model.hh
+++ b/modules/gui/src/scene_win/scene_win_model.hh
@@ -23,6 +23,8 @@
   Author: Stefan Scheuber, Marco Biasini, Ansgar Philippsen
  */
 
+#include <QStringList>
+#include <QMimeData>
 #include <QMap>
 #include <QAbstractItemModel>
 
@@ -88,6 +90,10 @@ public:
                        const QVariant& value=QVariant(), 
                        int role=Qt::DisplayRole);
 
+  virtual QStringList mimeTypes() const;
+  Qt::DropActions supportedDragActions() const;
+  virtual QMimeData* mimeData(const QModelIndexList& indexes) const;
+
   // scene observer interface
   virtual void NodeAdded(const gfx::GfxNodeP& node);
   virtual void NodeRemoved(const gfx::GfxNodeP& node);
diff --git a/modules/gui/src/sequence/sequence_model.cc b/modules/gui/src/sequence/sequence_model.cc
deleted file mode 100644
index 428952657..000000000
--- a/modules/gui/src/sequence/sequence_model.cc
+++ /dev/null
@@ -1,265 +0,0 @@
-//------------------------------------------------------------------------------
-// This file is part of the OpenStructure project <www.openstructure.org>
-//
-// Copyright (C) 2008-2010 by the OpenStructure authors
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License as published by the Free
-// Software Foundation; either version 3.0 of the License, or (at your option)
-// any later version.
-// This library is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
-// details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this library; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-//------------------------------------------------------------------------------
-
-/*
-  Author: Stefan Scheuber
- */
-
-#include <QMap>
-#include <QMapIterator>
-
-#include <QtGui>
-
-#include "sequence_model.hh"
-
-namespace ost { namespace gui {
-
-SequenceModel::SequenceModel(QObject *parent)
-    : QAbstractTableModel(parent), max_columns(0)
-{
-  this->beginInsertRows(QModelIndex(),this->rowCount(),this->rowCount());
-  objects_.append(new ViewObject(this));
-  this->endInsertRows();
-}
-
-void SequenceModel::InsertSequence(QString& name, seq::SequenceHandle& seq){
-  int cols = this->columnCount();
-  int new_cols = seq.GetLength();
-  this->beginInsertRows(QModelIndex(),this->rowCount(),this->rowCount());
-  objects_.append(new ViewObject(seq, name, this));
-  if(new_cols > cols){
-    this->max_columns = new_cols;
-    this->beginInsertColumns(QModelIndex(), cols, new_cols);
-    this->endInsertColumns();
-  }
-  this->endInsertRows();
-}
-
-void SequenceModel::InsertChain(QString& name, mol::ChainView& view){
-  int cols = this->columnCount();
-  int new_cols = view.GetResidueCount();
-  this->beginInsertRows(QModelIndex(),this->rowCount(),this->rowCount());
-  objects_.append(new ViewObject(view, name, this));
-  if(new_cols > cols){
-    this->max_columns = new_cols;
-    this->beginInsertColumns(QModelIndex(), cols, new_cols);
-    this->endInsertColumns();
-  }
-  this->endInsertRows();
-}
-
-void SequenceModel::InsertSequences(const QList<QString>& names, seq::SequenceList& list){
-  this->beginInsertRows(this->index(this->rowCount(),0),this->rowCount(),this->rowCount()+list.GetCount());
-  objects_.append(new ViewObject(list, names, this));
-  this->endInsertRows();
-}
-
-void SequenceModel::InsertGfxEntity(gfx::EntityP& ent){
-  mol::EntityView view=ent->GetView();
-  int size = view.GetChainList().size();
-  int cols = this->columnCount();
-  this->beginInsertRows(QModelIndex(),this->rowCount(),this->rowCount()+size);
-  ViewObject* obj = new ViewObject(ent, this);
-  objects_.append(obj);
-  int new_cols = obj->GetMaxColumnCount();
-  if(new_cols > cols){
-    this->max_columns = new_cols;
-    this->beginInsertColumns(QModelIndex(), cols, new_cols);
-    this->endInsertColumns();
-  }
-  this->endInsertRows();
-}
-
-void SequenceModel::RemoveGfxEntity(gfx::EntityP& entity){
-  if(ViewObject* obj = this->GetItem(entity)){
-    int index = this->GetGlobalRow(obj,0);
-    this->beginRemoveRows(QModelIndex(),index,index+obj->GetRowCount()-1);
-    int cols_before = this->columnCount();
-    objects_.removeOne(obj);
-    this->endRemoveRows();
-    int cols = this->columnCount();
-    if(cols_before>cols){
-      this->max_columns = cols;
-      this->beginRemoveColumns(QModelIndex(), cols, cols_before);
-      this->endRemoveColumns();
-    }
-  }
-}
-
-ViewObject* SequenceModel::GetItem(gfx::EntityP& entity){
-  if(entity != NULL){
-    for (int i = 0 ; i< objects_.size(); i++){
-      if(entity == objects_[i]->GetGfxObject()){
-        return objects_[i];
-      }
-    }
-  }
-  return NULL;
-}
-
-const PainterList& SequenceModel::GetPainters(const QModelIndex& index) const{
-  QPair<int, ViewObject*> pair = this->GetRowWithItem(index);
-  if(pair.second){
-    pair.second->GetRow(pair.first);
-    return pair.second->GetRow(pair.first)->GetPainters();
-  }
-  assert(false);
-}
-
-QPair<int, ViewObject*> SequenceModel::GetRowWithItem(int row) const{
-  if(!objects_.isEmpty()){
-    int rows = 0;
-    int i = -1;
-    int last_row = 0;
-    while (rows <= row && i < objects_.size()){
-      i++;
-      last_row =objects_[i]->GetRowCount();
-      rows += last_row;
-    }
-    int sub_index = row - (rows-last_row);
-    return QPair<int, ViewObject*>(sub_index, objects_[i]);
-  }
-  return QPair<int, ViewObject*>(-1, NULL);
-}
-
-QPair<int, ViewObject*> SequenceModel::GetRowWithItem(const QModelIndex& index) const{
-  return this->GetRowWithItem(index.row());
-}
-
-ViewObject* SequenceModel::GetItem(const QModelIndex& index) const
-{
-  return this->GetRowWithItem(index).second;
-}
-
-int SequenceModel::GetGlobalRow(ViewObject* obj, int row) const
-{
-  int glob_row = -1;
-  int index = objects_.indexOf(obj);
-  if(index >= 0){
-    glob_row = 0;
-    for(int i=0; i<index; i++){
-      glob_row += objects_[i]->GetRowCount();
-    }
-    return glob_row + row;
-  }
-  return glob_row;
-}
-
-QModelIndexList SequenceModel::GetModelIndexes(gfx::EntityP& entity, const mol::EntityView& view)
-{
-  QModelIndexList list;
-  if(ViewObject* object = this->GetItem(entity)){
-    QMap<int, QList<int> > indexes = object->GetIndexesForView(view);
-    QMapIterator< int, QList<int> > i(indexes);
-    while (i.hasNext()) {
-      i.next();
-      int row = this->GetGlobalRow(object, i.key());
-      const QList<int>& index_list = i.value();
-      for(int i=0; i<index_list.size(); i++){
-        list.append(this->index(row,index_list[i]));
-      }
-    }
-  }
-  return list;
-}
-
-void SequenceModel::SelectionChanged(const QItemSelection& sel, const QItemSelection& desel)
-{
-  QMap<int,QPair<QSet<int>,QSet<int> > > sel_map;
-  const QModelIndexList& sel_indexes = sel.indexes();
-  for(int i =0; i< sel_indexes.size(); i++){
-     sel_map[sel_indexes[i].row()].first.insert(sel_indexes[i].column());
-  }
-
-  const QModelIndexList& desel_indexes = desel.indexes();
-  for(int i =0; i< desel_indexes.size(); i++){
-     sel_map[desel_indexes[i].row()].second.insert(desel_indexes[i].column());
-  }
-
-  QMapIterator< int,QPair<QSet<int>,QSet<int> > > i(sel_map);
-  while (i.hasNext()) {
-    i.next();
-    QPair<int, ViewObject*> item = this->GetRowWithItem(i.key());
-    item.second->SetSelection(item.first,i.value().first, i.value().second);
-  }
-}
-
-void SequenceModel::DoubleClicked(const QModelIndex& index)
-{
-  QPair<int, ViewObject*> item = this->GetRowWithItem(index);
-  if(item.second){
-    item.second->DoubleClicked(item.first,index.column());
-  }
-}
-
-int SequenceModel::rowCount(const QModelIndex& parent) const
-{
-  int rows = 0;
-  for (int i = 0; i<objects_.size(); i++){
-    rows += objects_[i]->GetRowCount();
-  }
-  return rows;
-}
-
-int SequenceModel::columnCount(const QModelIndex& parent) const
-{
-  return max_columns;
-}
-
-QVariant SequenceModel::data(const QModelIndex& index, int role) const
-{
-  QPair<int, ViewObject*> item = this->GetRowWithItem(index);
-  if(!item.second) return QVariant();
-  QVariant data = item.second->GetData(item.first,index.column(),role);
-  return data;
-}
-
-QVariant SequenceModel::headerData(int section, Qt::Orientation orientation,
-                                    int role) const
-{
-  if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
-    return QVariant("");
-  }
-  return QVariant();
-}
-
-Qt::ItemFlags SequenceModel::flags(const QModelIndex& index) const
-{
-  QPair<int, ViewObject*> item = GetRowWithItem(index);
-  if(item.second){
-    return item.second->Flags(item.first, index.column());
-  }
-  return QAbstractItemModel::flags(index);
-}
-
-void SequenceModel::ZoomIn()
-{
-  for (int i = 0; i<objects_.size(); i++){
-    objects_[i]->ZoomIn();
-  }
-}
-
-void SequenceModel::ZoomOut()
-{
-  for (int i = 0; i<objects_.size(); i++){
-    objects_[i]->ZoomOut();
-  }
-}
-
-}}
diff --git a/modules/gui/src/sequence/sequence_viewer.cc b/modules/gui/src/sequence/sequence_viewer.cc
deleted file mode 100644
index fd6a3cf2b..000000000
--- a/modules/gui/src/sequence/sequence_viewer.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-//------------------------------------------------------------------------------
-// This file is part of the OpenStructure project <www.openstructure.org>
-//
-// Copyright (C) 2008-2010 by the OpenStructure authors
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License as published by the Free
-// Software Foundation; either version 3.0 of the License, or (at your option)
-// any later version.
-// This library is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
-// details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this library; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-//------------------------------------------------------------------------------
-
-/*
-  Author: Stefan Scheuber
- */
-#include <boost/pointer_cast.hpp>
-
-#include <QVBoxLayout>
-#include <QPushButton>
-#include <QHeaderView>
-#include <QAbstractItemView>
-
-#include <ost/mol/chain_view.hh>
-#include <ost/mol/entity_view.hh>
-
-#include <ost/seq/sequence_handle.hh>
-
-#include <ost/gfx/entity.hh>
-#include <ost/gfx/scene.hh>
-#include <ost/gfx/gfx_node_visitor.hh>
-
-#include <ost/gui/widget_registry.hh>
-#include <ost/gui/gosty_app.hh>
-
-#include "sequence_model.hh"
-#include "sequence_viewer.hh"
-
-namespace ost { namespace gui {
-
-class SequenceViewerV2Factory: public WidgetFactory {
-public:
-  SequenceViewerV2Factory() :
-    WidgetFactory("ost::gui::SequenceViewerV2", "Sequence Viewer V2") {
-  }
-
-  virtual Widget* Create(QWidget* parent) {
-    return GostyApp::Instance()->GetSequenceViewerV2();
-  }
-};
-
-OST_REGISTER_WIDGET(SequenceViewerV2, SequenceViewerV2Factory);
-
-struct GetNodesVisitor: public gfx::GfxNodeVisitor {
-  GetNodesVisitor(): nodes_() {}
-  virtual void VisitObject(gfx::GfxObj* o, const Stack& st) {
-    nodes_.push_back(o->shared_from_this());
-  }
-  gfx::NodePtrList nodes_;
-  gfx::NodePtrList GetNodes(){return nodes_;}
-};
-
-SequenceViewerV2::SequenceViewerV2(QWidget* parent): Widget(NULL,parent)
-{
-  gfx::Scene::Instance().AttachObserver(this);
-  model_ = new SequenceModel(this);
-
-  QVBoxLayout* layout = new QVBoxLayout(this);
-  layout->setMargin(0);
-  layout->setSpacing(0);
-
-  seq_table_view_ = new SequenceTableView(model_);
-  layout->addWidget(seq_table_view_);
-  this->setLayout(layout);
-  connect(model_,SIGNAL(columnsInserted(const QModelIndex&, int, int)),seq_table_view_,SLOT(columnCountChanged(const QModelIndex&, int, int)));
-  connect(model_,SIGNAL(rowsInserted(const QModelIndex&, int, int)),seq_table_view_,SLOT(rowCountChanged(const QModelIndex&, int, int)));
-
-  seq_table_view_->horizontalHeader()->setMinimumSectionSize(2);
-  seq_table_view_->verticalHeader()->setMinimumSectionSize(2);
-  seq_table_view_->setSelectionMode(QAbstractItemView::ExtendedSelection);
-  connect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
-  connect(seq_table_view_,SIGNAL(doubleClicked(const QModelIndex&)),model_,SLOT(DoubleClicked(const QModelIndex&)));
-  connect(seq_table_view_->GetStaticColumn(),SIGNAL(doubleClicked(const QModelIndex&)),this,SLOT(DoubleClicked(const QModelIndex&)));
-  connect(seq_table_view_->GetStaticRow(),SIGNAL(doubleClicked(const QModelIndex&)),this,SLOT(DoubleClicked(const QModelIndex&)));
-  connect(seq_table_view_,SIGNAL(MouseWheelEvent(QWheelEvent*)),this,SLOT(MouseWheelEvent(QWheelEvent*)));
-
-  gfx::GfxNodeP root_node = gfx::Scene::Instance().GetRootNode();
-  GetNodesVisitor gnv;
-  gfx::Scene::Instance().Apply(gnv);
-  gfx::NodePtrList list = gnv.GetNodes();
-  for(unsigned int i=0; i<list.size();i++){
-    this->NodeAdded(list[i]);
-  }
-}
-
-void SequenceViewerV2::NodeAdded(const gfx::GfxNodeP& n)
-{
-  if (gfx::EntityP o=boost::dynamic_pointer_cast<gfx::Entity>(n)) {
-    model_->InsertGfxEntity(o);
-    seq_table_view_->resizeColumnsToContents();
-    seq_table_view_->resizeRowsToContents();
-  }
-}
-
-void SequenceViewerV2::NodeRemoved(const gfx::GfxNodeP& node)
-{
-  if (gfx::EntityP o=boost::dynamic_pointer_cast<gfx::Entity>(node)) {
-    model_->RemoveGfxEntity(o);
-  }
-}
-
-void SequenceViewerV2::SelectionModelChanged(const QItemSelection& sel, const QItemSelection& desel)
-{
-  gfx::Scene::Instance().DetachObserver(this);
-  model_->SelectionChanged(sel, desel);
-  gfx::Scene::Instance().AttachObserver(this);
-}
-
-void SequenceViewerV2::SelectionChanged(const gfx::GfxObjP& o,
-                                      const mol::EntityView& view)
-{
-  disconnect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
-  QItemSelectionModel* model = seq_table_view_->selectionModel();
-  gfx::EntityP entity=boost::dynamic_pointer_cast<gfx::Entity>(o);
-  if(entity){
-    const QModelIndexList& list = model_->GetModelIndexes(entity, view);
-    QSet<int> rows_visited;
-    for(int i = 0; i<list.size(); i++){
-      int row =list[i].row();
-      if(!rows_visited.contains(row)){
-        model->select(list[i],QItemSelectionModel::Rows|QItemSelectionModel::Deselect);
-        rows_visited.insert(row);
-      }
-    }
-    for(int i = 0; i<list.size(); i++){
-      model->select(list[i],QItemSelectionModel::Select);
-    }
-  }
-  connect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
-}
-
-void SequenceViewerV2::DoubleClicked(const QModelIndex& index)
-{
-  disconnect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
-  model_->DoubleClicked(index);
-  connect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
-}
-
-void SequenceViewerV2::MouseWheelEvent(QWheelEvent* event)
-{
-  int delta = event->delta();
-  if (event->orientation() == Qt::Vertical) {
-    if(delta>0){
-      model_->ZoomIn();
-      seq_table_view_->viewport()->update();
-      seq_table_view_->resizeColumnsToContents();
-      seq_table_view_->resizeRowsToContents();
-    }
-    else if(delta<0){
-      model_->ZoomOut();
-      seq_table_view_->viewport()->update();
-      seq_table_view_->resizeColumnsToContents();
-      seq_table_view_->resizeRowsToContents();
-    }
-  }
-  event->accept();
-}
-
-SequenceViewerV2::~SequenceViewerV2(){
-  gfx::Scene::Instance().DetachObserver(this);
-}
-
-}}
diff --git a/modules/gui/src/sequence/view_object.cc b/modules/gui/src/sequence/view_object.cc
deleted file mode 100644
index e422027e7..000000000
--- a/modules/gui/src/sequence/view_object.cc
+++ /dev/null
@@ -1,232 +0,0 @@
-//------------------------------------------------------------------------------
-// This file is part of the OpenStructure project <www.openstructure.org>
-//
-// Copyright (C) 2008-2010 by the OpenStructure authors
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License as published by the Free
-// Software Foundation; either version 3.0 of the License, or (at your option)
-// any later version.
-// This library is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
-// details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this library; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-//------------------------------------------------------------------------------
-
-/*
-  Author: Stefan Scheuber
- */
-
-
-#include <QtGui>
-
-#include <ost/mol/mol.hh>
-#include <ost/mol/view_op.hh>
-
-#include "sequence_row.hh"
-#include "secstr_row.hh"
-#include "title_row.hh"
-
-#include "painter.hh"
-#include "seq_secstr_painter.hh"
-#include "seq_selection_painter.hh"
-#include "seq_text_painter.hh"
-#include "tick_painter.hh"
-
-#include "view_object.hh"
-
-namespace ost { namespace gui {
-
-ViewObject::ViewObject(seq::SequenceList& sequences, const QList<QString>& names, QObject *parent): QObject(parent)
-{
-  if(names.size() == sequences.GetCount()){
-    for(int i=0; i<sequences.GetCount(); i++){
-      seq::SequenceHandle seq = sequences[i];
-      this->AddSequence(seq, names[i]);
-    }
-  }
-}
-
-ViewObject::ViewObject(seq::SequenceHandle& sequence, const QString& name, QObject *parent): QObject(parent), entity_(gfx::EntityP())
-{
-  this->AddSequence(sequence, name);
-}
-
-ViewObject::ViewObject(mol::ChainView& chain, const QString& name, QObject *parent): QObject(parent), entity_(gfx::EntityP())
-{
-  this->AddChain(chain, name);
-}
-
-ViewObject::ViewObject(gfx::EntityP& entity, QObject* parent): QObject(parent), entity_(entity)
-{
-  mol::EntityView view =entity->GetView();
-  for (mol::ChainViewList::const_iterator c=view.GetChainList().begin(),
-       e1=view.GetChainList().end(); c!=e1; ++c) {
-    mol::ChainView chain=*c;
-    QString name = QString(entity->GetName().c_str());
-    if (chain.GetName()!="" && chain.GetName()!=" ") {
-      name= name + " ("+chain.GetName().c_str()+")";
-    }
-    this->AddChain(chain, name);
-  }
-}
-
-ViewObject::ViewObject(QObject* parent): QObject(parent)
-{
-  TitleRow* new_row = new TitleRow(this);
-  Painter* p = new TickPainter(this);
-  new_row->InsertPainter(p);
-  rows_.append(new_row);
-}
-
-void ViewObject::InsertRow(int pos, BaseRow* row)
-{
-  if(pos >= 0 && pos <= rows_.size()){
-    rows_.insert(pos,row);
-  }
-}
-
-void ViewObject::RemoveRow(BaseRow* row)
-{
-  rows_.removeAll(row);
-}
-
-BaseRow* ViewObject::GetRow(int pos)
-{
-   if(pos >= 0 && pos < rows_.size()){
-     return rows_[pos];
-   }
-   return NULL;
-}
-
-int ViewObject::GetRowCount()
-{
-  return rows_.size();
-}
-
-void ViewObject::AddSequence(seq::SequenceHandle& sequence, const QString& name)
-{
-  SequenceRow* new_row = new SequenceRow(name, sequence, this);
-  Painter* p = new SeqSelectionPainter(this);
-  new_row->InsertPainter(p);
-  p = new SeqTextPainter(this);
-  new_row->InsertPainter(p);
-  rows_.append(new_row);
-}
-
-void ViewObject::AddChain(mol::ChainView& chain, const QString& name)
-{
-  SecStrRow* new_row = new SecStrRow(name, chain, this);
-  Painter* p = new SeqSelectionPainter(this);
-  new_row->InsertPainter(p);
-  p = new SeqSecStrPainter(this);
-  new_row->InsertPainter(p);
-  p = new SeqTextPainter(this);
-  new_row->InsertPainter(p);
-  rows_.append(new_row);
-}
-
-void ViewObject::AttachGfxObject(gfx::EntityP& ent)
-{
-  entity_ = ent;
-}
-
-gfx::EntityP& ViewObject::GetGfxObject()
-{
-  return entity_;
-}
-
-void ViewObject::SetSelection(int row, const QSet<int>& added, const QSet<int>& removed)
-{
-  if(SequenceRow* sequence_row = qobject_cast<SequenceRow*>(rows_[row])){
-    sequence_row->SetSelection(added,removed);
-  }
-}
-
-QVariant ViewObject::GetData(int row, int column, int role)
-{
-  if(row<0 || row >= rows_.size())return QVariant();
-
-  return rows_[row]->GetData(column,role);
-}
-
-int ViewObject::GetMaxColumnCount() const
-{
-  int columns = 0;
-  for(int i = 0; i < rows_.size(); i++){
-    int col_length = rows_[i]->GetColumnCount();
-    if(columns < col_length){
-      columns = col_length;
-    }
-  }
-  return columns;
-}
-
-bool ViewObject::SetData(int row, int column, const QVariant& value, int role)
-{
-  if(row<0 || row >= rows_.size())return false;
-
-  return rows_[row]->SetData(column, value, role);
-}
-
-void ViewObject::DoubleClicked(int row, int column)
-{
-  if(row>=0 || row < rows_.size()){
-    rows_[row]->DoubleClicked(column);
-  }
-}
-
-void ViewObject::ZoomIn()
-{
-  for(int i=0; i< rows_.size(); i++){
-    rows_[i]->ZoomIn();
-  }
-}
-
-void ViewObject::ZoomOut()
-{
-  for(int i=0; i< rows_.size(); i++){
-    rows_[i]->ZoomOut();
-  }
-}
-
-QMap<int, QList<int> > ViewObject::GetIndexesForView(const mol::EntityView& view)
-{
-  if(view.GetChainCount()==0){
-    return QMap<int, QList<int> >();
-  }
-  else{
-    QMap<int, QList<int> > selected_indexes;
-    for(int i=0; i< rows_.size(); i++){
-      if(SecStrRow* secstr_row = qobject_cast<SecStrRow*>(rows_[i])){
-        mol::ChainView dst_chain=(secstr_row->GetChain());
-        seq::SequenceHandle seq = secstr_row->GetSequence();
-        if (mol::ChainView src_chain=view.FindChain(dst_chain.GetName())) {
-          // for each residue in the selection deduce index in sequence
-          for (mol::ResidueViewList::const_iterator j=src_chain.GetResidueList().begin(),
-             e2=src_chain.GetResidueList().end(); j!=e2; ++j) {
-            mol::ResidueView dst_res=dst_chain.FindResidue(j->GetHandle());
-            assert(dst_res.IsValid());
-            int p=dst_res.GetIndex()+1;
-            assert(p>=0 && p<=seq.GetLength());
-            selected_indexes[i].append(p);
-          }
-        }
-      }
-    }
-    return selected_indexes;
-  }
-}
-
-Qt::ItemFlags ViewObject::Flags(int row, int column) const
-{
-  if(row<0 || row >= rows_.size())return Qt::NoItemFlags;
-
-  return rows_[row]->Flags(column);
-}
-
-}}
diff --git a/modules/gui/src/sequence_viewer/align_properties_painter.cc b/modules/gui/src/sequence_viewer/align_properties_painter.cc
new file mode 100644
index 000000000..e51c0536a
--- /dev/null
+++ b/modules/gui/src/sequence_viewer/align_properties_painter.cc
@@ -0,0 +1,78 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+/*
+  Author: Stefan Scheuber
+ */
+
+
+#include <QtGui>
+
+#include "align_properties_painter.hh"
+
+namespace ost { namespace gui {
+
+namespace {
+
+QMap<QString,QColor> GetColorMap(){
+  QMap<QString,QColor> map;
+  map["G"]=QColor(175,175,175,100);
+  map["A"]=QColor(175,175,175,100);
+  map["V"]=QColor(175,175,175,100);
+  map["L"]=QColor(175,175,175,100);
+  map["I"]=QColor(175,175,175,100);
+  map["F"]=QColor(255,165,100);
+  map["Y"]=QColor(255,165,100);
+  map["W"]=QColor(255,165,100);
+  map["C"]=QColor(255,255,0,100);
+  map["M"]=QColor(255,255,0,100);
+  map["S"]=QColor(0,255,0,100);
+  map["T"]=QColor(0,255,0,100);
+  map["K"]=QColor(255,0,0,100);
+  map["R"]=QColor(255,0,0,100);
+  map["H"]=QColor(255,0,0,100);
+  map["D"]=QColor(0,0,255,100);
+  map["E"]=QColor(0,0,255,100);
+  map["N"]=QColor(0,0,255,100);
+  map["Q"]=QColor(0,0,255,100);
+  map["P"]=QColor(0,255,255,100);
+  return map;
+}
+
+}
+
+QMap<QString,QColor> AlignPropertiesPainter::color_map_ = GetColorMap();
+
+
+AlignPropertiesPainter::AlignPropertiesPainter(QObject* parent)
+    : Painter(parent)
+{}
+
+void AlignPropertiesPainter::Paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index){
+  painter->save();
+  if (index.column()>0){
+    QString text = index.data(Qt::DisplayRole).toString();
+    if(color_map_.contains(text)){
+      painter->fillRect(option.rect, color_map_[text]);
+    }
+  }
+  painter->restore();
+}
+
+}}
diff --git a/modules/gui/pymod/sequence_viewer_proxyV2.hh b/modules/gui/src/sequence_viewer/align_properties_painter.hh
similarity index 70%
rename from modules/gui/pymod/sequence_viewer_proxyV2.hh
rename to modules/gui/src/sequence_viewer/align_properties_painter.hh
index 7d7e1f269..d33331cc6 100644
--- a/modules/gui/pymod/sequence_viewer_proxyV2.hh
+++ b/modules/gui/src/sequence_viewer/align_properties_painter.hh
@@ -16,30 +16,29 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
-#ifndef OST_GUI_SEQUENCE_VIEWER_PROXY_V2_HH
-#define OST_GUI_SEQUENCE_VIEWER_PROXY_V2_HH
+#ifndef OST_SEQUENCE_VIEWER_ALIGN_PROPERTIES_PAINTER
+#define OST_SEQUENCE_VIEWER_ALIGN_PROPERTIES_PAINTER
 
-#include <ost/gui/sequence/sequence_viewer.hh>
+/*
+  Author: Stefan Scheuber
+ */
 
-#include "sip_handler.hh"
+#include <QObject>
+
+#include "painter.hh"
 
 namespace ost { namespace gui {
 
-class  SequenceViewerProxyV2 : public SipHandler<SequenceViewerV2> {
 
+
+class AlignPropertiesPainter : public Painter
+{
+  Q_OBJECT
 public:
-  SequenceViewerProxyV2(SequenceViewerV2* seq_viewer=new SequenceViewerV2()):
-    SipHandler<SequenceViewerV2>(seq_viewer)
-  { }
-  
-  void Show()  
-  {
-    return Me()->show();
-  }
-  void Hide()  
-  {
-    return Me()->hide();
-  }
+  AlignPropertiesPainter(QObject* parent = 0);
+  void Paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index);
+private:
+  static QMap<QString,QColor> color_map_;
 };
 
 }}
diff --git a/modules/gui/src/sequence_viewer/alignment_view_object.cc b/modules/gui/src/sequence_viewer/alignment_view_object.cc
new file mode 100644
index 000000000..9aa233194
--- /dev/null
+++ b/modules/gui/src/sequence_viewer/alignment_view_object.cc
@@ -0,0 +1,212 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+/*
+  Author: Stefan Scheuber
+ */
+
+
+#include <QtGui>
+
+#include <ost/mol/mol.hh>
+#include <ost/mol/view_op.hh>
+
+#include <ost/seq/aligned_region.hh>
+#include <ost/seq/alg/conservation.hh>
+
+#include "sequence_row.hh"
+#include "secstr_row.hh"
+
+#include "painter.hh"
+#include "background_painter.hh"
+#include "seq_secstr_painter.hh"
+#include "seq_selection_painter.hh"
+#include "seq_text_painter.hh"
+
+#include "alignment_view_object.hh"
+
+namespace ost { namespace gui {
+
+namespace {
+QMap<QString,int> GetGroupMap(){
+  QMap<QString,int> map;
+  map["G"]=1;
+  map["A"]=1;
+  map["V"]=1;
+  map["L"]=1;
+  map["I"]=1;
+  map["F"]=2;
+  map["Y"]=2;
+  map["W"]=2;
+  map["C"]=3;
+  map["M"]=3;
+  map["S"]=4;
+  map["T"]=4;
+  map["K"]=5;
+  map["R"]=5;
+  map["H"]=5;
+  map["D"]=6;
+  map["E"]=6;
+  map["N"]=6;
+  map["Q"]=6;
+  map["P"]=7;
+  return map;
+}
+
+QColor GetColor(int cons){
+  int color = 255 - int((float(cons) / 100) * 200);
+  return QColor(color,color,color);
+}
+
+QColor GetForeGroundColor(QColor background){
+  if(background == Qt::transparent){
+    return Qt::black;
+  }
+  int gray = 255 - background.red();
+  return QColor(gray,gray,gray);
+}
+
+}
+
+QMap<QString,int> AlignmentViewObject::group_map_ = GetGroupMap();
+
+
+const QString AlignmentViewObject::conservation_mode_1 = "Highlight conservation 1";
+const QString AlignmentViewObject::conservation_mode_2 = "Highlight conservation 2";
+
+AlignmentViewObject::AlignmentViewObject(const seq::AlignmentHandle& alignment, QObject* parent): SequenceViewObject(parent), alignment_(alignment)
+{
+  for(int i=0; i<alignment.GetCount(); i++){
+    seq::SequenceHandle seq_handle = alignment.GetSequence(i).Copy();
+    this->AddSequence(seq_handle, seq_handle.GetName().c_str());
+  }
+
+  std::vector<Real> values = seq::alg::Conservation(alignment,false);
+
+  gradient_.SetColorAt(0,gfx::Color(0,0,1));
+  gradient_.SetColorAt(0.5,gfx::Color(1,1,1));
+  gradient_.SetColorAt(1,gfx::Color(1,0,0));
+  //Calculate Conservation Mode 1
+  for(unsigned int i=0; i<values.size(); i++){
+    gfx::Color color = gradient_.GetColorAt(values[i]);
+    conservation_1_[i] = QColor(color.Red()*255,color.Green()*255,color.Blue()*255,100);
+  }
+
+  //Calculate Conservation Mode 2
+  for(int j=0; j<alignment.GetLength(); j++){
+    int group = 0;
+    QString element = "";
+    for(int i=0; i<alignment.GetCount();i++){
+      QString code = QString(alignment.GetOneLetterCode(i,j));
+      if(element.size()==0){
+        element = code;
+      }
+      else if (element != code){
+        element = "  ";
+      }
+      if(group_map_.contains(code) && group>=0){
+        if(group == 0) {
+            group = group_map_[code];
+        }
+        else if(group_map_[code] != group){
+          group = -1;
+        }
+      }
+      else{
+        group = -1;
+      }
+
+    }
+    if(element.size()==1){
+      conservation_2_[j] = QColor(175,175,175);
+    }
+    else if(group > 0){
+      conservation_2_[j] = QColor(200,200,200);
+    }
+    else{
+      conservation_2_[j] = Qt::transparent;
+    }
+  }
+  this->AddDisplayMode(conservation_mode_1);
+  this->AddDisplayMode(conservation_mode_2);
+}
+
+
+QVariant AlignmentViewObject::GetData(int row, int column, int role)
+{
+  if(column > 0){
+    if(this->GetCurrentDisplayMode() == conservation_mode_1){
+      if(role == Qt::UserRole+3 ){
+        if(column -1 < conservation_1_.size()){
+          return QVariant(conservation_1_[column-1]);
+        }
+          return QVariant(Qt::transparent);
+      }
+
+      if(role == Qt::ForegroundRole){
+        if(column -1 < conservation_1_.size()){
+          if(conservation_1_[column-1].red()>128){
+            return QVariant(Qt::black);
+          }
+          else{
+            return QVariant(Qt::white);
+          }
+        }
+        return QVariant(Qt::transparent);
+      }
+    }
+    else if(this->GetCurrentDisplayMode() == conservation_mode_2){
+      if(role == Qt::UserRole+3 ){
+        if(column -1 < conservation_2_.size()){
+          return QVariant(conservation_2_[column-1]);
+        }
+        return QVariant(Qt::transparent);
+      }
+      if(role == Qt::ForegroundRole){
+        if(column -1 < conservation_2_.size()){
+            return QVariant(Qt::black);
+        }
+        return QVariant(Qt::transparent);
+      }
+    }
+  }
+  return BaseViewObject::GetData(row,column,role);
+}
+
+void AlignmentViewObject::SetDisplayMode(const QString& mode)
+{
+  if(this->display_modes_.contains(mode) && mode != this->GetCurrentDisplayMode()){
+    if(mode == conservation_mode_1 || mode == conservation_mode_2){
+      for(int i=0 ; i<this->GetRowCount(); i++){
+        BaseRow* row = this->GetRow(i);
+        row->RemovePainter(seq_secondary_structure_painter);
+        row->RemovePainter(align_properties_painter);
+        row->InsertPainter(conservation_painter,1);
+      }
+    }
+  }
+  SequenceViewObject::SetDisplayMode(mode);
+}
+
+const seq::AlignmentHandle& AlignmentViewObject::GetAlignment()
+{
+  return alignment_;
+}
+
+}}
diff --git a/modules/gui/src/sequence_viewer/alignment_view_object.hh b/modules/gui/src/sequence_viewer/alignment_view_object.hh
new file mode 100644
index 000000000..b8fee2800
--- /dev/null
+++ b/modules/gui/src/sequence_viewer/alignment_view_object.hh
@@ -0,0 +1,61 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#ifndef OST_SEQUENCE_VIEWER_ALIGNMENT_VIEW_OBJECT
+#define OST_SEQUENCE_VIEWER_ALIGNMENT_VIEW_OBJECT
+
+/*
+  Author: Stefan Scheuber
+ */
+
+#include <ost/seq/alignment_handle.hh>
+
+#include <ost/gfx/gradient.hh>
+
+#include "sequence_view_object.hh"
+
+namespace ost { namespace gui {
+
+class AlignmentViewObject : public SequenceViewObject
+{
+  Q_OBJECT
+
+public:
+  AlignmentViewObject(const seq::AlignmentHandle& alignment, QObject* parent = 0);
+
+  QVariant GetData(int row, int column, int role);
+  const seq::AlignmentHandle& GetAlignment();
+
+  void SetDisplayMode(const QString& mode);
+
+private:
+  gfx::Gradient gradient_;
+  seq::AlignmentHandle alignment_;
+  QMap<int, QColor> conservation_1_;
+  QMap<int, QColor> conservation_2_;
+
+  static QMap<QString,int> group_map_;
+
+  static const QString conservation_mode_1;
+  static const QString conservation_mode_2;
+};
+
+
+}}
+
+#endif
diff --git a/modules/gui/src/sequence_viewer/background_painter.cc b/modules/gui/src/sequence_viewer/background_painter.cc
new file mode 100644
index 000000000..25cf4c650
--- /dev/null
+++ b/modules/gui/src/sequence_viewer/background_painter.cc
@@ -0,0 +1,51 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+/*
+  Author: Stefan Scheuber
+ */
+
+
+#include <QtGui>
+
+#include "background_painter.hh"
+
+namespace ost { namespace gui {
+
+BackgroundPainter::BackgroundPainter(QObject* parent)
+    : Painter(parent)
+{}
+
+void BackgroundPainter::Paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index){
+  painter->save();
+  if (index.column()>0 && (index.column()-1)%10 < 5){
+    painter->fillRect(option.rect, QColor(240,240,240));
+
+  }
+  else{
+    painter->fillRect(option.rect, QColor(255,255,255));
+  }
+  if(index.row()>0 && (index.column())%10 == 0){
+    painter->setPen(QPen(QColor(135,135,135)));
+    painter->drawLine(option.rect.topRight(),option.rect.bottomRight());
+  }
+  painter->restore();
+}
+
+}}
diff --git a/modules/base/src/integrity_error.cc b/modules/gui/src/sequence_viewer/background_painter.hh
similarity index 71%
rename from modules/base/src/integrity_error.cc
rename to modules/gui/src/sequence_viewer/background_painter.hh
index ced74b0c9..942e1dde5 100644
--- a/modules/base/src/integrity_error.cc
+++ b/modules/gui/src/sequence_viewer/background_painter.hh
@@ -16,14 +16,28 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
-#include "integrity_error.hh"
-#include <ost/message.hh>
+#ifndef OST_SEQUENCE_VIEWER_BACKGROUND_PAINTER
+#define OST_SEQUENCE_VIEWER_BACKGROUND_PAINTER
 
-namespace ost {
-IntegrityError::IntegrityError(const String& msg):
-  Error(msg)
+/*
+  Author: Stefan Scheuber
+ */
+
+#include <QObject>
+
+#include "painter.hh"
+
+namespace ost { namespace gui {
+
+class BackgroundPainter : public Painter
 {
-  
-}
+  Q_OBJECT
+public:
+  BackgroundPainter(QObject* parent = 0);
+  void Paint(QPainter *painter, const QStyleOptionViewItem &option,
+      const QModelIndex &index);
+};
+
+}}
 
-}
+#endif
diff --git a/modules/gui/src/sequence/base_row.cc b/modules/gui/src/sequence_viewer/base_row.cc
similarity index 97%
rename from modules/gui/src/sequence/base_row.cc
rename to modules/gui/src/sequence_viewer/base_row.cc
index e2a57450b..16dfb0af3 100644
--- a/modules/gui/src/sequence/base_row.cc
+++ b/modules/gui/src/sequence_viewer/base_row.cc
@@ -130,6 +130,9 @@ Qt::ItemFlags BaseRow::Flags(int column) const
 void BaseRow::DoubleClicked(int column)
 { }
 
+void BaseRow::SetSelection(const QSet<int>& added, const QSet<int>& removed)
+{ }
+
 void BaseRow::ZoomIn()
 {
   QFont font = this->GetFont();
diff --git a/modules/gui/src/sequence/base_row.hh b/modules/gui/src/sequence_viewer/base_row.hh
similarity index 96%
rename from modules/gui/src/sequence/base_row.hh
rename to modules/gui/src/sequence_viewer/base_row.hh
index 3a69ca0e6..6f20d872b 100644
--- a/modules/gui/src/sequence/base_row.hh
+++ b/modules/gui/src/sequence_viewer/base_row.hh
@@ -59,6 +59,7 @@ public:
   virtual bool SetData(int column, const QVariant& value, int role);
   virtual Qt::ItemFlags Flags(int column) const;
   virtual void DoubleClicked(int column);
+  virtual void SetSelection(const QSet<int>& added, const QSet<int>& removed);
 
   virtual void ZoomIn();
   virtual void ZoomOut();
diff --git a/modules/gui/src/sequence_viewer/base_view_object.cc b/modules/gui/src/sequence_viewer/base_view_object.cc
new file mode 100644
index 000000000..72953aa3e
--- /dev/null
+++ b/modules/gui/src/sequence_viewer/base_view_object.cc
@@ -0,0 +1,144 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+/*
+  Author: Stefan Scheuber
+ */
+
+
+#include <QtGui>
+
+#include "base_view_object.hh"
+
+namespace ost { namespace gui {
+
+BaseViewObject::BaseViewObject(QObject* parent): QObject(parent)
+{ }
+
+void BaseViewObject::InsertRow(int pos, BaseRow* row)
+{
+  if(pos >= 0 && pos <= rows_.size()){
+    rows_.insert(pos,row);
+  }
+}
+
+void BaseViewObject::RemoveRow(BaseRow* row)
+{
+  rows_.removeAll(row);
+}
+
+BaseRow* BaseViewObject::GetRow(int pos)
+{
+   if(pos >= 0 && pos < rows_.size()){
+     return rows_[pos];
+   }
+   return NULL;
+}
+
+int BaseViewObject::GetRowCount()
+{
+  return rows_.size();
+}
+
+void BaseViewObject::SetSelection(int row, const QSet<int>& added, const QSet<int>& removed)
+{
+  if(row>=0 && row < rows_.size()){
+    rows_[row]->SetSelection(added,removed);
+  }
+}
+
+QVariant BaseViewObject::GetData(int row, int column, int role)
+{
+  if(row<0 || row >= rows_.size())return QVariant();
+
+  return rows_[row]->GetData(column,role);
+}
+
+int BaseViewObject::GetMaxColumnCount() const
+{
+  int columns = 0;
+  for(int i = 0; i < rows_.size(); i++){
+    int col_length = rows_[i]->GetColumnCount();
+    if(columns < col_length){
+      columns = col_length;
+    }
+  }
+  return columns;
+}
+
+bool BaseViewObject::SetData(int row, int column, const QVariant& value, int role)
+{
+  if(row<0 || row >= rows_.size())return false;
+
+  return rows_[row]->SetData(column, value, role);
+}
+
+const QStringList& BaseViewObject::GetDisplayModes()
+{
+  return display_modes_;
+}
+
+const QString& BaseViewObject::GetCurrentDisplayMode()
+{
+  return current_display_mode_;
+}
+
+void BaseViewObject::SetDisplayMode(const QString& mode)
+{
+  if(display_modes_.contains(mode)){
+    this->current_display_mode_ = mode;
+  }
+}
+
+void BaseViewObject::AddDisplayMode(const QString& mode)
+{
+  if(!display_modes_.contains(mode)){
+    this->display_modes_.append(mode);
+  }
+}
+
+void BaseViewObject::DoubleClicked(int row, int column)
+{
+  if(row>=0 || row < rows_.size()){
+    rows_[row]->DoubleClicked(column);
+  }
+}
+
+void BaseViewObject::ZoomIn()
+{
+  for(int i=0; i< rows_.size(); i++){
+    rows_[i]->ZoomIn();
+  }
+}
+
+void BaseViewObject::ZoomOut()
+{
+  for(int i=0; i< rows_.size(); i++){
+    rows_[i]->ZoomOut();
+  }
+}
+
+Qt::ItemFlags BaseViewObject::Flags(int row, int column) const
+{
+  if(row<0 || row >= rows_.size())return Qt::NoItemFlags;
+
+  return rows_[row]->Flags(column);
+}
+
+}}
diff --git a/modules/gui/src/sequence/sequence_viewer.hh b/modules/gui/src/sequence_viewer/base_view_object.hh
similarity index 52%
rename from modules/gui/src/sequence/sequence_viewer.hh
rename to modules/gui/src/sequence_viewer/base_view_object.hh
index 3940c68fa..90526bfa3 100644
--- a/modules/gui/src/sequence/sequence_viewer.hh
+++ b/modules/gui/src/sequence_viewer/base_view_object.hh
@@ -16,52 +16,58 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
-#ifndef OST_SEQUENCE_VIEWER_SEQUENCE_VIEWER
-#define OST_SEQUENCE_VIEWER_SEQUENCE_VIEWER
+#ifndef OST_SEQUENCE_VIEWER_BASE_VIEW_OBJECT
+#define OST_SEQUENCE_VIEWER_BASE_VIEW_OBJECT
 
 /*
   Author: Stefan Scheuber
  */
 
-#include <QWidget>
+#include <QObject>
+#include <QList>
 
-#include <ost/gfx/scene.hh>
-#include <ost/gfx/gfx_object.hh>
+#include "base_row.hh"
 
-#include <ost/gui/widget.hh>
-
-#include <ost/gui/module_config.hh>
-
-#include "sequence_model.hh"
-#include "sequence_table_view.hh"
 
 namespace ost { namespace gui {
 
-/// \brief QTableView with first column not moving
-class DLLEXPORT_OST_GUI SequenceViewerV2 : public Widget, public gfx::SceneObserver  {
+class BaseViewObject : public QObject
+{
   Q_OBJECT
+
+
 public:
-  SequenceViewerV2(QWidget* parent=NULL);
-  ~SequenceViewerV2();
+  BaseViewObject(QObject* parent = 0);
 
-  virtual void NodeAdded(const gfx::GfxNodeP& node);
-  virtual void NodeRemoved(const gfx::GfxNodeP& node);
-  virtual void SelectionChanged(const gfx::GfxObjP& o, const mol::EntityView& view);
+  void InsertRow(int pos, BaseRow* row);
+  void RemoveRow(BaseRow* row);
+  BaseRow* GetRow(int pos);
+  int GetRowCount();
+  int GetMaxColumnCount() const;
 
-  virtual bool Restore(const QString&){return true;};
-  virtual bool Save(const QString&){return true;};
+  virtual void SetSelection(int row, const QSet<int>& added, const QSet<int>& removed);
 
-private:
-  SequenceModel* model_;
-  SequenceTableView* seq_table_view_;
+  virtual QVariant GetData(int row, int column, int role);
+  virtual bool SetData(int row, int column, const QVariant& value, int role);
+  virtual Qt::ItemFlags Flags(int row, int column) const;
 
-private slots:
-  void SelectionModelChanged(const QItemSelection&, const QItemSelection&);
-  void DoubleClicked(const QModelIndex& index);
-  void MouseWheelEvent(QWheelEvent* event);
+  virtual const QStringList& GetDisplayModes();
+  virtual const QString& GetCurrentDisplayMode();
+  virtual void SetDisplayMode(const QString& mode);
 
+  void DoubleClicked(int row, int column);
+  void ZoomIn();
+  void ZoomOut();
+
+protected:
+  virtual void AddDisplayMode(const QString& mode);
+
+  QList<BaseRow*> rows_;
+  QString current_display_mode_;
+  QStringList display_modes_;
 };
 
+
 }}
 
 #endif
diff --git a/modules/gui/pymod/export_sequence_viewerV2.cc b/modules/gui/src/sequence_viewer/conservation_painter.cc
similarity index 67%
rename from modules/gui/pymod/export_sequence_viewerV2.cc
rename to modules/gui/src/sequence_viewer/conservation_painter.cc
index cd010952f..7bab56edc 100644
--- a/modules/gui/pymod/export_sequence_viewerV2.cc
+++ b/modules/gui/src/sequence_viewer/conservation_painter.cc
@@ -16,24 +16,30 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
-#include <boost/python.hpp>
 
-#include <ost/gui/sequence/sequence_viewer.hh>
+/*
+  Author: Stefan Scheuber
+ */
 
-#include "sip_handler.hh"
 
-using namespace boost::python;
-using namespace ost;
-using namespace ost::gui;
+#include <QtGui>
 
+#include "conservation_painter.hh"
 
-void export_SequenceViewerV2()
-{
-  class_<SequenceViewerV2, boost::noncopyable >("SequenceViewerV2",init<>())
-    .def("Show", &SequenceViewerV2::show)
-    .def("Hide", &SequenceViewerV2::hide)
-    .def("GetQObject",&get_py_qobject<SequenceViewerV2>)
-    .add_property("qobject", &get_py_qobject<SequenceViewerV2>)
-  ;
+namespace ost { namespace gui {
+
+
+ConservationPainter::ConservationPainter(QObject* parent)
+    : Painter(parent)
+{}
+
+void ConservationPainter::Paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index){
+  painter->save();
+  if (index.column()>0){
+    QColor cons = index.data(Qt::UserRole+3).value<QColor>();
+    painter->fillRect(option.rect, cons);
+  }
+  painter->restore();
 }
 
+}}
diff --git a/modules/gui/src/sequence_viewer/conservation_painter.hh b/modules/gui/src/sequence_viewer/conservation_painter.hh
new file mode 100644
index 000000000..c6549f661
--- /dev/null
+++ b/modules/gui/src/sequence_viewer/conservation_painter.hh
@@ -0,0 +1,44 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#ifndef OST_SEQUENCE_VIEWER_CONSERVATION_PAINTER
+#define OST_SEQUENCE_VIEWER_CONSERVATION_PAINTER
+
+/*
+  Author: Stefan Scheuber
+ */
+
+#include <QObject>
+
+#include "painter.hh"
+
+namespace ost { namespace gui {
+
+
+
+class ConservationPainter : public Painter
+{
+  Q_OBJECT
+public:
+  ConservationPainter(QObject* parent = 0);
+  void Paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index);
+};
+
+}}
+
+#endif
diff --git a/modules/gui/src/sequence/painter.hh b/modules/gui/src/sequence_viewer/painter.hh
similarity index 100%
rename from modules/gui/src/sequence/painter.hh
rename to modules/gui/src/sequence_viewer/painter.hh
diff --git a/modules/gui/src/sequence/secstr_row.cc b/modules/gui/src/sequence_viewer/secstr_row.cc
similarity index 98%
rename from modules/gui/src/sequence/secstr_row.cc
rename to modules/gui/src/sequence_viewer/secstr_row.cc
index e6017f357..180a47469 100644
--- a/modules/gui/src/sequence/secstr_row.cc
+++ b/modules/gui/src/sequence_viewer/secstr_row.cc
@@ -33,7 +33,7 @@
 
 namespace ost { namespace gui {
 
-SecStrRow::SecStrRow(const QString& name, mol::ChainView& chain, ViewObject* parent) : SequenceRow(name,parent)
+SecStrRow::SecStrRow(const QString& name, mol::ChainView& chain, SequenceViewObject* parent) : SequenceRow(name,parent)
 { this->SetChain(chain); }
 
 void SecStrRow::SetSequence(seq::SequenceHandle& sequence)
diff --git a/modules/gui/src/sequence/secstr_row.hh b/modules/gui/src/sequence_viewer/secstr_row.hh
similarity index 95%
rename from modules/gui/src/sequence/secstr_row.hh
rename to modules/gui/src/sequence_viewer/secstr_row.hh
index f52766032..4b6bd2762 100644
--- a/modules/gui/src/sequence/secstr_row.hh
+++ b/modules/gui/src/sequence_viewer/secstr_row.hh
@@ -38,7 +38,7 @@ class SecStrRow : public SequenceRow
   Q_OBJECT
 
 public:
-  SecStrRow(const QString& name, mol::ChainView& chain, ViewObject* parent);
+  SecStrRow(const QString& name, mol::ChainView& chain, SequenceViewObject* parent);
 
   virtual QVariant GetData(int column, int role) const;
   virtual void DoubleClicked(int column);
diff --git a/modules/gui/src/sequence/seq_secstr_painter.cc b/modules/gui/src/sequence_viewer/seq_secstr_painter.cc
similarity index 100%
rename from modules/gui/src/sequence/seq_secstr_painter.cc
rename to modules/gui/src/sequence_viewer/seq_secstr_painter.cc
diff --git a/modules/gui/src/sequence/seq_secstr_painter.hh b/modules/gui/src/sequence_viewer/seq_secstr_painter.hh
similarity index 100%
rename from modules/gui/src/sequence/seq_secstr_painter.hh
rename to modules/gui/src/sequence_viewer/seq_secstr_painter.hh
diff --git a/modules/gui/src/sequence/seq_selection_painter.cc b/modules/gui/src/sequence_viewer/seq_selection_painter.cc
similarity index 77%
rename from modules/gui/src/sequence/seq_selection_painter.cc
rename to modules/gui/src/sequence_viewer/seq_selection_painter.cc
index e9b0c4d5c..847317196 100644
--- a/modules/gui/src/sequence/seq_selection_painter.cc
+++ b/modules/gui/src/sequence_viewer/seq_selection_painter.cc
@@ -29,27 +29,25 @@
 namespace ost { namespace gui {
 
 SeqSelectionPainter::SeqSelectionPainter(QObject* parent)
-    : Painter(parent)
-{}
+    : Painter(parent), focus_color_(255,0,0,0), mouse_over_color_(240,240,240,192)
+{
+
+}
 
 void SeqSelectionPainter::Paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index){
   painter->save();
-  if ((index.column()-1)%10 > 4){
-    painter->fillRect(option.rect, QColor(240,240,240));
-
-  }
-  if((index.column())%10 == 0){
-    painter->setPen(QPen(QColor(135,135,135)));
-    painter->drawLine(option.rect.topRight(),option.rect.bottomRight());
-  }
+  /*
   if (option.state & QStyle::State_HasFocus){
-    painter->fillRect(option.rect, QColor(240,240,0,60));
+    painter->fillRect(option.rect, focus_color_);
   }
+  */
   if (option.state & QStyle::State_MouseOver){
-    painter->fillRect(option.rect, QColor(240,240,240,128));
+    painter->fillRect(option.rect, mouse_over_color_);
   }
   if (option.state & QStyle::State_Selected){
-    painter->fillRect(option.rect, QColor(0,240,0,128));
+    QColor color = option.palette.highlight().color();
+    color.setAlpha(128);
+    painter->fillRect(option.rect, color);
   }
   painter->restore();
 }
diff --git a/modules/gui/src/sequence/seq_selection_painter.hh b/modules/gui/src/sequence_viewer/seq_selection_painter.hh
similarity index 96%
rename from modules/gui/src/sequence/seq_selection_painter.hh
rename to modules/gui/src/sequence_viewer/seq_selection_painter.hh
index 416f423c0..a98d5afb6 100644
--- a/modules/gui/src/sequence/seq_selection_painter.hh
+++ b/modules/gui/src/sequence_viewer/seq_selection_painter.hh
@@ -36,6 +36,9 @@ public:
   SeqSelectionPainter(QObject* parent = 0);
   void Paint(QPainter *painter, const QStyleOptionViewItem &option,
       const QModelIndex &index);
+private:
+  QColor focus_color_;
+  QColor mouse_over_color_;
 };
 
 }}
diff --git a/modules/gui/src/sequence/seq_text_painter.cc b/modules/gui/src/sequence_viewer/seq_text_painter.cc
similarity index 96%
rename from modules/gui/src/sequence/seq_text_painter.cc
rename to modules/gui/src/sequence_viewer/seq_text_painter.cc
index 30c1e1623..50334bf39 100644
--- a/modules/gui/src/sequence/seq_text_painter.cc
+++ b/modules/gui/src/sequence_viewer/seq_text_painter.cc
@@ -34,7 +34,7 @@ SeqTextPainter::SeqTextPainter(QObject* parent)
 
 void SeqTextPainter::Paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index){
   painter->save();
-  painter->setPen(QPen(Qt::black));
+  painter->setPen(index.data(Qt::ForegroundRole).value<QColor>());
   QVariant value = index.data(Qt::DisplayRole);
   if (value.isValid()){
     QString text = value.toString();
diff --git a/modules/gui/src/sequence/seq_text_painter.hh b/modules/gui/src/sequence_viewer/seq_text_painter.hh
similarity index 100%
rename from modules/gui/src/sequence/seq_text_painter.hh
rename to modules/gui/src/sequence_viewer/seq_text_painter.hh
diff --git a/modules/gui/src/sequence/sequence_delegate.cc b/modules/gui/src/sequence_viewer/sequence_delegate.cc
similarity index 100%
rename from modules/gui/src/sequence/sequence_delegate.cc
rename to modules/gui/src/sequence_viewer/sequence_delegate.cc
diff --git a/modules/gui/src/sequence/sequence_delegate.hh b/modules/gui/src/sequence_viewer/sequence_delegate.hh
similarity index 100%
rename from modules/gui/src/sequence/sequence_delegate.hh
rename to modules/gui/src/sequence_viewer/sequence_delegate.hh
diff --git a/modules/gui/src/sequence_viewer/sequence_item.cc b/modules/gui/src/sequence_viewer/sequence_item.cc
deleted file mode 100644
index 6200f6c15..000000000
--- a/modules/gui/src/sequence_viewer/sequence_item.cc
+++ /dev/null
@@ -1,494 +0,0 @@
-//------------------------------------------------------------------------------
-// This file is part of the OpenStructure project <www.openstructure.org>
-//
-// Copyright (C) 2008-2010 by the OpenStructure authors
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License as published by the Free
-// Software Foundation; either version 3.0 of the License, or (at your option)
-// any later version.
-// This library is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
-// details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this library; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-//------------------------------------------------------------------------------
-/*
-  Author: Marco Biasini
- */
- 
-#include <ost/mol/mol.hh>
-#include <boost/bind.hpp>
-
-#include "sequence_item.hh"
-#include "sequence_scene.hh"
-
-#include <QPainter>
-#include <QGraphicsSceneMouseEvent>
-#include <QGraphicsSceneContextMenuEvent>
-#include <QGraphicsItem>
-#include <QDebug>
-
-namespace ost { namespace gui {
-
-using boost::bind;
-
-Knob::Knob(const QString& text, const QColor& color, 
-           SequenceItem* parent):
-  QGraphicsItem(parent)
-{
-  
-}
-  
-void Knob::paint(QPainter* painter, const QStyleOptionGraphicsItem*,
-                 QWidget* widget)
-{
-  painter->setBrush(QBrush(color_));
-  painter->setPen(QPen(color_.darker()));
-  painter->drawEllipse(this->boundingRect());
-  if (this->isUnderMouse()) {
-    painter->setPen(QPen(color_.darker()));
-  } else {
-    painter->setPen(QPen(Qt::white));
-  }
-  painter->drawText(this->boundingRect(), Qt::AlignCenter, text_);  
-}
-
-QRectF Knob::boundingRect() const
-{
-  return QRectF(0.0, 0.0, 15.0, 15.0);
-}
-
-
-SequenceHeader::SequenceHeader(SequenceItem* parent):
-  QGraphicsItem(parent)
-{
-  font_=QFont("Courier", 12);
-  font_.setKerning(false);
-  font_.setFixedPitch(true);
-}
-
-  
-void SequenceHeader::paint(QPainter* painter, const QStyleOptionGraphicsItem*,
-                           QWidget* widget)
-{
-  SequenceItem* si=dynamic_cast<SequenceItem*>(this->parentItem());
-  painter->setFont(font_);
-  QFontMetrics m(font_);
-  QString name(si->GetSequence().GetName().c_str());
-  QRectF br=this->boundingRect();
-  name=m.elidedText(name, Qt::ElideMiddle, br.width());
-  painter->drawText(br, Qt::AlignTop, name);
-}
-
-QRectF SequenceHeader::boundingRect() const
-{
-  QFontMetrics metrics(font_);
-  SequenceItem* si=dynamic_cast<SequenceItem*>(this->parentItem());
-  QString name(si->GetSequence().GetName().c_str());
-  QRectF rect(0, -2,name.size()*si->GetCharWidth()*1.1, 
-              si->GetCharHeight()+2);
-  SequenceScene* s=dynamic_cast<SequenceScene*>(this->scene());
-  rect.setWidth(std::min(qreal(s->GetHeaderWidth()), rect.width()));
-  return rect;
-}
-
-SequenceBody::SequenceBody(SequenceItem* parent):
-  QGraphicsItem(parent)
-{
-  
-}
-
-  
-void SequenceBody::paint(QPainter* painter, const QStyleOptionGraphicsItem*,
-                         QWidget* widget)
-{  
-  SequenceItem* si=dynamic_cast<SequenceItem*>(this->parentItem());
-  seq::SequenceHandle seq=si->GetSequence();
-  if (!seq.IsValid()) {
-    return;
-  }
-  QString qstr(seq.GetString().c_str());
-  QColor sel_color(Qt::yellow);  
-  if (si->IsSecStructureVisible()) {
-    sel_color.setAlpha(50);
-    painter->setBrush(QBrush(sel_color));
-    painter->setPen(QPen(QColor(Qt::yellow).darker()));  
-    painter->drawPath(si->GetSecStructPaths());    
-  }
-  painter->setFont(si->GetFont());
-  painter->setPen(QPen(Qt::black));  
-  QString tt("X");
-  QRectF br=this->boundingRect();
-  for (int i=0; i<qstr.size(); ++i) {
-    tt[0]=qstr[i];
-    QRectF rect(br.left()+i*si->GetCharWidth(), br.top(), 
-                br.width(), br.height());    
-    painter->drawText(rect, Qt::AlignLeft|Qt::AlignVCenter, tt);    
-  }
-
-  sel_color=QColor(Qt::green).lighter();
-  painter->setPen(QPen(Qt::green));  
-  sel_color.setAlpha(100);
-  painter->setBrush(QBrush(sel_color));
-  QRectF text_bounds=painter->boundingRect(boundingRect(), 
-                                           Qt::AlignLeft|Qt::AlignVCenter,
-                                           qstr);
-  const SequenceItem::Selection& sel=si->GetSelection();
-  for (size_t i=0; i<sel.size(); ++i) {
-    painter->drawRect(QRectF(sel[i].Loc*si->GetCharWidth(), 0, 
-                             sel[i].Length*si->GetCharWidth(),
-                             si->GetCharHeight()));
-  }
-}
-
-QRectF SequenceBody::boundingRect() const
-{
-  SequenceItem* si=dynamic_cast<SequenceItem*>(this->parentItem());
-  seq::SequenceHandle seq=si->GetSequence();
-  if (!seq.IsValid()) {
-    return QRectF();
-  }
-  return QRectF(0, -2, seq.GetLength()*si->GetCharWidth(), 
-                si->GetCharHeight()+2);  
-}
-
-
-SequenceItem::SequenceItem(const seq::SequenceHandle& seq, 
-                           QGraphicsItem* parent):
-  QGraphicsItem(parent), seq_(seq), show_sec_struct_(true)
-{
-  header_=new SequenceHeader(this);  
-  body_=new SequenceBody(this);
-  body_->translate(120.0, 0.0);
-  font_=QFont("Courier", 12);
-  font_.setKerning(false);
-  font_.setFixedPitch(true);
-  QFontMetrics metrics(font_);
-  advance_=metrics.boundingRect('W').width();
-  height_=metrics.boundingRect('|').height();
-  ascent_=metrics.ascent();
-  this->setAcceptedMouseButtons(Qt::LeftButton);
-  this->ExtractSecStructSegments();
-  selection_change_=false;
-}
-
-SequenceHeader* SequenceItem::GetHeader()
-{
-  return header_;
-}
-
-SequenceBody* SequenceItem::GetBody()
-{
-  return body_;
-}
-
-const seq::SequenceHandle& SequenceItem::GetSequence() const
-{
-  return seq_;
-}
-
-QRectF SequenceItem::GetCharBounds(int pos) const
-{
-  QPointF a(pos*advance_, 0);
-  return QRectF(this->mapToScene(a), QSizeF(advance_, height_));
-}
-
-float SequenceItem::GetCharWidth() const
-{
-  return advance_;
-}
-
-float SequenceItem::GetCharHeight() const
-{
-  return height_;
-}
-
-void SequenceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*,
-                         QWidget* widget)
-{
-}
-
-QRectF SequenceItem::boundingRect() const
-{
-  QRectF child_r(this->childrenBoundingRect());
-  if (show_sec_struct_) {
-    return QRectF(child_r.topLeft(), 
-                  QSize(child_r.width(), child_r.height()*2.5));    
-  } else {
-    return QRectF(child_r.topLeft(), 
-                  QSize(child_r.width(), child_r.height()));
-  }
-}
-
-void SequenceItem::ExtractSecStructSegments()
-{
-  if (!seq_.HasAttachedView()) {
-    return;
-  }
-  mol::ChainView chain=seq_.GetAttachedView().GetChainList()[0];
-  sec_=mol::alg::ExtractSecStructureSegments(chain);
-  this->SecStructSegmentsToPaths();
-}
-
-void SequenceHeader::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
-{
-  //...
-}
-void SequenceBody::mousePressEvent(QGraphicsSceneMouseEvent* event)
-{
-  SequenceItem* si=dynamic_cast<SequenceItem*>(this->parentItem());  
-  event->accept();
-  last_index_=-1;
-  good_ole_click_=true;
-  merge_select_=event->modifiers() & Qt::ShiftModifier;
-  si->BeginSelectionChange();
-}
-
-void SequenceBody::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
-{
-  SequenceItem* si=dynamic_cast<SequenceItem*>(this->parentItem());    
-  int index=std::max(0, int(event->pos().x()/si->GetCharWidth()));  
-  // find the secondary structure element -- if any that we are in
-  mol::alg::SecStructureSegments::iterator i=si->GetSecStructSegments().begin(),
-                                           e=si->GetSecStructSegments().end();  
-  for (;i!=e; ++i) {
-    if (i->first<=index && i->last>=index) {
-      si->Select(i->first, i->last+1, !merge_select_);
-      break;
-    }
-  }
-  good_ole_click_=false;
-}
-void SequenceHeader::mousePressEvent(QGraphicsSceneMouseEvent* event)
-{
-  event->accept();
-}
-
-void SequenceHeader::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
-{
-  SequenceItem* si=dynamic_cast<SequenceItem*>(this->parentItem());
-  if (si->IsEverythingSelected()) {
-    si->ClearSelection();
-  } else {
-    si->SelectAll();
-  }
-
-}
-
-void SequenceBody::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
-{
-  SequenceItem* si=dynamic_cast<SequenceItem*>(this->parentItem());    
-  if (good_ole_click_) {
-    int index=std::max(0, int(event->pos().x()/si->GetCharWidth()));
-    si->Select(index, index+1, !merge_select_);    
-  }
-  si->EndSelectionChange();
-}
-
-void SequenceBody::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
-{
-  SequenceItem* si=dynamic_cast<SequenceItem*>(this->parentItem());    
-  good_ole_click_=false;  
-  if (!si->GetSequence().IsValid()) {
-    return;
-  }
-  float x=event->pos().x();
-  int index=std::max(0, int(x/si->GetCharWidth()));
-  if (last_index_!=-1 && last_index_!=index) {
-    si->Select(last_index_, index, !merge_select_);
-  } else {
-    last_index_=index;
-  }
-}
-
-void SequenceItem::StackToPath(std::vector<QPointF>& stack)
-{
-  if (!stack.empty()) {
-    sec_paths_.moveTo(QPointF(stack.front().x(), stack.front().y()+.5*ascent_));
-    for (std::vector<QPointF>::iterator j=stack.begin()+1, 
-         e2=stack.end(); j!=e2; ++j) {
-      sec_paths_.lineTo(QPointF(j->x(), j->y()+0.5*ascent_));
-    }
-    for (std::vector<QPointF>::reverse_iterator j=stack.rbegin(), 
-         e2=stack.rend(); j!=e2; ++j) {
-      sec_paths_.lineTo(QPointF(j->x(), -j->y()+.5*ascent_));
-    }        
-    sec_paths_.closeSubpath();
-    stack.clear();
-  }  
-}
-
-void SequenceItem::SecStructSegmentsToPaths()
-{
-  sec_paths_=QPainterPath();
-  
-  sec_paths_.setFillRule(Qt::WindingFill);
-  std::vector<QPointF> stack;
-  int last_end=-2;
-  for (mol::alg::SecStructureSegments::iterator i=sec_.begin(), 
-       e=sec_.end(); i!=e; ++i) {
-    mol::alg::SecStructureSegment s=*i;
-    if (last_end!=s.first-1) {
-      this->StackToPath(stack);
-    }
-    if (s.ss_type.IsCoil()) {
-      stack.push_back(QPointF(s.first*advance_, -.6*height_));
-      stack.push_back(QPointF((s.last+1)*advance_,  -.6*height_));
-    } else if (s.ss_type.IsHelical()) {
-      stack.push_back(QPointF(s.first*advance_, -.6*height_));
-      stack.push_back(QPointF(s.first*advance_, -.9*height_));
-      stack.push_back(QPointF((s.last+1)*advance_, -.9*height_));
-      stack.push_back(QPointF((s.last+1)*advance_, -.6*height_));
-    } else if (s.ss_type.IsExtended()) {
-      stack.push_back(QPointF(s.first*advance_, -.6*height_));
-      stack.push_back(QPointF(s.first*advance_, -.9*height_));
-      stack.push_back(QPointF((s.last-0.5)*advance_, -.9*height_));
-      stack.push_back(QPointF((s.last-0.5)*advance_, -1.3*height_));
-      stack.push_back(QPointF((s.last+1)*advance_, -.6*height_));
-      
-    }
-    last_end=s.last;    
-  }
-  this->StackToPath(stack);  
-}
-
-void SequenceItem::Select(int i1, int i2, bool clear)
-{
-  if (selection_change_>0) {
-    selection_=ref_sel_;    
-  }
-  int a1=std::min(i1, i2);
-  int len=std::abs(i1-i2);
-  Range sel_start(a1, len);
-  Range* sel=&sel_start;
-  bool modified=false;
-  if (clear) {
-    selection_.clear();
-    selection_.push_back(*sel);    
-  } else {
-    for (size_t i=0; i<selection_.size(); ++i) {
-      if (sel->Loc>=selection_[i].Loc && sel->Loc<selection_[i].End()) {
-        int old_end=selection_[i].End();        
-        if (sel->End()<=selection_[i].End()) {
-          selection_[i].Length=int(sel->Loc-selection_[i].Loc);
-          if (old_end-sel->End()>0) {
-            selection_.push_back(Range(sel->End(), old_end-sel->End()));
-          }          
-        } else {
-          selection_[i].Length=int(sel->Loc-selection_[i].Loc);
-          if (sel->End()-old_end>0) {
-            selection_.push_back(Range(old_end, sel->End()-old_end));
-          }
-        }
-        modified=true;
-        break;
-      } else if (sel->End()>selection_[i].Loc && 
-                 sel->End()<=selection_[i].End()) {
-        int nn=selection_[i].Loc;
-        selection_[i].Length-=sel->End()-selection_[i].Loc;
-        selection_[i].Loc=sel->End();
-        modified=true;
-        selection_.push_back(Range(sel->Loc, nn-sel->Loc));
-        break;
-      } else if (sel->Loc<selection_[i].Loc && 
-                 sel->End()>selection_[i].End()) {
-        selection_[i].Length=0;
-      } else if (sel->Loc==selection_[i].End()) {
-        selection_[i].Length+=sel->Length;
-        sel->Length=0;       
-        sel=&selection_[i];
-        modified=true;
-      } else if (sel->End()==selection_[i].Loc) {    
-        selection_[i].Loc-=sel->Length;  
-        selection_[i].Length+=sel->Length;
-        sel->Length=0;
-        sel=&selection_[i];        
-        modified=true;
-      }
-    }
-    if (!modified) {
-      selection_.push_back(Range(a1, len));      
-    }
-  }
-  Selection::iterator i=std::remove_if(selection_.begin(), selection_.end(),
-                                       bind(&Range::Length, _1)==size_t(0));
-  selection_.erase(i, selection_.end());
-  if (!selection_change_) {
-    emit this->SelectionChanged(this);
-  } else {
-    selection_change_=2;
-  }
-  update();
-}
-
-void SequenceItem::ClearSelection()
-{
-  selection_.clear();
-  if (selection_change_>0) {
-    selection_change_=2;
-  } else {
-    emit this->SelectionChanged(this);
-    update();    
-  }
-}
-
-void SequenceItem::SelectAll()
-{
-  if (!seq_.IsValid()) {
-    return;
-  }
-  selection_.clear();
-  selection_.push_back(Range(0, seq_.GetLength()));  
-  if (selection_change_>0) {
-    selection_change_=1;
-  } else {
-    emit this->SelectionChanged(this);  
-    update();
-  }
-}
-
-void SequenceItem::BeginSelectionChange()
-{
-  selection_change_=1;
-  ref_sel_=selection_;
-}
-
-void SequenceItem::EndSelectionChange()
-{
-  if (selection_change_==2) {
-    emit this->SelectionChanged(this);    
-  }
-  selection_change_=0;  
-}
-
-bool SequenceItem::IsEverythingSelected() const
-{
-  return selection_.size()==1 && selection_.front().Loc==0 && 
-         selection_.front().End()>=static_cast<size_t>(seq_.GetLength());
-}
-
-const SequenceItem::Selection& SequenceItem::GetSelection() const
-{
-  return selection_;
-}
-
-mol::alg::SecStructureSegments& SequenceItem::GetSecStructSegments()
-{
-  return sec_;
-}
-
-void SequenceItem::SetShowSecStructure(bool show)
-{
-  show_sec_struct_=show;
-}
-
-bool SequenceItem::IsSecStructureVisible() const
-{
-  return show_sec_struct_;
-}
-
-}}
diff --git a/modules/gui/src/sequence_viewer/sequence_item.hh b/modules/gui/src/sequence_viewer/sequence_item.hh
deleted file mode 100644
index aeaa63d1a..000000000
--- a/modules/gui/src/sequence_viewer/sequence_item.hh
+++ /dev/null
@@ -1,153 +0,0 @@
-//------------------------------------------------------------------------------
-// This file is part of the OpenStructure project <www.openstructure.org>
-//
-// Copyright (C) 2008-2010 by the OpenStructure authors
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License as published by the Free
-// Software Foundation; either version 3.0 of the License, or (at your option)
-// any later version.
-// This library is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
-// details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this library; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-//------------------------------------------------------------------------------
-#ifndef OST_GUI_SEQUENCE_ITEM_HH
-#define OST_GUI_SEQUENCE_ITEM_HH
-
-#include <ost/gui/module_config.hh>
-#include <ost/mol/sec_structure.hh>
-#include <ost/mol/alg/sec_structure_segments.hh>
-
-#include <ost/seq/sequence_handle.hh>
-
-#include <QGraphicsItem>
-#include <QFont>
-
-namespace ost { namespace gui {
-
-class SequenceItem;
-class SequenceHeader;
-
-class DLLEXPORT_OST_GUI Knob : public QGraphicsItem {
-public:
-  Knob(const QString& text, const QColor& color, 
-       SequenceItem* parent=NULL);
-  
-  virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* opts,
-                     QWidget* widget=NULL);  
-  virtual QRectF boundingRect() const;
-private:
-  QString text_;
-  QColor  color_;
-};
-
-class DLLEXPORT_OST_GUI SequenceHeader : public QGraphicsItem {
-public:
-  SequenceHeader(SequenceItem* parent=NULL);
-  
-  virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* opts,
-                     QWidget* widget=NULL);
-  virtual QRectF boundingRect() const;                     
-protected:
-  virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
-  virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);  
-  virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent* event);
-private:
-  QFont font_;
-};
-
-class DLLEXPORT_OST_GUI SequenceBody : public QGraphicsItem {
-public:
-  SequenceBody(SequenceItem* parent=NULL);
-  
-  virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* opts,
-                     QWidget* widget=NULL);
-  virtual QRectF boundingRect() const;         
-protected:
-  virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
-  virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);  
-  virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
-
-  virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event);    
-private:
-  QFont    font_;
-  bool     merge_select_;
-  bool     good_ole_click_;
-  int      last_index_;  
-};
-
-
-class DLLEXPORT_OST_GUI SequenceItem : public QObject, // required for signals 
-                                       public QGraphicsItem {
-  Q_OBJECT
-public:
-  typedef std::vector<Range> Selection;  
-  
-  SequenceItem(const seq::SequenceHandle& seq, QGraphicsItem* parent=NULL);
-  
-  /// \brief get sequence
-  const seq::SequenceHandle& GetSequence() const;
-  
-  virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* opts,
-                     QWidget* widget=NULL);
-  virtual QRectF boundingRect() const;                     
-  
-  QRectF GetCharBounds(int pos) const;
-  
-  float GetCharWidth() const;  
-  float GetCharHeight() const;
-  
-  SequenceBody* GetBody();
-  SequenceHeader* GetHeader();
-  QPainterPath& GetSecStructPaths() { return sec_paths_; }
-  QFont GetFont() { return font_; }
-  
-  const Selection& GetSelection() const;
-  void Select(int i1, int i2, bool clear=true);
-    
-  void BeginSelectionChange();
-  void EndSelectionChange();  
-  
-  bool IsEverythingSelected() const;
-  void ClearSelection();
-  void SelectAll();
-  void SetShowSecStructure(bool show=true);
-  bool IsSecStructureVisible() const;
-  
-  mol::alg::SecStructureSegments& GetSecStructSegments();
-signals:
-
-  /// \brief emitted whenever the selection changes
-  /// 
-  /// When using BeginSelectionChange(), no signal is emitted until 
-  /// EndSelectionChange() is called.
-  void SelectionChanged(SequenceItem* item);
-private:
-  void ExtractSecStructSegments();
-  void SecStructSegmentsToPaths();
-  void StackToPath(std::vector<QPointF>& stack);
-  
-  QPainterPath                     sec_paths_;
-  mol::alg::SecStructureSegments   sec_;  
-  SequenceHeader*                  header_;
-  SequenceBody*                    body_;
-  seq::SequenceHandle              seq_;
-  QFont                            font_;
-  Selection                        selection_;
-  Selection                        ref_sel_;
-  float                            advance_;
-  float                            height_; 
-  float                            ascent_;
-  int                              selection_change_;
-  bool                             show_sec_struct_;
-};
-
-typedef std::vector<SequenceItem*> SequenceItemList;
-}}
-
-#endif
diff --git a/modules/gui/src/sequence_viewer/sequence_model.cc b/modules/gui/src/sequence_viewer/sequence_model.cc
new file mode 100644
index 000000000..923a24c0f
--- /dev/null
+++ b/modules/gui/src/sequence_viewer/sequence_model.cc
@@ -0,0 +1,466 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+/*
+  Author: Stefan Scheuber
+ */
+
+#include <QMap>
+#include <QMapIterator>
+
+#include <QtGui>
+
+#include "title_row.hh"
+
+#include "background_painter.hh"
+#include "tick_painter.hh"
+
+#include "sequence_model.hh"
+
+namespace ost { namespace gui {
+
+SequenceModel::SequenceModel(QObject *parent)
+    : QAbstractTableModel(parent), max_columns(0)
+{
+  this->beginInsertRows(QModelIndex(),this->rowCount(),this->rowCount());
+  BaseViewObject* title = new BaseViewObject(this);
+  TitleRow* title_row = new TitleRow(title);
+  Painter* p = new BackgroundPainter(title_row);
+  title_row->InsertPainter(p);
+  p = new TickPainter(title_row);
+  title_row->InsertPainter(p);
+  title->InsertRow(0,title_row);
+  objects_.append(title);
+  this->endInsertRows();
+}
+
+void SequenceModel::InsertSequence(QString& name, seq::SequenceHandle& seq){
+  int cols = this->columnCount();
+  int new_cols = seq.GetLength();
+  this->beginInsertRows(QModelIndex(),this->rowCount(),this->rowCount());
+  objects_.append(new SequenceViewObject(seq, name, this));
+  if(new_cols > cols){
+    this->max_columns = new_cols;
+    this->beginInsertColumns(QModelIndex(), cols, new_cols);
+    this->endInsertColumns();
+  }
+  this->endInsertRows();
+}
+
+void SequenceModel::InsertChain(QString& name, mol::ChainView& view){
+  int cols = this->columnCount();
+  int new_cols = view.GetResidueCount();
+  this->beginInsertRows(QModelIndex(),this->rowCount(),this->rowCount());
+  objects_.append(new SequenceViewObject(view, name, this));
+  if(new_cols > cols){
+    this->max_columns = new_cols;
+    this->beginInsertColumns(QModelIndex(), cols, new_cols);
+    this->endInsertColumns();
+  }
+  this->endInsertRows();
+}
+
+void SequenceModel::InsertAlignment(const seq::AlignmentHandle& alignment){
+  int cols = this->columnCount();
+  int new_cols = alignment.GetLength();
+  this->beginInsertRows(QModelIndex(),this->rowCount(),this->rowCount()+alignment.GetCount()-1);
+  objects_.append(new AlignmentViewObject(alignment, this));
+  if(new_cols > cols){
+    this->max_columns = new_cols;
+    this->beginInsertColumns(QModelIndex(), cols, new_cols);
+    this->endInsertColumns();
+  }
+  this->endInsertRows();
+}
+
+void SequenceModel::InsertSequences(const QList<QString>& names, seq::SequenceList& list){
+  this->beginInsertRows(this->index(this->rowCount(),0),this->rowCount(),this->rowCount()+list.GetCount());
+  objects_.append(new SequenceViewObject(list, names, this));
+  this->endInsertRows();
+}
+
+void SequenceModel::InsertGfxEntity(gfx::EntityP& ent){
+  mol::EntityView view=ent->GetView();
+  int size = view.GetChainList().size();
+  int cols = this->columnCount();
+  this->beginInsertRows(QModelIndex(),this->rowCount(),this->rowCount()+size);
+  SequenceViewObject* obj = new SequenceViewObject(ent, this);
+  objects_.append(obj);
+  int new_cols = obj->GetMaxColumnCount();
+  if(new_cols > cols){
+    this->max_columns = new_cols;
+    this->beginInsertColumns(QModelIndex(), cols, new_cols);
+    this->endInsertColumns();
+  }
+  this->endInsertRows();
+}
+
+void SequenceModel::RemoveGfxEntity(gfx::EntityP& entity){
+  if(SequenceViewObject* obj = this->GetItem(entity)){
+    int index = this->GetGlobalRow(obj,0);
+    this->beginRemoveRows(QModelIndex(),index,index+obj->GetRowCount()-1);
+    int cols_before = this->columnCount();
+    objects_.removeOne(obj);
+    this->endRemoveRows();
+    int cols = this->GetColumnCount();
+    if(cols_before>cols){
+      this->max_columns = cols;
+      this->beginRemoveColumns(QModelIndex(), cols, cols_before);
+      this->endRemoveColumns();
+    }
+  }
+}
+
+void SequenceModel::RemoveAlignment(const seq::AlignmentHandle& alignment){
+  if(AlignmentViewObject* obj = this->GetItem(alignment)){
+    int index = this->GetGlobalRow(obj,0);
+    this->beginRemoveRows(QModelIndex(),index,index+obj->GetRowCount()-1);
+    int cols_before = this->columnCount();
+    objects_.removeOne(obj);
+    this->endRemoveRows();
+    int cols = this->GetColumnCount();
+    if(cols_before>cols){
+      this->max_columns = cols;
+      this->beginRemoveColumns(QModelIndex(), cols, cols_before);
+      this->endRemoveColumns();
+    }
+  }
+}
+
+int SequenceModel::GetColumnCount() const{
+  int cols = 0;
+  for(int i = 0; i<objects_.size();i++){
+    int ob_cols = objects_[i]->GetMaxColumnCount();
+    if(ob_cols>cols){
+      cols = ob_cols;
+    }
+  }
+  return cols;
+}
+
+SequenceViewObject* SequenceModel::GetItem(const gfx::EntityP& entity){
+  if(entity != NULL){
+    for (int i = 0 ; i< objects_.size(); i++){
+      if(SequenceViewObject* seq_view_object = qobject_cast<SequenceViewObject*>(objects_[i])){
+        if(entity == seq_view_object->GetGfxObject()){
+          return seq_view_object;
+        }
+      }
+    }
+  }
+  return NULL;
+}
+
+AlignmentViewObject* SequenceModel::GetItem(const seq::AlignmentHandle& alignment){
+  for (int i = 0 ; i< objects_.size(); i++){
+    if(AlignmentViewObject* alignment_object = qobject_cast<AlignmentViewObject*>(objects_[i])){
+      if(alignment == alignment_object->GetAlignment()){
+        return alignment_object;
+      }
+    }
+  }
+  return NULL;
+}
+
+const PainterList& SequenceModel::GetPainters(const QModelIndex& index) const{
+  QPair<int, BaseViewObject*> pair = this->GetRowWithItem(index);
+  if(pair.second){
+    return pair.second->GetRow(pair.first)->GetPainters();
+  }
+  return empty_painter_list_;
+}
+
+QPair<int, BaseViewObject*> SequenceModel::GetRowWithItem(int row) const{
+  if(!objects_.isEmpty()){
+    int rows = 0;
+    int i = -1;
+    int last_row = 0;
+    while (rows <= row && i < objects_.size()){
+      i++;
+      last_row =objects_[i]->GetRowCount();
+      rows += last_row;
+    }
+    int sub_index = row - (rows-last_row);
+    return QPair<int, BaseViewObject*>(sub_index, objects_[i]);
+  }
+  return QPair<int, BaseViewObject*>(-1, NULL);
+}
+
+QPair<int, BaseViewObject*> SequenceModel::GetRowWithItem(const QModelIndex& index) const{
+  return this->GetRowWithItem(index.row());
+}
+
+BaseViewObject* SequenceModel::GetItem(const QModelIndex& index) const
+{
+  return this->GetRowWithItem(index).second;
+}
+
+int SequenceModel::GetGlobalRow(BaseViewObject* obj, int row) const
+{
+  int glob_row = -1;
+  int index = objects_.indexOf(obj);
+  if(index >= 0){
+    glob_row = 0;
+    for(int i=0; i<index; i++){
+      glob_row += objects_[i]->GetRowCount();
+    }
+    return glob_row + row;
+  }
+  return glob_row;
+}
+
+QModelIndexList SequenceModel::GetModelIndexes(gfx::EntityP& entity, const mol::EntityView& view)
+{
+  QModelIndexList list;
+  if(BaseViewObject* object = this->GetItem(entity)){
+    if(SequenceViewObject* seq_view_object = qobject_cast<SequenceViewObject*>(object)){
+      QMap<int, QList<int> > indexes = seq_view_object->GetIndexesForView(view);
+      QMapIterator< int, QList<int> > i(indexes);
+      while (i.hasNext()) {
+        i.next();
+        int row = this->GetGlobalRow(seq_view_object, i.key());
+        const QList<int>& index_list = i.value();
+        for(int i=0; i<index_list.size(); i++){
+          list.append(this->index(row,index_list[i]));
+        }
+      }
+    }
+  }
+  return list;
+}
+
+QModelIndexList SequenceModel::GetModelIndexes(const QString& subject, const QString& sequence_name)
+{
+  QModelIndexList list;
+  for (int i = 0; i<objects_.size(); i++){
+    if(SequenceViewObject* seq_view_object = qobject_cast<SequenceViewObject*>(objects_[i])){
+      QMap<int, QList<int> > indexes = seq_view_object->GetIndexesForSubject(subject,sequence_name);
+      QMapIterator< int, QList<int> > iter(indexes);
+      while (iter.hasNext()) {
+        iter.next();
+        int row = this->GetGlobalRow(seq_view_object, iter.key());
+        const QList<int>& index_list = iter.value();
+        for(int j=0; j<index_list.size(); j++){
+          list.append(this->index(row,index_list[j]));
+        }
+      }
+    }
+  }
+  return list;
+}
+
+void SequenceModel::SelectionChanged(const QItemSelection& sel, const QItemSelection& desel)
+{
+  QMap<int,QPair<QSet<int>,QSet<int> > > sel_map;
+  const QModelIndexList& sel_indexes = sel.indexes();
+  for(int i =0; i< sel_indexes.size(); i++){
+     sel_map[sel_indexes[i].row()].first.insert(sel_indexes[i].column());
+  }
+
+  const QModelIndexList& desel_indexes = desel.indexes();
+  for(int i =0; i< desel_indexes.size(); i++){
+     sel_map[desel_indexes[i].row()].second.insert(desel_indexes[i].column());
+  }
+
+  QMapIterator< int,QPair<QSet<int>,QSet<int> > > i(sel_map);
+  while (i.hasNext()) {
+    i.next();
+    QPair<int, BaseViewObject*> item = this->GetRowWithItem(i.key());
+    item.second->SetSelection(item.first,i.value().first, i.value().second);
+  }
+}
+
+void SequenceModel::DoubleClicked(const QModelIndex& index)
+{
+  QPair<int, BaseViewObject*> item = this->GetRowWithItem(index);
+  if(item.second){
+    item.second->DoubleClicked(item.first,index.column());
+  }
+}
+
+const QStringList& SequenceModel::GetDisplayModes()
+{
+  display_modes_.clear();
+  QMap<QString,int> string_map;
+  for (int i = 0; i<objects_.size(); i++){
+    const QStringList& list = objects_[i]->GetDisplayModes();
+    for(int j=0; j<list.size(); j++){
+      if(!string_map.contains(list.at(j))){
+        string_map.insert(list.at(j),1);
+      }
+      else {
+        string_map[list.at(j)] = string_map[list.at(j)] + 1;
+      }
+    }
+  }
+  bool removed = false;
+  QMapIterator<QString, int> i(string_map);
+  while (i.hasNext()) {
+    i.next();
+    if(objects_.size()-1 <= i.value()){
+      display_modes_.append(i.key());
+    }
+    else{
+      removed = true;
+    }
+  }
+  if(removed){
+    display_modes_.insert(0," ");
+  }
+  return display_modes_;
+}
+
+const QStringList& SequenceModel::GetDisplayModes(const gfx::EntityP& entity)
+{
+  BaseViewObject* item = this->GetItem(entity);
+  if(item){
+    return item->GetDisplayModes();
+  }
+  else{
+    return empty_string_list_;
+  }
+}
+
+const QStringList& SequenceModel::GetDisplayModes(const seq::AlignmentHandle& alignment)
+{
+  BaseViewObject* item = this->GetItem(alignment);
+  if(item){
+    return item->GetDisplayModes();
+  }
+  else{
+    return empty_string_list_;
+  }
+}
+
+const QString& SequenceModel::GetCurrentDisplayMode()
+{
+  current_display_mode_.clear();
+  for (int i = 0; i<objects_.size(); i++){
+    const QString& mode = objects_[i]->GetCurrentDisplayMode();
+    if(current_display_mode_.isEmpty()){
+      current_display_mode_ = mode;
+    }
+    else if(current_display_mode_ != mode){
+      current_display_mode_ = " ";
+      break;
+    }
+  }
+  return current_display_mode_;
+}
+
+const QString& SequenceModel::GetCurrentDisplayMode(const gfx::EntityP& entity)
+{
+  BaseViewObject* item = this->GetItem(entity);
+  if(item){
+    return item->GetCurrentDisplayMode();
+  }
+  else{
+    return empty_string_;
+  }
+}
+
+const QString& SequenceModel::GetCurrentDisplayMode(const seq::AlignmentHandle& alignment)
+{
+  BaseViewObject* item = this->GetItem(alignment);
+  if(item){
+    return item->GetCurrentDisplayMode();
+  }
+  else{
+    return empty_string_;
+  }
+}
+
+void SequenceModel::SetDisplayMode(const QString& mode)
+{
+  for (int i = 0; i<objects_.size(); i++){
+    objects_[i]->SetDisplayMode(mode);
+  }
+}
+
+void SequenceModel::SetDisplayMode(const gfx::EntityP& entity, const QString& mode)
+{
+  BaseViewObject* item = this->GetItem(entity);
+  if(item){
+    return item->SetDisplayMode(mode);
+  }
+}
+
+void SequenceModel::SetDisplayMode(const seq::AlignmentHandle& alignment, const QString& mode)
+{
+  BaseViewObject* item = this->GetItem(alignment);
+  if(item){
+    return item->SetDisplayMode(mode);
+  }
+}
+
+int SequenceModel::rowCount(const QModelIndex& parent) const
+{
+  int rows = 0;
+  for (int i = 0; i<objects_.size(); i++){
+    rows += objects_[i]->GetRowCount();
+  }
+  return rows;
+}
+
+int SequenceModel::columnCount(const QModelIndex& parent) const
+{
+  return max_columns;
+}
+
+QVariant SequenceModel::data(const QModelIndex& index, int role) const
+{
+  QPair<int, BaseViewObject*> item = this->GetRowWithItem(index);
+  if(!item.second) return QVariant();
+  QVariant data = item.second->GetData(item.first,index.column(),role);
+  return data;
+}
+
+QVariant SequenceModel::headerData(int section, Qt::Orientation orientation,
+                                    int role) const
+{
+  if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
+    return QVariant("");
+  }
+  return QVariant();
+}
+
+Qt::ItemFlags SequenceModel::flags(const QModelIndex& index) const
+{
+  QPair<int, BaseViewObject*> item = GetRowWithItem(index);
+  if(item.second){
+    return item.second->Flags(item.first, index.column());
+  }
+  return QAbstractItemModel::flags(index);
+}
+
+void SequenceModel::ZoomIn()
+{
+  for (int i = 0; i<objects_.size(); i++){
+    objects_[i]->ZoomIn();
+  }
+}
+
+void SequenceModel::ZoomOut()
+{
+  for (int i = 0; i<objects_.size(); i++){
+    objects_[i]->ZoomOut();
+  }
+}
+
+}}
diff --git a/modules/gui/src/sequence/sequence_model.hh b/modules/gui/src/sequence_viewer/sequence_model.hh
similarity index 61%
rename from modules/gui/src/sequence/sequence_model.hh
rename to modules/gui/src/sequence_viewer/sequence_model.hh
index 50618db9c..d0afbbc4d 100644
--- a/modules/gui/src/sequence/sequence_model.hh
+++ b/modules/gui/src/sequence_viewer/sequence_model.hh
@@ -29,9 +29,13 @@
 #include <ost/mol/chain_view.hh>
 
 #include <ost/seq/sequence_list.hh>
+#include <ost/seq/alignment_handle.hh>
 
-#include "sequence_model.hh"
-#include "view_object.hh"
+#include <ost/gfx/entity.hh>
+
+#include "base_view_object.hh"
+#include "alignment_view_object.hh"
+#include "sequence_view_object.hh"
 
 namespace ost { namespace gui {
 
@@ -42,16 +46,30 @@ class SequenceModel : public QAbstractTableModel
 public:
   SequenceModel(QObject *parent = 0);
 
+  void InsertAlignment(const seq::AlignmentHandle& alignment);
   void InsertGfxEntity(gfx::EntityP& entity);
   void InsertChain(QString& name, mol::ChainView& view);
   void InsertSequence(QString& name, seq::SequenceHandle& seq);
   void InsertSequences(const QList<QString>& names, seq::SequenceList& list);
 
+  void RemoveAlignment(const seq::AlignmentHandle& alignment);
   void RemoveGfxEntity(gfx::EntityP& entity);
 
   QModelIndexList GetModelIndexes(gfx::EntityP& entity, const mol::EntityView& view);
-  int GetGlobalRow(ViewObject* obj, int row) const;
+  QModelIndexList GetModelIndexes(const QString& subject, const QString& sequence_name=QString());
+
+  int GetGlobalRow(BaseViewObject* obj, int row) const;
+
 
+  const QStringList& GetDisplayModes();
+  const QStringList& GetDisplayModes(const gfx::EntityP& entity);
+  const QStringList& GetDisplayModes(const seq::AlignmentHandle& alignment);
+  const QString& GetCurrentDisplayMode();
+  const QString& GetCurrentDisplayMode(const gfx::EntityP& entity);
+  const QString& GetCurrentDisplayMode(const seq::AlignmentHandle& alignment);
+  void SetDisplayMode(const QString& mode);
+  void SetDisplayMode(const gfx::EntityP& entity, const QString& mode);
+  void SetDisplayMode(const seq::AlignmentHandle& alignment, const QString& mode);
 
   const PainterList& GetPainters(const QModelIndex& index) const;
 
@@ -72,15 +90,21 @@ public slots:
   void ZoomOut();
   void DoubleClicked(const QModelIndex& index);
   void SelectionChanged(const QItemSelection& sel, const QItemSelection& desel);
-
 private:
-  ViewObject* GetItem(gfx::EntityP& entity);
-  ViewObject* GetItem(const QModelIndex& index) const;
-  QPair<int, ViewObject*> GetRowWithItem(int row) const;
-  QPair<int, ViewObject*> GetRowWithItem(const QModelIndex& index) const;
-
-  QList<ViewObject*> objects_;
+  int GetColumnCount() const;
+  SequenceViewObject* GetItem(const gfx::EntityP& entity);
+  AlignmentViewObject* GetItem(const seq::AlignmentHandle& alignment);
+  BaseViewObject* GetItem(const QModelIndex& index) const;
+  QPair<int, BaseViewObject*> GetRowWithItem(int row) const;
+  QPair<int, BaseViewObject*> GetRowWithItem(const QModelIndex& index) const;
+
+  QList<BaseViewObject*> objects_;
   int max_columns;
+  PainterList empty_painter_list_;
+  QString empty_string_;
+  QStringList empty_string_list_;
+  QStringList display_modes_;
+  QString current_display_mode_;
 };
 
 
diff --git a/modules/gui/src/sequence/sequence_row.cc b/modules/gui/src/sequence_viewer/sequence_row.cc
similarity index 82%
rename from modules/gui/src/sequence/sequence_row.cc
rename to modules/gui/src/sequence_viewer/sequence_row.cc
index b9f758053..f614799f1 100644
--- a/modules/gui/src/sequence/sequence_row.cc
+++ b/modules/gui/src/sequence_viewer/sequence_row.cc
@@ -29,16 +29,22 @@
 
 #include <ost/gfx/entity.hh>
 
-#include "view_object.hh"
+#include "sequence_view_object.hh"
 #include "sequence_row.hh"
 
 namespace ost { namespace gui {
 
-SequenceRow::SequenceRow(const QString& name, seq::SequenceHandle& sequence, ViewObject* parent) : BaseRow(QFont("Courier",11),parent), name_(name), name_font_(QFont("Courier",11)), sequence_(sequence)
-{ }
+SequenceRow::SequenceRow(const QString& name, seq::SequenceHandle& sequence, SequenceViewObject* parent) : BaseRow(QFont("Courier",11),parent), name_(name), name_font_(QFont("Courier",11)), sequence_(sequence)
+{
+  name_font_.setBold(true);
+  name_font_.setItalic(true);
+}
 
-SequenceRow::SequenceRow(const QString& name, ViewObject* parent) : BaseRow(QFont("Courier",11),parent), name_(name)
-{ }
+SequenceRow::SequenceRow(const QString& name, SequenceViewObject* parent) : BaseRow(QFont("Courier",11),parent), name_(name), name_font_(QFont("Courier",11))
+{
+  name_font_.setBold(true);
+  name_font_.setItalic(true);
+}
 
 int SequenceRow::GetColumnCount() const
 {
@@ -69,12 +75,22 @@ QVariant SequenceRow::GetData(int column, int role) const
 {
   if(column<0 || column > sequence_.GetLength())return QVariant();
 
+  if (role == Qt::ForegroundRole){
+    return QColor(Qt::black);
+  }
+
   if(column == 0) {
     if (role == Qt::DisplayRole){
       return QVariant(this->name_);
     }
     if (role == Qt::FontRole){
-      return QVariant(name_font_);
+      return QVariant(this->name_font_);
+    }
+    if (role == Qt::TextAlignmentRole){
+      return QVariant(Qt::AlignLeft|Qt::AlignVCenter);
+    }
+    if (role==Qt::ToolTipRole){
+      return QVariant(this->name_);
     }
   }
   else if(column > 0) {
@@ -96,7 +112,7 @@ QVariant SequenceRow::GetData(int column, int role) const
 
 Qt::ItemFlags SequenceRow::Flags(int column) const
 {
-  if(column<0 || column > this->GetColumnCount())return Qt::NoItemFlags;
+  if(column<0 || column >= this->GetColumnCount())return Qt::NoItemFlags;
 
   if(column==0){
     return Qt::ItemIsSelectable|Qt::ItemIsEnabled;
@@ -119,7 +135,7 @@ void SequenceRow::DoubleClicked(int column)
 
 void SequenceRow::SetSelection(const QSet<int>& added, const QSet<int>& removed)
 {
-  ViewObject* view_object = qobject_cast<ViewObject*>(this->parent());
+  SequenceViewObject* view_object = qobject_cast<SequenceViewObject*>(this->parent());
   if(view_object){
     if(gfx::EntityP entity = view_object->GetGfxObject()){
       mol::EntityView sel = entity->GetSelection();
diff --git a/modules/gui/src/sequence/sequence_row.hh b/modules/gui/src/sequence_viewer/sequence_row.hh
similarity index 90%
rename from modules/gui/src/sequence/sequence_row.hh
rename to modules/gui/src/sequence_viewer/sequence_row.hh
index 58c0a2dad..51979f330 100644
--- a/modules/gui/src/sequence/sequence_row.hh
+++ b/modules/gui/src/sequence_viewer/sequence_row.hh
@@ -31,15 +31,15 @@
 
 namespace ost { namespace gui {
 
-class ViewObject;
+class SequenceViewObject;
 
 class SequenceRow : public BaseRow
 {
   Q_OBJECT
 
 public:
-  SequenceRow(const QString& name, seq::SequenceHandle& sequence, ViewObject* parent);
-  SequenceRow(const QString& name, ViewObject* parent);
+  SequenceRow(const QString& name, seq::SequenceHandle& sequence, SequenceViewObject* parent);
+  SequenceRow(const QString& name, SequenceViewObject* parent);
 
   virtual int GetColumnCount() const;
 
@@ -53,7 +53,7 @@ public:
   virtual void SetSequence(seq::SequenceHandle& sequence);
   const seq::SequenceHandle& GetSequence() const;
 
-  void SetSelection(const QSet<int>& added, const QSet<int>& removed);
+  virtual void SetSelection(const QSet<int>& added, const QSet<int>& removed);
 
 private:
   QString name_;
diff --git a/modules/gui/src/sequence_viewer/sequence_scene.cc b/modules/gui/src/sequence_viewer/sequence_scene.cc
deleted file mode 100644
index 4b77a71e3..000000000
--- a/modules/gui/src/sequence_viewer/sequence_scene.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-//------------------------------------------------------------------------------
-// This file is part of the OpenStructure project <www.openstructure.org>
-//
-// Copyright (C) 2008-2010 by the OpenStructure authors
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License as published by the Free
-// Software Foundation; either version 3.0 of the License, or (at your option)
-// any later version.
-// This library is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
-// details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this library; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-//------------------------------------------------------------------------------
-#include "sequence_scene.hh"
-#include <boost/bind.hpp>
-#include <QPainter>
-
-namespace ost { namespace gui {
-
-using boost::bind;
-
-void SequenceScene::drawBackground(QPainter* painter, const QRectF& rect)
-{
-  if (sequences_.empty()) {
-    return;
-  }
-  QBrush stripe_brushes[]={
-    QBrush(QColor(Qt::white)),
-    QBrush(QColor(245, 245, 245))
-  };
-  float width=sequences_[0]->GetCharWidth()*5;
-  QRectF stripe(QPointF(((int(rect.left()/width)-1)-1)*width+header_width_,
-                        rect.top()), 
-                QSizeF(width, rect.height()));
-  int n=round(rect.width()/width)+2;
-  int start=std::max(0, int(floor(rect.left()/width)))-1;  
-  for (int i=0; i<n; ++i, stripe.translate(width, 0.0)) {
-    painter->fillRect(stripe, stripe_brushes[(i+start+2) % 2]);
-  }
-  painter->setPen(QPen(Qt::gray));
-  const static int STEP_SIZE=10;
-  float s=sequences_[0]->GetCharWidth()*STEP_SIZE;
-  int n_rulers=round(rect.width()/s);
-  int first=std::max(0, int(floor(rect.left()/s)));
-  painter->fillRect(QRectF(QPointF(0.0, rect.top()), 
-                           QSizeF(header_width_, rect.height())),
-                    QBrush(Qt::white));  
-  for (int i=first;i<first+n_rulers+2; ++i) {
-    painter->drawText(QRectF(QPointF(i*s-50+header_width_, 
-                                     rect.top()), QSizeF(100, 30)),
-                      Qt::AlignCenter, QString::number(i*STEP_SIZE));
-    painter->drawLine(QPointF(i*s+header_width_, rect.top()+30), 
-                      QPointF(i*s+header_width_, rect.top()+30+rect.height()));
-  }
-
-}
-
-void SequenceScene::SetContextMenu(QMenu* menu)
-{
-  context_menu_=menu;
-}
-
-QMenu* SequenceScene::GetContextMenu()
-{
-  return context_menu_;
-}
-
-SequenceScene::SequenceScene(QObject* parent):
-  QGraphicsScene(parent), header_width_(120.0)
-{
-  connect(this, SIGNAL(sceneRectChanged(const QRectF&)), this, 
-          SLOT(OnSceneRectChange(const QRectF&)));
-  context_menu_=NULL;
-}
-
-void SequenceScene::RepackSequences()
-{
-  if (sequences_.empty()) {
-    return;
-  }
-  sequences_.front()->setPos(0.0, 50.0);
-  for (std::vector<SequenceItem*>::iterator i=sequences_.begin()+1, 
-       e=sequences_.end(); i!=e; ++i) {
-     (*i)->setPos(0.0, (*(i-1))->pos().y()+
-                 (*(i-1))->boundingRect().height());        
-  } 
-}
-
-void SequenceScene::AddSequence(SequenceItem* seq)
-{
-  this->addItem(seq);
-  if (!sequences_.empty()) {
-    seq->setPos(0.0, sequences_.back()->pos().y()+
-                sequences_.back()->boundingRect().height());
-  } else {
-    seq->setPos(0.0, 50.0);
-  }
-  sequences_.push_back(seq);
-  update();
-}
-
-void SequenceScene::RemoveSequence(SequenceItem* seq)
-{
-  this->removeItem(seq);
-  std::vector<SequenceItem*>::iterator f=std::find(sequences_.begin(),
-    sequences_.end(), seq);
-  if(f != sequences_.end())
-  {
-    sequences_.erase(f);
-  }
-  RepackSequences();
-}
-
-void SequenceScene::SetHeaderWidth(float width)
-{
-  header_width_=width;
-  update();
-}
-
-float SequenceScene:: GetHeaderWidth() const
-{
-  return header_width_;
-}
-
-void SequenceScene::OnSceneRectChange(const QRectF& rect)
-{
-}
-
-}}
diff --git a/modules/gui/src/sequence_viewer/sequence_scene.hh b/modules/gui/src/sequence_viewer/sequence_scene.hh
deleted file mode 100644
index 2547d9fbd..000000000
--- a/modules/gui/src/sequence_viewer/sequence_scene.hh
+++ /dev/null
@@ -1,67 +0,0 @@
-//------------------------------------------------------------------------------
-// This file is part of the OpenStructure project <www.openstructure.org>
-//
-// Copyright (C) 2008-2010 by the OpenStructure authors
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License as published by the Free
-// Software Foundation; either version 3.0 of the License, or (at your option)
-// any later version.
-// This library is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
-// details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this library; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-//------------------------------------------------------------------------------
-#ifndef OST_GUI_SEQUENCE_SCENE_HH
-#define OST_GUI_SEQUENCE_SCENE_HH
-
-#include <ost/gui/module_config.hh>
-#include <ost/gui/sequence_viewer/sequence_item.hh>
-
-#include <QGraphicsScene>
-
-namespace ost { namespace gui {
-
-
-class SequenceScene : public QGraphicsScene {
-  Q_OBJECT
-public:
-  typedef std::vector<Range> Selection;
-
-  SequenceScene(QObject* parent=NULL);
-
-  void SetContextMenu(QMenu* menu);
-
-  QMenu* GetContextMenu();
-  std::vector<SequenceItem*>& GetSequences() { return sequences_; }
-  const Selection& GetSelection() const;
-
-  /// \brief get length of longest sequence (including gaps) in the alignment
-  void GetMaxSequenceLength();
-
-  
-  void SetHeaderWidth(float width);
-  float GetHeaderWidth() const;
-  void AddSequence(SequenceItem* seq);
-  void RemoveSequence(SequenceItem* seq);
-  void RepackSequences();
-public slots:
-  void OnSceneRectChange(const QRectF& rect);  
-protected: 
-  virtual void drawBackground(QPainter* painter, const QRectF& rect);
-private:
-  void UpdateAlignment();
-  Selection                  selection_;
-  Selection                  ref_sel_;
-  std::vector<SequenceItem*> sequences_;
-  QMenu*                     context_menu_;
-  float                      header_width_;
-};
-
-}}
-
-#endif
diff --git a/modules/gui/src/sequence_viewer/sequence_search_bar.cc b/modules/gui/src/sequence_viewer/sequence_search_bar.cc
index 808d45904..9ae88675e 100644
--- a/modules/gui/src/sequence_viewer/sequence_search_bar.cc
+++ b/modules/gui/src/sequence_viewer/sequence_search_bar.cc
@@ -21,7 +21,6 @@
  */
 
 #include "sequence_search_bar.hh"
-#include "sequence_item.hh"
 
 #include <QHBoxLayout>
 #include <QLineEdit>
@@ -32,7 +31,7 @@
 
 namespace ost { namespace gui { 
 
-SequenceSearchBar::SequenceSearchBar(QWidget* parent):
+SeqSearchBar::SeqSearchBar(QWidget* parent):
   QWidget(parent)
 {
   subject_=new QLineEdit(this);
@@ -41,13 +40,13 @@ SequenceSearchBar::SequenceSearchBar(QWidget* parent):
   QHBoxLayout* l= new QHBoxLayout(this);
   l->addSpacing(2);
   l->addWidget(subject_, 0);
+  l->setStretch(0,1);
   l->addWidget(search_all_, 0);
   QLabel* label=new QLabel("search in:", this);
   l->addSpacing(10);
   l->addWidget(label, 0);
   l->addWidget(search_in_, 0);
-  l->addStretch(1);
-  subject_->setMaximumWidth(200);
+  //subject_->setMaximumWidth(200);
   setLayout(l);
   l->setSizeConstraint(QLayout::SetMaximumSize);
   l->setMargin(1);  
@@ -67,23 +66,22 @@ SequenceSearchBar::SequenceSearchBar(QWidget* parent):
           SLOT(OnSearchInChanged(int)));
 }
   
-void SequenceSearchBar::Show(const std::vector<SequenceItem*>& sequences)
+void SeqSearchBar::UpdateItems(const QStringList& sequences)
 {
   search_in_->clear();
-  
-  for (size_t i=0;i<sequences.size(); ++i) {
-    QString name(sequences[i]->GetSequence().GetName().c_str());
-    search_in_->addItem(name);
+
+  for(int i=0;i< sequences.size(); i++){
+  search_in_->addItem(sequences[i]);
   }
+
   if (sequences.empty()) {
     search_all_->setCheckState(Qt::Checked);  
     search_in_->setEnabled(false);
   }
-  this->show();
   subject_->setFocus(Qt::ActiveWindowFocusReason);  
   subject_->selectAll();  
 }
-void SequenceSearchBar::OnSearchAllChanged(int state)
+void SeqSearchBar::OnSearchAllChanged(int state)
 {
   if (state==Qt::Unchecked) {
     search_in_->setEnabled(true);
@@ -91,22 +89,22 @@ void SequenceSearchBar::OnSearchAllChanged(int state)
     search_in_->setEnabled(false);
   }
   emit Changed(subject_->text(), search_all_->checkState()==Qt::Checked, 
-               search_in_->currentIndex());
+               search_in_->currentText());
 }
 
-void SequenceSearchBar::OnSearchInChanged(int index)
+void SeqSearchBar::OnSearchInChanged(int index)
 {
   emit Changed(subject_->text(), search_all_->checkState()==Qt::Checked, 
-               search_in_->currentIndex());
+               search_in_->currentText());
 }
 
-void SequenceSearchBar::OnSubjectChanged(const QString& str)
+void SeqSearchBar::OnSubjectChanged(const QString& str)
 {
   emit Changed(str, search_all_->checkState()==Qt::Checked, 
-               search_in_->currentIndex());
+               search_in_->currentText());
 }
 
-void SequenceSearchBar::paintEvent(QPaintEvent* paint_event)
+void SeqSearchBar::paintEvent(QPaintEvent* paint_event)
 {
   QPainter p(this);
   p.setBrush(QBrush(QColor(Qt::blue).lighter(300)));
@@ -115,7 +113,7 @@ void SequenceSearchBar::paintEvent(QPaintEvent* paint_event)
   paint_event->accept();
 }
 
-void SequenceSearchBar::keyPressEvent(QKeyEvent* key_event)
+void SeqSearchBar::keyPressEvent(QKeyEvent* key_event)
 {
   if (key_event->key()==Qt::Key_Escape) {
     this->hide();
diff --git a/modules/gui/src/sequence_viewer/sequence_search_bar.hh b/modules/gui/src/sequence_viewer/sequence_search_bar.hh
index fae7280dc..865a42be2 100644
--- a/modules/gui/src/sequence_viewer/sequence_search_bar.hh
+++ b/modules/gui/src/sequence_viewer/sequence_search_bar.hh
@@ -16,8 +16,8 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
-#ifndef OST_SEQUENCE_SEARCH_BAR_HH
-#define OST_SEQUENCE_SEARCH_BAR_HH
+#ifndef OST_SEQUENCE_VIEWER_SEQUENCE_SEARCH_BAR_HH
+#define OST_SEQUENCE_VIEWER_SEQUENCE_SEARCH_BAR_HH
 
 /*
   Author: Marco Biasini
@@ -27,20 +27,19 @@
 #include <QWidget>
 #include <QComboBox>
 #include <QCheckBox>
+#include <QSet>
 
 namespace ost { namespace gui {
 
-class SequenceItem;  
-
 /// \brief search bar to search in multiple sequence alignment
-class DLLEXPORT_OST_GUI SequenceSearchBar : public QWidget {
+class DLLEXPORT_OST_GUI SeqSearchBar : public QWidget {
   Q_OBJECT
 public:
-  SequenceSearchBar(QWidget* parent=NULL);
+  SeqSearchBar(QWidget* parent=NULL);
   
-  void Show(const std::vector<SequenceItem*>& sequences);
+  void UpdateItems(const QStringList& sequences);
 signals:
-  void Changed(const QString&, bool, int);
+  void Changed(const QString&, bool, const QString&);
 public slots:
    void OnSubjectChanged(const QString&);
    void OnSearchInChanged(int);
diff --git a/modules/gui/src/sequence/sequence_table_view.cc b/modules/gui/src/sequence_viewer/sequence_table_view.cc
similarity index 87%
rename from modules/gui/src/sequence/sequence_table_view.cc
rename to modules/gui/src/sequence_viewer/sequence_table_view.cc
index 2152c1a6b..807c130da 100644
--- a/modules/gui/src/sequence/sequence_table_view.cc
+++ b/modules/gui/src/sequence_viewer/sequence_table_view.cc
@@ -66,11 +66,14 @@ SequenceTableView::SequenceTableView(QAbstractItemModel * model)
 
   delegate_ = new SequenceDelegate(qobject_cast<SequenceModel*>(this->model()),this);
 
+#if !(defined(__APPLE__) && (QT_VERSION>=0x040600))
   this->InitStaticRow();
   this->InitStaticColumn();
-//  this->viewport()->stackUnder(static_row_);
   this->InitStaticField();
-//  this->viewport()->stackUnder(static_field_);
+  this->viewport()->stackUnder(static_field_);
+  this->viewport()->stackUnder(static_column_);
+  this->viewport()->stackUnder(static_row_);
+#endif
  }
 
 void SequenceTableView::InitStaticColumn()
@@ -82,7 +85,6 @@ void SequenceTableView::InitStaticColumn()
   static_column_->verticalHeader()->hide();
   static_column_->horizontalHeader()->hide();
 
-  //this->viewport()->stackUnder(static_column_);
   static_column_->setSelectionBehavior(SelectRows);
   static_column_->setSelectionModel(this->selectionModel());
   for(int col=1; col<this->model()->columnCount(); col++){
@@ -95,8 +97,9 @@ void SequenceTableView::InitStaticColumn()
   static_column_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   static_column_->show();
   static_column_->setStyleSheet("QTableView { border: 0px;"
-                                 "background-color: #F6F6F6;"
-                                 "selection-background-color: #EEEEEE}"
+                                 "selection-color: #4f4f4f;"
+                                 "selection-background-color: white;"
+                                 "background-color: white}"
                                  "QTableView::item{ border: none;"
                                  "padding: 0px; border-width: 0px; margin: 0px;}");
   static_column_->setShowGrid(false);
@@ -130,8 +133,7 @@ void SequenceTableView::InitStaticRow()
   static_row_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   static_row_->show();
   static_row_->setStyleSheet("QTableView { border: 0px;"
-                                 "background-color: #F6F6F6;"
-                                 "selection-background-color: #EEEEEE}"
+                                 "background-color: #FFFFFF}"
                                  "QTableView::item{ border: none;"
                                  "padding: 0px; border-width: 0px; margin: 0px;}");
   static_row_->setShowGrid(false);
@@ -169,8 +171,9 @@ void SequenceTableView::InitStaticField(){
   static_field_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   static_field_->show();
   static_field_->setStyleSheet("QTableView { border: 0px;"
-                                 "background-color: #E0E0E0;"
-                                 "selection-background-color: #EEEEEE}"
+                                 "selection-color: transparent;"
+                                 "selection-background-color: transparent;"
+                                 "background-color: white}"
                                  "QTableView::item{ border: none;"
                                  "padding: 0px; border-width: 0px; margin: 0px;}");
   static_field_->setShowGrid(false);
@@ -186,7 +189,8 @@ void SequenceTableView::InitStaticField(){
   this->updateStaticField();
 }
 void SequenceTableView::ResizeWidth(int index, int, int size)
-{
+{ 
+#if !(defined(__APPLE__) && (QT_VERSION>=0x040600))  
   if(index == 0){
     static_column_->setColumnWidth(0,size);
     static_field_->setColumnWidth(0,size);
@@ -194,10 +198,12 @@ void SequenceTableView::ResizeWidth(int index, int, int size)
     this->updateStaticField();
   }
   static_row_->setRowHeight(index,size);
+#endif  
 }
 
 void SequenceTableView::ResizeHeight(int index, int, int size)
 {
+#if !(defined(__APPLE__) && (QT_VERSION>=0x040600))
   static_column_->setRowHeight(index, size);
   if(index == 0){
     static_row_->setRowHeight(0,size);
@@ -205,14 +211,17 @@ void SequenceTableView::ResizeHeight(int index, int, int size)
     this->updateStaticRow();
     this->updateStaticField();
   }
+#endif
 }
 
 void SequenceTableView::resizeEvent(QResizeEvent * event)
 {
   QTableView::resizeEvent(event);
+#if !(defined(__APPLE__) && (QT_VERSION>=0x040600))
   this->updateStaticColumn();
   this->updateStaticRow();
   this->updateStaticField();
+#endif  
 }
 
 QModelIndex SequenceTableView::moveCursor(CursorAction action, Qt::KeyboardModifiers modifiers)
@@ -236,9 +245,13 @@ QModelIndex SequenceTableView::moveCursor(CursorAction action, Qt::KeyboardModif
 }
 
 void SequenceTableView::scrollTo(const QModelIndex & index, ScrollHint hint){
+#if !(defined(__APPLE__) && (QT_VERSION>=0x040600))
   if(index.column()>0 && index.row()>0){
     QTableView::scrollTo(index, hint);
   }
+#else
+  QTableView::scrollTo(index, hint);
+#endif
 }
 
 void SequenceTableView::updateStaticColumn()
@@ -267,18 +280,23 @@ void SequenceTableView::updateStaticField(){
 }
 
 void SequenceTableView::columnCountChanged(const QModelIndex& index, int old_count, int new_count){
-  if(old_count >= 0 && old_count <= new_count){
+  if(old_count >= 0 && old_count <= new_count) {
+  
     if(old_count == 0)old_count = 1;
     for(int col=old_count; col<=new_count; col++){
+#if !(defined(__APPLE__) && (QT_VERSION>=0x040600))        
       static_column_->setColumnHidden(col, true);
       static_field_->setColumnHidden(col,true);
+#endif          
       this->setItemDelegateForColumn(col, delegate_);
     }
+
   }
 }
 
 void SequenceTableView::rowCountChanged(const QModelIndex& index, int old_count, int new_count){
   if(old_count >= 0 && old_count <= new_count){
+#if !(defined(__APPLE__) && (QT_VERSION>=0x040600))    
     if(old_count == 0){
       old_count = 1;
     }
@@ -286,23 +304,28 @@ void SequenceTableView::rowCountChanged(const QModelIndex& index, int old_count,
       static_row_->setRowHidden(row, true);
       static_field_->setRowHidden(row,true);
     }
+#endif
   }
 }
 
 
 void SequenceTableView::resizeColumnsToContents(){
   QTableView::resizeColumnsToContents();
+#if !(defined(__APPLE__) && (QT_VERSION>=0x040600))    
   static_column_->setColumnWidth(0,this->columnWidth(0));
   static_field_->setColumnWidth(0,this->columnWidth(0));
   for(int i = 0; i < this->model()->columnCount(); i++){
     static_row_->setColumnWidth(i,this->columnWidth(i));
   }
+
   this->updateStaticColumn();
   this->updateStaticField();
+#endif  
 }
 
 void SequenceTableView::resizeRowsToContents(){
   QTableView::resizeRowsToContents();
+#if !(defined(__APPLE__) && (QT_VERSION>=0x040600))
   static_row_->setRowHeight(0,this->rowHeight(0));
   static_field_->setRowHeight(0,this->rowHeight(0));
   for(int i = 0; i < this->model()->columnCount(); i++){
@@ -310,17 +333,21 @@ void SequenceTableView::resizeRowsToContents(){
   }
   this->updateStaticRow();
   this->updateStaticField();
+#endif  
 }
 
-QTableView* SequenceTableView::GetStaticRow(){
+QTableView* SequenceTableView::GetStaticRow()
+{
   return static_row_;
 }
 
-QTableView* SequenceTableView::GetStaticColumn(){
+QTableView* SequenceTableView::GetStaticColumn()
+{
   return static_column_;
 }
 
-QTableView* SequenceTableView::GetStaticField(){
+QTableView* SequenceTableView::GetStaticField()
+{
   return static_field_;
 }
 
@@ -352,6 +379,16 @@ void SequenceTableView::wheelEvent(QWheelEvent* event)
   }
 }
 
+void SequenceTableView::keyPressEvent(QKeyEvent* event)
+{
+  if(event->matches(QKeySequence::Copy)){
+    emit CopyEvent(event);
+  }
+  else{
+    QTableView::keyPressEvent(event);
+  }
+}
+
 SequenceTableView::~SequenceTableView(){}
 
 }}
diff --git a/modules/gui/src/sequence/sequence_table_view.hh b/modules/gui/src/sequence_viewer/sequence_table_view.hh
similarity index 95%
rename from modules/gui/src/sequence/sequence_table_view.hh
rename to modules/gui/src/sequence_viewer/sequence_table_view.hh
index f8c07ee81..e138d07ea 100644
--- a/modules/gui/src/sequence/sequence_table_view.hh
+++ b/modules/gui/src/sequence_viewer/sequence_table_view.hh
@@ -44,6 +44,7 @@ public:
 
 signals:
   void MouseWheelEvent(QWheelEvent* event);
+  void CopyEvent(QKeyEvent* event);
 
 public slots:
   void columnCountChanged(const QModelIndex& index, int old_count, int new_count);
@@ -55,7 +56,8 @@ protected:
   virtual void mouseDoubleClickEvent(QMouseEvent* event);
   virtual void mouseReleaseEvent(QMouseEvent* event);
   virtual void resizeEvent(QResizeEvent* event);
-  virtual void wheelEvent (QWheelEvent* event);
+  virtual void wheelEvent(QWheelEvent* event);
+  virtual void keyPressEvent(QKeyEvent* event);
   virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
   void scrollTo (const QModelIndex & index, ScrollHint hint = EnsureVisible);
 
diff --git a/modules/gui/src/sequence_viewer/sequence_view_object.cc b/modules/gui/src/sequence_viewer/sequence_view_object.cc
new file mode 100644
index 000000000..8b63980bf
--- /dev/null
+++ b/modules/gui/src/sequence_viewer/sequence_view_object.cc
@@ -0,0 +1,213 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+/*
+  Author: Stefan Scheuber
+ */
+
+
+#include <QtGui>
+
+#include <ost/mol/mol.hh>
+#include <ost/mol/view_op.hh>
+
+#include "sequence_row.hh"
+#include "secstr_row.hh"
+
+#include "sequence_view_object.hh"
+
+namespace ost { namespace gui {
+
+const QString SequenceViewObject::properties_mode = "Highlight properties";
+const QString SequenceViewObject::secondary_structure_mode = "Secondary structure";
+
+AlignPropertiesPainter* SequenceViewObject::align_properties_painter = new AlignPropertiesPainter();
+ConservationPainter* SequenceViewObject::conservation_painter = new ConservationPainter();
+BackgroundPainter* SequenceViewObject::background_painter = new BackgroundPainter();
+SeqSecStrPainter* SequenceViewObject::seq_secondary_structure_painter = new SeqSecStrPainter();
+SeqSelectionPainter* SequenceViewObject::seq_selection_painter = new SeqSelectionPainter();
+SeqTextPainter* SequenceViewObject::seq_text_painter = new SeqTextPainter();
+
+SequenceViewObject::SequenceViewObject(seq::SequenceList& sequences, const QList<QString>& names, QObject *parent): BaseViewObject(parent), entity_(gfx::EntityP())
+{
+  this->Init();
+  if(names.size() == sequences.GetCount()){
+    for(int i=0; i<sequences.GetCount(); i++){
+      seq::SequenceHandle seq = sequences[i];
+      this->AddSequence(seq, names[i]);
+    }
+  }
+  this->SetDisplayMode(properties_mode);
+}
+
+SequenceViewObject::SequenceViewObject(seq::SequenceHandle& sequence, const QString& name, QObject *parent): BaseViewObject(parent), entity_(gfx::EntityP())
+{
+  this->Init();
+  this->AddSequence(sequence, name);
+  this->SetDisplayMode(properties_mode);
+}
+
+SequenceViewObject::SequenceViewObject(mol::ChainView& chain, const QString& name, QObject *parent): BaseViewObject(parent), entity_(gfx::EntityP())
+{
+  this->Init();
+  this->AddChain(chain, name);
+  this->SetDisplayMode(properties_mode);
+}
+
+SequenceViewObject::SequenceViewObject(gfx::EntityP& entity, QObject* parent): BaseViewObject(parent), entity_(entity)
+{
+  this->Init();
+  mol::EntityView view =entity->GetView();
+  for (mol::ChainViewList::const_iterator c=view.GetChainList().begin(),
+       e1=view.GetChainList().end(); c!=e1; ++c) {
+    mol::ChainView chain=*c;
+    QString name = QString(entity->GetName().c_str());
+    if (chain.GetName()!="" && chain.GetName()!=" ") {
+      name= name + " ("+chain.GetName().c_str()+")";
+    }
+    this->AddChain(chain, name);
+  }
+  this->SetDisplayMode(secondary_structure_mode);
+}
+
+SequenceViewObject::SequenceViewObject(QObject* parent): BaseViewObject(parent), entity_(gfx::EntityP())
+{
+  this->Init();
+  this->SetDisplayMode(properties_mode);
+}
+
+void SequenceViewObject::Init()
+{
+  this->AddDisplayMode(properties_mode);
+  if(entity_){
+    this->AddDisplayMode(secondary_structure_mode);
+  }
+}
+
+void SequenceViewObject::AddSequence(seq::SequenceHandle& sequence, const QString& name)
+{
+  SequenceRow* new_row = new SequenceRow(name, sequence, this);
+  new_row->InsertPainter(background_painter);
+  new_row->InsertPainter(align_properties_painter);
+  new_row->InsertPainter(seq_text_painter);
+  new_row->InsertPainter(seq_selection_painter);
+  rows_.append(new_row);
+}
+
+void SequenceViewObject::AddChain(mol::ChainView& chain, const QString& name)
+{
+  SecStrRow* new_row = new SecStrRow(name, chain, this);
+  new_row->InsertPainter(background_painter);
+  new_row->InsertPainter(seq_secondary_structure_painter);
+  new_row->InsertPainter(seq_text_painter);
+  new_row->InsertPainter(seq_selection_painter);
+  rows_.append(new_row);
+}
+
+void SequenceViewObject::AttachGfxObject(gfx::EntityP& ent)
+{
+  entity_ = ent;
+}
+
+gfx::EntityP& SequenceViewObject::GetGfxObject()
+{
+  return entity_;
+}
+
+void SequenceViewObject::SetDisplayMode(const QString& mode)
+{
+  if(this->display_modes_.contains(mode) &&  mode != this->GetCurrentDisplayMode()){
+    if(mode == properties_mode){
+      for(int i=0 ; i<this->GetRowCount(); i++){
+        BaseRow* row = this->GetRow(i);
+        row->RemovePainter(seq_secondary_structure_painter);
+        row->RemovePainter(conservation_painter);
+        row->InsertPainter(align_properties_painter,1);
+      }
+    }
+    else if(mode == secondary_structure_mode){
+      for(int i=0 ; i<this->GetRowCount(); i++){
+        BaseRow* row = this->GetRow(i);
+        row->RemovePainter(align_properties_painter);
+        row->RemovePainter(conservation_painter);
+        row->InsertPainter(seq_secondary_structure_painter,1);
+      }
+    }
+  }
+  BaseViewObject::SetDisplayMode(mode);
+}
+
+QMap<int, QList<int> > SequenceViewObject::GetIndexesForView(const mol::EntityView& view)
+{
+  if(view.GetChainCount()==0){
+    return QMap<int, QList<int> >();
+  }
+  else{
+    QMap<int, QList<int> > selected_indexes;
+    for(int i=0; i< rows_.size(); i++){
+      if(SecStrRow* secstr_row = qobject_cast<SecStrRow*>(rows_[i])){
+        mol::ChainView dst_chain=(secstr_row->GetChain());
+        seq::SequenceHandle seq = secstr_row->GetSequence();
+        if (mol::ChainView src_chain=view.FindChain(dst_chain.GetName())) {
+          // for each residue in the selection deduce index in sequence
+          for (mol::ResidueViewList::const_iterator j=src_chain.GetResidueList().begin(),
+             e2=src_chain.GetResidueList().end(); j!=e2; ++j) {
+            mol::ResidueView dst_res=dst_chain.FindResidue(j->GetHandle());
+            assert(dst_res.IsValid());
+            int p=dst_res.GetIndex()+1;
+            assert(p>=0 && p<=seq.GetLength());
+            selected_indexes[i].append(p);
+          }
+        }
+      }
+    }
+    return selected_indexes;
+  }
+}
+
+QMap<int, QList<int> > SequenceViewObject::GetIndexesForSubject(const QString& subject, const QString& sequence_name)
+{
+  if(subject.size()==0){
+    return QMap<int, QList<int> >();
+  }
+  QMap<int, QList<int> > selected_indexes;
+  String subject_str = subject.toStdString();
+  for(int i=0; i< rows_.size(); i++){
+    if(SequenceRow* secstr_row = qobject_cast<SequenceRow*>(rows_[i])){
+      if(sequence_name.size()==0 || sequence_name==secstr_row->GetName()){
+        seq::SequenceHandle seq = secstr_row->GetSequence();
+        String seq_str=seq.GetString();
+        size_t pos=0;
+        size_t first=String::npos;
+        while ((pos=seq_str.find(subject_str, pos))!=String::npos) {
+          if (first==String::npos) {
+            first=pos;
+          }
+          for(int j=0; j < subject.size(); j++){
+            selected_indexes[i].append(pos+j+1);
+          }
+          pos+=subject.length();
+        }
+      }
+    }
+  }
+  return selected_indexes;
+}
+
+}}
diff --git a/modules/gui/src/sequence/view_object.hh b/modules/gui/src/sequence_viewer/sequence_view_object.hh
similarity index 54%
rename from modules/gui/src/sequence/view_object.hh
rename to modules/gui/src/sequence_viewer/sequence_view_object.hh
index a6d99bc74..2ad390a95 100644
--- a/modules/gui/src/sequence/view_object.hh
+++ b/modules/gui/src/sequence_viewer/sequence_view_object.hh
@@ -16,50 +16,44 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
-#ifndef OST_SEQUENCE_VIEWER_VIEW_OBJECT
-#define OST_SEQUENCE_VIEWER_VIEW_OBJECT
+#ifndef OST_SEQUENCE_VIEWER_SEQUENCE_VIEW_OBJECT
+#define OST_SEQUENCE_VIEWER_SEQUENCE_VIEW_OBJECT
 
 /*
   Author: Stefan Scheuber
  */
 
-#include <QObject>
-#include <QPair>
-#include <QList>
-#include <QVarLengthArray>
-#include <QFont>
-#include <QSize>
 
-#include <ost/mol/alg/sec_structure_segments.hh>
 #include <ost/mol/entity_handle.hh>
 
 #include <ost/gfx/entity.hh>
 
 #include <ost/seq/sequence_list.hh>
 
-#include "base_row.hh"
+#include "align_properties_painter.hh"
+#include "conservation_painter.hh"
+#include "background_painter.hh"
+#include "seq_secstr_painter.hh"
+#include "seq_selection_painter.hh"
+#include "seq_text_painter.hh"
+
+#include "base_view_object.hh"
 
 
 namespace ost { namespace gui {
 
-class ViewObject : public QObject
+class SequenceViewObject : public BaseViewObject
 {
   Q_OBJECT
 
-
 public:
-  ViewObject(seq::SequenceList& sequences, const QList<QString>& names, QObject* parent = 0);
-  ViewObject(seq::SequenceHandle& sequence, const QString& name, QObject* parent = 0);
-  ViewObject(mol::ChainView& chain, const QString& name, QObject* parent = 0);
-  ViewObject(gfx::EntityP& entity, QObject* parent = 0);
-  ViewObject(QObject* parent = 0);
+  SequenceViewObject(seq::SequenceList& sequences, const QList<QString>& names, QObject* parent = 0);
+  SequenceViewObject(seq::SequenceHandle& sequence, const QString& name, QObject* parent = 0);
+  SequenceViewObject(mol::ChainView& chain, const QString& name, QObject* parent = 0);
+  SequenceViewObject(gfx::EntityP& entity, QObject* parent = 0);
+  SequenceViewObject(QObject* parent = 0);
 
-  void InsertRow(int pos, BaseRow* row);
-  void RemoveRow(BaseRow* row);
-
-  BaseRow* GetRow(int pos);
-  int GetRowCount();
-  int GetMaxColumnCount() const;
+  void Init();
 
   void AddSequence(seq::SequenceHandle& sequence, const QString& name=QString());
   void AddChain(mol::ChainView& chain, const QString& name=QString());
@@ -67,21 +61,26 @@ public:
   void AttachGfxObject(gfx::EntityP& ent);
   gfx::EntityP& GetGfxObject();
 
-  void SetSelection(int row, const QSet<int>& added, const QSet<int>& removed);
+  virtual void SetDisplayMode(const QString& mode);
 
-  QVariant GetData(int row, int column, int role);
-  bool SetData(int row, int column, const QVariant& value, int role);
-  Qt::ItemFlags Flags(int row, int column) const;
+  QMap<int, QList<int> > GetIndexesForView(const mol::EntityView& view);
+  QMap<int, QList<int> > GetIndexesForSubject(const QString& subject, const QString& sequence_name=QString());
 
-  void DoubleClicked(int row, int column);
-  void ZoomIn();
-  void ZoomOut();
+protected:
+  static const QString properties_mode;
+  static const QString secondary_structure_mode;
 
-  QMap<int, QList<int> > GetIndexesForView(const mol::EntityView& view);
+  static AlignPropertiesPainter* align_properties_painter;
+  static ConservationPainter* conservation_painter;
+  static BackgroundPainter* background_painter;
+  static SeqSecStrPainter* seq_secondary_structure_painter;
+  static SeqSelectionPainter* seq_selection_painter;
+  static SeqTextPainter* seq_text_painter;
 
 private:
-  QList<BaseRow*> rows_;
   gfx::EntityP entity_;
+
+
 };
 
 
diff --git a/modules/gui/src/sequence_viewer/sequence_viewer.cc b/modules/gui/src/sequence_viewer/sequence_viewer.cc
index 05d5d03cf..c5d86d783 100644
--- a/modules/gui/src/sequence_viewer/sequence_viewer.cc
+++ b/modules/gui/src/sequence_viewer/sequence_viewer.cc
@@ -16,25 +16,54 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
+
+/*
+  Author: Stefan Scheuber
+ */
+#include <boost/pointer_cast.hpp>
+
+#include <QAbstractItemView>
+#include <QApplication>
+#include <QClipboard>
+#include <QDir>
+#include <QHeaderView>
 #include <QMenu>
+#include <QPushButton>
+#include <QShortcut>
+#include <QVBoxLayout>
+#include <QVarLengthArray>
 
-#include <ost/dyn_cast.hh>
-#include <ost/mol/view_op.hh>
+#include <ost/platform.hh>
+#include <ost/mol/chain_view.hh>
+#include <ost/mol/entity_view.hh>
+
+#include <ost/seq/sequence_handle.hh>
 
 #include <ost/gfx/entity.hh>
 #include <ost/gfx/scene.hh>
 #include <ost/gfx/gfx_node_visitor.hh>
-#include <ost/gfx/gfx_node.hh>
-#include <ost/gfx/gfx_object.hh>
 
 #include <ost/gui/widget_registry.hh>
 #include <ost/gui/gosty_app.hh>
 
+#include "sequence_model.hh"
 #include "sequence_viewer.hh"
 
-
 namespace ost { namespace gui {
 
+class SequenceViewerFactory: public WidgetFactory {
+public:
+  SequenceViewerFactory() :
+    WidgetFactory("ost::gui::SequenceViewer", "Sequence Viewer") {
+  }
+
+  virtual Widget* Create(QWidget* parent) {
+    return GostyApp::Instance()->GetSequenceViewer();
+  }
+};
+
+OST_REGISTER_WIDGET(SequenceViewer, SequenceViewerFactory);
+
 struct GetNodesVisitor: public gfx::GfxNodeVisitor {
   GetNodesVisitor(): nodes_() {}
   virtual void VisitObject(gfx::GfxObj* o, const Stack& st) {
@@ -44,199 +73,349 @@ struct GetNodesVisitor: public gfx::GfxNodeVisitor {
   gfx::NodePtrList GetNodes(){return nodes_;}
 };
 
-class SequenceViewerFactory: public WidgetFactory {
-public:
-	SequenceViewerFactory() :
-    WidgetFactory("ost::gui::SequenceViewer", "Sequence Viewer") {
+SequenceViewer::SequenceViewer(bool stand_alone, QWidget* parent): Widget(NULL,parent)
+{
+  model_ = new SequenceModel(this);
+
+  QVBoxLayout* layout = new QVBoxLayout(this);
+  layout->setMargin(0);
+  layout->setSpacing(0);
+  this->setLayout(layout);
+
+  this->InitActions();
+
+
+  if(stand_alone){
+    this->InitMenuBar();
   }
+  this->InitSearchBar();
+  this->InitView();
 
-  virtual Widget* Create(QWidget* parent) {
-    return GostyApp::Instance()->GetSequenceViewer();
+  if(!stand_alone){
+    gfx::Scene::Instance().AttachObserver(this);
+    gfx::GfxNodeP root_node = gfx::Scene::Instance().GetRootNode();
+    GetNodesVisitor gnv;
+    gfx::Scene::Instance().Apply(gnv);
+    gfx::NodePtrList list = gnv.GetNodes();
+    for(unsigned int i=0; i<list.size();i++){
+      this->NodeAdded(list[i]);
+    }
   }
-};
+}
 
-OST_REGISTER_WIDGET(SequenceViewer, SequenceViewerFactory);
+void SequenceViewer::InitMenuBar()
+{
+  toolbar_ = new QToolBar(this);
+  toolbar_->setToolButtonStyle(Qt::ToolButtonIconOnly);
+  toolbar_->setIconSize(QSize(16,16));
+  toolbar_->addActions(action_list_);
+  layout()->addWidget(toolbar_);
+}
 
-SequenceViewer::SequenceViewer(QWidget* parent):
-  SequenceViewerBase(parent), we_are_changing_the_selection_(false)
+void SequenceViewer::InitSearchBar()
 {
-  gfx::Scene::Instance().AttachObserver(this);
-  this->SetDisplayStyle(SequenceViewer::LOOSE);
+  seq_search_bar_ = new SeqSearchBar(this);
+  seq_search_bar_->hide();
+  layout()->addWidget(seq_search_bar_);
+  connect(seq_search_bar_, SIGNAL(Changed(const QString&, bool, const QString&)), this, SLOT(OnSearchBarUpdate(const QString&, bool, const QString&)));
+}
 
-  gfx::GfxNodeP root_node = gfx::Scene::Instance().GetRootNode();
-  GetNodesVisitor gnv;
-  gfx::Scene::Instance().Apply(gnv);
-  gfx::NodePtrList list = gnv.GetNodes();
-  for(unsigned int i=0; i<list.size();i++){
-    this->NodeAdded(list[i]);
-  }
+void SequenceViewer::InitView()
+{
+  seq_table_view_ = new SequenceTableView(model_);
+  layout()->addWidget(seq_table_view_);
+
+  connect(model_,SIGNAL(columnsInserted(const QModelIndex&, int, int)),seq_table_view_,SLOT(columnCountChanged(const QModelIndex&, int, int)));
+  connect(model_,SIGNAL(rowsInserted(const QModelIndex&, int, int)),seq_table_view_,SLOT(rowCountChanged(const QModelIndex&, int, int)));
+
+  seq_table_view_->horizontalHeader()->setMinimumSectionSize(2);
+  seq_table_view_->verticalHeader()->setMinimumSectionSize(2);
+  seq_table_view_->setSelectionMode(QAbstractItemView::ExtendedSelection);
+  connect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
+  connect(seq_table_view_,SIGNAL(doubleClicked(const QModelIndex&)),model_,SLOT(DoubleClicked(const QModelIndex&)));
+#if !(defined(__APPLE__) && (QT_VERSION>=0x040600))  
+  connect(seq_table_view_->GetStaticColumn(),SIGNAL(doubleClicked(const QModelIndex&)),this,SLOT(DoubleClicked(const QModelIndex&)));
+  connect(seq_table_view_->GetStaticRow(),SIGNAL(doubleClicked(const QModelIndex&)),this,SLOT(DoubleClicked(const QModelIndex&)));
+#endif
+  connect(seq_table_view_,SIGNAL(CopyEvent(QKeyEvent*)),this,SLOT(CopyEvent(QKeyEvent*)));
+  connect(seq_table_view_,SIGNAL(MouseWheelEvent(QWheelEvent*)),this,SLOT(MouseWheelEvent(QWheelEvent*)));
 }
 
-SequenceViewer::~SequenceViewer()
+void SequenceViewer::InitActions()
 {
-  gfx::Scene::Instance().DetachObserver(this);
+  QDir icon_path(GetSharedDataPath().c_str());
+  icon_path.cd("gui");
+  icon_path.cd("icons");
+
+  QAction* find_action = new QAction(this);
+  find_action->setText("Find Dialog");
+  find_action->setShortcut(QKeySequence(tr("Ctrl+F")));
+  find_action->setCheckable(true);
+  find_action->setToolTip("Display Find-Dialog (Ctrl+F)");
+  find_action->setIcon(QIcon(icon_path.absolutePath()+QDir::separator()+QString("find_icon.png")));
+  action_list_.append(find_action);
+  connect(find_action, SIGNAL(triggered(bool)), this, SLOT(FindInSequence()));
+
+  display_mode_actions_ = new QActionGroup(this);
+  QAction* menu_action = new QAction(this);
+  menu_action->setText("Menubar");
+  menu_action->setShortcut(QKeySequence(tr("Ctrl+M")));
+  menu_action->setToolTip("Display Options (Ctrl+M)");
+  menu_action->setIcon(QIcon(icon_path.absolutePath()+QDir::separator()+QString("menubar_icon.png")));
+  action_list_.append(menu_action);
+  connect(menu_action, SIGNAL(triggered(bool)), this, SLOT(DisplayMenu()));
 }
 
 void SequenceViewer::NodeAdded(const gfx::GfxNodeP& n)
 {
-  if (gfx::EntityP o=dyn_cast<gfx::Entity>(n)) {
-    // extract all chains 
-    mol::EntityView v=o->GetView();
-    for (mol::ChainViewList::const_iterator c=v.GetChainList().begin(),
-         e1=v.GetChainList().end(); c!=e1; ++c) {
-      mol::ChainView chain=*c;
-      String seq_str;
-      seq_str.reserve(chain.GetResidueCount());
-      for (mol::ResidueViewList::const_iterator r=chain.GetResidueList().begin(),
-           e2=chain.GetResidueList().end(); r!=e2; ++r) {
-        mol::ResidueView res=*r;
-        seq_str.append(1, res.GetOneLetterCode());
-      }
-      if (seq_str.empty()) {
-        continue;
-      }      
-      String name=o->GetName();
-      if (chain.GetName()!="" && chain.GetName()!=" ") {
-        name+=" ("+chain.GetName()+")";
-      }
-      seq::SequenceHandle seq=seq::CreateSequence(name, seq_str);
-      mol::EntityView v_one_chain=v.GetHandle().CreateEmptyView();
-      v_one_chain.AddChain(chain, mol::ViewAddFlag::INCLUDE_ALL);
-      seq.AttachView(v_one_chain);
-      SequenceItem* item=new SequenceItem(seq);
-      connect(item, SIGNAL(SelectionChanged(SequenceItem*)),
-              this, SLOT(ItemSelectionChanged(SequenceItem*)));
-      this->AddSequence(item);
-      obj_map_.insert(std::make_pair(item, o));      
-    }
+  if (gfx::EntityP o=boost::dynamic_pointer_cast<gfx::Entity>(n)) {
+    model_->InsertGfxEntity(o);
+    seq_table_view_->resizeColumnsToContents();
+    seq_table_view_->resizeRowsToContents();
+  }
+  this->UpdateSearchBar();
+}
+
+void SequenceViewer::NodeRemoved(const gfx::GfxNodeP& node)
+{
+  if (gfx::EntityP o=boost::dynamic_pointer_cast<gfx::Entity>(node)) {
+    model_->RemoveGfxEntity(o);
+  }
+}
+
+void SequenceViewer::AddAlignment(const seq::AlignmentHandle& alignment)
+{
+  if(alignment.GetCount()>0 && alignment.GetLength()>0){
+    model_->InsertAlignment(alignment);
+    seq_table_view_->resizeColumnsToContents();
+    seq_table_view_->resizeRowsToContents();
   }
 }
 
-void SequenceViewer::ItemSelectionChanged(SequenceItem* item)
+void SequenceViewer::RemoveAlignment(const seq::AlignmentHandle& alignment)
+{
+  model_->RemoveAlignment(alignment);
+}
+
+void SequenceViewer::UpdateSearchBar()
+{
+  QStringList sequence_names_;
+  for(int i = 1; i< model_->rowCount(); i++){
+    QString name = model_->data(model_->index(i,0),Qt::DisplayRole).toString();
+    sequence_names_.append(name);
+  }
+  seq_search_bar_->UpdateItems(sequence_names_);
+}
+
+void SequenceViewer::SelectionModelChanged(const QItemSelection& sel, const QItemSelection& desel)
+{
+  gfx::Scene::Instance().DetachObserver(this);
+  model_->SelectionChanged(sel, desel);
+  gfx::Scene::Instance().AttachObserver(this);
+}
+
+void SequenceViewer::SelectionChanged(const gfx::GfxObjP& o,
+                                      const mol::EntityView& view)
 {
-  if (we_are_changing_the_selection_==true) {
-    return;
+  disconnect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
+  gfx::EntityP entity=boost::dynamic_pointer_cast<gfx::Entity>(o);
+  if(entity){
+    const QModelIndexList& list = model_->GetModelIndexes(entity, view);
+    this->SelectList(list);
   }
-  we_are_changing_the_selection_=true;
-  // map sequence item back to graphical object
-  if (gfx::GfxObjP p=this->GfxObjForSeqItem(item)) {
-    gfx::EntityP ec=dyn_cast<gfx::Entity>(p);
-    seq::SequenceHandle seq=item->GetSequence();
-    mol::EntityView att_v=seq.GetAttachedView();
-    if (!att_v) {
-      we_are_changing_the_selection_=false;      
-      return;
+  connect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
+}
+
+void SequenceViewer::DoubleClicked(const QModelIndex& index)
+{
+  disconnect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
+  model_->DoubleClicked(index);
+  connect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
+}
+
+void SequenceViewer::MouseWheelEvent(QWheelEvent* event)
+{
+  int delta = event->delta();
+  if (event->orientation() == Qt::Vertical) {
+    if(delta>0){
+      model_->ZoomIn();
+      seq_table_view_->viewport()->update();
+      seq_table_view_->resizeColumnsToContents();
+      seq_table_view_->resizeRowsToContents();
     }
-    const SequenceItem::Selection& sel=item->GetSelection();
-    // reset selection of "our" chain
-    mol::EntityView sel_v=ec->GetSelection();
-    if (mol::ChainView c=sel_v.FindChain(att_v.GetChainList().front().GetHandle())) {
-      sel_v.RemoveChain(c);
+    else if(delta<0){
+      model_->ZoomOut();
+      seq_table_view_->viewport()->update();
+      seq_table_view_->resizeColumnsToContents();
+      seq_table_view_->resizeRowsToContents();
     }
-    if (sel.empty()) {
-      try {
-        ec->SetSelection(sel_v);        
-      } catch(...) {
+  }
+  event->accept();
+}
+
+void SequenceViewer::CopyEvent(QKeyEvent* event)
+{
+  QItemSelectionModel* model = seq_table_view_->selectionModel();
+  const QModelIndexList& list = model->selectedIndexes();
+  if(list.size()>0){
+    QString clipboard_string;
+    QSet<int> rows;
+    int min_col=model_->columnCount();
+    int max_col=0;
+    for(int i = 0; i < list.size(); i++){
+      if(list[i].column()>max_col){
+        max_col = list[i].column();
+      }
+      if(list[i].column()<min_col){
+        min_col = list[i].column();
       }
-      we_are_changing_the_selection_=false;      
-      return;
-    }   
-    for (SequenceItem::Selection::const_iterator j=sel.begin(),
-         e=sel.end(); j!=e; ++j) {
-      for (size_t k=j->Loc; k<j->End(); ++k) {
-        if (int(k)>seq.GetLength() || seq.GetOneLetterCode(k)=='-') {
-          continue;
+      rows.insert(list[i].row());
+    }
+
+    bool first_row = true;
+    for(int i = 1; i < model_->rowCount(); i++){
+      if(rows.contains(i)){
+        if(!first_row){
+          clipboard_string.append("\n");
         }
-        if (mol::ResidueView rv=seq.GetResidue(k)) {
-          sel_v.AddResidue(rv, mol::ViewAddFlag::INCLUDE_ATOMS);
+        for(int j=min_col; j<=max_col; j++){
+          const QModelIndex& index = model_->index(i,j);
+          if(model->isSelected(index)){
+            clipboard_string.append(model_->data(index,Qt::DisplayRole).toString());
+          }
+          else{
+            clipboard_string.append('-');
+          }
         }
+        first_row = false;
       }
     }
-    sel_v.AddAllInclusiveBonds();
-    try {
-      ec->SetSelection(sel_v);      
-    } catch(...) {
-    }
+    QApplication::clipboard()->setText(clipboard_string);
+  }
+  event->accept();
+}
 
+void SequenceViewer::FindInSequence()
+{
+  if(seq_search_bar_->isHidden()){
+    seq_search_bar_->show();
+  }
+  else{
+    seq_search_bar_->hide();
   }
-  we_are_changing_the_selection_=false;
 }
 
-void SequenceViewer::NodeRemoved(const gfx::GfxNodeP& node)
+void SequenceViewer::OnSearchBarUpdate(const QString& subject,
+                                           bool search_in_all, const QString& name)
 {
-  if (gfx::EntityP o=dyn_cast<gfx::Entity>(node)) {
-    SequenceItemList seq_items=this->SeqItemsForGfxObj(o);
-    for (SequenceItemList::iterator i=seq_items.begin(),
-     e=seq_items.end(); i!=e; ++i) {
-    SequenceItem* seq_item=*i;
-    this->RemoveSequence(seq_item);
-    delete seq_item;
-    }
+  seq_table_view_->selectionModel()->clear();
+  if(search_in_all){
+    const QModelIndexList& list = model_->GetModelIndexes(subject);
+    this->SelectList(list);
+  }
+  else{
+    const QModelIndexList& list = model_->GetModelIndexes(subject,name);
+    this->SelectList(list);
   }
 }
 
-void SequenceViewer::SelectionChanged(const gfx::GfxObjP& o, 
-                                      const mol::EntityView& view)
+void SequenceViewer::SelectList(const QModelIndexList& list)
 {
-  if (we_are_changing_the_selection_) {
-    return;
+  QItemSelectionModel* model = seq_table_view_->selectionModel();
+  QSet<int> rows_visited;
+  for(int i = 0; i<list.size(); i++){
+    int row =list[i].row();
+    if(!rows_visited.contains(row)){
+      model->select(list[i],QItemSelectionModel::Rows|QItemSelectionModel::Deselect);
+      rows_visited.insert(row);
+    }
   }
-  we_are_changing_the_selection_=true;
-  gfx::EntityP ec=dyn_cast<gfx::Entity>(o);
-  
+  for(int i = 0; i<list.size(); i++){
+    model->select(list[i],QItemSelectionModel::Select);
+  }
+}
 
-  std::vector<bool> selected_cols;
-  selected_cols.resize(this->GetLongestSequenceLength(), false);
+const QStringList& SequenceViewer::GetDisplayModes()
+{
+  return model_->GetDisplayModes();
+}
+const QStringList& SequenceViewer::GetDisplayModes(const seq::AlignmentHandle& alignment)
+{
+  return model_->GetDisplayModes(alignment);
+}
+const QStringList& SequenceViewer::GetDisplayModes(const gfx::EntityP& entity)
+{
+  return model_->GetDisplayModes(entity);
+}
 
-  // get affected sequence items
-  SequenceItemList seq_items=this->SeqItemsForGfxObj(o);
+const QString& SequenceViewer::GetCurrentDisplayMode()
+{
+  return model_->GetCurrentDisplayMode();
+}
+const QString& SequenceViewer::GetCurrentDisplayMode(const seq::AlignmentHandle& alignment)
+{
+  return model_->GetCurrentDisplayMode(alignment);
+}
+const QString& SequenceViewer::GetCurrentDisplayMode(const gfx::EntityP& entity)
+{
+  return model_->GetCurrentDisplayMode(entity);
+}
 
-  for (SequenceItemList::iterator i=seq_items.begin(), 
-       e=seq_items.end(); i!=e; ++i) {
-    SequenceItem* seq_item=*i;
+void SequenceViewer::ChangeDisplayMode(const QString& string)
+{
+  model_->SetDisplayMode(string);
+  seq_table_view_->viewport()->update();
+}
 
-    if(view.GetChainCount()==0){
-        this->SelectColumns(seq_item, selected_cols);
-    }
-    else
-    {
-    seq::SequenceHandle seq=seq_item->GetSequence();
-    mol::ChainView dst_chain=(seq.GetAttachedView().GetChainList())[0];
-    if (mol::ChainView src_chain=view.FindChain(dst_chain.GetName())) {
-        // for each residue in the selection deduce index in sequence
-        for (mol::ResidueViewList::const_iterator j=src_chain.GetResidueList().begin(),
-           e2=src_chain.GetResidueList().end(); j!=e2; ++j) {
-        mol::ResidueView dst_res=dst_chain.FindResidue(j->GetHandle());
-        assert(dst_res.IsValid());
-        int p=seq.GetPos(dst_res.GetIndex());
-        assert(p>=0 && p<=seq.GetLength());
-        selected_cols[p]=true;
-        }
-        this->SelectColumns(seq_item, selected_cols);
-        std::fill(selected_cols.begin(), selected_cols.end(), false);
-      }
-    }
-  }
-  we_are_changing_the_selection_=false;  
+void SequenceViewer::ChangeDisplayMode(const seq::AlignmentHandle& alignment, const QString& string)
+{
+  model_->SetDisplayMode(alignment, string);
+  seq_table_view_->viewport()->update();
 }
 
-SequenceItemList SequenceViewer::SeqItemsForGfxObj(const gfx::GfxObjP& obj)
+void SequenceViewer::ChangeDisplayMode(const gfx::EntityP& entity, const QString& string)
 {
-  SequenceItemList seq_items;
-  gfx::EntityP ec=dyn_cast<gfx::Entity>(obj);
-  std::map<SequenceItem*, gfx::EntityP>::iterator i,e;
-  for (i=obj_map_.begin(), e=obj_map_.end(); i!=e; ++i) {
-    if (i->second==ec) {
-      seq_items.push_back(i->first);
+  model_->SetDisplayMode(entity, string);
+  seq_table_view_->viewport()->update();
+}
+
+ActionList SequenceViewer::GetActions()
+{
+  return action_list_;
+}
+
+void SequenceViewer::DisplayMenu()
+{
+  QMenu* menu = new QMenu();
+  QList<QAction*> actions = display_mode_actions_->actions();
+  for(int i=0;i<actions.size();i++){
+    display_mode_actions_->removeAction(actions[i]);
+  }
+  const QStringList& display_modes = this->GetDisplayModes();
+  for(int i=0; i<display_modes.size(); i++){
+    QString ident(display_modes[i]);
+    QAction* action = new QAction(ident,menu);
+    action->setCheckable(true);
+    connect(action,SIGNAL(triggered(bool)),this,SLOT(ChangeDisplayMode()));
+    display_mode_actions_->addAction(action);
+    if(display_modes[i] == this->GetCurrentDisplayMode() ){
+      action->setChecked(true);
     }
+    menu->addAction(action);
   }
-  return seq_items;
+  menu->exec(QCursor::pos());
 }
 
-gfx::GfxObjP SequenceViewer::GfxObjForSeqItem(SequenceItem* item)
+void SequenceViewer::ChangeDisplayMode()
 {
-  std::map<SequenceItem*, gfx::EntityP>::iterator i=obj_map_.find(item);
-  return (i!=obj_map_.end()) ? i->second : gfx::EntityP();
+  QAction* action = display_mode_actions_->checkedAction();
+  if(action){
+    this->ChangeDisplayMode(action->text());
+  }
+}
+
+SequenceViewer::~SequenceViewer(){
+  gfx::Scene::Instance().DetachObserver(this);
 }
 
 }}
diff --git a/modules/gui/src/sequence_viewer/sequence_viewer.hh b/modules/gui/src/sequence_viewer/sequence_viewer.hh
index 0b5811dc1..e4f8d55f2 100644
--- a/modules/gui/src/sequence_viewer/sequence_viewer.hh
+++ b/modules/gui/src/sequence_viewer/sequence_viewer.hh
@@ -16,45 +16,93 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
-#ifndef OST_SEQUENCE_VIEWER_HH
-#define OST_SEQUENCE_VIEWER_HH
+#ifndef OST_SEQUENCE_VIEWER_SEQUENCE_VIEWER
+#define OST_SEQUENCE_VIEWER_SEQUENCE_VIEWER
 
 /*
-  Author: Marco Biasini
+  Author: Stefan Scheuber
  */
 
-#include <map>
+#include <QWidget>
+#include <QActionGroup>
+#include <QToolBar>
 
-#include <ost/gfx/scene_observer.hh>
-#include <ost/gui/sequence_viewer/sequence_viewer_base.hh>
-#include <ost/gfx/entity.hh>
+#include <ost/seq/alignment_handle.hh>
 
-namespace ost { namespace gui {
+#include <ost/gfx/scene.hh>
+#include <ost/gfx/gfx_object.hh>
+
+#include <ost/gui/widget.hh>
+
+#include <ost/gui/module_config.hh>
 
-class SequenceItem;
+#include "sequence_search_bar.hh"
+#include "sequence_model.hh"
+#include "sequence_table_view.hh"
+
+namespace ost { namespace gui {
 
-/// \brief sequence view
-class DLLEXPORT_OST_GUI SequenceViewer : public SequenceViewerBase, 
-                                         public gfx::SceneObserver {
+/// \brief QTableView with first column not moving
+class DLLEXPORT_OST_GUI SequenceViewer : public Widget, public gfx::SceneObserver  {
   Q_OBJECT
 public:
-  SequenceViewer(QWidget* parent=NULL);
+  SequenceViewer(bool stand_alone=true, QWidget* parent=NULL);
   ~SequenceViewer();
-  
+
   virtual void NodeAdded(const gfx::GfxNodeP& node);
-  
   virtual void NodeRemoved(const gfx::GfxNodeP& node);
-  
-  virtual void SelectionChanged(const gfx::GfxObjP& obj, const mol::EntityView& sel);
+  virtual void SelectionChanged(const gfx::GfxObjP& o, const mol::EntityView& view);
+
+  virtual void AddAlignment(const seq::AlignmentHandle& alignment);
+  virtual void RemoveAlignment(const seq::AlignmentHandle& alignment);
+
+  virtual bool Restore(const QString&){return true;};
+  virtual bool Save(const QString&){return true;};
+
+  virtual const QStringList& GetDisplayModes();
+  virtual const QStringList& GetDisplayModes(const seq::AlignmentHandle& alignment);
+  virtual const QStringList& GetDisplayModes(const gfx::EntityP& entity);
+
+  virtual const QString& GetCurrentDisplayMode();
+  virtual const QString& GetCurrentDisplayMode(const seq::AlignmentHandle& alignment);
+  virtual const QString& GetCurrentDisplayMode(const gfx::EntityP& entity);
+
+  virtual ActionList GetActions();
+
 public slots:
-  void ItemSelectionChanged(SequenceItem* item);
+  void ChangeDisplayMode(const QString&);
+  void ChangeDisplayMode(const seq::AlignmentHandle&, const QString&);
+  void ChangeDisplayMode(const gfx::EntityP&, const QString&);
+  void DisplayMenu();
+  //internal
+  void OnSearchBarUpdate(const QString&, bool, const QString&);
+
 private:
-  SequenceItemList SeqItemsForGfxObj(const gfx::GfxObjP& obj);
-  gfx::GfxObjP GfxObjForSeqItem(SequenceItem* seq_item);  
-  std::map<SequenceItem*, gfx::EntityP>  obj_map_;
-  bool we_are_changing_the_selection_;
+  void InitActions();
+  void InitView();
+  void InitSearchBar();
+  void InitMenuBar();
+  void UpdateSearchBar();
+  void SelectList(const QModelIndexList& list);
+  QToolBar* toolbar_;
+  SeqSearchBar* seq_search_bar_;
+  SequenceModel* model_;
+  SequenceTableView* seq_table_view_;
+
+  ActionList action_list_;
+
+  QActionGroup* display_mode_actions_;
+
+private slots:
+  void ChangeDisplayMode();
+  void FindInSequence();
+  void SelectionModelChanged(const QItemSelection&, const QItemSelection&);
+  void DoubleClicked(const QModelIndex& index);
+  void MouseWheelEvent(QWheelEvent* event);
+  void CopyEvent(QKeyEvent* event);
+
 };
- 
+
 }}
 
 #endif
diff --git a/modules/gui/src/sequence_viewer/sequence_viewer_base.cc b/modules/gui/src/sequence_viewer/sequence_viewer_base.cc
deleted file mode 100644
index 61cae9aac..000000000
--- a/modules/gui/src/sequence_viewer/sequence_viewer_base.cc
+++ /dev/null
@@ -1,237 +0,0 @@
-//------------------------------------------------------------------------------
-// This file is part of the OpenStructure project <www.openstructure.org>
-//
-// Copyright (C) 2008-2010 by the OpenStructure authors
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License as published by the Free
-// Software Foundation; either version 3.0 of the License, or (at your option)
-// any later version.
-// This library is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
-// details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this library; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-//------------------------------------------------------------------------------
-#include "sequence_viewer_base.hh"
-#include "sequence_search_bar.hh"
-#include <QShortcut>
-#include <QVBoxLayout>
-#include <QPainter>
-
-namespace ost { namespace gui {
-
-SequenceViewerBase::SequenceViewerBase(QWidget* parent):
-  Widget(NULL, parent),  style_(DENSE), sel_mode_(ROW),
-  scene_(new SequenceScene(this)), search_bar_(new SequenceSearchBar(this)),
-  view_(new QGraphicsView(NULL, this))
-{
-  QVBoxLayout* l=new QVBoxLayout;
-  this->setLayout(l);
-  l->setMargin(0);
-  l->setSpacing(0);
-  view_->setScene(scene_);
-  l->addWidget(search_bar_, 0);  
-  l->addWidget(view_, 1);  
-  view_->setScene(scene_);
-  view_->setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing);
-  view_->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);  
-  QShortcut* shortcut=new QShortcut(QKeySequence(tr("Ctrl+F")), this);  
-  connect(shortcut, SIGNAL(activated()), this, SLOT(FindInSequence()));    
-  connect(search_bar_, SIGNAL(Changed(const QString&, bool, int)), this,
-          SLOT(OnSearchBarUpdate(const QString&, bool, int)));  
-  search_bar_->hide();
-  view_->setAlignment(Qt::AlignLeft|Qt::AlignTop);
-}
-
-namespace {
-  
-size_t update_select_state(seq::SequenceHandle seq, const String& subject,
-                           std::vector<bool>& sel_state)
-{
-  size_t pos=0;
-  size_t first=String::npos;
-  String seq_str=seq.GetString();
-  while ((pos=seq_str.find(subject, pos))!=String::npos) {
-    if (first==String::npos) {
-      first=pos;
-    }
-    std::fill_n(sel_state.begin()+pos, subject.length(), true);
-    pos+=subject.length();
-  }
-  return first;
-}
-
-
-void set_sel(std::vector<bool>& selected, SequenceItem* item)
-{
-  std::vector<bool>::iterator c=selected.begin();
-  item->ClearSelection();
-  while (c!=selected.end()) {
-    std::vector<bool>::iterator e=c;
-    while ((*(++e))==*c && e!=selected.end()) {}
-    if (*c) {
-      // this is really ugly!
-      item->BeginSelectionChange();      
-      item->Select(c-selected.begin(), e-selected.begin(), false);
-    }
-    c=e;
-  }
-  item->EndSelectionChange();
-}
-
-}
-
-void SequenceViewerBase::FindInSequence()
-{
-  if (scene_->GetSequences().empty()) {
-    return;
-  }
-  search_bar_->Show(scene_->GetSequences());
-}
-
-int SequenceViewerBase::GetLongestSequenceLength() const
-{
-  std::vector<SequenceItem*>::iterator i=scene_->GetSequences().begin(),
-                                       e=scene_->GetSequences().end();  
-  int longest=0;
-  for (; i!=e; ++i) {
-    longest=std::max(longest, (*i)->GetSequence().GetLength());
-  }
-  return longest;
-}
-
-void SequenceViewerBase::SelectColumns(std::vector<bool>& selected_cols)
-{
-  std::vector<SequenceItem*>::iterator i=scene_->GetSequences().begin(),
-                                       e=scene_->GetSequences().end();
-  for (; i!=e; ++i) {
-    set_sel(selected_cols, *i);
-  }
-}
-
-void SequenceViewerBase::SelectColumns(SequenceItem* seq_item,
-                                       std::vector<bool>& selected_cols)
-{
-  set_sel(selected_cols, seq_item);
-}
-
-void SequenceViewerBase::ClearSelection()
-{
-  std::vector<SequenceItem*>::iterator i=scene_->GetSequences().begin(),
-                                       e=scene_->GetSequences().end();
-  for (; i!=e; ++i) {
-    (*i)->ClearSelection();
-  }
-}
-
-void SequenceViewerBase::OnSearchBarUpdate(const QString& subject, 
-                                           bool search_in_all, int seq_id)
-{
-  String std_subj=subject.toStdString();
-  this->ClearSelection();  
-  if (scene_->GetSequences().empty() || (seq_id==-1 && !search_in_all)) {
-    return;
-  }  
-  if (subject.size()==0) {
-    return;
-  }  
-  
-  std::vector<bool> selected;
-  selected.resize(GetLongestSequenceLength(), false);
-  /// \todo implement selection for SelMode==COLUMN
-  std::pair<int, size_t> first(0, String::npos);
-  if (search_in_all) {
-    for (size_t i=0; i<scene_->GetSequences().size(); ++i) {
-      (scene_->GetSequences())[i]->ClearSelection();
-      seq::SequenceHandle s=(scene_->GetSequences())[i]->GetSequence();
-      size_t pos=update_select_state(s, std_subj, selected);
-      if (pos!=String::npos && first.second==String::npos) {
-        first.second=pos;
-        first.first=i;
-      }
-      if (sel_mode_==ROW) {
-        set_sel(selected, (scene_->GetSequences())[i]); 
-        std::fill_n(selected.begin(), selected.size(), false);        
-      }
-    }
-  } else {
-    first.first=seq_id;
-    SequenceItem* s=(scene_->GetSequences())[seq_id];
-    size_t pos=update_select_state(s->GetSequence(), std_subj, selected);
-    if (pos!=String::npos) {
-      first.second=pos;
-    }
-    if (sel_mode_==ROW) {
-      set_sel(selected, s);
-    }
-  } 
-  if (sel_mode_==COLUMN) {
-    this->SelectColumns(selected);
-  }
-  if (first.second!=String::npos) {
-    QRectF r=(scene_->GetSequences()[first.first]->GetCharBounds(first.second));
-
-    view_->ensureVisible(r);
-  }
-  scene_->update();
-}
-
-void SequenceViewerBase::SetDisplayStyle(Style style)
-{
-  style_=style;
-  for (std::vector<SequenceItem*>::iterator i=scene_->GetSequences().begin(),
-       e=scene_->GetSequences().end(); i!=e; ++i) {
-    (*i)->SetShowSecStructure(style_==LOOSE);
-  }
-  scene_->RepackSequences();
-}
-
-void SequenceViewerBase::SetSelMode(SelMode mode)
-{
-  sel_mode_=mode;
-}
-
-SequenceViewerBase::SelMode SequenceViewerBase::GetSelMode() const
-{
-  return sel_mode_;
-}
-
-SequenceViewerBase::Style SequenceViewerBase::GetDisplayStyle() const
-{
-  return style_;
-}
-
-void SequenceViewerBase::AddSequence(SequenceItem* seq)
-{
-  seq->SetShowSecStructure(style_==LOOSE);
-  scene_->AddSequence(seq);
-  QRectF rect=scene_->itemsBoundingRect();
-  view_->setSceneRect(QRectF(0, 0, +rect.left()+rect.width(), 
-                             rect.height()+rect.top()));
-}
-
-void SequenceViewerBase::RemoveSequence(SequenceItem* seq)
-{
-  scene_->RemoveSequence(seq);
-}
-
-void SequenceViewerBase::Clear()
-{
-
-}
-
-bool SequenceViewerBase::Restore(const QString& prefix)
-{
-  return true;
-}
-
-bool SequenceViewerBase::Save(const QString& prefix)
-{
-  return true;
-}
-
-}}
diff --git a/modules/gui/src/sequence_viewer/sequence_viewer_base.hh b/modules/gui/src/sequence_viewer/sequence_viewer_base.hh
deleted file mode 100644
index 6bc183765..000000000
--- a/modules/gui/src/sequence_viewer/sequence_viewer_base.hh
+++ /dev/null
@@ -1,99 +0,0 @@
-//------------------------------------------------------------------------------
-// This file is part of the OpenStructure project <www.openstructure.org>
-//
-// Copyright (C) 2008-2010 by the OpenStructure authors
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License as published by the Free
-// Software Foundation; either version 3.0 of the License, or (at your option)
-// any later version.
-// This library is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
-// details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this library; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-//------------------------------------------------------------------------------
-#ifndef OST_GUI_SEQUENCE_VIEWER_BASE_HH
-#define OST_GUI_SEQUENCE_VIEWER_BASE_HH
-/*
-  Author: Marco Biasini
- */
-
-#include <ost/gui/sequence_viewer/sequence_item.hh>
-#include <ost/gui/sequence_viewer/sequence_scene.hh>
-
-#include <ost/gui/widget.hh>
-
-#include <QGraphicsView>
-
-namespace ost { namespace gui {
-
-class SequenceSearchBar;
-
-/// \brief base class for sequence viewers
-/// 
-/// subclassed by AlignmentViewer and SequenceViewer
-class DLLEXPORT_OST_GUI SequenceViewerBase : public Widget {
-  Q_OBJECT
-public:
-  typedef enum {
-    DENSE,
-    LOOSE,
-  } Style;
-  
-  typedef enum {
-    COLUMN,
-    ROW
-  } SelMode;
-public:
-  SequenceViewerBase(QWidget* parent=NULL);
-  void SetDisplayStyle(Style style);
-  
-  void SetSelMode(SelMode mode);
-  
-  SelMode GetSelMode() const;
-  Style GetDisplayStyle() const;
-  
-  /// \brief add sequence
-  /// 
-  /// issue: should we copy the sequence object to avoid weird side-effects?
-  void AddSequence(SequenceItem* seq);
-  
-  /// \brief remove sequence
-  void RemoveSequence(SequenceItem* seq);
-  
-  /// \brief select columns in all sequences
-  void SelectColumns(std::vector<bool>& selected_cols);
-  
-  /// \brief select columns in sequence
-  void SelectColumns(SequenceItem* seq, std::vector<bool>& selected_cols);
-  /// \brief get length of longest sequence including gaps
-  int GetLongestSequenceLength() const;
-  /// \brief remove all sequences
-  void Clear();
-
-  virtual bool Restore(const QString& prefix);
-  virtual bool Save(const QString& prefix);
-public slots:
-  /// \brief clear selection
-  void ClearSelection();
-  
-  /// \internal
-  void OnSearchBarUpdate(const QString&, bool, int);
-  
-  /// \brief show sequence search bar
-  void FindInSequence();
-
-private:
-  Style               style_;  
-  SelMode             sel_mode_;
-  SequenceScene*      scene_;
-  SequenceSearchBar*  search_bar_;  
-  QGraphicsView*      view_;
-};
-
-}}
-#endif
diff --git a/modules/gui/src/sequence/tick_painter.cc b/modules/gui/src/sequence_viewer/tick_painter.cc
similarity index 100%
rename from modules/gui/src/sequence/tick_painter.cc
rename to modules/gui/src/sequence_viewer/tick_painter.cc
diff --git a/modules/gui/src/sequence/tick_painter.hh b/modules/gui/src/sequence_viewer/tick_painter.hh
similarity index 100%
rename from modules/gui/src/sequence/tick_painter.hh
rename to modules/gui/src/sequence_viewer/tick_painter.hh
diff --git a/modules/gui/src/sequence/title_row.cc b/modules/gui/src/sequence_viewer/title_row.cc
similarity index 89%
rename from modules/gui/src/sequence/title_row.cc
rename to modules/gui/src/sequence_viewer/title_row.cc
index 39013b3d7..727aa0239 100644
--- a/modules/gui/src/sequence/title_row.cc
+++ b/modules/gui/src/sequence_viewer/title_row.cc
@@ -77,10 +77,11 @@ Qt::ItemFlags TitleRow::Flags(int column) const
 void TitleRow::DoubleClicked(int column)
 {
  if(this->parent()){
-   SequenceModel* model = qobject_cast<SequenceModel*>(this->parent()->parent());
-   int rows = model->rowCount()-1;
-   QItemSelection add = QItemSelection(model->index(1,column),model->index(rows,column));
-   model->SelectionChanged(add,QItemSelection());
+   if(SequenceModel* model = qobject_cast<SequenceModel*>(this->parent()->parent())){
+     int rows = model->rowCount()-1;
+     QItemSelection add = QItemSelection(model->index(1,column),model->index(rows,column));
+     model->SelectionChanged(add,QItemSelection());
+   }
  }
 }
 
diff --git a/modules/gui/src/sequence/title_row.hh b/modules/gui/src/sequence_viewer/title_row.hh
similarity index 100%
rename from modules/gui/src/sequence/title_row.hh
rename to modules/gui/src/sequence_viewer/title_row.hh
diff --git a/modules/img/alg/doc/alg.rst b/modules/img/alg/doc/alg.rst
new file mode 100644
index 000000000..3e0f673de
--- /dev/null
+++ b/modules/img/alg/doc/alg.rst
@@ -0,0 +1,67 @@
+:mod:`~ost.img.alg` - Image Processing Algorithms
+================================================================================
+
+.. module:: ost.img.alg
+  :synopsis: Image processing algorithms
+  
+Usage of Image Algorithms
+--------------------------------------------------------------------------------
+
+Image algorithms are objects. To execute them, the algorithms are applied to an 
+image by passing it to the :meth:`ost.img.ImageHandle.Apply` or 
+:meth:`ost.img.ImageHandle.ApplyIP` method:
+
+.. code-block:: python
+  
+  image=img.CreateImage(img.Size(200, 200))
+  fft_image=image.Apply(img.alg.FFT())
+  image.ApplyIP(img.alg.FFT())
+  
+  
+.. class:: FFT
+
+  Fast Fourier Transforms the image. The FFT algorithms is aware of the 
+  image's domain. The following rules apply:
+  
+   * SPATIAL -> HALF_FREQUENCY
+   * HALF_FREQUENCY -> SPATIAL
+   * FREQUENCY -> COMPLEX_SPATIAL
+   * COMPLEX_SPATIAL -> FREQUENCY
+
+.. class:: GaussianFilter(sigma=1.0)
+
+  Applies a gaussian filter to the supplied image. Sigma is given in pixels.
+
+  Implemented after I.T.Young, L.J. van Vliet,"Recursive implementation of the
+  Gaussian filter", Signal Processing, 44(1995), 139-151
+
+Filters in Fourier Space
+--------------------------------------------------------------------------------
+
+The following filters operate in Fourier Space. If the image they are applied on is in spatial domain, they will first be converted to frequency domain and then converted back after the filter has been applied.
+  
+.. class:: LowpassFilter(freq_limit)
+
+  Filters an image by masking out frequencies higher than
+  `freg_limit`.
+
+  .. method:: GetLimit()
+    
+    Returns the frequency limit
+    
+  .. method:: SetLimit(freq)
+    
+    Set the frequency limit
+    
+.. class:: HighpassFilter
+ 
+  Filters an image by masking out frequences lower than `freq_limit`
+  
+  .. method:: GetLimit()
+    
+    Returns the frequency limit
+    
+  .. method:: SetLimit(freq)
+    
+    Set the frequency limit
+  
\ No newline at end of file
diff --git a/modules/img/alg/src/highest_peak_search_3d.cc b/modules/img/alg/src/highest_peak_search_3d.cc
index aaedb0994..eeedd054f 100644
--- a/modules/img/alg/src/highest_peak_search_3d.cc
+++ b/modules/img/alg/src/highest_peak_search_3d.cc
@@ -74,42 +74,43 @@ namespace detail {
         bool insert=true;
         bool remove_smaller=false;
         img::PeakList::iterator min_it;
+
         if(!list_.empty()) {
           min_it = list_.begin();
-        }
 
-        for(img::PeakList::iterator it=list_.begin();it!=list_.end();++it)
-        {
-          if(it->GetValue() < min_it->GetValue()) min_it = it;
-          if (it->GetValue() >= cand_peak.GetValue() && detail::is_within(cand_peak, *it, exclusion_radius_)) {
-            insert=false;
-          } else if (cand_peak.GetValue() >= it->GetValue() && detail::is_within(cand_peak, *it, exclusion_radius_)) {
-            remove_smaller=true;
+          for(img::PeakList::iterator it=list_.begin();it!=list_.end();++it)
+          {
+            if(it->GetValue() < min_it->GetValue()) min_it = it;
+            if (it->GetValue() >= cand_peak.GetValue() && detail::is_within(cand_peak, *it, exclusion_radius_)) {
+              insert=false;
+            } else if (cand_peak.GetValue() >= it->GetValue() && detail::is_within(cand_peak, *it, exclusion_radius_)) {
+              remove_smaller=true;
+            }
           }
-        }
 
-        if (!insert) return false;
+          if (!insert) return false;
 
-        if (cand_peak.GetValue() < min_it->GetValue()) {
-          return false;
-        }
+          if (cand_peak.GetValue() < min_it->GetValue()) {
+            return false;
+          }
 
-        if (remove_smaller)
-        {
-          img::PeakList::iterator new_end = remove_if(list_.begin(),list_.end(),
-          detail::is_smaller_and_within_radius(cand_peak,exclusion_radius_));
-          list_.erase(new_end,list_.end());
-        }
+          if (remove_smaller)
+          {
+            img::PeakList::iterator new_end = remove_if(list_.begin(),list_.end(),
+            detail::is_smaller_and_within_radius(cand_peak,exclusion_radius_));
+            list_.erase(new_end,list_.end());
+          }
 
-        if (list_.size() == max_num_peaks_) {
-          list_.erase(min_it);
+          if (list_.size() == max_num_peaks_) {
+            list_.erase(min_it);
+          }
         }
 
         list_.push_back(cand_peak);
         return true;
       }
 
-      //! Gets list of peaks from collector
+       //! Gets list of peaks from collector
       img::PeakList GetPeakList() const { return list_; }
 
       //! Clears the peak list removing all peaks in the list
@@ -117,7 +118,7 @@ namespace detail {
 
     private:
 
-      img::PeakList list_;
+      img::PeakList list_;      
       unsigned int max_num_peaks_;
       int exclusion_radius_;
 
@@ -133,8 +134,13 @@ template <typename T, class D>
     LOG_VERBOSE(" max number of peaks: " << max_num_peaks_ << std::endl);
     LOG_VERBOSE(" exclusion radius: " << exclusion_radius_ << std::endl);
     LOG_VERBOSE(" threshold: " << threshold_ << std::endl);
- 
-    if(ext_list_.size()==0) 
+
+    if (max_num_peaks_ < 1)
+    {
+      throw Error("Error: Maximum number of peaks smaller than 1. Cannot create peak list");
+    }
+
+    if(ext_list_.size()==0)
     {
       LOG_VERBOSE(" excluded regions: none" << std::endl);
     } 
diff --git a/modules/img/alg/src/histogram.hh b/modules/img/alg/src/histogram.hh
index f974247da..7805d40fc 100644
--- a/modules/img/alg/src/histogram.hh
+++ b/modules/img/alg/src/histogram.hh
@@ -17,6 +17,8 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
+#ifndef OST_IMG_ALG_HISTOGRAM_HH
+#define OST_IMG_ALG_HISTOGRAM_HH
 
 /*
   Author: Ansgar Philippsen
@@ -75,3 +77,5 @@ typedef ImageStateNonModAlgorithm<HistogramBase> Histogram;
 OST_IMG_ALG_EXPLICIT_INST_DECL(class,ImageStateNonModAlgorithm<alg::HistogramBase>)
 
 }} // namespaces
+
+#endif
diff --git a/modules/img/alg/tests/test_discrete_shrink.cc b/modules/img/alg/tests/test_discrete_shrink.cc
index 30be5ab06..337a15736 100644
--- a/modules/img/alg/tests/test_discrete_shrink.cc
+++ b/modules/img/alg/tests/test_discrete_shrink.cc
@@ -53,7 +53,7 @@ void test()
       h.GetReal(p2+Point(1,0))+
       h.GetReal(p2+Point(0,1))+
       h.GetReal(p2+Point(1,1)));
-    BOOST_CHECK(std::fabs(sm-rh.GetReal(it))<1e-10);
+    BOOST_CHECK_SMALL(Real(std::fabs(sm-rh.GetReal(it))),Real(1e-7));
   }
   
 }
diff --git a/modules/img/alg/tests/test_filter.cc b/modules/img/alg/tests/test_filter.cc
index d64b26038..400bc1bd4 100644
--- a/modules/img/alg/tests/test_filter.cc
+++ b/modules/img/alg/tests/test_filter.cc
@@ -21,8 +21,9 @@
 /*
   Author: Ansgar Philippsen
 */
-
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
+
 #include <iostream>
 #include <ost/img/image.hh>
 #include <ost/img/alg/filter.hh>
@@ -450,9 +451,9 @@ void FourierFiltersTest()
 }
 
 
-DLLEXPORT_IMG_ALG boost::unit_test::test_suite::test_suite* init_unit_test_suite( int argc, char* argv[] )
+boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
 {
-    boost::unit_test::test_suite::test_suite* test = BOOST_TEST_SUITE( "FiltersTest" );
+    boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "FiltersTest" );
 
     test->add( BOOST_TEST_CASE( &LineIterator1DTest ) );
     test->add( BOOST_TEST_CASE( &LineIterator2DTest ) );
diff --git a/modules/img/alg/tests/test_utils.hh b/modules/img/alg/tests/test_utils.hh
index 0eb527642..26687e164 100644
--- a/modules/img/alg/tests/test_utils.hh
+++ b/modules/img/alg/tests/test_utils.hh
@@ -27,7 +27,8 @@
 
 #include <iostream>
 
-#include <boost/test/test_tools.hpp>
+#define BOOST_TEST_DYN_LINK
+#include <boost/test/unit_test.hpp>
 
 //#include <img/base.hh>
 #include <ost/img/image_state.hh>
diff --git a/modules/img/alg/tests/tests.hh b/modules/img/alg/tests/tests.hh
index 46ff55ebf..97b66c8a9 100644
--- a/modules/img/alg/tests/tests.hh
+++ b/modules/img/alg/tests/tests.hh
@@ -22,5 +22,6 @@
   Author: Ansgar Philippsen
 */
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
diff --git a/modules/img/base/doc/img.rst b/modules/img/base/doc/img.rst
new file mode 100644
index 000000000..53243c904
--- /dev/null
+++ b/modules/img/base/doc/img.rst
@@ -0,0 +1,186 @@
+:mod:`~ost.img` Images and Density Maps
+================================================================================
+  
+.. module:: ost.img
+   :synopsis: Images and density maps
+              
+Introduction : The ImageHandle
+--------------------------------------------------------------------------------
+
+OpenStructure offers extensive processing capabilities for planar 2d images and
+3d maps using the img module. Images are manipulated through the use of
+dox[ost::img::ImageHandle|ImageHandles].
+
+ImageHandles provide a clean and efficient interface to interact with images and 
+maps. An :class:`ImageHandle` can store an image in either real ('SPATIAL') or 
+Fourier ('FREQUENCY') space and always keep track of the currently active 
+domain. This means,for example that one can apply a Fourier Transformation to an 
+ImageHandle containing a 'SPATIAL' image and the ImageHandle will correctly 
+identify the new active domain as 'FREQUENCY'. The ImageHandle also understands, 
+for example, that applying a Fourier Transform to a centrosymmetric 'FREQUENCY' 
+image results in a real 'SPATIAL' image, but applying it to a 
+non-centrosymmetric one results in a complex 'SPATIAL' image.
+
+Furthermore, the ImageHandle will make sure that real and Fourier space 
+information about the image are always in sync. If, for example, the pixel 
+sampling is changed while the current active domain is real space, the pixel 
+sampling in Fourier space will be adjusted accordingly, and vice versa.
+
+Moreover, the ImageHandle allows the extraction of both complex and real numeric 
+values from images in any active domain. If the domain is complex in nature, but 
+a real numeric value is requested, the amplitude of the complex number will be 
+returned. If the numerical nature of the domain is real and a complex number is 
+requested, the complex part will be set to 0.
+
+Creating  and visualizing ImageHandles
+--------------------------------------------------------------------------------
+As a first step, enter the following lines in the OpenStructure python console:
+
+  .. code-block:: python
+  
+    im=img.CreateImage(img.Size(200,200))
+
+This will create an empty, 2D image, with a height and width of 200 pixels, whose
+origin (ie the pixel with the coordinates <0,0>) is in the top-left corner.
+
+  .. code-block:: python
+  
+    v=gui.CreateDataViewer(im)
+
+A viewer window will pop up (see below), showing a white frame on a black background.
+The inner area of the white frame is the image, which is empty.
+
+Reading and writing into an image
+-------------------------------------------------------------------------------
+
+Data can be read and written from and into an image using the following commands:
+
+  .. code-block:: python
+  
+    # writes the real value 23.4 into pixel 10,10
+    im.SetReal(img.Point(10,10),23.4)
+    # reads the value in pixel 10,10
+    val=im.GetReal(img.Point(10,10))
+    
+The complex equivalents are also available    
+
+  .. code-block:: python
+  
+    # writes the complex value value 2+3j into pixel 10,10
+    im.SetComplex(img.Point(10,10),2+3j)
+    # reads the value in pixel 10,10
+    val=im.GetComplex(img.Point(10,10))
+
+The image knows in which domain it is, and will adjust the type of data being written
+accordingly. For example, if one writes a complex value in a 'SPATIAL' image, the value
+will be automatically converted to a real one by taking the amplitude of the complex number
+On the other hand, if one writes a real value in a 'FREQUENCY' image, the value is automatically
+converted to complex by setting the imaginary part to 0.
+
+## Applying algorithms
+
+Let us fill the image with random values.
+
+  .. code-block:: python
+  
+    rand_alg = img.alg.Randomize() # create algorithm object
+    im.ApplyIP( rand_alg ) # apply algorithm object in-place
+
+As you can see, applying an algorithm is conceptually a two-step process. First,
+an instance of an algorithm class is created, yielding an algorithm object (in 
+this case 'rand\_alg'). In a second step, the algorithm object is applied to an 
+image, either in-place, modifying the image, or out-of-place, leaving the 
+original image untouched, and returning the result as a new image. Note that the 
+in-place/out-of-place logic is decoupled from the algorithm object.
+
+Now that we have some (noisy) data present, let us run another algorithm, this 
+time a Gaussian filter with a sigma of 4 pixel.
+
+  .. code-block:: python
+  
+    im.ApplyIP( img.alg.GaussianFilter(4.0) ) # apply temporary algorithm object in-place
+
+As you can see, it is not always necessary to create an independent algorithm 
+instance first, in many cases a temporary object will suffice (this applies to 
+the randomization algorithm as well, 'im.ApplyIP(alg.Randomize())' would have 
+been fine). However, when used this way, the algorithm class will cease to exist 
+as soon as the algorithm is applied. This can be important if the algorithm 
+stores some values that need to be recovered later. For example:
+
+  .. code-block:: python
+  
+    stat=img.alg.Stat()
+    im.ApplyIP(stat)
+    mean=stat.GetMean()
+    
+Algorithms are stateful objects and can store values. The 'Stat' algorithm 
+computes basic statistics about the image it is applied on (maximum and minimum 
+values, standard deviations, etc). The data are stored within the algorithm 
+instance and can be recovered using the algorithm's methods. It would obviously 
+make very little sense not to create an instance of the 'Stat' algorithm. When 
+the algorithms ceases to exist, all information would be lost.
+
+Applying a Fourier Transform
+--------------------------------------------------------------------------------
+
+An image is Fourier-transformed using the 'img.alg.FFT()' algorithm object:
+
+  .. code-block:: python
+  
+    im=io.LoadImage("imagename.tif") # load the image
+    # create an instance of the fft algorithm object
+    fft=img.alg.FFT() 
+    # do the actual Fourier transformation
+    im_ft=im.Apply(fft) 
+    # back-transform
+    im2 = im_ft.Apply(fft) 
+    # if this is run from within the dng graphical frontend, open viewers to
+    # look at the images
+    gui.CreateDataViewer(im)
+    gui.CreateDataViewer(im_ft)
+    gui.CreateDataViewer(im2)
+ 
+It is not really necessary to use the 'fft' variable to store the 'im.alg.FFT()' 
+instance, a temporary object can be used, since the 'FFT' algorithm object is stateless. In addition, the algorithm can be applied in-place to avoid the 
+creation of a second image:
+
+  .. code-block:: python
+  
+    im=io.LoadImage("imagename.tif") # load the image
+    # do the actual Fourier transformation, in-place using temporary object
+    im.ApplyIP(alg.FFT()) 
+    # repeating this command will do the back-transform
+    im.ApplyIP(alg.FFT()) 
+
+As said before, the 'alg.FFT()' algorithm does not require a direction to be given, this is implicitly
+determined by the active domain of the underlying image state: a 'SPATIAL' image will always be
+transformed to the 'FREQUENCY' domain, and vice-versa.
+
+Extracting and Pasting Images
+--------------------------------------------------------------------------------
+
+An image can be extracted and pasted into another image using the 'Extract()' 
+and 'Paste()' member functions:
+
+  .. code-block:: python
+  
+    # load the image
+    im=io.LoadImage("imagename.tif")
+    # generate a subimage from the region going from (10,10) to (30,30)
+    im2=im.Extract(img.Extent(img.Point(10,10),img.Point(30,30)))
+    # generate an empty image with the same size as the original image
+    im3=img.CreateImage(im.GetExtent())
+    # paste the subimage into the empty image
+    im3.Paste(im2)
+
+Note that the extent is fully honored for the paste operation, i.e. only the
+region where the pasted-to and the pasted-in image overlap will be affected.
+
+
+
+  ..
+     |                                                   |                                                                     |                                                                          |
+     |:-------------------------------------------------:|:-------------------------------------------------------------------:|:------------------------------------------------------------------------:|
+     |![Empty Image] (docs/tut/dv1.jpg "Empty Image")    | ![After Randomization] (docs/tut/dv2.jpg "After Randomization")     | ![After Gaussian Filtering] (docs/tut/dv3.jpg "After Randomization")  |
+     |Empty Image                                        | After Randomization                                                 | After Gaussian Filtering                                                 |
+     
\ No newline at end of file
diff --git a/modules/img/base/pymod/export_mask.cc b/modules/img/base/pymod/export_mask.cc
index 6db4cf05e..3385d8ffc 100644
--- a/modules/img/base/pymod/export_mask.cc
+++ b/modules/img/base/pymod/export_mask.cc
@@ -26,6 +26,7 @@
 using namespace boost::python;
 
 #include <ost/img/mask.hh>
+#include <ost/img/mask_info_convert.hh>
 
 namespace ost { namespace img {
 
@@ -100,5 +101,7 @@ void export_Mask()
   def("Mask",mask2);
   def("Mask",mask3);
   def("Mask",mask4);
+  def("InfoToMask",InfoToMask);
+  def("MaskToInfo",MaskToInfo);
 
 }
diff --git a/modules/img/base/src/CMakeLists.txt b/modules/img/base/src/CMakeLists.txt
index 0d0e7e47a..97ea2ed0b 100644
--- a/modules/img/base/src/CMakeLists.txt
+++ b/modules/img/base/src/CMakeLists.txt
@@ -29,6 +29,7 @@ extent_mask.cc
 spherical_mask.cc
 mask_op.cc
 circle_mask.cc
+mask_info_convert.cc
 image_list.cc
 physical_units.cc
 progress.cc
@@ -86,6 +87,7 @@ spherical_mask.hh
 mask_op.hh
 mask.hh
 circle_mask.hh
+mask_info_convert.hh
 image_list.hh
 physical_units.hh
 progress.hh
@@ -105,4 +107,4 @@ module(NAME img SOURCES "${OST_IMG_SOURCES}"
        HEADERS ${OST_IMG_RASTER_IMAGE_HEADERS} IN_DIR raster_image
                 ${OST_IMG_IMAGE_STATE_HEADERS} IN_DIR image_state
                 ${OST_IMG_HEADERS}
-       DEPENDS_ON geom base)
+       DEPENDS_ON geom base info)
diff --git a/modules/img/base/src/function_base.hh b/modules/img/base/src/function_base.hh
index efb654bd2..6360ac36b 100644
--- a/modules/img/base/src/function_base.hh
+++ b/modules/img/base/src/function_base.hh
@@ -27,6 +27,7 @@
 #ifndef IMG_FUNCTION_BASE_H
 #define IMG_FUNCTION_BASE_H
 
+#include "module_config.hh"
 #include "data.hh"
 #include "data_observer.hh"
 #include "observable.hh"
diff --git a/modules/img/base/src/image_state/image_state_impl.cc b/modules/img/base/src/image_state/image_state_impl.cc
index 190728a10..020d21651 100644
--- a/modules/img/base/src/image_state/image_state_impl.cc
+++ b/modules/img/base/src/image_state/image_state_impl.cc
@@ -72,7 +72,8 @@ template <typename T, class D>
 ImageStateImpl<T,D>::ImageStateImpl(const ImageStateImpl<T,D>& s):
   domain_(s.domain_),
   data_(s.data_),
-  sampling_(s.sampling_)
+  sampling_(s.sampling_),
+  absolute_origin_(s.absolute_origin_)
 {
   sampling_.SetDomain(domain_.GetDomain());
 }
@@ -85,6 +86,7 @@ ImageStateImpl<T,D>& ImageStateImpl<T,D>::operator=(const ImageStateImpl<T,D>& s
     domain_=s.domain_;
     data_=s.data_; // copy
     sampling_=s.sampling_;
+    absolute_origin_=s.absolute_origin_;
     sampling_.SetDomain(domain_.GetDomain());
   }
   return *this;
diff --git a/modules/img/base/src/image_state/image_state_visitor.hh b/modules/img/base/src/image_state/image_state_visitor.hh
index 7fc7c7e50..408941d9c 100644
--- a/modules/img/base/src/image_state/image_state_visitor.hh
+++ b/modules/img/base/src/image_state/image_state_visitor.hh
@@ -299,7 +299,7 @@ public:
   See also common algorithms, e.g. img::alg::Stat
 */
 template <class FNC>
-class DLLEXPORT_OST_IMG_BASE ImageStateNonModVisitor: public FNC, public ImageStateNonModVisitorBase {
+class DLLEXPORT ImageStateNonModVisitor: public FNC, public ImageStateNonModVisitorBase {
 public:
   
   IMAGE_STATE_VISITOR_CTOR_ADAPTERS(ImageStateNonModVisitor)
@@ -354,7 +354,7 @@ public:
 
 */
 template <class FNC>
-class DLLEXPORT_OST_IMG_BASE ImageStateModIPVisitor: public FNC, public ImageStateModIPVisitorBase {
+class DLLEXPORT ImageStateModIPVisitor: public FNC, public ImageStateModIPVisitorBase {
 public:
   IMAGE_STATE_VISITOR_CTOR_ADAPTERS(ImageStateModIPVisitor)
 
@@ -461,7 +461,7 @@ public:
 
 */
 template <class FNC>
-class DLLEXPORT_OST_IMG_BASE ImageStateModOPVisitor: public FNC, public ImageStateModOPVisitorBase {
+class DLLEXPORT ImageStateModOPVisitor: public FNC, public ImageStateModOPVisitorBase {
 public:
 
   IMAGE_STATE_VISITOR_CTOR_ADAPTERS(ImageStateModOPVisitor)
diff --git a/modules/img/base/src/mask_info_convert.cc b/modules/img/base/src/mask_info_convert.cc
new file mode 100644
index 000000000..de40f80a4
--- /dev/null
+++ b/modules/img/base/src/mask_info_convert.cc
@@ -0,0 +1,227 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+// Copyright (C) 2003-2010 by the IPLT authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+/*
+  Authors: Andreas Schenk, Ansgar Philippsen
+*/
+
+#include <stack>
+
+#include <ost/info/info_visitor.hh>
+#include <ost/info/info.hh>
+#include "mask_info_convert.hh"
+#include "polygon_mask.hh"
+#include "circle_mask.hh"
+#include "extent_mask.hh"
+#include "composite_mask.hh"
+#include "inverted_mask.hh"
+#include "spherical_mask.hh"
+#include "mask_visitor.hh"
+
+namespace ost{ namespace img {
+
+namespace {
+
+
+
+class PolygonInfoVisitor: public info::InfoConstVisitor
+{
+public:
+  PolygonInfoVisitor():
+    p_()
+  {}
+
+  Polygon2 GetPolygon() const {return p_;}
+
+  virtual bool VisitGroup(const info::InfoGroup& group)
+  {
+    if(group.GetName()=="Polygon"){
+      return true;
+    } else if(group.GetName()=="Node"){
+      p_.AddNode(geom::Vec2(group.GetItem("x").AsFloat(),
+			    group.GetItem("y").AsFloat()));
+      return false;
+    }
+    return true;
+  }
+
+  virtual void VisitGroupFinish(const info::InfoGroup& group)
+  {}
+
+private:
+  Polygon2 p_;  
+};
+
+// this is used recursively
+class MaskInfoVisitor: public info::InfoConstVisitor
+{
+public:
+  MaskInfoVisitor():
+    mask_list_()
+  {}
+
+  std::vector<MaskPtr> GetMaskList() const {return mask_list_;}
+
+  virtual bool VisitGroup(const info::InfoGroup& group) 
+  {
+    String name=group.GetName();
+    if(name=="Composite"){
+      String opname=group.GetItem("Operator").GetValue();
+      MaskInfoVisitor miv;
+      group.Apply(miv,false); // subgroups
+      std::vector<MaskPtr> mpl = miv.GetMaskList();
+      mask_list_.push_back(MaskPtr(new CompositeMask(mpl[0],mpl[1],opname)));
+      return false;
+    }else if(name=="Invert"){
+      MaskInfoVisitor miv;
+      group.Apply(miv,false); // subgroups
+      std::vector<MaskPtr> mpl = miv.GetMaskList();
+      mask_list_.push_back(MaskPtr(new InvertedMask(mpl[0])));
+      return false;
+    }else if(name=="Circle"){
+      Circle2 c;
+      c.SetRadius(group.GetItem("Radius").AsFloat());
+      c.SetCenter(geom::Vec2(group.GetItem("Center/x").AsFloat(),
+			     group.GetItem("Center/y").AsFloat()));
+      mask_list_.push_back(MaskPtr(new CircleMask(c)));
+      return false;
+    }else if(name=="Polygon"){
+      PolygonInfoVisitor pvis;
+      group.Apply(pvis);
+      mask_list_.push_back(MaskPtr(new PolygonMask(pvis.GetPolygon())));
+      return false;
+    }else if(name=="Extent"){
+      Extent e(Point(group.GetItem("Start/x").AsInt(),
+		     group.GetItem("Start/y").AsInt()),
+	       Point(group.GetItem("End/x").AsInt(),
+		     group.GetItem("End/y").AsInt()));
+      mask_list_.push_back(MaskPtr(new ExtentMask(e)));
+      return false;
+    }else if(name=="Sphere"){
+      Sphere s;
+      s.SetRadius(group.GetItem("Radius").AsFloat());
+      s.SetOrigin(geom::Vec3(group.GetItem("Origin/x").AsFloat(),
+			     group.GetItem("Origin/y").AsFloat(),
+			     group.GetItem("Origin/z").AsFloat()));
+      mask_list_.push_back(MaskPtr(new SphericalMask(s)));
+      return false;
+    }
+    return true;    
+  }
+
+  virtual void VisitGroupFinish(const info::InfoGroup& group)
+  {
+  }
+
+private:
+  std::vector<MaskPtr> mask_list_;
+};
+
+
+// mask visitor for mask->info conversion
+class MaskToInfoVisitor: public MaskVisitor
+{
+  typedef std::stack<info::InfoGroup> InfoGroupStack;
+public:
+  MaskToInfoVisitor(info::InfoGroup& g):
+    igs_()
+  {
+    igs_.push(g);
+  }
+  virtual void VisitCircleMask(CircleMask& m) 
+  {
+    info::InfoGroup cg=igs_.top().CreateGroup("Circle");
+    info::InfoGroup centerg=cg.CreateGroup("Center");
+    centerg.CreateItem("x","").SetFloat(m.GetCenter()[0]);
+    centerg.CreateItem("y","").SetFloat(m.GetCenter()[1]);
+    cg.CreateItem("Radius","").SetFloat(m.GetRadius());
+  }
+  virtual void VisitCompositeMask(CompositeMask& m) 
+  {
+    info::InfoGroup compg=igs_.top().CreateGroup("Composite");
+    compg.CreateItem("Operator",m.GetOperatorName());
+    igs_.push(compg);
+  }
+  virtual void VisitCompositeMaskFinish(CompositeMask& m) 
+  {
+    igs_.pop();
+  }
+  virtual void VisitExtentMask(ExtentMask& m) 
+  {
+    info::InfoGroup extg=igs_.top().CreateGroup("Extent");
+    info::InfoGroup startg=extg.CreateGroup("Start");
+    startg.CreateItem("x","").SetInt(m.GetStart()[0]);
+    startg.CreateItem("y","").SetInt(m.GetStart()[1]);
+    info::InfoGroup endg=extg.CreateGroup("End");
+    endg.CreateItem("x","").SetInt(m.GetEnd()[0]);
+    endg.CreateItem("y","").SetInt(m.GetEnd()[1]);
+  }
+  virtual void VisitInvertedMask(InvertedMask& m) 
+  {
+    info::InfoGroup invertg=igs_.top().CreateGroup("Invert");
+    igs_.push(invertg);
+  }
+  virtual void VisitInvertedMaskFinish(InvertedMask& m) 
+  {
+    igs_.pop();
+  }
+  virtual void VisitPolygonMask(PolygonMask& m) 
+  {
+    info::InfoGroup polyg=igs_.top().CreateGroup("Polygon");
+    for(unsigned int nn=0;nn<m.GetNodeCount();++nn) {
+      info::InfoGroup nodeg=polyg.CreateGroup("Node");
+      geom::Vec2 node=m.GetNode(nn);
+      nodeg.CreateItem("x","").SetFloat(node[0]);
+      nodeg.CreateItem("y","").SetFloat(node[1]);
+    }
+  }
+  virtual void VisitSphericalMask(SphericalMask& m) 
+  {
+    info::InfoGroup cg=igs_.top().CreateGroup("Sphere");
+    info::InfoGroup centerg=cg.CreateGroup("Origin");
+    centerg.CreateItem("x","").SetFloat(m.GetOrigin()[0]);
+    centerg.CreateItem("y","").SetFloat(m.GetOrigin()[1]);
+    centerg.CreateItem("z","").SetFloat(m.GetOrigin()[2]);
+    cg.CreateItem("Radius","").SetFloat(m.GetRadius());
+  }
+private:
+  InfoGroupStack igs_;
+};
+
+} // anon ns
+
+MaskPtr DLLEXPORT InfoToMask(const info::InfoGroup& g)
+{
+  MaskInfoVisitor vis;
+  g.Apply(vis);
+  std::vector<MaskPtr> mlist = vis.GetMaskList();
+  if(!mlist.empty()) {
+    return mlist[0];
+  }
+  return MaskPtr();
+}
+
+void MaskToInfo(const MaskPtr& mptr ,info::InfoGroup& g)
+{
+  MaskToInfoVisitor vis(g);
+  mptr->Apply(vis);
+}
+
+}} //ns
diff --git a/modules/img/base/src/mask_info_convert.hh b/modules/img/base/src/mask_info_convert.hh
new file mode 100644
index 000000000..04a01eac4
--- /dev/null
+++ b/modules/img/base/src/mask_info_convert.hh
@@ -0,0 +1,38 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+// Copyright (C) 2003-2010 by the IPLT authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+/*
+  Authors: Andreas Schenk, Ansgar Philippsen
+*/
+
+#ifndef MASK_INFO_CONVERT_HH_
+#define MASK_INFO_CONVERT_HH_
+
+#include <ost/info/info_group.hh>
+#include "mask_base_fw.hh"
+
+namespace ost { namespace img {
+
+MaskPtr DLLEXPORT InfoToMask(const info::InfoGroup& g);
+void DLLEXPORT MaskToInfo(const MaskPtr& mptr, info::InfoGroup& g);
+
+}} //ns
+
+#endif /*MASK_INFO_CONVERT_HH_*/
diff --git a/modules/img/base/src/null_function.hh b/modules/img/base/src/null_function.hh
index 29087c848..232438243 100644
--- a/modules/img/base/src/null_function.hh
+++ b/modules/img/base/src/null_function.hh
@@ -27,6 +27,7 @@
 #ifndef IMG_NULL_FUNCTION_H
 #define IMG_NULL_FUNCTION_H
 
+#include "module_config.hh"
 #include "function_base.hh"
 
 namespace ost { namespace img {
@@ -36,7 +37,7 @@ namespace ost { namespace img {
   Implements Function interface, will always
   return zero
 */
-class DLLEXPORT_OST_IMG_BASE NullFunction: public Function {
+class DLLEXPORT NullFunction: public Function {
 public:
   NullFunction():
     Function(SPATIAL) 
@@ -47,6 +48,8 @@ public:
   virtual Real GetIntpolReal(const Vec3& v) const {return 0.0;}
 
   virtual Complex GetIntpolComplex(const Vec3& v) const {return Complex(0.0,0.0);}
+  
+  virtual ~NullFunction(){};
 };
 
 }} // namespace
diff --git a/modules/img/base/src/observable.hh b/modules/img/base/src/observable.hh
index 77c004110..831d1c8ea 100644
--- a/modules/img/base/src/observable.hh
+++ b/modules/img/base/src/observable.hh
@@ -39,7 +39,7 @@ namespace ost { namespace img {
   and ObserverUpdate
 */
 template <class T>
-class DLLEXPORT_OST_IMG_BASE Observable {
+class DLLEXPORT Observable {
   typedef std::list<T *> ObserverList;
   typedef typename ObserverList::iterator ObserverIter;
   typedef typename ObserverList::const_iterator ObserverConstIter;
diff --git a/modules/img/base/tests/CMakeLists.txt b/modules/img/base/tests/CMakeLists.txt
index b51491b9d..420287a47 100644
--- a/modules/img/base/tests/CMakeLists.txt
+++ b/modules/img/base/tests/CMakeLists.txt
@@ -17,6 +17,6 @@ tests.cc
 
 
 ost_unittest(img "${OST_IMG_BASE_UNIT_TESTS}")
-if(NOT WIN32)
+
 target_link_libraries(img_tests ost_img_alg)
-endif()
+
diff --git a/modules/img/base/tests/test_data.hh b/modules/img/base/tests/test_data.hh
index 1e72598ed..34f80f1d8 100644
--- a/modules/img/base/tests/test_data.hh
+++ b/modules/img/base/tests/test_data.hh
@@ -25,6 +25,7 @@
 #ifndef IMG_TEST_DATA_H
 #define IMG_TEST_DATA_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_domains.cc b/modules/img/base/tests/test_domains.cc
index 05cf10217..8a8d22935 100644
--- a/modules/img/base/tests/test_domains.cc
+++ b/modules/img/base/tests/test_domains.cc
@@ -24,6 +24,7 @@
 
 #include <sstream>
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_extent.hh b/modules/img/base/tests/test_extent.hh
index 4d452b217..75eb950c4 100644
--- a/modules/img/base/tests/test_extent.hh
+++ b/modules/img/base/tests/test_extent.hh
@@ -25,6 +25,7 @@
 #ifndef IMG_TEST_EXTENT_H
 #define IMG_TEST_EXTENT_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_function.hh b/modules/img/base/tests/test_function.hh
index 4e1d05295..c0c9f509c 100644
--- a/modules/img/base/tests/test_function.hh
+++ b/modules/img/base/tests/test_function.hh
@@ -25,6 +25,7 @@
 #ifndef IMG_TEST_FUNCTION_H
 #define IMG_TEST_FUNCTION_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_image.cc b/modules/img/base/tests/test_image.cc
index 38c4431e5..dde2a034f 100644
--- a/modules/img/base/tests/test_image.cc
+++ b/modules/img/base/tests/test_image.cc
@@ -312,7 +312,7 @@ void test_ImageOps()
   ImageHandle h3=h1+h2;
   for(ExtentIterator it(Extent(Point(-4,-3),Point(4,5))); !it.AtEnd(); ++it) {
     if(ex1.Contains(it) && ex2.Contains(it)) {
-      BOOST_REQUIRE(std::fabs(h3.GetReal(it)-(h1.GetReal(it)+h2.GetReal(it)))<1e-10);
+      BOOST_REQUIRE(check_close(std::fabs(h3.GetReal(it)-(h1.GetReal(it)+h2.GetReal(it))),Real(0.0),1e-6));
     } else if (ex1.Contains(it)) {
       BOOST_REQUIRE(h3.GetReal(it)==h1.GetReal(it));
     } else {
@@ -324,7 +324,7 @@ void test_ImageOps()
   h3=h1-h2;
   for(ExtentIterator it(Extent(Point(-2,-1),Point(1,2))); !it.AtEnd(); ++it) {
     if(ex1.Contains(it) && ex2.Contains(it)) {
-      BOOST_REQUIRE(std::fabs(h3.GetReal(it)-(h1.GetReal(it)-h2.GetReal(it)))<1e-10);
+      BOOST_REQUIRE(check_close(std::fabs(h3.GetReal(it)-(h1.GetReal(it)-h2.GetReal(it))),Real(0.0),1e-6));
     } else if (ex1.Contains(it)) {
       BOOST_REQUIRE(h3.GetReal(it)==h1.GetReal(it));
     } else {
diff --git a/modules/img/base/tests/test_image.hh b/modules/img/base/tests/test_image.hh
index 7120d2338..a8119a975 100644
--- a/modules/img/base/tests/test_image.hh
+++ b/modules/img/base/tests/test_image.hh
@@ -25,6 +25,7 @@
 #ifndef IMG_TEST_IMAGE_H
 #define IMG_TEST_IMAGE_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_image_factory.hh b/modules/img/base/tests/test_image_factory.hh
index 6912f1369..aeaffb84e 100644
--- a/modules/img/base/tests/test_image_factory.hh
+++ b/modules/img/base/tests/test_image_factory.hh
@@ -25,6 +25,7 @@
 #ifndef IMG_TEST_IMAGE_FACTORY_H
 #define IMG_TEST_IMAGE_FACTORY_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_image_impl.hh b/modules/img/base/tests/test_image_impl.hh
index 5cbee44f5..10effda5f 100644
--- a/modules/img/base/tests/test_image_impl.hh
+++ b/modules/img/base/tests/test_image_impl.hh
@@ -25,6 +25,7 @@
 #ifndef IMG_TEST_IMAGE_IMPL_H
 #define IMG_TEST_IMAGE_IMPL_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_image_state.hh b/modules/img/base/tests/test_image_state.hh
index b288c5a04..13735a9ad 100644
--- a/modules/img/base/tests/test_image_state.hh
+++ b/modules/img/base/tests/test_image_state.hh
@@ -25,6 +25,7 @@
 #ifndef TEST_IMAGE_STATE_H
 #define TEST_IMAGE_STATE_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_image_state_visitor.hh b/modules/img/base/tests/test_image_state_visitor.hh
index 6cbe26de8..a85f5130e 100644
--- a/modules/img/base/tests/test_image_state_visitor.hh
+++ b/modules/img/base/tests/test_image_state_visitor.hh
@@ -25,6 +25,7 @@
 #ifndef IMG_TEST_IMAGE_STATE_VISITOR_H
 #define IMG_TEST_IMAGE_STATE_VISITOR_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_index.hh b/modules/img/base/tests/test_index.hh
index 5056c4db2..9c21122b2 100644
--- a/modules/img/base/tests/test_index.hh
+++ b/modules/img/base/tests/test_index.hh
@@ -25,6 +25,7 @@
 #ifndef IMG_TEST_INDEX_H
 #define IMG_TEST_INDEX_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_point.hh b/modules/img/base/tests/test_point.hh
index 1c5d20a57..6b790bc07 100644
--- a/modules/img/base/tests/test_point.hh
+++ b/modules/img/base/tests/test_point.hh
@@ -25,6 +25,7 @@
 #ifndef IMG_TEST_POINT_H
 #define IMG_TEST_POINT_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_sampling.hh b/modules/img/base/tests/test_sampling.hh
index 6854438fc..cb808f567 100644
--- a/modules/img/base/tests/test_sampling.hh
+++ b/modules/img/base/tests/test_sampling.hh
@@ -25,6 +25,7 @@
 #ifndef IMG_TEST_SAMPLING_H
 #define IMG_TEST_SAMPLING_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_size.hh b/modules/img/base/tests/test_size.hh
index 2a35c3e85..61b456f29 100644
--- a/modules/img/base/tests/test_size.hh
+++ b/modules/img/base/tests/test_size.hh
@@ -25,6 +25,7 @@
 #ifndef IMG_TEST_SIZE_H
 #define IMG_TEST_SIZE_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_transform.hh b/modules/img/base/tests/test_transform.hh
index cf6b002f7..2569640d5 100644
--- a/modules/img/base/tests/test_transform.hh
+++ b/modules/img/base/tests/test_transform.hh
@@ -25,6 +25,7 @@
 #ifndef IMG_TEST_TRANSFORM_H
 #define IMG_TEST_TRANSFORM_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/img/base/tests/test_value_holder.hh b/modules/img/base/tests/test_value_holder.hh
index 6f2de7bb2..ecf2d998d 100644
--- a/modules/img/base/tests/test_value_holder.hh
+++ b/modules/img/base/tests/test_value_holder.hh
@@ -25,6 +25,7 @@
 #ifndef IMG_TEST_VALUE_HOLDER_H
 #define IMG_TEST_VALUE_HOLDER_H
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
 
diff --git a/modules/index.rst b/modules/index.rst
index 52dcde170..cdb3284d5 100644
--- a/modules/index.rst
+++ b/modules/index.rst
@@ -2,7 +2,39 @@ OpenStructure documentation
 ================================================================================
 
 .. toctree::
+  :maxdepth: 2
+  
+Introduction
+--------------------------------------------------------------------------------  
 
-  geom/doc/geom
-  conop/doc/conop
-  mol/base/doc/mol
\ No newline at end of file
+.. toctree::
+  :maxdepth: 2
+
+  intro
+  install
+  
+Modules
+--------------------------------------------------------------------------------
+
+.. toctree::
+  :maxdepth: 2
+
+  base/generic
+  img/base/img
+  img/alg/alg
+  geom/geom
+  conop/conop
+  mol/base/mol
+  seq/base/seq
+  base/base
+  io/io
+
+Extending OpenStructure
+--------------------------------------------------------------------------------
+
+.. toctree::
+  :maxdepth: 2
+  
+  newmodule
+  external
+  
\ No newline at end of file
diff --git a/modules/io/doc/formats.rst b/modules/io/doc/formats.rst
new file mode 100644
index 000000000..ceef7e5f2
--- /dev/null
+++ b/modules/io/doc/formats.rst
@@ -0,0 +1,81 @@
+Supported File Formats
+================================================================================
+
+Structure File Formats
+--------------------------------------------------------------------------------
+
+The following file formats are supported by :func:`~ost.io.LoadEntity`. 
+
+
+  
+PDB - Brookhaven PDB File
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Fine grained control over PDB file import is available via the 
+:func:`~ost.io.LoadPDB` function. The PDB importer support loading gzipped PDB 
+files. gzipped PDB files are detected by the .gz file extension.
+
+*Recognized File Extensions*
+  ent, pdb, ent.gz, pdb.gz
+
+*Format Name*
+  pdb
+
+PQR
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+*Recognized File Extensions*
+  pqr
+
+*Format Name*
+  pqr
+
+CRD - CARD format file used by CHARMM
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+*Recognized File Extensions*
+  crd
+  
+SDF
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+*Recognized File Extensions*
+  sdf
+  
+Sequence File Formats
+--------------------------------------------------------------------------------
+
+FASTA
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+*Recognized File Extensions*
+  fasta, fna, fas, fa, fsa
+  
+*Format Name*
+  fasta
+
+ClustalW
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+*Recognized File Extensions*
+  aln
+  
+*Format Name*
+  clustal
+
+Promod
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+*Recognized File Extensions*
+  ali
+  
+*Format Name*
+  promod
+
+PIR
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+*Recognized File Extensions*
+  pir
+  
+*Format Name*
+  pir
\ No newline at end of file
diff --git a/modules/io/doc/io.rst b/modules/io/doc/io.rst
new file mode 100644
index 000000000..21c38bc4f
--- /dev/null
+++ b/modules/io/doc/io.rst
@@ -0,0 +1,103 @@
+:mod:`~ost.io` - Input and Output of Sequences, Structures and Maps
+================================================================================
+
+.. module:: ost.io
+  :synopsis: Input and output of sequences, structures and density maps
+
+The io module deals with input and output of :class:`entities 
+<ost.mol.EntityHandle>`, :class:`alignments <ost.seq.AlignmentHandle>`, and
+:class:`images <ost.img.ImageHandle>`. Importers for common file formats such 
+as PDB, SDF, FASTA, CLUSTAL W, DX and CHARMM trajectory files are available. 
+
+Molecular Structures
+--------------------------------------------------------------------------------
+
+Loading Molecular Structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The :mod:`~ost.io` modules offers several ways to load molecular structures 
+depending on your requirements. The most general way is offered by 
+:func:`~ost.io.LoadEntity`, which will automatically detect the file format based 
+on the file extension.
+
+.. function:: LoadEntity(filename, format='auto')
+
+  Load entity from disk. If format is set to 'auto', the function guesses the 
+  filetype based on the extension of the file. Files ending in '.pdb', '.ent', 
+  '.ent.gz', '.pdb.gz' will automatically be loaded as PDB files, for example. 
+  For files without or exotic extensions, the format can be set explicitly as 
+  the second parameter. 
+  
+  .. code-block:: python
+
+    # recognizes SDF file by file extension
+    ent=io.LoadEntity('file.sdf')
+
+    # In this case, there is no file extensions, so you have to say it's a 
+    # SDF file explicitly
+    ent=io.LoadEntity('file', 'sdf')
+
+  For a list of file formats supported by :func:`LoadEntity`, see :doc:`formats`.
+  
+  :raises: :exc:`~ost.io.IOUnknownFormatException` if the format string supplied 
+      is not recognized or the file format can not be detected based on the 
+      file extension
+      
+      :exc:`~ost.io.IOException` if the import fails due to an erroneous or 
+      inexistent file
+
+Some of the formats have a dedicated function that allows you to tweak many 
+parameters that affect the import. PDB files can be loaded with 
+:func:`~ost.io.LoadPDB`. It offers a tighter control over the exact loading 
+behaviour.
+
+.. autofunction:: ost.io.LoadPDB
+
+
+Saving Molecular Structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Saving a complete entity or a view is a matter of calling 
+:func:`~ost.io.SaveEntity`.
+
+.. code-block:: python
+  
+  ent=io.LoadEntity('protein.pdb')
+  # save full entity
+  io.SaveEntity(ent, 'full.pdb')
+  # only save C-alpha atoms
+  io.SaveEntity(ent.Select('aname=CA and peptide=true'), 'calpha.pdb')
+  
+:func:`~ost.io.SavePDB` provides a simple way to save several entities into one 
+file:
+
+
+.. code-block:: python
+  
+  ent=io.LoadEntity('protein.pdb')
+  # Save complete entity
+  io.SavePDB(ent, 'full.pdb')
+  # Save chain A and chain B separately
+  io.SavePDB([ent.Select('cname=A'), ent.Select('cname=B')], 'split.pdb')
+
+
+.. function:: SaveEntity(ent, filename, format='auto')
+  
+  Save entity to disk. If format is set to 'auto', the function guesses the 
+  filetype based on the file extension, otherwise the supplied format is checked 
+  against the available export plugins.
+  
+  :param ent: The entity to be saved
+  :type  ent: :class:`~ost.mol.EntityHandle` or :class:`~ost.mol.EntityView`
+  :param filename: The filename
+  :type  filename: string
+  :param format: Name of the format
+  :type  format: string
+  
+  :raises: :exc:`~ost.io.IOUnknownFormatException` if the format string supplied 
+      is not recognized or the file format can not be detected based on the 
+      file extension
+      
+.. autofunction:: ost.io.SavePDB
+
+  
\ No newline at end of file
diff --git a/modules/io/pymod/__init__.py b/modules/io/pymod/__init__.py
index 344f97129..095cacb89 100644
--- a/modules/io/pymod/__init__.py
+++ b/modules/io/pymod/__init__.py
@@ -17,29 +17,35 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 #------------------------------------------------------------------------------
 from _io import *
-from ost import mol,conop
+from ost import mol, conop
 
 def LoadPDB(filename, restrict_chains="", no_hetatms=False,
             fault_tolerant=False, load_multi=False,
             join_spread_atom_records=False, calpha_only=False):
   """
-  Load PDB file from disk.
+  Load PDB file from disk and returns one or more entities. Several options 
+  allow to customize the exact behaviour of the PDB import.
 
-  If restrict_chains is not an empty string, only chains listed in the
-  string will be imported.
+  :param restrict_chains: If not an empty string, only chains listed in the
+     string will be imported.
 
-  If fault_tolerant is set to true, the import will succeed, even if the
-  PDB contains faulty records. The faulty records will be ignored in that
-  case.
+  :param fault_tolerant: If True, the import will succeed, even if the
+     PDB contains faulty records. The faulty records will be ignored and import 
+     continues as if the records haven't been present.
 
-  If not_hetatms is set to True, HETATM records will be ignored
+  :param no_hetatms: If set to True, HETATM records will be ignored
 
-  If load_multi is set to true, a list of entities will be returned instead
-  of only the first.
+  :param load_multi: If set to True, a list of entities will be returned instead
+     of only the first. This is useful when dealing with multi-PDB files.
 
-  If join_spread_atom_records is set to true, atom records belonging to the
-  same residue are joined, even if they do not appear sequentially in the PDB
-  file.
+  :param join_spread_atom_records: If set to true, atom records belonging to the
+     same residue are joined, even if they do not appear sequentially in the PDB
+     file.
+  :rtype: :class:`~ost.mol.EntityHandle` or a list thereof if `load_multi` is 
+      True.
+      
+  :raises: :exc:`~ost.io.IOException` if the import fails due to an erroneous or 
+      inexistent file
   """
   conop_inst=conop.Conopology.Instance()
   builder=conop_inst.GetBuilder("DEFAULT")
@@ -78,7 +84,13 @@ def LoadPDB(filename, restrict_chains="", no_hetatms=False,
 
 def SavePDB(models, filename):
   """
-  Save entity or list of entities to disk
+  Save entity or list of entities to disk. If a list of entities is supplied the 
+  PDB file will be saved as a multi PDB file. Each of the entities is wrapped 
+  into a MODEL/ENDMDL pair.
+  
+  :param models: The entity or list of entities (handles or views) to be saved
+  :param filename: The filename
+  :type  filename: string
   """
   if not getattr(models, '__len__', None):
     models=[models]
diff --git a/modules/io/src/CMakeLists.txt b/modules/io/src/CMakeLists.txt
index e77cfda20..f61c471d3 100644
--- a/modules/io/src/CMakeLists.txt
+++ b/modules/io/src/CMakeLists.txt
@@ -13,6 +13,7 @@ io_utils.hh
 io_exception.hh
 convert.hh
 converting_streams.hh
+formatted_line.hh
 )
 
 set(OST_IO_SOURCES
diff --git a/modules/io/src/formatted_line.hh b/modules/io/src/formatted_line.hh
new file mode 100644
index 000000000..444a4e4aa
--- /dev/null
+++ b/modules/io/src/formatted_line.hh
@@ -0,0 +1,239 @@
+#ifndef OST_IO_FORMATTED_LINE_HH
+#define OST_IO_FORMATTED_LINE_HH
+
+#ifdef _MSC_VER
+#define snprintf _snprintf
+#endif
+
+#include <cstdio>
+
+#include <ost/string_ref.hh>
+
+/*
+  Author: Marco Biasini
+ */
+
+namespace ost { namespace io {
+
+namespace fmt {
+
+struct LPadded : public StringRef {
+  LPadded(const char* s, size_t l): 
+    StringRef(s, l)
+  { }
+  
+  explicit LPadded(const String& s): StringRef(s.data(), s.size())
+  { }
+  
+  explicit LPadded(const char* s): StringRef(s, strlen(s))
+  { }
+};
+
+struct RPadded : public StringRef {
+  RPadded(const char* s, size_t l): 
+    StringRef(s, l)
+  { }
+  
+  explicit RPadded(const String& s): StringRef(s.data(), s.size())
+  { }
+  
+  explicit RPadded(const char* s): StringRef(s, strlen(s))
+  { }
+};
+
+
+struct LPaddedInt {
+  LPaddedInt(int val) {
+    size_t curr=0;
+    bool minus=val<0;
+    val=std::abs(val);
+    if (minus) {
+      data[curr]='-';
+      ++curr;
+    }
+    do {
+      int m=val%10;
+      data[curr]='0'+m;
+      ++curr;
+      val/=10;
+    } while(val);
+    // swap
+    for (size_t i=0, e=(curr-int(minus))/2; i<e; ++i) {
+      std::swap(data[int(minus)+i], data[curr-i-1]);
+    }
+    data[curr]='\0';
+    len=curr;
+  }
+  char   data[20];
+  size_t len;
+};
+
+// BIG FAT WARNING: Before using this class to output floats with lots of 
+// digits, make sure you indeed get the result you want. The function has 
+// not been tested enough for numerical stability.
+struct LPaddedFloat {
+  LPaddedFloat(Real val, int prec)
+  {
+    switch(prec){
+      case 0:
+        len = snprintf(data, sizeof(data), "%.0f", val);
+        break;
+      case 1:
+        len = snprintf(data, sizeof(data), "%.1f", val);
+        break;
+      case 2:
+        len = snprintf(data, sizeof(data), "%.2f", val);
+        break;
+      case 3:
+        len = snprintf(data, sizeof(data), "%.3f", val);
+        break;
+      default:
+        Real rounded_val=round(val*pow(Real(10), prec))*pow(Real(0.1), prec);
+        size_t curr=0;
+        bool minus=rounded_val<0;
+        rounded_val=std::abs(rounded_val);
+        int int_val=int(rounded_val);
+        if (minus) {
+          data[curr]='-';
+          ++curr;
+        }
+        do {
+          int m=int_val%10;
+          data[curr]='0'+m;
+          ++curr;
+          int_val/=10;
+        } while(int_val);
+        // swap
+        for (size_t i=0, e=(curr-int(minus))/2; i<e; ++i) {
+          std::swap(data[int(minus)+i], data[curr-i-1]);
+        }
+        data[curr]='\0';
+        len=curr;
+        if (prec==0) {
+          return;
+        }
+        data[curr]='.';
+        curr++;
+        rounded_val-=int(rounded_val);
+        while(prec>0) {
+          rounded_val*=10;
+          int m=int(rounded_val);
+          rounded_val-=int(rounded_val);
+          data[curr]='0'+m;
+          curr++;
+          --prec;
+        }
+        data[curr]='\0';
+        len=curr;
+    }
+  }
+  char   data[20];
+  size_t len;  
+};
+
+
+
+}
+
+class LineSlice {
+public:
+  LineSlice(char* data, size_t l): data_(data), len_(l) 
+  {
+  }
+
+  LineSlice& operator=(const StringRef& str)
+  {
+    assert(str.length()==len_);
+    memcpy(data_, str.data(), str.size());
+    return *this;
+  }
+  
+  LineSlice& operator=(const fmt::LPadded& str)
+  {
+    assert(str.size()<=len_);
+    memcpy(data_+len_-str.size(), str.data(), str.size());
+    return *this;
+  }
+  
+  LineSlice& operator=(const fmt::RPadded& str)
+  {
+    assert(str.size()<=len_);
+    memcpy(data_, str.data(), str.size());
+    return *this;
+  }
+  
+  LineSlice& operator=(const fmt::LPaddedInt& i) 
+  {
+    assert(i.len<=len_);
+    memcpy(data_+len_-i.len, i.data, i.len);
+    return *this;
+  }
+  
+  LineSlice& operator=(const fmt::LPaddedFloat& f)
+  {
+    assert(f.len<=len_);
+    memcpy(data_+len_-f.len, f.data, f.len);
+    return *this;
+  }
+  void Clear()
+  {
+    memset(data_, ' ', len_);
+  }
+private:
+  char* data_;
+  size_t len_;
+};
+
+class FormattedLine {
+public:
+  FormattedLine(size_t width): 
+    data_(new char[width]), len_(width)
+  {
+    this->Clear();
+  }
+  
+  void Clear()
+  {
+    memset(data_, ' ', len_);
+  }
+  ~FormattedLine() { delete[] data_; }
+  
+  LineSlice operator()(int start, int len) 
+  { 
+    assert(start>=0 && start+len<=static_cast<int>(len_));
+    return LineSlice(data_+start, len);
+  }
+  
+  const char* Data() const { return data_; }
+  
+  size_t GetWidth() const { return len_; }
+  
+  char operator[](size_t index) const
+  {
+    assert(index<len_);
+    return data_[index];
+  }
+  
+  char& operator[](size_t index)
+  {
+    assert(index<len_);
+    return data_[index];
+  }
+private:
+  FormattedLine& operator=(const FormattedLine& rhs);
+  FormattedLine(const FormattedLine& rhs);
+  char*       data_;
+  size_t      len_;
+};
+
+inline std::ostream& operator<<(std::ostream& stream, const FormattedLine& line)
+{
+  stream.write(line.Data(), line.GetWidth()); 
+  stream << std::endl;
+  return stream;
+}
+
+
+}}
+
+#endif
diff --git a/modules/io/src/mol/CMakeLists.txt b/modules/io/src/mol/CMakeLists.txt
index 5cdf0462b..860b4df0d 100644
--- a/modules/io/src/mol/CMakeLists.txt
+++ b/modules/io/src/mol/CMakeLists.txt
@@ -6,6 +6,8 @@ entity_io_pdb_handler.cc
 pdb_io.cc
 pdb_writer.cc
 entity_io_sdf_handler.cc	
+sdf_reader.cc
+sdf_writer.cc
 save_entity.cc
 load_entity.cc
 surface_io_msms_handler.cc
@@ -26,6 +28,8 @@ pdb_reader.hh
 entity_io_pdb_handler.hh	
 pdb_writer.hh
 entity_io_sdf_handler.hh	
+sdf_reader.hh
+sdf_writer.hh
 save_entity.hh
 load_entity.hh			
 surface_io_handler.hh
diff --git a/modules/io/src/mol/entity_io_mae_handler.cc b/modules/io/src/mol/entity_io_mae_handler.cc
index 03700f62a..d002a7120 100644
--- a/modules/io/src/mol/entity_io_mae_handler.cc
+++ b/modules/io/src/mol/entity_io_mae_handler.cc
@@ -133,7 +133,7 @@ void MAEReader::Import(mol::EntityHandle& ent)
           } else {
             // parsing atom line
             std::vector<std::string> tokens=tokenize(line);
-            for(int i=0;i<tokens.size();++i) {
+            for(size_t i=0;i<tokens.size();++i) {
               LOG_DUMP( "[" << tokens[i] << "] ");
             }
             LOGN_DUMP("");
diff --git a/modules/io/src/mol/entity_io_sdf_handler.cc b/modules/io/src/mol/entity_io_sdf_handler.cc
index f9c49479f..72ec53cbc 100644
--- a/modules/io/src/mol/entity_io_sdf_handler.cc
+++ b/modules/io/src/mol/entity_io_sdf_handler.cc
@@ -16,392 +16,50 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
-#include <iostream>
-#include <sstream>
-#include <iomanip>
+/*
+  Author: Tobias Schmidt
+ */
 
-#include <boost/filesystem/fstream.hpp>
-#include <boost/filesystem/convenience.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/format.hpp>
 #include <ost/log.hh>
-#include <ost/conop/conop.hh>
-#include <ost/io/io_exception.hh>
+#include <ost/io/sdf_writer.hh>
+#include <ost/io/sdf_reader.hh>
+
 #include "entity_io_sdf_handler.hh"
 
 namespace ost { namespace io {
 
-using boost::format;
 
 bool EntityIOSDFHandler::RequiresBuilder() const
 {
   return false;
 }
 
-// import data from provided stream
-void EntityIOSDFHandler::Import(mol::EntityHandle& ent, std::istream& instream)
+void EntityIOSDFHandler::Import(mol::EntityHandle& ent,
+                                std::istream& instream)
 {
-  String line;
-  mol::XCSEditor editor=ent.RequestXCSEditor(mol::BUFFERED_EDIT);
-  while (std::getline(instream,line)) {
-    ++line_num;
-
-    if (line_num<=4) {
-      ParseAndAddHeader(line, line_num, ent, editor);
-    } else if (line_num<=atom_count_+4) {
-      ParseAndAddAtom(line, line_num, ent, true, editor);
-    } else if (line_num<=bond_count_+atom_count_+4) {
-      ParseAndAddBond(line, line_num, ent, editor);
-    } else if (boost::iequals(line.substr(0,2), "> ")) {
-      // parse data items
-      int data_header_start = line.find('<');
-      String data_header = line.substr(data_header_start+1,line.rfind('>')-data_header_start-1);
-      if(data_header.empty()) {
-        String msg="Bad data line %d: Could not find data header";
-        throw IOException(str(format(msg) % line_num));
-      }
-      String data_value="";
-      while(std::getline(instream,line) && !boost::iequals(line, "")) {
-        data_value.append(line);
-      }
-      curr_chain_.SetStringProp(data_header, data_value);
-    } else if (boost::iequals(line, "$$$$")) {
-      LOGN_MESSAGE("MOLECULE " << curr_chain_.GetName() << " (" << chain_count_ << ") added.")
-      NextMolecule();
-    }
-  }
-
-  LOGN_MESSAGE("imported " << chain_count_ << " chains, " << residue_count_ 
-               << " residues, " << atom_count_ << " atoms");
+  SDFReader reader(instream);
+  reader.Import(ent);
 }
 
-
-
 void EntityIOSDFHandler::Import(mol::EntityHandle& ent,
                                 const boost::filesystem::path& loc)
 {
-  ClearState();
-  boost::filesystem::ifstream instream(loc);
-  if(!instream) throw IOException("could not open "+loc.string());  
-  this->Import(ent, instream);
-}
-
-void EntityIOSDFHandler::ClearState()
-{
-  curr_chain_=mol::ChainHandle();
-  curr_residue_=mol::ResidueHandle();
-  chain_count_=0;
-  residue_count_=0;
-  atom_count_=0;
-  bond_count_=0;
-  line_num=0;
-}
-
-void EntityIOSDFHandler::NextMolecule()
-{
-  residue_count_=0;
-  atom_count_=0;
-  bond_count_=0;
-  line_num=0;
-}
-
-void EntityIOSDFHandler::ParseAndAddHeader(const String& line, int line_num,
-                                           mol::EntityHandle& ent, mol::XCSEditor& editor)
-{
-  LOGN_TRACE( "line: [" << line << "]" );
-  format chain_fmter("%05i_%s");
-  switch(line_num)
-  {
-    case 1:  // title line
-    {
-      ++chain_count_;
-      String s_title=line;
-      String s_chain;
-      chain_fmter % chain_count_ % boost::trim_copy(s_title);
-      s_chain=chain_fmter.str();
-      if(s_chain.empty()) {
-        String msg="Bad molecule name line %d: Line is empty";
-        throw IOException(str(format(msg) % line_num));
-      }
-      curr_chain_=editor.InsertChain(s_chain);
-      LOGN_DUMP("new chain " << s_chain);
-
-      mol::ResidueKey rkey=boost::trim_copy(s_title);
-      mol::ResNum rnum(++residue_count_);
-      curr_residue_=editor.AppendResidue(curr_chain_, rkey, rnum);
-      LOGN_DUMP("new residue " << rkey << "(" << rnum << ")");
-      break;
-    }
-    case 2:  // user information line
-      break;
-    case 3:  // comments line
-      break;
-    case 4:  // counts line
-    {
-      String s_anum=line.substr(0,3);
-      try {
-        atom_count_=boost::lexical_cast<int>(boost::trim_copy(s_anum));
-      } catch(boost::bad_lexical_cast&) {
-        String msg="Bad counts line %d: Can't convert number of atoms"
-                   " '%s' to integral constant.";
-        throw IOException(str(format(msg) % line_num % s_anum));
-      }
-      String s_bnum=line.substr(3,3);
-      try {
-        bond_count_=boost::lexical_cast<int>(boost::trim_copy(s_bnum));
-      } catch(boost::bad_lexical_cast&) {
-        String msg="Bad counts line %d: Can't convert number of bonds"
-                   " '%s' to integral constant.";
-        throw IOException(str(format(msg) % line_num % s_bnum));
-      }
-      break;
-    }
-  }
-}
-
-void EntityIOSDFHandler::ParseAndAddAtom(const String& line, int line_num,
-                                         mol::EntityHandle& ent, bool hetatm,
-                                         mol::XCSEditor& editor)
-{
-
-  LOGN_TRACE( "line: [" << line << "]" );
-
-  if(line.length()<48 || line.length()>69) {
-    String msg="Bad atom line %d: Not correct number of characters on the"
-               " line: %i (should be between 48 and 69)";
-    throw IOException(str(format(msg) % line_num % line.length()));
-  }
-  int anum = line_num-4;  // start at 1 on fifth line since first four lines are header
-  String s_posx=line.substr(0,10);
-  String s_posy=line.substr(10,10);
-  String s_posz=line.substr(20,10);
-  String s_ele=line.substr(31,3);
-  String s_charge=line.substr(36,3);
-
-  geom::Vec3 apos;
-  try {
-    apos=geom::Vec3(boost::lexical_cast<Real>(boost::trim_copy(s_posx)),
-                    boost::lexical_cast<Real>(boost::trim_copy(s_posy)),
-                    boost::lexical_cast<Real>(boost::trim_copy(s_posz)));
-  } catch(boost::bad_lexical_cast&) {
-    String msg="Bad atom line %d: Can't convert coordinates to "
-               "floating point numbers";
-    throw IOException(str(format(msg) % line_num));
-  }
-
-  String ele=boost::trim_copy(s_ele);
-  String aname=boost::lexical_cast<String>(anum);
-
-  mol::AtomProp aprop;
-  aprop.element=ele;
-  aprop.radius=conop::Conopology::Instance().GetDefaultAtomRadius(ele);
-  aprop.mass=conop::Conopology::Instance().GetDefaultAtomMass(ele);
-  aprop.is_hetatm=hetatm;
-  
-  try {
-    aprop.charge=boost::lexical_cast<Real>(boost::trim_copy(s_charge));
-    if(aprop.charge != 0) {
-      aprop.charge=4-aprop.charge;
-    } //4-sdf_charge=real_charge if not 0
-  } catch(boost::bad_lexical_cast&) {
-    String msg="Bad atom line %d: Can't convert charge"
-               " '%s' to integral constant.";
-    throw IOException(str(format(msg) % line_num % s_charge));
-  }
-
-  LOGN_DUMP("adding atom " << aname << " (" << s_ele << ") @" << apos);
-
-  editor.InsertAtom(curr_residue_, aname,apos,aprop);
-}
-
-
-void EntityIOSDFHandler::ParseAndAddBond(const String& line, int line_num,
-                                         mol::EntityHandle& ent, mol::XCSEditor& editor)
-{
-
-  LOGN_TRACE( "line: [" << line << "]" );
-
-  if(line.length()<18 || line.length()>21) {
-    String msg="Bad bond line %d: Not correct number of characters on the"
-               " line: %i (should be between 18 and 21)";
-    throw IOException(str(format(msg) % line_num % line.length()));
-  }
-
-  String s_first_name=line.substr(0,3);
-  String s_second_name=line.substr(3,3);
-  String s_type=line.substr(6,3);
-  String first_name, second_name;
-  unsigned char type;
-  mol::BondHandle bond;
-  
-  first_name=boost::trim_copy(s_first_name);
-  second_name=boost::trim_copy(s_second_name);
-
-  try {
-    type=boost::lexical_cast<int>(boost::trim_copy(s_type));
-  } catch(boost::bad_lexical_cast&) {
-    String msg="Bad bond line %d: Can't convert bond type number"
-                " '%s' to integral constant.";
-    throw IOException(str(format(msg) % line_num % s_type));
-  }
-
-  mol::AtomHandle first,second;
-
-  first = ent.FindAtom(curr_chain_.GetName(), mol::ResNum(residue_count_), first_name);
-  second = ent.FindAtom(curr_chain_.GetName(), mol::ResNum(residue_count_), second_name);
-
-  if(first.IsValid() && second.IsValid()) {
-    bond = editor.Connect(first, second);
-    bond.SetBondOrder(type);
-  } else {
-    String msg="Bad bond line %d: Can't find the atom names '%s', '%s'"
-               " in entity.";
-    throw IOException(str(format(msg) % line_num % first % second));
-  }
-
-  LOGN_DUMP("adding bond " << s_first_name << " " << s_second_name << " (" << s_type << ") ");
-}
-
-namespace {
-
-  using boost::format;
-  
-  class SDFAtomWriter : public mol::EntityVisitor {
-    public:
-      SDFAtomWriter(std::ostream& ostream, std::map<long, int>& atom_indices) 
-      : ostr_(ostream), atom_indices_(atom_indices), counter_(0) {
-	atom_indices_.clear();
-      }
-    private:
-    public:
-      virtual bool VisitAtom(const mol::AtomHandle& atom) {
-        atom_indices_[atom.GetHashCode()] = ++counter_;
-        ostr_ << format("%10.4f") % atom.GetPos()[0]
-              << format("%10.4f") % atom.GetPos()[1]
-              << format("%10.4f ") % atom.GetPos()[2]
-              << format("%-3s") % atom.GetElement()
-              << " 0  0  0  0  0  0"
-              << std::endl;
-        return true;
-      }  
-    private:
-      std::ostream&      ostr_;
-      std::map<long, int>& atom_indices_;
-      int counter_;
-  };
-  
-  class SDFBondWriter : public mol::EntityVisitor {
-  public:
-    SDFBondWriter(std::ostream& ostream, std::map<long, int>& atom_indices) 
-      : ostr_(ostream), atom_indices_(atom_indices), counter_(0) {
-    }
-  private:
-  public:
-    virtual bool VisitAtom(const mol::AtomHandle& atom) {
-      counter_++;
-      mol::AtomHandleList atoms = atom.GetBondPartners();
-      mol::AtomHandleList::iterator atom_iter = atoms.begin();
-      for(; atom_iter != atoms.end(); ++atom_iter) {
-        int atom_index = atom_indices_.find((*atom_iter).GetHashCode())->second;
-        if(atom_index > counter_) {
-          int type = 1;
-          mol::BondHandle bond = atom.FindBondToAtom(*atom_iter);
-          if(bond.IsValid()) type = bond.GetBondOrder();
-          ostr_ << format("%3i") % counter_
-                << format("%3i") % atom_index
-                << format("%3i") % type
-                << "  0  0  0"
-                << std::endl;
-        }
-      }
-      return true;
-    }
-     
-  private:
-    std::ostream&      ostr_;
-    std::map<long, int>& atom_indices_;
-    int counter_;
-  };
-
-  class SDFWriter : public mol::EntityVisitor {
-  public:
-    SDFWriter(std::ostream& ostream)
-      : ostr_(ostream), counter_(0) {
-    }
-  private:
-  public:
-    virtual bool VisitChain(const mol::ChainHandle& chain) {
-      // print end of molecule line
-      if(counter_ != 0) {
-        ostr_ << "$$$$" << std::endl;
-        counter_ = 0;
-        atom_indices_.clear();
-      }
-      // print header lines
-      ostr_ << chain.GetName() << std::endl;
-      ostr_ << std::endl;
-      ostr_ << std::endl;
-
-      // print counts line
-      ostr_ << format("%3d") % chain.GetAtomCount()
-            << format("%3d") % chain.GetBondCount()
-            << "  0  0  0  0  0  0  0  0999 V2000"
-            << std::endl;
-      
-      // write atom block
-      SDFAtomWriter atom_writer(ostr_, atom_indices_);
-      mol::ChainHandle non_const_chain = chain;
-      non_const_chain.Apply(atom_writer);
-      
-      // write bond block
-      SDFBondWriter bond_writer(ostr_, atom_indices_);
-      non_const_chain.Apply(bond_writer);
-      
-      // write property block
-      //TODO: wirte property block
-      ostr_ << "M  END" << std::endl;
-      
-      // write data block
-      std::map<String,GenericPropValue> prop_map = non_const_chain.GetPropMap();
-      std::map<String,GenericPropValue>::iterator iter;
-      for(iter = prop_map.begin(); iter != prop_map.end(); ++iter) {
-        ostr_ << "> <" << (*iter).first << ">" << std::endl;
-        ostr_ << (*iter).second << std::endl;
-        ostr_ << std::endl;
-      }
-      
-      // write molecule endline
-      ostr_ << "$$$$" << std::endl;
-      
-      return true;
-    }
-
-
-    
-  private:
-    std::ostream&      ostr_;
-    int                counter_;
-    std::map<long,int> atom_indices_;
-  };
-
+  SDFReader reader(loc);
+  reader.Import(ent);
 }
 
 void EntityIOSDFHandler::Export(const mol::EntityView& ent,
                                 const boost::filesystem::path& loc) const {
 
-  boost::filesystem::ofstream outfile(loc);
-  if(!outfile) throw IOException("could not open "+loc.string()+" for writing");
-  this->Export(ent, outfile);
+  SDFWriter writer(loc);
+  writer.Write(ent);
 }
 
-// export data from entity view to provided stream
 void EntityIOSDFHandler::Export(const mol::EntityView& ent, 
                     std::ostream& outstream) const
 {
-  SDFWriter writer(outstream);  
-  mol::EntityView non_const_view = ent;
-  non_const_view.Apply(writer);
+  SDFWriter writer(outstream);
+  writer.Write(ent);
 }
 
 namespace {
@@ -436,16 +94,12 @@ bool EntityIOSDFHandler::ProvidesExport(const boost::filesystem::path& loc,
   return sdf_handler_is_responsible_for(loc, type);
 }
 
-
-
 mol::EntityHandle LoadSDF(const String& file_name) {
 
     mol::EntityHandle ent_handle=mol::CreateEntity();
     EntityIOSDFHandler ent_io;
     ent_io.Import(ent_handle,file_name);
 
-    LOG_DUMP("running conopology" << std::endl);
-
     return ent_handle;
 }
 
diff --git a/modules/io/src/mol/entity_io_sdf_handler.hh b/modules/io/src/mol/entity_io_sdf_handler.hh
index 1baa629d4..cebf2fa5e 100644
--- a/modules/io/src/mol/entity_io_sdf_handler.hh
+++ b/modules/io/src/mol/entity_io_sdf_handler.hh
@@ -20,7 +20,6 @@
 #define OST_IO_ENTITY_IO_PLUGIN_SDF_H
 
 #include <ost/io/mol/entity_io_handler.hh>
-#include <ost//mol/xcs_editor.hh>
 
 namespace ost { namespace io {
 
@@ -45,29 +44,6 @@ public:
 
   static String GetFormatName() { return String("Sdf"); }
   static String GetFormatDescription() { return String("Structure-data format from Molecular Design Limited"); }
-
-private:
-  void ClearState();
-
-  void NextMolecule();
-
-  void ParseAndAddHeader(const String& line, int line_num, mol::EntityHandle& ent,
-                         mol::XCSEditor& editor);
-
-  void ParseAndAddAtom(const String& line, int line_num, mol::EntityHandle& ent, 
-                       bool hetatm, mol::XCSEditor& editor);
-
-  void ParseAndAddBond(const String& line, int line_num, mol::EntityHandle& ent,
-                       mol::XCSEditor& editor);
-
-  mol::ChainHandle curr_chain_;
-  mol::ResidueHandle curr_residue_;
-  int chain_count_;
-  int residue_count_;
-  int atom_count_;
-  int bond_count_;
-  int line_num;
-
 };
 
 typedef EntityIOHandlerFactory<EntityIOSDFHandler> EntityIOSDFHandlerFactory;
diff --git a/modules/io/src/mol/pdb_reader.cc b/modules/io/src/mol/pdb_reader.cc
index f26e77672..21db6adf0 100644
--- a/modules/io/src/mol/pdb_reader.cc
+++ b/modules/io/src/mol/pdb_reader.cc
@@ -404,8 +404,8 @@ void PDBReader::ParseAndAddAtom(const StringRef& line, int line_num,
   }
   // b-factors and occ are replaced by radius and charge if PQR file format
   if(is_pqr_) {
-    occ=std::make_pair(true, 1.0);
-    temp=std::make_pair(true, 0.0);
+    occ=std::make_pair(true, Real(1.0));
+    temp=std::make_pair(true, Real(0.0));
     if (line.length()>=60) {
       charge=line.substr(54,6).ltrim().to_float();      
     }
diff --git a/modules/io/src/mol/pdb_writer.cc b/modules/io/src/mol/pdb_writer.cc
index 775bec870..7b89e1f09 100644
--- a/modules/io/src/mol/pdb_writer.cc
+++ b/modules/io/src/mol/pdb_writer.cc
@@ -19,9 +19,12 @@
 /*
   Author: Marco Biasini
  */
+#include <locale>
 #include <boost/format.hpp>
 #include <string.h>
+
 #include <ost/io/io_exception.hh>
+
 #include "pdb_writer.hh"
 
 using boost::format;
@@ -31,63 +34,119 @@ namespace ost { namespace io {
 
 namespace {
 
-void write_atom(std::ostream& ostr, const mol::AtomHandle& atom, int atomnum, 
+// determine whether the element name has to be shifted to to the left by one
+// column.
+bool shift_left(const String& atom_name, bool is_hetatm, 
+                const String& element, float mass) 
+{
+  if (is_hetatm==false) {
+    return false;
+  }
+
+  if (isdigit(atom_name[0]) || atom_name=="UNK" ||
+      atom_name.length()==4) {
+    return true;
+  }
+  if (mass>34) {
+    if (element=="W" || element=="V") {
+      return false;
+    }    
+    return true;
+  }
+  return (element=="K" || element=="CA" || element=="NA" || 
+          element=="MG" || element=="LI");
+}
+
+void write_atom(std::ostream& ostr, FormattedLine& line, 
+                const mol::AtomHandle& atom, int atomnum, 
                 bool is_pqr)
 {
   mol::ResidueHandle res=atom.GetResidue();
   char ins_code=res.GetNumber().GetInsCode();
-  String record_name=atom.GetAtomProps().is_hetatm ? "HETATM" : "ATOM  ";
-  String aname_str=atom.GetName();
-  if(aname_str.length()<4) {
-    aname_str=" "+aname_str;
-  }
+  StringRef record_name(atom.IsHetAtom() ? "HETATM" : "ATOM  ", 6);
   std::vector<String> names=atom.GetAltGroupNames();
+  
+  geom::Vec3 p=atom.GetPos();
+  line( 0, 6)=record_name;
+  line( 6, 5)=fmt::LPaddedInt(atomnum);
+  String atom_name=atom.GetName();
+  if (atom_name.size()>4) {
+    throw IOException("Atom name '"+atom.GetQualifiedName()+
+                      "' is too long for PDB output. At most 4 character "
+                      "are allowed");
+  }
+  if (shift_left(atom_name, atom.IsHetAtom(), atom.GetElement(), 
+                 atom.GetMass())) {
+    line(12, 4)=fmt::RPadded(atom_name);
+  } else {
+    line(13, 3)=fmt::RPadded(atom_name);
+  }
+  if (res.GetKey().size()>3) {
+    throw IOException("Residue name '"+res.GetQualifiedName()+
+                      "' is too long for PDB output. At most 3 characters are "
+                      "allowed");
+  }
+  line(17, 3)=fmt::LPadded(res.GetKey());
+  
+  String chain_name=res.GetChain().GetName();
+  if (chain_name.size()>0) {
+    if (chain_name.size()==1) {
+      line[21]=chain_name[0];
+    } else {
+      throw IOException("PDB format only support single-letter chain names");
+    }
+  }
+  line(22, 4)=fmt::LPaddedInt(res.GetNumber().GetNum());
+  if (ins_code!=0) {
+    line[26]=ins_code;
+  }
+  
+  // deal with alternative atom locations
   if (names.empty()) {
-    geom::Vec3 p=atom.GetPos();
-    String ins_str=(ins_code==0 ? " " : String(1, ins_code));
-    ostr << record_name << format("%5d") % atomnum
-         << format(" %-4s") % aname_str
-         << " "
-         << format("%.3s") % res.GetKey()
-         << format(" %.1s") % res.GetChain().GetName()
-         << format("%4d%s") % res.GetNumber().GetNum() %  ins_str
-         << "   "
-         << format("%8.3f%8.3f%8.3f") % p[0] % p[1] % p[2];
-    if(is_pqr) {
-      ostr << format("%6.2f") % atom.GetAtomProps().charge
-           << format("%6.2f") % atom.GetAtomProps().radius;
+    line(30, 8)=fmt::LPaddedFloat(p[0],  3);
+    line(38, 8)=fmt::LPaddedFloat(p[1],  3);
+    line(46, 8)=fmt::LPaddedFloat(p[2],  3);
+    
+    if (is_pqr) {
+      line(54, 6)=fmt::LPaddedFloat(atom.GetCharge(), 2);
+      line(60, 6)=fmt::LPaddedFloat(atom.GetRadius(), 2);
     } else {
-      ostr << format("%6.2f") % atom.GetAtomProps().occupancy
-           << format("%6.2f") % atom.GetAtomProps().b_factor;
+      line(54, 6)=fmt::LPaddedFloat(atom.GetOccupancy(), 2);
+      line(60, 6)=fmt::LPaddedFloat(atom.GetBFactor(), 2);
     }
-    ostr << format("%10s%2s") % "" % atom.GetAtomProps().element
-         << std::endl
-    ;    
+    
+    line(76, 2)=fmt::LPadded(atom.GetElement());
+    ostr << line;
   } else {
-    for (std::vector<String>::const_iterator i=names.begin(), 
-         e=names.end(); i!=e; ++i) {
-       geom::Vec3 p=atom.GetAltPos(*i);
-       String ins_str=(ins_code==0 ? " " : String(1, ins_code));
-       ostr << record_name << format("%5d") % atomnum
-            << format(" %-4s") % aname_str
-            << *i
-            << format("%.3s") % res.GetKey()
-            << format(" %.1s") % res.GetChain().GetName()
-            << format("%4d%s") % res.GetNumber().GetNum() %  ins_str
-            << "   "
-            << format("%8.3f%8.3f%8.3f") % p[0] % p[1] % p[2];
-       if(is_pqr) {
-         ostr << format("%6.2f") % atom.GetAtomProps().charge
-              << format("%6.2f") % atom.GetAtomProps().radius;
-       } else {
-         ostr << format("%6.2f") % atom.GetAtomProps().occupancy
-              << format("%6.2f") % atom.GetAtomProps().b_factor;
-       }
-       ostr << format("%10s%2s") % "" % atom.GetAtomProps().element
-            << std::endl
-       ;       
+    for (std::vector<String>::const_iterator
+         i=names.begin(), e=names.end(); i!=e; ++i) {
+      p=atom.GetAltPos(*i);
+      line(30, 50).Clear();
+
+      if (i->size()>1) {
+        throw IOException("Alternative atom indicator '"+atom.GetQualifiedName()+
+                          "("+*i+")' too long for PDB output. At most 1 "
+                          "character is allowed");
+      }
+      line[16]=(*i)[0];
+      line(30, 8)=fmt::LPaddedFloat(p[0],  3);
+      line(38, 8)=fmt::LPaddedFloat(p[1],  3);
+      line(46, 8)=fmt::LPaddedFloat(p[2],  3);
+
+      if (is_pqr) {
+       line(54, 6)=fmt::LPaddedFloat(atom.GetCharge(), 2);
+       line(60, 6)=fmt::LPaddedFloat(atom.GetRadius(), 2);
+      } else {
+       line(54, 6)=fmt::LPaddedFloat(atom.GetOccupancy(), 2);
+       line(60, 6)=fmt::LPaddedFloat(atom.GetBFactor(), 2);
+      }
+
+      line(76, 2)=fmt::LPadded(atom.GetElement());
+      ostr << line;
     }
   }
+
+  line.Clear();
 }
 
 void write_conect(std::ostream& ostr, int atom_index,
@@ -109,35 +168,63 @@ void write_conect(std::ostream& ostr, int atom_index,
 
 class PDBWriterImpl : public mol::EntityVisitor {
 public:
-  PDBWriterImpl(std::ostream& ostream, std::map<long,int>& atom_indices)
-    : ostr_(ostream), counter_(0), is_pqr_(false), last_chain_(),
-      atom_indices_(atom_indices) {
+  PDBWriterImpl(std::ostream& ostream, FormattedLine& line, 
+                std::map<long,int>& atom_indices)
+    : ostr_(ostream), counter_(0), is_pqr_(false),
+      atom_indices_(atom_indices), line_(line), peptide_(false) {
   }
 private:
 public:
   virtual bool VisitAtom(const mol::AtomHandle& atom) {
     counter_++;
-    if (last_chain_!=atom.GetResidue().GetChain()) {
-      if (last_chain_.IsValid()) {
-        ostr_ << "TER" << std::endl;
-      }
-      last_chain_=atom.GetResidue().GetChain();
-    }    
-    write_atom(ostr_, atom, counter_, is_pqr_);
+    write_atom(ostr_, line_, atom, counter_, is_pqr_);
     if (atom.GetAtomProps().is_hetatm) {
       atom_indices_[atom.GetHashCode()]=counter_;
     }
     return true;
   }
+  
+  virtual bool VisitResidue(const mol::ResidueHandle& res)
+  {
+    if (res.IsPeptideLinking()) {
+      peptide_=true;
+    } else {
+      if (peptide_) {
+        this->WriteTer(prev_);
+      }
+      peptide_=false;
+    }
+    prev_=res;
+    return true;
+  }
+  
+  void WriteTer(mol::ResidueHandle res)
+  {
+    counter_++;
+    line_(0, 6)=StringRef("TER   ", 6);
+    line_( 6, 5)=fmt::LPaddedInt(counter_);
+    line_(17, 3)=fmt::LPadded(res.GetKey());
+    line_[21]=res.GetChain().GetName()[0];
+    line_(22, 4)=fmt::LPaddedInt(res.GetNumber().GetNum());
+    char ins_code=res.GetNumber().GetInsCode();
+    if (ins_code!=0) {
+      line_[26]=ins_code;
+    }    
+    ostr_ << line_;
+    line_.Clear();
+  }
+  
   void SetIsPQR(bool t) {
     is_pqr_=t;
   }
 private:
-  std::ostream&    ostr_;
-  int              counter_;
-  bool             is_pqr_;
-  mol::ChainHandle last_chain_;
+  std::ostream&       ostr_;
+  int                 counter_;
+  bool                is_pqr_;
   std::map<long,int>& atom_indices_;
+  FormattedLine&      line_;
+  mol::ResidueHandle  prev_;
+  bool                peptide_;
 };
 
 class PDBConectWriterImpl : public mol::EntityVisitor {
@@ -172,18 +259,32 @@ private:
   std::map<long,int>& atom_indices_;
 };
 
+struct ForcePOSIX {
+  std::locale old_locale;
+  ForcePOSIX(){
+    old_locale=std::locale();
+    setlocale(LC_NUMERIC, "POSIX");
+  }
+  ~ForcePOSIX(){
+    setlocale(LC_NUMERIC, old_locale.name().c_str());
+  }
+};
+
 }
 
 PDBWriter::PDBWriter(std::ostream& stream):
-  outfile_(), outstream_(stream)
-{}
+  outfile_(), outstream_(stream), mol_count_(0), line_(80)
+{
+  
+}
 
 PDBWriter::PDBWriter(const boost::filesystem::path& filename):
-  outfile_(filename.file_string().c_str()), outstream_(outfile_), mol_count_(0)
+  outfile_(filename.file_string().c_str()), outstream_(outfile_), 
+  mol_count_(0), line_(80)
 {}
 
 PDBWriter::PDBWriter(const String& filename):
-  outfile_(filename.c_str()), outstream_(outfile_), mol_count_(0)
+  outfile_(filename.c_str()), outstream_(outfile_), mol_count_(0), line_(80)
 {}
 
 void PDBWriter::WriteModelLeader()
@@ -207,8 +308,9 @@ void PDBWriter::WriteModelTrailer()
 template <typename H>
 void PDBWriter::WriteModel(H ent)
 {
+  ForcePOSIX posix = ForcePOSIX();
   this->WriteModelLeader();
-  PDBWriterImpl writer(outstream_,atom_indices_);
+  PDBWriterImpl writer(outstream_,line_, atom_indices_);
   if (PDB::Flags() & PDB::PQR_FORMAT) {
     writer.SetIsPQR(true);
   }
@@ -230,19 +332,13 @@ void PDBWriter::Write(const mol::EntityHandle& ent)
 
 void PDBWriter::Write(const mol::AtomHandleList& atoms)
 {
+  ForcePOSIX posix = ForcePOSIX();
   this->WriteModelLeader();
   int counter=1;
   mol::ChainHandle last_chain;
   for (mol::AtomHandleList::const_iterator i=atoms.begin(),
        e=atoms.end(); i!=e; ++i, ++counter) {
-
-    if (last_chain!=(*i).GetResidue().GetChain()) {
-      if (last_chain.IsValid()) {
-        outstream_ << "TER" << std::endl;
-      }
-      last_chain=(*i).GetResidue().GetChain();
-    }
-    write_atom(outstream_, *i, counter, PDB::Flags() & PDB::PQR_FORMAT);
+    write_atom(outstream_, line_, *i, counter, (PDB::Flags() & PDB::PQR_FORMAT) != 0);
   }
   this->WriteModelTrailer();
 }
diff --git a/modules/io/src/mol/pdb_writer.hh b/modules/io/src/mol/pdb_writer.hh
index 68a9332a9..40ed1cbff 100644
--- a/modules/io/src/mol/pdb_writer.hh
+++ b/modules/io/src/mol/pdb_writer.hh
@@ -28,9 +28,11 @@
 #include <boost/filesystem/fstream.hpp>
 #include <boost/iostreams/filtering_stream.hpp>
 
+#include <ost/mol/mol.hh>
+
 #include <ost/io/module_config.hh>
+#include <ost/io/formatted_line.hh>
 
-#include <ost/mol/mol.hh>
 
 #include "pdb_io.hh"
 
@@ -58,6 +60,7 @@ private:
   std::ostream&   outstream_;
   int mol_count_;
   std::map<long, int> atom_indices_;
+  FormattedLine       line_;
 };
  
 }}
diff --git a/modules/io/src/mol/sdf_reader.cc b/modules/io/src/mol/sdf_reader.cc
new file mode 100644
index 000000000..e2f0fabd2
--- /dev/null
+++ b/modules/io/src/mol/sdf_reader.cc
@@ -0,0 +1,275 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+/*
+  Author: Tobias Schmidt
+ */
+
+#include <boost/algorithm/string.hpp>
+#include <boost/format.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include <ost/conop/conop.hh>
+#include <ost/io/io_exception.hh>
+#include <ost/log.hh>
+#include <ost/mol/xcs_editor.hh>
+
+#include "sdf_reader.hh"
+
+namespace ost { namespace io {
+
+using boost::format;
+
+SDFReader::SDFReader(const String& filename)
+  : infile_(filename), instream_(infile_) {
+  this->ClearState();
+}
+
+SDFReader::SDFReader(const boost::filesystem::path& loc)
+  : infile_(loc), instream_(infile_) {
+  this->ClearState();
+}
+
+SDFReader::SDFReader(std::istream& instream)
+  : infile_(), instream_(instream) {
+  this->ClearState();
+}
+
+// import data from provided stream
+void SDFReader::Import(mol::EntityHandle& ent)
+{
+  String line;
+  mol::XCSEditor editor=ent.RequestXCSEditor(mol::BUFFERED_EDIT);
+  while (std::getline(instream_,line)) {
+    ++line_num;
+
+    if (line_num<=4) {
+      ParseAndAddHeader(line, line_num, ent, editor);
+    } else if (line_num<=atom_count_+4) {
+      ParseAndAddAtom(line, line_num, ent, true, editor);
+    } else if (line_num<=bond_count_+atom_count_+4) {
+      ParseAndAddBond(line, line_num, ent, editor);
+    } else if (boost::iequals(line.substr(0,2), "> ")) {
+      // parse data items
+      int data_header_start = line.find('<');
+      if(data_header_start==-1) {
+        String msg="Bad data line %d: Could not find start or end of header";
+        throw IOException(str(format(msg) % line_num));
+      }
+      String data_header = line.substr(data_header_start+1,line.rfind('>')-data_header_start-1);
+      if(data_header.empty()) {
+        String msg="Bad data line %d: Could not find data header";
+        throw IOException(str(format(msg) % line_num));
+      }
+      String data_value="";
+      while(std::getline(instream_,line) && !boost::iequals(line, "")) {
+        data_value.append(line);
+      }
+      curr_chain_.SetStringProp(data_header, data_value);
+    } else if (boost::iequals(line, "$$$$")) {
+      LOGN_MESSAGE("MOLECULE " << curr_chain_.GetName() << " (" << chain_count_ << ") added.")
+      NextMolecule();
+    }
+  }
+
+  LOGN_MESSAGE("imported " << chain_count_ << " chains, " << residue_count_
+               << " residues, " << atom_count_ << " atoms");
+}
+
+void SDFReader::ClearState()
+{
+  curr_chain_=mol::ChainHandle();
+  curr_residue_=mol::ResidueHandle();
+  chain_count_=0;
+  residue_count_=0;
+  atom_count_=0;
+  bond_count_=0;
+  line_num=0;
+}
+
+void SDFReader::NextMolecule()
+{
+  residue_count_=0;
+  atom_count_=0;
+  bond_count_=0;
+  line_num=0;
+}
+
+void SDFReader::ParseAndAddHeader(const String& line, int line_num,
+                                  mol::EntityHandle& ent, mol::XCSEditor& editor)
+{
+  LOGN_TRACE( "line: [" << line << "]" );
+  format chain_fmter("%05i_%s");
+  switch(line_num)
+  {
+    case 1:  // title line
+    {
+      ++chain_count_;
+      String s_title=line;
+      String s_chain;
+      chain_fmter % chain_count_ % boost::trim_copy(s_title);
+      s_chain=chain_fmter.str();
+      if(s_chain.empty()) {
+        String msg="Bad molecule name line %d: Line is empty";
+        throw IOException(str(format(msg) % line_num));
+      }
+      curr_chain_=editor.InsertChain(s_chain);
+      LOGN_DUMP("new chain " << s_chain);
+
+      mol::ResidueKey rkey=boost::trim_copy(s_title);
+      mol::ResNum rnum(++residue_count_);
+      curr_residue_=editor.AppendResidue(curr_chain_, rkey, rnum);
+      LOGN_DUMP("new residue " << rkey << "(" << rnum << ")");
+      break;
+    }
+    case 2:  // user information line
+      break;
+    case 3:  // comments line
+      break;
+    case 4:  // counts line
+    {
+      String s_anum=line.substr(0,3);
+      try {
+        atom_count_=boost::lexical_cast<int>(boost::trim_copy(s_anum));
+      } catch(boost::bad_lexical_cast&) {
+        String msg="Bad counts line %d: Can't convert number of atoms"
+                   " '%s' to integral constant.";
+        throw IOException(str(format(msg) % line_num % s_anum));
+      }
+      String s_bnum=line.substr(3,3);
+      try {
+        bond_count_=boost::lexical_cast<int>(boost::trim_copy(s_bnum));
+      } catch(boost::bad_lexical_cast&) {
+        String msg="Bad counts line %d: Can't convert number of bonds"
+                   " '%s' to integral constant.";
+        throw IOException(str(format(msg) % line_num % s_bnum));
+      }
+      break;
+    }
+  }
+}
+
+void SDFReader::ParseAndAddAtom(const String& line, int line_num,
+                                mol::EntityHandle& ent, bool hetatm,
+                                mol::XCSEditor& editor)
+{
+
+  LOGN_TRACE( "line: [" << line << "]" );
+
+  if(line.length()<48 || line.length()>69) {
+    String msg="Bad atom line %d: Not correct number of characters on the"
+               " line: %i (should be between 48 and 69)";
+    throw IOException(str(format(msg) % line_num % line.length()));
+  }
+  int anum = line_num-4;  // start at 1 on fifth line since first four lines are header
+  String s_posx=line.substr(0,10);
+  String s_posy=line.substr(10,10);
+  String s_posz=line.substr(20,10);
+  String s_ele=line.substr(31,3);
+  String s_charge=line.substr(36,3);
+
+  geom::Vec3 apos;
+  try {
+    apos=geom::Vec3(boost::lexical_cast<Real>(boost::trim_copy(s_posx)),
+                    boost::lexical_cast<Real>(boost::trim_copy(s_posy)),
+                    boost::lexical_cast<Real>(boost::trim_copy(s_posz)));
+  } catch(boost::bad_lexical_cast&) {
+    String msg="Bad atom line %d: Can't convert coordinates to "
+               "floating point numbers";
+    throw IOException(str(format(msg) % line_num));
+  }
+
+  String ele=boost::trim_copy(s_ele);
+  String aname=boost::lexical_cast<String>(anum);
+
+  mol::AtomProp aprop;
+  aprop.element=ele;
+  aprop.radius=conop::Conopology::Instance().GetDefaultAtomRadius(ele);
+  aprop.mass=conop::Conopology::Instance().GetDefaultAtomMass(ele);
+  aprop.is_hetatm=hetatm;
+
+  try {
+    aprop.charge=boost::lexical_cast<Real>(boost::trim_copy(s_charge));
+    if(aprop.charge != 0) {
+      aprop.charge=4-aprop.charge;
+    } //4-sdf_charge=real_charge if not 0
+  } catch(boost::bad_lexical_cast&) {
+    String msg="Bad atom line %d: Can't convert charge"
+               " '%s' to integral constant.";
+    throw IOException(str(format(msg) % line_num % s_charge));
+  }
+
+  LOGN_DUMP("adding atom " << aname << " (" << s_ele << ") @" << apos);
+
+  editor.InsertAtom(curr_residue_, aname,apos,aprop);
+}
+
+
+void SDFReader::ParseAndAddBond(const String& line, int line_num,
+                                mol::EntityHandle& ent, mol::XCSEditor& editor)
+{
+
+  LOGN_TRACE( "line: [" << line << "]" );
+
+  if(line.length()<18 || line.length()>21) {
+    String msg="Bad bond line %d: Not correct number of characters on the"
+               " line: %i (should be between 18 and 21)";
+    throw IOException(str(format(msg) % line_num % line.length()));
+  }
+
+  String s_first_name=line.substr(0,3);
+  String s_second_name=line.substr(3,3);
+  String s_type=line.substr(6,3);
+  String first_name, second_name;
+  unsigned char type;
+  mol::BondHandle bond;
+
+  first_name=boost::trim_copy(s_first_name);
+  second_name=boost::trim_copy(s_second_name);
+
+  try {
+    type=boost::lexical_cast<int>(boost::trim_copy(s_type));
+    if (type<1 || type>8) {
+      String msg="Bad bond line %d: Bond type number"
+                      " '%s' not within accepted range (1-8).";
+      throw IOException(str(format(msg) % line_num % s_type));
+    }
+  } catch(boost::bad_lexical_cast&) {
+    String msg="Bad bond line %d: Can't convert bond type number"
+                " '%s' to integral constant.";
+    throw IOException(str(format(msg) % line_num % s_type));
+  }
+
+  mol::AtomHandle first,second;
+
+  first = ent.FindAtom(curr_chain_.GetName(), mol::ResNum(residue_count_), first_name);
+  second = ent.FindAtom(curr_chain_.GetName(), mol::ResNum(residue_count_), second_name);
+
+  if(first.IsValid() && second.IsValid()) {
+    bond = editor.Connect(first, second);
+    bond.SetBondOrder(type);
+  } else {
+    String msg="Bad bond line %d: Can't find the atom names '%s', '%s'"
+               " in entity.";
+    throw IOException(str(format(msg) % line_num % first % second));
+  }
+
+  LOGN_DUMP("adding bond " << s_first_name << " " << s_second_name << " (" << s_type << ") ");
+}
+
+}}
diff --git a/modules/io/src/mol/sdf_reader.hh b/modules/io/src/mol/sdf_reader.hh
new file mode 100644
index 000000000..0401e6ab7
--- /dev/null
+++ b/modules/io/src/mol/sdf_reader.hh
@@ -0,0 +1,67 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+/*
+  Author: Tobias Schmidt
+ */
+#ifndef OST_IO_SDF_READER_HH
+#define OST_IO_SDF_READER_HH
+
+#include <boost/filesystem/fstream.hpp>
+#include <ost/mol/mol.hh>
+#include <ost/io/module_config.hh>
+
+namespace ost { namespace io {
+
+class DLLEXPORT_OST_IO SDFReader {
+public:
+  SDFReader(const String& filename);
+  SDFReader(const boost::filesystem::path& loc);
+  SDFReader(std::istream& instream);
+
+  bool HasNext();
+
+  void Import(mol::EntityHandle& ent);
+
+private:
+  void ClearState();
+  void NextMolecule();
+
+  void ParseAndAddHeader(const String& line, int line_num, mol::EntityHandle& ent,
+                         mol::XCSEditor& editor);
+
+  void ParseAndAddAtom(const String& line, int line_num, mol::EntityHandle& ent,
+                       bool hetatm, mol::XCSEditor& editor);
+
+  void ParseAndAddBond(const String& line, int line_num, mol::EntityHandle& ent,
+                       mol::XCSEditor& editor);
+
+  mol::ChainHandle curr_chain_;
+  mol::ResidueHandle curr_residue_;
+  int chain_count_;
+  int residue_count_;
+  int atom_count_;
+  int bond_count_;
+  int line_num;
+  boost::filesystem::ifstream infile_;
+  std::istream& instream_;
+};
+
+}}
+
+#endif
diff --git a/modules/io/src/mol/sdf_writer.cc b/modules/io/src/mol/sdf_writer.cc
new file mode 100644
index 000000000..b6243b4a6
--- /dev/null
+++ b/modules/io/src/mol/sdf_writer.cc
@@ -0,0 +1,158 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+/*
+  Author: Tobias Schmidt
+ */
+
+#include "sdf_writer.hh"
+
+namespace ost { namespace io {
+
+using boost::format;
+
+namespace {
+
+  class SDFAtomWriter : public mol::EntityVisitor {
+    public:
+      SDFAtomWriter(std::ostream& ostream, std::map<long, int>& atom_indices)
+      : ostr_(ostream), atom_indices_(atom_indices), counter_(0) {
+  atom_indices_.clear();
+      }
+    private:
+    public:
+      virtual bool VisitAtom(const mol::AtomHandle& atom) {
+        atom_indices_[atom.GetHashCode()] = ++counter_;
+        ostr_ << format("%10.4f") % atom.GetPos()[0]
+              << format("%10.4f") % atom.GetPos()[1]
+              << format("%10.4f ") % atom.GetPos()[2]
+              << format("%-3s") % atom.GetElement()
+              << " 0  0  0  0  0  0"
+              << std::endl;
+        return true;
+      }
+    private:
+      std::ostream&      ostr_;
+      std::map<long, int>& atom_indices_;
+      int counter_;
+  };
+
+  class SDFBondWriter : public mol::EntityVisitor {
+  public:
+    SDFBondWriter(std::ostream& ostream, std::map<long, int>& atom_indices)
+      : ostr_(ostream), atom_indices_(atom_indices), counter_(0) {
+    }
+  private:
+  public:
+    virtual bool VisitAtom(const mol::AtomHandle& atom) {
+      counter_++;
+      mol::AtomHandleList atoms = atom.GetBondPartners();
+      mol::AtomHandleList::iterator atom_iter = atoms.begin();
+      for(; atom_iter != atoms.end(); ++atom_iter) {
+        int atom_index = atom_indices_.find((*atom_iter).GetHashCode())->second;
+        if(atom_index > counter_) {
+          int type = 1;
+          mol::BondHandle bond = atom.FindBondToAtom(*atom_iter);
+          if(bond.IsValid()) type = bond.GetBondOrder();
+          ostr_ << format("%3i") % counter_
+                << format("%3i") % atom_index
+                << format("%3i") % type
+                << "  0  0  0"
+                << std::endl;
+        }
+      }
+      return true;
+    }
+
+  private:
+    std::ostream&      ostr_;
+    std::map<long, int>& atom_indices_;
+    int counter_;
+  };
+}
+
+SDFWriter::SDFWriter(std::ostream& ostream)
+  : outfile_(), ostr_(ostream), counter_(0) {
+}
+
+SDFWriter::SDFWriter(const String& filename)
+  : outfile_(filename.c_str()), ostr_(outfile_), counter_(0) {
+}
+
+SDFWriter::SDFWriter(const boost::filesystem::path& filename)
+  : outfile_(filename.file_string().c_str()), ostr_(outfile_), counter_(0) {
+}
+
+void SDFWriter::Write(const mol::EntityView& ent) {
+  mol::EntityView non_const_view = ent;
+  non_const_view.Apply(*this);
+}
+
+void SDFWriter::Write(const mol::EntityHandle& ent) {
+  mol::EntityHandle non_const_handle = ent;
+  non_const_handle.Apply(*this);
+}
+
+bool SDFWriter::VisitChain(const mol::ChainHandle& chain) {
+  // print end of molecule line
+  if(counter_ != 0) {
+    ostr_ << "$$$$" << std::endl;
+    counter_ = 0;
+    atom_indices_.clear();
+  }
+
+  // print header lines
+  ostr_ << chain.GetName().substr(6) << std::endl;
+  ostr_ << std::endl;
+  ostr_ << std::endl;
+
+  // print counts line
+  ostr_ << format("%3d") % chain.GetAtomCount()
+        << format("%3d") % chain.GetBondCount()
+        << "  0  0  0  0            999 V2000"
+        << std::endl;
+
+  // write atom block
+  SDFAtomWriter atom_writer(ostr_, atom_indices_);
+  mol::ChainHandle non_const_chain = chain;
+  non_const_chain.Apply(atom_writer);
+
+  // write bond block
+  SDFBondWriter bond_writer(ostr_, atom_indices_);
+  non_const_chain.Apply(bond_writer);
+
+  // write property block
+  //TODO: write property block
+  ostr_ << "M  END" << std::endl;
+
+  // write data block
+  std::map<String,GenericPropValue> prop_map = non_const_chain.GetPropMap();
+  std::map<String,GenericPropValue>::iterator iter;
+  for(iter = prop_map.begin(); iter != prop_map.end(); ++iter) {
+    ostr_ << "> <" << (*iter).first << ">" << std::endl;
+    ostr_ << (*iter).second << std::endl;
+    ostr_ << std::endl;
+  }
+
+  // write molecule endline
+  ostr_ << "$$$$" << std::endl;
+
+  return true;
+}
+
+}}
diff --git a/modules/io/src/mol/sdf_writer.hh b/modules/io/src/mol/sdf_writer.hh
new file mode 100644
index 000000000..62a365d49
--- /dev/null
+++ b/modules/io/src/mol/sdf_writer.hh
@@ -0,0 +1,61 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+/*
+  Author: Tobias Schmidt
+ */
+#ifndef OST_IO_SDF_WRITER_HH
+#define OST_IO_SDF_WRITER_HH
+
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+
+#include <boost/filesystem/fstream.hpp>
+#include <boost/filesystem/convenience.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/format.hpp>
+#include <ost/log.hh>
+#include <ost/conop/conop.hh>
+#include <ost/io/io_exception.hh>
+#include <ost/mol/mol.hh>
+
+namespace ost { namespace io {
+
+class DLLEXPORT_OST_IO SDFWriter : public mol::EntityVisitor {
+public:
+  SDFWriter(std::ostream& ostream);
+  SDFWriter(const String& filename);
+  SDFWriter(const boost::filesystem::path& filename);
+
+  void Write(const mol::EntityView& ent);
+  void Write(const mol::EntityHandle& ent);
+
+private:
+  virtual bool VisitChain(const mol::ChainHandle& chain);
+
+  std::ofstream      outfile_;
+  std::ostream&      ostr_;
+  int                counter_;
+  std::map<long,int> atom_indices_;
+};
+
+}}
+
+#endif
diff --git a/modules/io/tests/test_io_pdb.cc b/modules/io/tests/test_io_pdb.cc
index 811c459a8..3b9b691c3 100644
--- a/modules/io/tests/test_io_pdb.cc
+++ b/modules/io/tests/test_io_pdb.cc
@@ -16,9 +16,12 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
+#include <ost/test_utils/compare_files.hh>
 #include <ost/mol/mol.hh>
+#include <ost/conop/conop.hh>
 #include <ost/io/mol/entity_io_pdb_handler.hh>
 #include <ost/io/pdb_reader.hh>
+#include <ost/io/pdb_writer.hh>
 #include <ost/io/io_exception.hh>
 #define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
@@ -160,18 +163,17 @@ BOOST_AUTO_TEST_CASE(anisou_record)
   mol::AtomHandle a1=ent.FindAtom("A", mol::ResNum(7), "N");
   BOOST_REQUIRE(a1.IsValid());
   mol::AtomProp props=a1.GetAtomProps();
-  BOOST_CHECK_CLOSE( 0.0100, props.anisou(0, 0), 1e-4);
-  BOOST_CHECK_CLOSE(-0.0016, props.anisou(1, 0), 1e-4);
-  BOOST_CHECK_CLOSE(-0.0026, props.anisou(2, 0), 1e-4);
-  BOOST_CHECK_CLOSE(-0.0016, props.anisou(0, 1), 1e-4);
-  BOOST_CHECK_CLOSE( 0.0110, props.anisou(1, 1), 1e-4);
-  BOOST_CHECK_CLOSE(-0.0054, props.anisou(2, 1), 1e-4);
-  BOOST_CHECK_CLOSE(-0.0026, props.anisou(0, 2), 1e-4);
-  BOOST_CHECK_CLOSE(-0.0054, props.anisou(1, 2), 1e-4);
-  BOOST_CHECK_CLOSE( 0.0120, props.anisou(2, 2), 1e-4);    
+  BOOST_CHECK_CLOSE(Real( 0.0100), props.anisou(0, 0), Real(1e-4));
+  BOOST_CHECK_CLOSE(Real(-0.0016), props.anisou(1, 0), Real(1e-4));
+  BOOST_CHECK_CLOSE(Real(-0.0026), props.anisou(2, 0), Real(1e-4));
+  BOOST_CHECK_CLOSE(Real(-0.0016), props.anisou(0, 1), Real(1e-4));
+  BOOST_CHECK_CLOSE(Real( 0.0110), props.anisou(1, 1), Real(1e-4));
+  BOOST_CHECK_CLOSE(Real(-0.0054), props.anisou(2, 1), Real(1e-4));
+  BOOST_CHECK_CLOSE(Real(-0.0026), props.anisou(0, 2), Real(1e-4));
+  BOOST_CHECK_CLOSE(Real(-0.0054), props.anisou(1, 2), Real(1e-4));
+  BOOST_CHECK_CLOSE(Real( 0.0120), props.anisou(2, 2), Real(1e-4));    
 }
 
-
 BOOST_AUTO_TEST_CASE(only_66_cols)
 {
   String fname("testfiles/pdb/short.pdb");
@@ -186,7 +188,54 @@ BOOST_AUTO_TEST_CASE(no_endmdl_record)
   PDBReader reader(fname);
   mol::EntityHandle ent=mol::CreateEntity();
   BOOST_CHECK_THROW(reader.Import(ent), IOException);
+}
 
+BOOST_AUTO_TEST_CASE(write_atom)
+{
+  std::stringstream out;
+  PDBWriter writer(out);
+  
+  mol::EntityHandle ent=mol::CreateEntity();
+  mol::XCSEditor edi=ent.RequestXCSEditor();
+  mol::ChainHandle ch=edi.InsertChain("A");
+  mol::ResidueHandle r=edi.AppendResidue(ch, "GLY");
+  mol::AtomProp c_prop;
+  c_prop.element="C";
+  c_prop.occupancy=1.0;
+  c_prop.b_factor=128.0;
+  mol::AtomHandle a=edi.InsertAtom(r, "CA", geom::Vec3(32.0, -128.0, -2.5), 
+                                   c_prop);
+  writer.Write(ent);
+  String s=out.str();
+  BOOST_CHECK_EQUAL(s.substr(0, 54), 
+                    "ATOM      1  CA  GLY A   1      32.000-128.000  -2.500");
+  BOOST_CHECK_EQUAL(s.substr(54, 26), 
+                    "  1.00128.00           C  ");
+}
+
+BOOST_AUTO_TEST_CASE(write_hetatom)
+{
+  std::stringstream out;
+  PDBWriter writer(out);
+  
+  mol::EntityHandle ent=mol::CreateEntity();
+  mol::XCSEditor edi=ent.RequestXCSEditor();
+  mol::ChainHandle ch=edi.InsertChain("A");
+  mol::ResidueHandle r=edi.AppendResidue(ch, "CA");
+  mol::AtomProp c_prop;
+  c_prop.element="CA";
+  c_prop.is_hetatm=true;
+  c_prop.mass=40.01;
+  c_prop.occupancy=1.0;
+  c_prop.b_factor=40.75;
+  mol::AtomHandle a=edi.InsertAtom(r, "CA", geom::Vec3(32.0, -128.0, -2.5), 
+                                   c_prop);
+  writer.Write(ent);
+  String s=out.str();
+  BOOST_CHECK_EQUAL(s.substr(0, 54), 
+                    "HETATM    1 CA    CA A   1      32.000-128.000  -2.500");
+  BOOST_CHECK_EQUAL(s.substr(54, 26), 
+                    "  1.00 40.75          CA  ");
 }
 
 BOOST_AUTO_TEST_CASE(no_endmdl_record_fault_tolerant)
@@ -207,4 +256,98 @@ BOOST_AUTO_TEST_CASE(no_endmdl_record_fault_tolerant)
   PDB::PopFlags();
 }
 
+BOOST_AUTO_TEST_CASE(alt_loc_import_export)
+{
+  String fname("testfiles/pdb/alt-loc.pdb");  
+  // this scope is required to force the writer stream to be closed before 
+  // opening the file again in compare_files. Avoids a race condition.
+  {
+    PDBReader reader(fname);
+    PDBWriter writer(String("testfiles/pdb/alt-loc-out.pdb"));
+    
+    mol::EntityHandle ent=mol::CreateEntity();
+    reader.Import(ent);
+    writer.Write(ent);
+  }
+  BOOST_CHECK(compare_files("testfiles/pdb/alt-loc.pdb", 
+                            "testfiles/pdb/alt-loc-out.pdb"));
+}
+
+BOOST_AUTO_TEST_CASE(write_ter)
+{
+  String fname("testfiles/pdb/ter.pdb");  
+  // this scope is required to force the writer stream to be closed before 
+  // opening the file again in compare_files. Avoids a race condition.
+  {
+    PDBReader reader(fname);
+    PDBWriter writer(String("testfiles/pdb/ter-out.pdb"));
+    
+    mol::EntityHandle ent=mol::CreateEntity();
+    reader.Import(ent);
+    // we use conopology to mark amino acids as peptide-linking. this is require 
+    // for proper TER output
+    conop::Conopology& conop_inst=conop::Conopology::Instance();
+    conop_inst.ConnectAll(conop_inst.GetBuilder(), ent);
+    writer.Write(ent);
+  }
+  BOOST_CHECK(compare_files("testfiles/pdb/ter.pdb", 
+                            "testfiles/pdb/ter-out.pdb"));
+}
+
+BOOST_AUTO_TEST_CASE(write_conect)
+{
+  // this scope is required to force the writer stream to be closed before
+  // opening the file again in compare_files. Avoids a race condition.
+  {
+    PDBReader reader(String("testfiles/pdb/conect.pdb"));
+    PDBWriter writer(String("testfiles/pdb/conect-out.pdb"));
+    mol::EntityHandle ent=mol::CreateEntity();
+    reader.Import(ent);
+    conop::Conopology& conop_inst=conop::Conopology::Instance();
+    conop_inst.ConnectAll(conop_inst.GetBuilder(), ent);
+    writer.Write(ent);
+  }
+  BOOST_CHECK(compare_files("testfiles/pdb/conect.pdb",
+                            "testfiles/pdb/conect-out.pdb"));
+}
+
+BOOST_AUTO_TEST_CASE(res_name_too_long)
+{
+  std::stringstream out;
+  PDBWriter writer(out);
+  
+  mol::EntityHandle ent=mol::CreateEntity();
+  mol::XCSEditor edi=ent.RequestXCSEditor();
+  mol::ChainHandle ch=edi.InsertChain("A");
+  mol::ResidueHandle r=edi.AppendResidue(ch, "CALCIUM");
+  mol::AtomHandle a=edi.InsertAtom(r, "CA", geom::Vec3(32.0, -128.0, -2.5));
+  BOOST_CHECK_THROW(writer.Write(ent), IOException);
+}
+
+BOOST_AUTO_TEST_CASE(chain_name_too_long)
+{
+  std::stringstream out;
+  PDBWriter writer(out);
+  
+  mol::EntityHandle ent=mol::CreateEntity();
+  mol::XCSEditor edi=ent.RequestXCSEditor();
+  mol::ChainHandle ch=edi.InsertChain("AB");
+  mol::ResidueHandle r=edi.AppendResidue(ch, "CA");
+  mol::AtomHandle a=edi.InsertAtom(r, "CA", geom::Vec3(32.0, -128.0, -2.5));
+  BOOST_CHECK_THROW(writer.Write(ent), IOException);
+}
+
+BOOST_AUTO_TEST_CASE(atom_name_too_long)
+{
+  std::stringstream out;
+  PDBWriter writer(out);
+  
+  mol::EntityHandle ent=mol::CreateEntity();
+  mol::XCSEditor edi=ent.RequestXCSEditor();
+  mol::ChainHandle ch=edi.InsertChain("A");
+  mol::ResidueHandle r=edi.AppendResidue(ch, "CA");
+  mol::AtomHandle a=edi.InsertAtom(r, "CALCIUM", geom::Vec3(32.0, -128.0, -2.5));
+  BOOST_CHECK_THROW(writer.Write(ent), IOException);
+}
+
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/modules/io/tests/test_io_sdf.cc b/modules/io/tests/test_io_sdf.cc
index 71c773f39..bbf858427 100644
--- a/modules/io/tests/test_io_sdf.cc
+++ b/modules/io/tests/test_io_sdf.cc
@@ -16,33 +16,110 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
+#include <ost/test_utils/compare_files.hh>
 #include <ost/mol/mol.hh>
 #include <ost/io/mol/entity_io_sdf_handler.hh>
+#include <ost/io/save_entity.hh>
+#include <ost/io/io_exception.hh>
 #define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/algorithm/string.hpp>
+using boost::unit_test_framework::test_suite;
 
 using namespace ost;
 using namespace ost::io;
 
 BOOST_AUTO_TEST_SUITE( io )
 
-
-BOOST_AUTO_TEST_CASE(test_io_sdf) 
+BOOST_AUTO_TEST_CASE(test_sdf_import_handler)
 {
-  const String fname("testfiles/test_in.sdf");
+  String fname("testfiles/sdf/compound.sdf");
 
   mol::EntityHandle eh=mol::CreateEntity();
   EntityIOSDFHandler sdfh;
 
-  // check format
   BOOST_CHECK(EntityIOSDFHandler::ProvidesImport("","sdf"));
   BOOST_CHECK(EntityIOSDFHandler::ProvidesImport(fname));
   BOOST_CHECK(EntityIOSDFHandler::ProvidesImport("test_in.SDF"));
 
+  BOOST_CHECK(EntityIOSDFHandler::ProvidesExport("","sdf"));
+  BOOST_CHECK(EntityIOSDFHandler::ProvidesExport(fname));
+  BOOST_CHECK(EntityIOSDFHandler::ProvidesExport("test_in.SDF"));
+
+  sdfh.Import(eh,"testfiles/sdf/compound.sdf");
+}
+
+BOOST_AUTO_TEST_CASE(simple_sdf)
+{
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+  sdfh.Import(eh,"testfiles/sdf/simple.sdf");
+
+  // check compounds/atoms/bonds count
+  BOOST_CHECK_EQUAL(eh.GetChainCount(), 1);
+  BOOST_CHECK_EQUAL(eh.GetAtomCount(),  6);
+  BOOST_CHECK_EQUAL(eh.GetBondCount(),  6);
+  BOOST_CHECK_CLOSE(eh.GetMass(), Real(121.545502), Real(1e-4));
+
+  // check atom/bond types
+  mol::AtomHandle ah=eh.GetAtomList()[0];
+  mol::AtomHandle ah2=eh.GetAtomList()[5];
+
+  BOOST_CHECK_EQUAL(ah.GetElement(),  "N");
+  BOOST_CHECK_EQUAL(ah2.GetElement(), "Cl");
+  BOOST_CHECK_CLOSE(ah.GetRadius(),  Real(1.55), Real(1e-2));
+  BOOST_CHECK_CLOSE(ah2.GetRadius(), Real(1.75), Real(1e-2));
+  BOOST_CHECK_CLOSE(ah.GetMass(),  Real(14.0067), Real(1e-4));
+  BOOST_CHECK_CLOSE(ah2.GetMass(), Real(35.453), Real(1e-3));
+  BOOST_CHECK_EQUAL(ah.GetBondCount(),  3);
+  BOOST_CHECK_EQUAL(ah2.GetBondCount(), 1);
+  BOOST_CHECK_EQUAL(ah.GetCharge(),  1);
+  BOOST_CHECK_EQUAL(ah2.GetCharge(), 0);
+
+  mol::BondHandle bh=ah.GetBondList()[0];
+  BOOST_CHECK_EQUAL(bh.GetBondOrder(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(multiple_sdf)
+{
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+  sdfh.Import(eh,"testfiles/sdf/multiple.sdf");
+
+  // check number of compounds
+  BOOST_CHECK_EQUAL(eh.GetChainCount(), 4);
+}
+
+BOOST_AUTO_TEST_CASE(properties_sdf)
+{
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+  sdfh.Import(eh,"testfiles/sdf/properties.sdf");
+
+  // check number of compounds
+  mol::ChainHandleList chl=eh.GetChainList();
+  int count=1;
+  for (mol::ChainHandleList::iterator i=chl.begin();i!=chl.end();++i,count++)
+  {
+    BOOST_REQUIRE(i->HasProp("prop_one"));
+    BOOST_REQUIRE(i->HasProp("prop_two"));
+    BOOST_CHECK_CLOSE(boost::lexical_cast<Real>(i->GetStringProp("prop_one")),
+                      Real(count),Real(1e-4));
+    BOOST_CHECK_CLOSE(boost::lexical_cast<Real>(i->GetStringProp("prop_two")),
+                      Real(count*(-2.2)),Real(1e-4));
+  }
+}
+
+BOOST_AUTO_TEST_CASE(read_sdf)
+{
+  const String fname("testfiles/sdf/compound.sdf");
+
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+
   // check import
-  sdfh.Import(eh,"testfiles/test_in.sdf");
+  sdfh.Import(eh,"testfiles/sdf/compound.sdf");
 
   // check atoms/bonds
   BOOST_CHECK_EQUAL(eh.GetChainCount(), 4);
@@ -50,14 +127,107 @@ BOOST_AUTO_TEST_CASE(test_io_sdf)
   BOOST_CHECK_EQUAL(eh.GetBondCount(), 188);
 
   // check molecule name
-  mol::ChainHandle ch=eh.FindChain("00003_Displayed atoms");
+  mol::ChainHandle ch=eh.FindChain("00003_Test Ligand");
   BOOST_CHECK(ch.IsValid());
 
   // check properties
   BOOST_CHECK(ch.HasProp("r_i_glide_rmsd"));
-  BOOST_CHECK_EQUAL(boost::lexical_cast<Real>(boost::trim_copy
+  BOOST_CHECK_EQUAL(boost::lexical_cast<float>(boost::trim_copy
                      (ch.GetStringProp("r_i_glide_rmsd"))),
                      0.543804f);
 }
 
+BOOST_AUTO_TEST_CASE(write_sdf)
+{
+  // this scope is required to force the writer stream to be closed before
+  // opening the file again in compare_files. Avoids a race condition.
+  {
+    mol::EntityHandle eh=mol::CreateEntity();
+    EntityIOSDFHandler sdfh;
+    sdfh.Import(eh,"testfiles/sdf/compound.sdf");
+    SaveEntity(eh, "testfiles/sdf/compound-out.sdf");
+  }
+  BOOST_CHECK(compare_files("testfiles/sdf/compound.sdf",
+                            "testfiles/sdf/compound-out.sdf"));
+}
+
+BOOST_AUTO_TEST_CASE(wrong_atomcount_error_sdf)
+{
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+  BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf/wrong_atomcount.sdf"), IOException);
+}
+
+BOOST_AUTO_TEST_CASE(wrong_bondcount_error_sdf)
+{
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+  BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf/wrong_bondcount.sdf"), IOException);
+}
+
+BOOST_AUTO_TEST_CASE(wrong_atomlinelength_error_sdf)
+{
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+
+  BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf/wrong_atomlinelength.sdf"), IOException);
+}
+
+BOOST_AUTO_TEST_CASE(wrong_atompos_error_sdf)
+{
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+
+  BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf/wrong_atompos.sdf"), IOException);
+}
+
+BOOST_AUTO_TEST_CASE(wrong_charge_error_sdf)
+{
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+
+  BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf/wrong_charge.sdf"), IOException);
+}
+
+BOOST_AUTO_TEST_CASE(wrong_bondlinelength_error_sdf)
+{
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+
+  BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf/wrong_bondlinelength.sdf"), IOException);
+}
+
+BOOST_AUTO_TEST_CASE(wrong_bondtype_error_sdf)
+{
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+
+  BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf/wrong_bondtype.sdf"), IOException);
+}
+
+BOOST_AUTO_TEST_CASE(wrong_bondatomnumber_error_sdf)
+{
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+
+  BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf/wrong_bondatomnumber.sdf"), IOException);
+}
+
+BOOST_AUTO_TEST_CASE(wrong_dataheader_error_sdf)
+{
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+
+  BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf/wrong_dataheader.sdf"), IOException);
+}
+
+BOOST_AUTO_TEST_CASE(empty_dataheader_error_sdf)
+{
+  mol::EntityHandle eh=mol::CreateEntity();
+  EntityIOSDFHandler sdfh;
+
+  BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf/empty_dataheader.sdf"), IOException);
+}
+
+
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/modules/io/tests/testfiles/pdb/alt-loc.pdb b/modules/io/tests/testfiles/pdb/alt-loc.pdb
new file mode 100644
index 000000000..b08f83459
--- /dev/null
+++ b/modules/io/tests/testfiles/pdb/alt-loc.pdb
@@ -0,0 +1,3 @@
+ATOM      1  N  AMET A   1      16.000  64.000   0.000  0.50  1.00           N  
+ATOM      1  N  BMET A   1       8.000-128.000   0.000  0.50  1.00           N  
+END   
\ No newline at end of file
diff --git a/modules/io/tests/testfiles/pdb/conect.pdb b/modules/io/tests/testfiles/pdb/conect.pdb
new file mode 100644
index 000000000..b4ce6bd8e
--- /dev/null
+++ b/modules/io/tests/testfiles/pdb/conect.pdb
@@ -0,0 +1,46 @@
+ATOM      1  N   VAL A   1      -8.585  17.971  25.103  0.50 11.44           N  
+ATOM      2  CA  VAL A   1      -8.253  17.023  24.068  0.50 12.65           C  
+ATOM      3  C   VAL A   1      -7.312  17.705  23.054  0.50 16.06           C  
+ATOM      4  O   VAL A   1      -7.544  18.799  22.596  0.50 12.36           O  
+ATOM      5  CB  VAL A   1      -9.457  16.377  23.387  0.50 12.94           C  
+ATOM      6  CG1 VAL A   1      -9.264  14.902  23.055  0.50 11.08           C  
+ATOM      7  CG2 VAL A   1     -10.739  16.533  24.224  0.50 13.21           C  
+ATOM      8  N   VAL A   2      -6.277  16.910  22.755  0.50 16.75           N  
+ATOM      9  CA  VAL A   2      -5.196  17.143  21.863  0.50 16.61           C  
+ATOM     10  C   VAL A   2      -4.253  18.199  22.473  0.50 19.00           C  
+ATOM     11  O   VAL A   2      -4.434  18.654  23.600  0.50 17.27           O  
+ATOM     12  CB  VAL A   2      -5.589  17.486  20.437  0.50 18.24           C  
+ATOM     13  CG1 VAL A   2      -7.059  17.853  20.200  0.50 19.12           C  
+ATOM     14  CG2 VAL A   2      -4.672  18.535  19.802  0.50 14.29           C  
+TER      15      VAL A   2                                                      
+HETATM   16  N   PS0 A   3     -11.234  16.802  30.197  0.50  7.63           N  
+HETATM   17  CA  PS0 A   3     -11.284  16.497  28.779  0.50  6.15           C  
+HETATM   18  C   PS0 A   3     -10.818  17.753  28.010  0.50  8.61           C  
+HETATM   19  OS  PS0 A   3     -11.697  18.822  28.249  0.50  4.53           O  
+HETATM   20  CB  PS0 A   3     -12.670  16.079  28.322  0.50 12.53           C  
+HETATM   21  CG  PS0 A   3     -13.432  14.971  29.048  0.50 11.04           C  
+HETATM   22  CD1 PS0 A   3     -13.076  13.629  28.983  0.50 10.33           C  
+HETATM   23  CD2 PS0 A   3     -14.560  15.373  29.807  0.50 12.71           C  
+HETATM   24  CE1 PS0 A   3     -13.818  12.638  29.661  0.50 11.11           C  
+HETATM   25  CE2 PS0 A   3     -15.300  14.380  30.483  0.50 14.32           C  
+HETATM   26  CZ  PS0 A   3     -14.917  13.043  30.412  0.50 10.61           C  
+HETATM   27  CM  PS0 A   3      -9.405  18.196  28.546  0.50  6.25           C  
+HETATM   28  O   HOH A   4      -3.126  40.621  48.726  1.00 47.60           O  
+HETATM   29  O   HOH A   5      -2.279  35.565  45.117  1.00 43.93           O  
+HETATM   30  O   HOH A   6       5.765  35.848  41.846  1.00 36.24           O  
+HETATM   31  O   HOH A   7     -12.666  40.044  22.441  1.00 41.24           O  
+HETATM   32  O   HOH A   8      -4.462  37.411  18.124  1.00 30.94           O  
+HETATM   33  O   HOH A   9      -1.109  26.454  19.470  1.00 39.06           O  
+CONECT   16   17
+CONECT   17   16   18   20
+CONECT   18   17   19   27
+CONECT   19   18
+CONECT   20   17   21
+CONECT   21   20   22   23
+CONECT   22   21   24
+CONECT   23   21   25
+CONECT   24   22   26
+CONECT   25   23   26
+CONECT   26   24   25
+CONECT   27   18
+END   
\ No newline at end of file
diff --git a/modules/io/tests/testfiles/pdb/ter.pdb b/modules/io/tests/testfiles/pdb/ter.pdb
new file mode 100644
index 000000000..fb85bb403
--- /dev/null
+++ b/modules/io/tests/testfiles/pdb/ter.pdb
@@ -0,0 +1,15 @@
+ATOM      1  N   THR A 161      29.926 -12.642 -13.047  1.00 25.35           N  
+ATOM      2  CA  THR A 161      29.978 -12.367 -11.602  1.00 25.36           C  
+ATOM      3  C   THR A 161      29.215 -13.430 -10.777  1.00 27.67           C  
+ATOM      4  O   THR A 161      29.065 -13.298  -9.552  1.00 26.09           O  
+ATOM      5  CB  THR A 161      29.363 -11.029 -11.309  1.00 24.99           C  
+ATOM      6  OG1 THR A 161      28.023 -11.041 -11.744  1.00 22.56           O  
+ATOM      7  CG2 THR A 161      29.998  -9.872 -12.148  1.00 23.85           C  
+ATOM      8  N   ALA A 162      28.657 -14.427 -11.463  1.00 28.77           N  
+ATOM      9  CA  ALA A 162      28.111 -15.569 -10.810  1.00 30.99           C  
+ATOM     10  C   ALA A 162      29.301 -16.453 -10.436  1.00 33.52           C  
+ATOM     11  O   ALA A 162      29.230 -17.243  -9.498  1.00 36.04           O  
+ATOM     12  CB  ALA A 162      27.155 -16.295 -11.713  1.00 30.93           C  
+TER      13      ALA A 162                                                      
+HETATM   14  O   HOH A 164      25.516   0.940  27.392  1.00 38.40           O  
+END   
\ No newline at end of file
diff --git a/modules/io/tests/testfiles/test_in.sdf b/modules/io/tests/testfiles/sdf/compound.sdf
similarity index 97%
rename from modules/io/tests/testfiles/test_in.sdf
rename to modules/io/tests/testfiles/sdf/compound.sdf
index 9d7bdcfc1..66ddbb589 100644
--- a/modules/io/tests/testfiles/test_in.sdf
+++ b/modules/io/tests/testfiles/sdf/compound.sdf
@@ -1,7 +1,7 @@
-Displayed atoms
-                    3D
- Structure written by MMmdl.
- 45 47  0  0  1  0            999 V2000
+Test Ligand
+
+
+ 45 47  0  0  0  0            999 V2000
    35.9455    5.9021   22.1706 C   0  0  0  0  0  0
    34.6074    5.5226   22.4445 O   0  0  0  0  0  0
    33.9561    6.2475   23.4088 C   0  0  0  0  0  0
@@ -95,32 +95,29 @@ Displayed atoms
  26 27  1  0  0  0
  27 45  1  0  0  0
 M  END
+> <i_i_glide_confnum>
+2
+
 > <i_i_glide_lignum>
 1
 
-> <r_i_docking_score>
--8.84426
+> <i_i_glide_posenum>
+352
 
-> <r_i_glide_gscore>
+> <r_i_docking_score>
 -8.84426
 
-> <r_i_glide_lipo>
--2.84534
-
-> <r_i_glide_hbond>
--0.960751
-
-> <r_i_glide_metal>
--0
+> <r_i_glide_ecoul>
+-16.1644
 
-> <r_i_glide_rewards>
--0.799851
+> <r_i_glide_einternal>
+6.78671
 
-> <r_i_glide_evdw>
--46.0502
+> <r_i_glide_emodel>
+-96.9661
 
-> <r_i_glide_ecoul>
--16.1644
+> <r_i_glide_energy>
+-62.2146
 
 > <r_i_glide_erotb>
 0.517993
@@ -128,38 +125,41 @@ M  END
 > <r_i_glide_esite>
 -0.0291388
 
-> <r_i_glide_emodel>
--96.9661
+> <r_i_glide_evdw>
+-46.0502
 
-> <r_i_glide_energy>
--62.2146
+> <r_i_glide_gscore>
+-8.84426
 
-> <r_i_glide_einternal>
-6.78671
+> <r_i_glide_hbond>
+-0.960751
 
 > <r_i_glide_ligand_efficiency>
 -0.327565
 
+> <r_i_glide_ligand_efficiency_ln>
+-2.0588
+
 > <r_i_glide_ligand_efficiency_sa>
 -0.982695
 
-> <r_i_glide_ligand_efficiency_ln>
--2.0588
+> <r_i_glide_lipo>
+-2.84534
 
-> <i_i_glide_confnum>
-2
+> <r_i_glide_metal>
+-0
 
-> <i_i_glide_posenum>
-352
+> <r_i_glide_rewards>
+-0.799851
 
 > <r_i_glide_rmsd>
 0.6819
 
 $$$$
-Displayed atoms
-                    3D
- Structure written by MMmdl.
- 45 47  0  0  1  0            999 V2000
+Test Ligand
+
+
+ 45 47  0  0  0  0            999 V2000
    34.3938    4.9895   21.4537 C   0  0  0  0  0  0
    34.9786    5.7318   22.5298 O   0  0  0  0  0  0
    34.1450    6.3862   23.4047 C   0  0  0  0  0  0
@@ -253,32 +253,29 @@ Displayed atoms
  26 27  1  0  0  0
  27 45  1  0  0  0
 M  END
+> <i_i_glide_confnum>
+14
+
 > <i_i_glide_lignum>
 1
 
-> <r_i_docking_score>
--8.79327
+> <i_i_glide_posenum>
+302
 
-> <r_i_glide_gscore>
+> <r_i_docking_score>
 -8.79327
 
-> <r_i_glide_lipo>
--2.69167
-
-> <r_i_glide_hbond>
--0.966475
-
-> <r_i_glide_metal>
--0
+> <r_i_glide_ecoul>
+-16.9687
 
-> <r_i_glide_rewards>
--0.777126
+> <r_i_glide_einternal>
+5.76514
 
-> <r_i_glide_evdw>
--46.4187
+> <r_i_glide_emodel>
+-98.4298
 
-> <r_i_glide_ecoul>
--16.9687
+> <r_i_glide_energy>
+-63.3874
 
 > <r_i_glide_erotb>
 0.517993
@@ -286,38 +283,41 @@ M  END
 > <r_i_glide_esite>
 -0.00975737
 
-> <r_i_glide_emodel>
--98.4298
+> <r_i_glide_evdw>
+-46.4187
 
-> <r_i_glide_energy>
--63.3874
+> <r_i_glide_gscore>
+-8.79327
 
-> <r_i_glide_einternal>
-5.76514
+> <r_i_glide_hbond>
+-0.966475
 
 > <r_i_glide_ligand_efficiency>
 -0.325677
 
+> <r_i_glide_ligand_efficiency_ln>
+-2.04693
+
 > <r_i_glide_ligand_efficiency_sa>
 -0.97703
 
-> <r_i_glide_ligand_efficiency_ln>
--2.04693
+> <r_i_glide_lipo>
+-2.69167
 
-> <i_i_glide_confnum>
-14
+> <r_i_glide_metal>
+-0
 
-> <i_i_glide_posenum>
-302
+> <r_i_glide_rewards>
+-0.777126
 
 > <r_i_glide_rmsd>
 0.605551
 
 $$$$
-Displayed atoms
-                    3D
- Structure written by MMmdl.
- 45 47  0  0  1  0            999 V2000
+Test Ligand
+
+
+ 45 47  0  0  0  0            999 V2000
    36.2241    5.1749   22.8554 C   0  0  0  0  0  0
    35.0609    5.8871   22.4479 O   0  0  0  0  0  0
    34.2768    6.4601   23.4276 C   0  0  0  0  0  0
@@ -411,32 +411,29 @@ Displayed atoms
  26 27  1  0  0  0
  27 45  1  0  0  0
 M  END
+> <i_i_glide_confnum>
+1
+
 > <i_i_glide_lignum>
 1
 
-> <r_i_docking_score>
--8.70173
+> <i_i_glide_posenum>
+177
 
-> <r_i_glide_gscore>
+> <r_i_docking_score>
 -8.70173
 
-> <r_i_glide_lipo>
--2.74283
-
-> <r_i_glide_hbond>
--0.97397
-
-> <r_i_glide_metal>
--0
+> <r_i_glide_ecoul>
+-15.8862
 
-> <r_i_glide_rewards>
--0.764823
+> <r_i_glide_einternal>
+1.84397
 
-> <r_i_glide_evdw>
--46.5538
+> <r_i_glide_emodel>
+-99.0481
 
-> <r_i_glide_ecoul>
--15.8862
+> <r_i_glide_energy>
+-62.44
 
 > <r_i_glide_erotb>
 0.517993
@@ -444,38 +441,41 @@ M  END
 > <r_i_glide_esite>
 -0.0274759
 
-> <r_i_glide_emodel>
--99.0481
+> <r_i_glide_evdw>
+-46.5538
 
-> <r_i_glide_energy>
--62.44
+> <r_i_glide_gscore>
+-8.70173
 
-> <r_i_glide_einternal>
-1.84397
+> <r_i_glide_hbond>
+-0.97397
 
 > <r_i_glide_ligand_efficiency>
 -0.322286
 
+> <r_i_glide_ligand_efficiency_ln>
+-2.02562
+
 > <r_i_glide_ligand_efficiency_sa>
 -0.966858
 
-> <r_i_glide_ligand_efficiency_ln>
--2.02562
+> <r_i_glide_lipo>
+-2.74283
 
-> <i_i_glide_confnum>
-1
+> <r_i_glide_metal>
+-0
 
-> <i_i_glide_posenum>
-177
+> <r_i_glide_rewards>
+-0.764823
 
 > <r_i_glide_rmsd>
 0.543804
 
 $$$$
-Displayed atoms
-                    3D
- Structure written by MMmdl.
- 45 47  0  0  1  0            999 V2000
+Test Ligand
+
+
+ 45 47  0  0  0  0            999 V2000
    36.1312    5.0238   22.8745 C   0  0  0  0  0  0
    35.3492    6.1234   22.4285 O   0  0  0  0  0  0
    34.5144    6.6833   23.3611 C   0  0  0  0  0  0
@@ -569,32 +569,29 @@ Displayed atoms
  26 27  1  0  0  0
  27 45  1  0  0  0
 M  END
+> <i_i_glide_confnum>
+9
+
 > <i_i_glide_lignum>
 1
 
-> <r_i_docking_score>
--8.69162
+> <i_i_glide_posenum>
+294
 
-> <r_i_glide_gscore>
+> <r_i_docking_score>
 -8.69162
 
-> <r_i_glide_lipo>
--2.92829
-
-> <r_i_glide_hbond>
--0.870172
-
-> <r_i_glide_metal>
--0
+> <r_i_glide_ecoul>
+-14.7519
 
-> <r_i_glide_rewards>
--0.764823
+> <r_i_glide_einternal>
+5.89466
 
-> <r_i_glide_evdw>
--48.432
+> <r_i_glide_emodel>
+-97.7232
 
-> <r_i_glide_ecoul>
--14.7519
+> <r_i_glide_energy>
+-63.1839
 
 > <r_i_glide_erotb>
 0.517993
@@ -602,29 +599,32 @@ M  END
 > <r_i_glide_esite>
 -0.0119369
 
-> <r_i_glide_emodel>
--97.7232
+> <r_i_glide_evdw>
+-48.432
 
-> <r_i_glide_energy>
--63.1839
+> <r_i_glide_gscore>
+-8.69162
 
-> <r_i_glide_einternal>
-5.89466
+> <r_i_glide_hbond>
+-0.870172
 
 > <r_i_glide_ligand_efficiency>
 -0.321912
 
+> <r_i_glide_ligand_efficiency_ln>
+-2.02327
+
 > <r_i_glide_ligand_efficiency_sa>
 -0.965735
 
-> <r_i_glide_ligand_efficiency_ln>
--2.02327
+> <r_i_glide_lipo>
+-2.92829
 
-> <i_i_glide_confnum>
-9
+> <r_i_glide_metal>
+-0
 
-> <i_i_glide_posenum>
-294
+> <r_i_glide_rewards>
+-0.764823
 
 > <r_i_glide_rmsd>
 0.463026
diff --git a/modules/io/tests/testfiles/sdf/empty_dataheader.sdf b/modules/io/tests/testfiles/sdf/empty_dataheader.sdf
new file mode 100644
index 000000000..9de4a7b63
--- /dev/null
+++ b/modules/io/tests/testfiles/sdf/empty_dataheader.sdf
@@ -0,0 +1,48 @@
+Simple Ligand 1
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+> <>
+1
+
+> <prop_two>
+-2
+
+$$$$
+Simple Ligand 2
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+> <prop_one>
+2
+
+> <prop_two>
+-4
+
+$$$$
diff --git a/modules/io/tests/testfiles/sdf/multiple.sdf b/modules/io/tests/testfiles/sdf/multiple.sdf
new file mode 100644
index 000000000..7570f2d4d
--- /dev/null
+++ b/modules/io/tests/testfiles/sdf/multiple.sdf
@@ -0,0 +1,72 @@
+Simple Ligand 1
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+$$$$
+Simple Ligand 2
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+$$$$
+Simple Ligand 3
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+$$$$
+Simple Ligand 4
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+$$$$
diff --git a/modules/io/tests/testfiles/sdf/properties.sdf b/modules/io/tests/testfiles/sdf/properties.sdf
new file mode 100644
index 000000000..95a1b950f
--- /dev/null
+++ b/modules/io/tests/testfiles/sdf/properties.sdf
@@ -0,0 +1,48 @@
+Simple Ligand 1
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+> <prop_one>
+1
+
+> <prop_two>
+-2.2
+
+$$$$
+Simple Ligand 2
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+> <prop_one>
+2
+
+> <prop_two>
+-4.4
+
+$$$$
diff --git a/modules/io/tests/testfiles/sdf/simple.sdf b/modules/io/tests/testfiles/sdf/simple.sdf
new file mode 100644
index 000000000..beeb1acdd
--- /dev/null
+++ b/modules/io/tests/testfiles/sdf/simple.sdf
@@ -0,0 +1,18 @@
+Simple Ligand
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+$$$$
diff --git a/modules/io/tests/testfiles/sdf/wrong_atomcount.sdf b/modules/io/tests/testfiles/sdf/wrong_atomcount.sdf
new file mode 100644
index 000000000..ff9049fac
--- /dev/null
+++ b/modules/io/tests/testfiles/sdf/wrong_atomcount.sdf
@@ -0,0 +1,18 @@
+Simple Ligand
+
+ Teststructure
+  i  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+$$$$
diff --git a/modules/io/tests/testfiles/sdf/wrong_atomlinelength.sdf b/modules/io/tests/testfiles/sdf/wrong_atomlinelength.sdf
new file mode 100644
index 000000000..42f30f1a5
--- /dev/null
+++ b/modules/io/tests/testfiles/sdf/wrong_atomlinelength.sdf
@@ -0,0 +1,18 @@
+Simple Ligand
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0 
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+$$$$
diff --git a/modules/io/tests/testfiles/sdf/wrong_atompos.sdf b/modules/io/tests/testfiles/sdf/wrong_atompos.sdf
new file mode 100644
index 000000000..50d5268a0
--- /dev/null
+++ b/modules/io/tests/testfiles/sdf/wrong_atompos.sdf
@@ -0,0 +1,18 @@
+Simple Ligand
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+0.0000 1.0000    0.0000        O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+$$$$
diff --git a/modules/io/tests/testfiles/sdf/wrong_bondatomnumber.sdf b/modules/io/tests/testfiles/sdf/wrong_bondatomnumber.sdf
new file mode 100644
index 000000000..590827c4d
--- /dev/null
+++ b/modules/io/tests/testfiles/sdf/wrong_bondatomnumber.sdf
@@ -0,0 +1,18 @@
+Simple Ligand
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  8  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+$$$$
diff --git a/modules/io/tests/testfiles/sdf/wrong_bondcount.sdf b/modules/io/tests/testfiles/sdf/wrong_bondcount.sdf
new file mode 100644
index 000000000..3d6194d1b
--- /dev/null
+++ b/modules/io/tests/testfiles/sdf/wrong_bondcount.sdf
@@ -0,0 +1,18 @@
+Simple Ligand
+
+ Teststructure
+  6  i  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+$$$$
diff --git a/modules/io/tests/testfiles/sdf/wrong_bondlinelength.sdf b/modules/io/tests/testfiles/sdf/wrong_bondlinelength.sdf
new file mode 100644
index 000000000..5be46a393
--- /dev/null
+++ b/modules/io/tests/testfiles/sdf/wrong_bondlinelength.sdf
@@ -0,0 +1,18 @@
+Simple Ligand
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+$$$$
diff --git a/modules/io/tests/testfiles/sdf/wrong_bondtype.sdf b/modules/io/tests/testfiles/sdf/wrong_bondtype.sdf
new file mode 100644
index 000000000..432c10464
--- /dev/null
+++ b/modules/io/tests/testfiles/sdf/wrong_bondtype.sdf
@@ -0,0 +1,18 @@
+Simple Ligand
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6 -1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+$$$$
diff --git a/modules/io/tests/testfiles/sdf/wrong_charge.sdf b/modules/io/tests/testfiles/sdf/wrong_charge.sdf
new file mode 100644
index 000000000..01dba009e
--- /dev/null
+++ b/modules/io/tests/testfiles/sdf/wrong_charge.sdf
@@ -0,0 +1,18 @@
+Simple Ligand
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  i  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+$$$$
diff --git a/modules/io/tests/testfiles/sdf/wrong_dataheader.sdf b/modules/io/tests/testfiles/sdf/wrong_dataheader.sdf
new file mode 100644
index 000000000..b895448e6
--- /dev/null
+++ b/modules/io/tests/testfiles/sdf/wrong_dataheader.sdf
@@ -0,0 +1,48 @@
+Simple Ligand 1
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+> prop_one>
+1
+
+> <prop_two>
+-2
+
+$$$$
+Simple Ligand 2
+
+ Teststructure
+  6  6  0  0  1  0            999 V2000
+    0.0000    0.0000    0.0000 N   0  3  0  0  0  0
+    1.0000    0.0000    0.0000 C   0  0  0  0  0  0
+    0.0000    1.0000    0.0000 O   0  0  0  0  0  0
+    1.0000    1.0000    0.0000 S   0  0  0  0  0  0
+    2.0000    2.0000    0.0000 C   0  0  0  0  0  0
+   -1.0000   -1.0000    0.0000 Cl  0  0  0  0  0  0
+  1  2  2  0  0  0
+  1  3  1  0  0  0
+  1  6  1  0  0  0
+  2  4  1  0  0  0
+  3  4  1  0  0  0
+  4  5  3  0  0  0
+M  END
+> <prop_one>
+2
+
+> <prop_two>
+-4
+
+$$$$
diff --git a/modules/mol/alg/pymod/CMakeLists.txt b/modules/mol/alg/pymod/CMakeLists.txt
index 6c68c3fc4..30fae2eb1 100644
--- a/modules/mol/alg/pymod/CMakeLists.txt
+++ b/modules/mol/alg/pymod/CMakeLists.txt
@@ -7,6 +7,16 @@ set(OST_MOL_ALG_PYMOD_MODULES
   "__init__.py"
   views.py
 )
+
+if (ENABLE_IMG)
+
+  set(OST_MOL_ALG_PYMOD_SOURCES
+    ${OST_MOL_ALG_PYMOD_SOURCES}
+    export_entity_to_density.cc
+  )
+
+endif()
+
 pymod(NAME mol_alg OUTPUT_DIR ost/mol/alg CPP ${OST_MOL_ALG_PYMOD_SOURCES}
       PY ${OST_MOL_ALG_PYMOD_MODULES})
 
diff --git a/modules/mol/alg/pymod/export_entity_to_density.cc b/modules/mol/alg/pymod/export_entity_to_density.cc
new file mode 100644
index 000000000..bf9ace1fe
--- /dev/null
+++ b/modules/mol/alg/pymod/export_entity_to_density.cc
@@ -0,0 +1,49 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+/*
+ * Author Juergen Haas
+ */
+#include <boost/python.hpp>
+#include <ost/config.hh>
+
+#if OST_IMG_ENABLED
+
+#include <ost/mol/alg/entity_to_density.hh>
+
+using namespace boost::python;
+using namespace ost;
+using namespace ost::mol::alg;
+
+//"thin wrappers" for default parameters
+BOOST_PYTHON_FUNCTION_OVERLOADS(etd_rosetta, EntityToDensityRosetta, 4, 6)
+BOOST_PYTHON_FUNCTION_OVERLOADS(etd_scattering, EntityToDensityScattering, 4, 6)
+
+void export_entity_to_density()
+{
+    def("EntityToDensityRosetta",EntityToDensityRosetta,etd_rosetta());
+    def("EntityToDensityScattering",EntityToDensityScattering,etd_scattering());
+
+    enum_<DensityType>("DensityType")
+    .value("HIGH_RESOLUTION", HIGH_RESOLUTION)
+    .value("LOW_RESOLUTION", LOW_RESOLUTION)
+    .export_values()
+    ;
+}
+#endif
diff --git a/modules/mol/alg/pymod/wrap_mol_alg.cc b/modules/mol/alg/pymod/wrap_mol_alg.cc
index 1670b122e..ce0be429c 100644
--- a/modules/mol/alg/pymod/wrap_mol_alg.cc
+++ b/modules/mol/alg/pymod/wrap_mol_alg.cc
@@ -21,10 +21,19 @@
  * Author Juergen Haas
  */
 #include <boost/python.hpp>
+#include <ost/config.hh>
 using namespace boost::python;
 
 void export_svdSuperPose();
+
+#if OST_IMG_ENABLED
+void export_entity_to_density();
+#endif
+
 BOOST_PYTHON_MODULE(_mol_alg)
 {
   export_svdSuperPose();
+  #if OST_IMG_ENABLED
+  export_entity_to_density();
+  #endif
 }
diff --git a/modules/mol/alg/src/CMakeLists.txt b/modules/mol/alg/src/CMakeLists.txt
index 0eff2e75f..242eea3d8 100644
--- a/modules/mol/alg/src/CMakeLists.txt
+++ b/modules/mol/alg/src/CMakeLists.txt
@@ -9,8 +9,27 @@ set(OST_MOL_ALG_SOURCES
   sec_structure_segments.cc
 )
 
+set(MOL_ALG_DEPS mol)
+
+if (ENABLE_IMG)
+  set(OST_MOL_ALG_HEADERS
+    ${OST_MOL_ALG_HEADERS}
+    entity_to_density.hh
+  )
+
+  set(OST_MOL_ALG_SOURCES
+    ${OST_MOL_ALG_SOURCES}
+    entity_to_density.cc
+  )
+
+  set(MOL_ALG_DEPS ${MOL_ALG_DEPS} img img_alg)
+endif()
+
 module(NAME mol_alg SOURCES ${OST_MOL_ALG_SOURCES}
        HEADERS ${OST_MOL_ALG_HEADERS}
        HEADER_OUTPUT_DIR ost/mol/alg
-       DEPENDS_ON mol)
+       DEPENDS_ON ${MOL_ALG_DEPS})
 
+copy_if_different("." "${STAGE_DIR}/share/openstructure"
+                  "atom_scattering_properties.txt" "ATOM_SCATTERING_PROPS"
+                  "ost_mol_alg")
diff --git a/modules/mol/alg/src/atom_scattering_properties.txt b/modules/mol/alg/src/atom_scattering_properties.txt
new file mode 100644
index 000000000..107a71bdf
--- /dev/null
+++ b/modules/mol/alg/src/atom_scattering_properties.txt
@@ -0,0 +1,59 @@
+// SCATTERING PROPERTIES OF ATOMS
+// (used by the entity_to_density_function of OST/OPENSTRUCTURE)
+// Columns from left to right: 1) Element Symbol 2) Atomic Weight 3) c parameter used to compute scattering factors 4-7) a1-a4 parameters 8-11) b1-b4 parameters.
+// Sources: parameters for scattering factors: it.iucr.org/ International tables for crystallography. First online edition (2006), Vol.C,Ch 6.1, pp. 554-595
+// Atomic Weights: www.chem.qmul.ac.uk/iupac/AtWt/ based on 2005 table published in Pure Appl. Chem., 78, 2051-2066 (2006) with 2007 changes
+Al          26.982        1.115100        6.420200        1.900200        1.593600        1.964600        3.038700        0.742600       31.547199       85.088600
+As          74.922        2.531000       16.672300        6.070100        3.431300        4.277900        2.634500        0.264700       12.947900       47.797199
+At         210.000       13.710800       35.316299       19.021099        9.498870        7.425180        0.685870        3.974580       11.382400       45.471500
+Au         196.967       12.065800       16.881901       18.591299       25.558201        5.860000        0.461100        8.621600        1.482600       36.395599
+B           10.812       -0.193200        2.054500        1.332600        1.097900        0.706800       23.218500        1.021000       60.349800        0.140300
+Be           9.012        0.038500        1.591900        1.127800        0.539100        0.702900       43.642700        1.862300      103.483002        0.542000
+Br          79.904        2.955700       17.178900        5.235800        5.637700        3.985100        2.172300       16.579599        0.260900       41.432800
+C           12.011        0.215600        2.310000        1.020000        1.588600        0.865000       20.843899       10.207500        0.568700       51.651199
+Ca          40.078        1.375100        8.626600        7.387300        1.589900        1.021100       10.442100        0.659900       85.748398      178.436996
+Cd         112.412        5.069400       19.221399       17.644400        4.461000        1.602900        0.594600        6.908900       24.700800       87.482498
+Cl          35.453       -9.557400       11.460400        7.196400        6.255600        1.645500        0.010400        1.166200       18.519400       47.778400
+Co          58.933        1.011800       12.284100        7.340900        4.003400        2.348800        4.279100        0.278400       13.535900       71.169197
+Cr          51.996        1.183200       10.640600        7.353700        3.324000        1.492200        6.103800        0.392000       20.262600       98.739899
+Cu          63.546        1.191000       13.337999        7.167600        5.615800        1.673500        3.582800        0.247000       11.396600       64.812599
+F           18.998        0.277600        3.539200        2.641200        1.517000        1.024300       10.282499        4.294400        0.261500       26.147600
+Fe          55.845        1.036900       11.769500        7.357300        3.522200        2.304500        4.761100        0.307200       15.353500       76.880501
+Ga          69.723        1.718900       15.235400        6.700600        4.359100        2.962300        3.066900        0.241200       10.780500       61.413498
+Gd         157.253        2.419600       25.070900       19.079800       13.851800        3.545450        2.253410        0.181951       12.933100      101.397995
+Ge          72.641        2.131300       16.081600        6.374700        3.706800        3.683000        2.850900        0.251600       11.446800       54.762501
+Hf         178.492        8.581540       29.143999       15.172600       14.758600        4.300130        1.832620        9.599899        0.275116       72.028999
+Hg         200.592       12.608900       20.680901       19.041700       21.657499        5.967600        0.545000        8.448400        1.572900       38.324600
+I          126.904        4.071200       20.147200       18.994900        7.513800        2.273500        4.347000        0.381400       27.765999       66.877602
+Ir         192.217       11.472200       27.304899       16.729599       15.611500        5.833770        1.592790        8.865530        0.417916       45.001099
+K           39.098        1.422800        8.218599        7.439800        1.051900        0.865900       12.794900        0.774800      213.186996       41.684097
+Li           6.941        0.037700        1.128200        0.750800        0.617500        0.465300        3.954600        1.052400       85.390503      168.261002
+Mg          24.305        0.858400        5.420400        2.173500        1.226900        2.307300        2.827500       79.261101        0.380800        7.193700
+Mn          54.938        1.089600       11.281900        7.357300        3.019300        2.244100        5.340900        0.343200       17.867399       83.754303
+Mo          95.962        4.387500        3.702500       17.235600       12.887600        3.742900        0.277200        1.095800       11.004000       61.658401
+N           14.007       11.528999       12.212600        3.132200        2.012500        1.166300        0.005700        9.893300       28.997499        0.582600
+Na          22.990        0.676000        4.762600        3.173600        1.267400        1.112800        3.285000        8.842199        0.313600      129.423996
+Ni          58.693        1.034100       12.837600        7.292000        4.443800        2.380000        3.878500        0.256500       12.176300       66.342102
+O           15.999        0.250800        3.048500        2.286800        1.546300        0.867000       13.277100        5.701100        0.323900       32.908897
+Os         190.233       11.000500       28.189400       16.154999       14.930500        5.675890        1.629030        8.979480        0.382661       48.164700
+P           30.974        1.114900        6.434500        4.179100        1.780000        1.490800        1.906700       27.157000        0.526000       68.164497
+Pb         207.210       13.411800       31.061699       13.063700       18.441999        5.969600        0.690200        2.357600        8.618000       47.257900
+Pd         106.421        5.265930       19.331900       15.501699        5.295370        0.605844        0.698655        7.989290       25.205200       76.898598
+Pt         195.085       11.688300       27.005899       17.763901       15.713100        5.783700        1.512930        8.811740        0.424593       38.610298
+Re         186.207       10.472000       28.762100       15.718900       14.556400        5.441740        1.671910        9.092270        0.350500       52.086098
+Rh         102.905        5.328000       19.295700       14.350100        4.734250        1.289180        0.751536        8.217580       25.874901       98.606201
+Ru         101.072        5.378740       19.267399       12.918200        4.863370        1.567560        0.808520        8.434669       24.799700       94.292801
+S           32.066        0.866900        6.905300        5.203400        1.437900        1.586300        1.467900       22.215099        0.253600       56.172001
+Sb         121.760        4.590900       19.641800       19.045500        5.037100        2.682700        5.303400        0.460700       27.907400       75.282501
+Se          78.963        2.840900       17.000599        5.819600        3.973100        4.354300        2.409800        0.272600       15.237200       43.816299
+Si          28.086        1.140700        6.291500        3.035300        1.989100        1.541000        2.438600       32.333698        0.678500       81.693695
+Sn         118.711        4.782100       19.188900       19.100500        4.458500        2.466300        5.830300        0.503100       26.890900       83.957100
+Ta         180.948        9.243540       29.202400       15.229300       14.513500        4.764920        1.773330        9.370460        0.295977       63.364399
+Te         127.603        4.352000       19.964399       19.013800        6.144870        2.523900        4.817420        0.420885       28.528400       70.840302
+U          238.029       13.396600       36.022800       23.412800       14.949100        4.188000        0.529300        3.325300       16.092699      100.612999
+V           50.942        1.219900       10.297100        7.351100        2.070300        2.057100        6.865700        0.438500       26.893799      102.477997
+W          183.841        9.887500       29.081800       15.430000       14.432700        5.119820        1.720290        9.225900        0.321703       57.056000
+Y           88.906        1.912130       17.775999       10.294600        5.726290        3.265880        1.402900       12.800600        0.125599      104.353996
+Zn          65.382        1.304100       14.074300        7.031800        5.162500        2.410000        3.265500        0.233300       10.316299       58.709702
+Zr         91.2240        2.069290       17.876499       10.948000        5.417320        3.657210        1.276180       11.916000        0.117622       87.662697
+
diff --git a/modules/mol/alg/src/entity_to_density.cc b/modules/mol/alg/src/entity_to_density.cc
new file mode 100644
index 000000000..269f23add
--- /dev/null
+++ b/modules/mol/alg/src/entity_to_density.cc
@@ -0,0 +1,442 @@
+#include <sstream>
+#include <cmath>
+
+#include <boost/filesystem/fstream.hpp>
+#include <boost/filesystem/convenience.hpp>
+#include <boost/algorithm/string.hpp>
+
+#include <ost/log.hh>
+#include <ost/platform.hh>
+#include <ost/img/alg/dft.hh>
+#include <ost/mol/mol.hh>
+
+#include "entity_to_density.hh"
+
+namespace ost { namespace mol { namespace alg {
+
+namespace detail {
+
+struct AtomScatteringProps {
+ String element;
+  Real atomic_weight;
+  Real c;
+  Real a1;
+  Real a2;
+  Real a3;
+  Real a4;
+  Real b1;
+  Real b2;
+  Real b3;
+  Real b4;
+};
+
+typedef std::vector<AtomScatteringProps> AtomScatteringPropsTable;
+
+void FillAtomScatteringPropsTable(AtomScatteringPropsTable& table)
+{
+  AtomScatteringProps atom_props;
+
+  String ost_root=GetSharedDataPath();
+  String filename = "/atom_scattering_properties.txt";
+  String fullpath = ost_root+filename;
+  boost::filesystem::path loc(fullpath);
+  boost::filesystem::ifstream infile(loc);
+  if (!infile) {
+    String msg;
+    std::stringstream msgstr(msg);
+    msgstr << "Couldn't find " << fullpath << std::endl;
+    throw ost::Error(msg);
+  }
+  String line;
+  std::getline(infile, line);
+  std::getline(infile, line);
+  std::getline(infile, line);
+  std::getline(infile, line);
+  std::getline(infile, line);
+  while (std::getline(infile, line))
+  {
+   std::stringstream line_stream(line);
+   line_stream >> atom_props.element
+               >> atom_props.atomic_weight
+               >> atom_props.c
+               >> atom_props.a1
+               >> atom_props.a2
+               >> atom_props.a3
+               >> atom_props.a4
+               >> atom_props.b1
+               >> atom_props.b2
+               >> atom_props.b3
+               >> atom_props.b4;
+    table.push_back(atom_props);
+  }
+};
+
+
+Real ScatteringFactor (Real frequency, const AtomScatteringProps& props,
+                         Real source_wavelength)
+{
+   Real scattering_factor =
+             props.a1*exp(-props.b1*frequency*frequency) +
+             props.a2*exp(-props.b2*frequency*frequency) +
+             props.a3*exp(-props.b3*frequency*frequency) +
+             props.a4*exp(-props.b4*frequency*frequency) +
+             props.c;
+
+   return scattering_factor;
+}
+
+
+class EntityToDensityHelperBase
+{
+
+public:
+
+  EntityToDensityHelperBase (const ost::mol::EntityView entity_view,
+                             Real falloff_start,
+                             Real falloff_end,
+                             Real source_wavelength,
+                             geom::Vec3 map_start,
+                             geom::Vec3 map_end
+                             ):
+      entity_view_(entity_view),
+      falloff_start_frequency_(1.0/falloff_start),
+      falloff_end_frequency_(1.0/falloff_end),
+      source_wavelength_(source_wavelength),
+      map_start_(map_start),map_end_(map_end)
+  {
+    if (scattering_props_table_loaded_ == false)
+    {
+      FillAtomScatteringPropsTable(scatt_props_table_);
+      scattering_props_table_loaded_ = true;
+    }
+  }
+
+  void VisitState(img::ComplexHalfFrequencyImageState& is) const
+  {
+
+    geom::Vec3 frequency_sampling =
+             is.GetSampling().GetFrequencySampling();
+
+    Real minus_2_pi = -2.0*M_PI;
+
+    uint x_limit = ceil(falloff_end_frequency_ / frequency_sampling[0]);
+    uint y_limit = ceil(falloff_end_frequency_ / frequency_sampling[1]);
+    uint z_limit = ceil(falloff_end_frequency_ / frequency_sampling[2]);
+     img::Extent reduced_extent = img::Extent
+             (img::Point(-x_limit,-y_limit,0),
+              img::Point(x_limit,y_limit,z_limit));
+
+    mol::AtomViewIter iterator_end = entity_view_.AtomsEnd();
+    for (mol::AtomViewIter iterator = entity_view_.AtomsBegin();
+           iterator!=iterator_end; ++iterator)
+    {
+      AtomScatteringPropsTable::iterator table_iter =
+                                             scatt_props_table_.begin();
+      bool found = false;
+      while (found != true && table_iter!=scatt_props_table_.end())
+      {
+        if ( (*table_iter).element == (*iterator).GetAtomProps().element)
+        {        
+          geom::Vec3 coord = (*iterator).GetPos();
+
+          if (coord[0] >= map_start_[0] &&
+              coord[0] <= map_end_[0] &&
+              coord[1] >= map_start_[1] &&
+              coord[1] <= map_end_[1] &&
+              coord[2] >= map_start_[2] &&
+              coord[2] <= map_end_[2])
+          {
+
+            // This part of the code assumes that the three axes
+            // of the map are at right angles and the origin at 0,0,0.
+            // Eventually, when maps and images will be merged,
+            // it will substituted by the map's xyz2uvw method
+
+            geom::Vec3 adjusted_coord  = coord-map_start_;
+
+            for (img::ExtentIterator mp_it(reduced_extent);
+               !mp_it.AtEnd();++mp_it)
+            {
+              img::Point mp_it_point = img::Point(mp_it);
+
+              geom::Vec3 frequency_sampling =
+                  is.GetSampling().GetFrequencySampling();
+
+              geom::Vec3 mp_it_vec = geom::Vec3(
+                (mp_it_point[0]*frequency_sampling[0]),
+                (mp_it_point[1]*frequency_sampling[1]),
+                (mp_it_point[2]*frequency_sampling[2])
+              );
+
+              Real frequency = Length(mp_it_vec);
+
+              Real sigma = (falloff_end_frequency_ -
+                              falloff_start_frequency_)/3.0;
+
+              if (frequency <= falloff_end_frequency_)
+              {
+                Real falloff_term = 1.0;
+                if (sigma!=0 && frequency >= falloff_start_frequency_)
+                {
+                  falloff_term=exp(-(frequency-falloff_start_frequency_)*
+                                        (frequency-falloff_start_frequency_)/
+                                        (2.0*sigma*sigma));
+                }
+                AtomScatteringProps scatt_props = (*table_iter);
+                Real scatt_fact = ScatteringFactor(frequency,
+                                                     scatt_props,
+                                                     source_wavelength_);
+
+                Real amp_term = scatt_fact*falloff_term;
+                Real exp = minus_2_pi * geom::Dot(mp_it_vec,adjusted_coord);
+                Real real = amp_term *std::cos(exp);
+                Real imag = amp_term *std::sin(exp);
+                is.Value(mp_it) = is.Value(mp_it)+Complex(real,imag);
+
+              }
+            }
+          }
+        }
+        ++table_iter;
+      }
+    }
+  }
+
+  template <typename T, class D>
+  void VisitState(img::ImageStateImpl<T,D>& is) const
+  {
+    assert(false);
+  }
+
+  static String GetAlgorithmName() {return "EntityToDensityHelper"; }
+
+private:
+
+  ost::mol::alg::DensityType density_type_;
+  Real limit_;
+  ost::mol::EntityView entity_view_;
+  Real falloff_start_frequency_;
+  Real falloff_end_frequency_;
+  static AtomScatteringPropsTable scatt_props_table_;
+  static bool scattering_props_table_loaded_;
+  Real source_wavelength_;
+  geom::Vec3 map_start_;
+  geom::Vec3 map_end_;
+
+};
+
+AtomScatteringPropsTable EntityToDensityHelperBase::scatt_props_table_ =
+          AtomScatteringPropsTable();
+bool EntityToDensityHelperBase::scattering_props_table_loaded_ = false;
+
+typedef img::ImageStateConstModIPAlgorithm<EntityToDensityHelperBase>
+        EntityToDensityHelper;
+
+
+
+class EntityToDensityRosettaHelperBase
+{
+
+public:
+
+  EntityToDensityRosettaHelperBase (const ost::mol::EntityView entity_view,
+                             const ost::mol::alg::DensityType& density_type,
+                             Real resolution):
+      density_type_(density_type), entity_view_(entity_view),
+      resolution_(resolution)
+  {
+    if (scattering_props_table_loaded_ == false)
+    {
+     FillAtomScatteringPropsTable(scatt_props_table_);
+     scattering_props_table_loaded_ = true;
+    }
+  }
+
+  void VisitState(img::RealSpatialImageState& is) const
+  {
+    geom::Vec3 map_start=is.IndexToCoord(is.GetExtent().GetStart());
+    geom::Vec3 map_end=is.IndexToCoord(is.GetExtent().GetEnd());
+    mol::EntityView effective_entity_view=entity_view_;
+    Real k,C;
+
+    if (density_type_ == HIGH_RESOLUTION)
+    {
+      k = (M_PI*M_PI)/(resolution_*resolution_);
+      C = sqrt((M_PI*M_PI*M_PI)/(k*k*k));
+      effective_entity_view = entity_view_;
+
+    } else {  // ROSETTA LOW RESOLUTION
+
+      k = (M_PI*M_PI)/((2.4+0.8*resolution_)*(2.4+0.8*resolution_));
+      C = sqrt((M_PI*M_PI*M_PI)/(k*k*k));
+
+      effective_entity_view = entity_view_.Select("aname=CA and peptide=true");
+    }
+
+    Real sigma = sqrt(1.0/(2.0*k));
+    Real four_sigma_squared = 16.0*sigma*sigma;
+    Real four_sigma = 4.0*sigma;
+
+    geom::Vec3 sampling = is.GetSampling().GetPixelSampling();
+    img::Extent is_extent = is.GetExtent();
+
+    mol::AtomViewIter iterator_end = effective_entity_view.AtomsEnd();
+    for (mol::AtomViewIter iterator = effective_entity_view.AtomsBegin();
+         iterator!=iterator_end; ++iterator) {
+      AtomScatteringPropsTable::iterator table_iter =
+                                             scatt_props_table_.begin();
+      bool found = false;
+      while (found != true && table_iter!=scatt_props_table_.end()) {
+        if ((*table_iter).element == (*iterator).GetAtomProps().element) {
+          found = true;
+          Real a = (*table_iter).atomic_weight;
+          geom::Vec3 coord = (*iterator).GetPos();
+          if (coord[0] >= map_start[0] &&
+              coord[0] <= map_end[0] &&
+              coord[1] >= map_start[1] &&
+              coord[1] <= map_end[1] &&
+              coord[2] >= map_start[2] &&
+              coord[2] <= map_end[2])
+          {
+
+            geom::Vec3 adjusted_coord  = coord-map_start;
+            geom::Vec3 pixel_coord=is.CoordToIndex(coord);
+            img::Point rounded_pixel_coord(round(pixel_coord[0]),
+                                            round(pixel_coord[1]),
+                                            round(pixel_coord[2]));
+
+            uint x_limit = ceil(2.0*four_sigma/sampling[0])+1;
+            uint y_limit = ceil(2.0*four_sigma/sampling[1])+1;
+            uint z_limit = ceil(2.0*four_sigma/sampling[2])+1;
+
+            img::Extent reduced_extent = img::Extent
+                                      (img::Size(x_limit,y_limit,z_limit),
+                                      rounded_pixel_coord);
+
+            img::Extent iteration_extent=
+                                  img::Overlap(is_extent,reduced_extent);
+
+            for (img::ExtentIterator mp_it(iteration_extent);
+              !mp_it.AtEnd();++mp_it)
+            {
+
+              img::Point mp_it_point = img::Point(mp_it);
+
+              geom::Vec3 mp_it_vec = geom::Vec3(
+                (mp_it_point[0]*sampling[0]),
+                (mp_it_point[1]*sampling[1]),
+                (mp_it_point[2]*sampling[2])
+              );
+
+              Real distance_squared = Length2(mp_it_vec-adjusted_coord);
+
+              if (distance_squared <= four_sigma_squared)
+              {
+                Real exp_term = exp(-k*distance_squared);
+                Real value = C * a * exp_term;
+                is.Value(mp_it_point) = is.Value(mp_it_point) + value;
+              }
+            }
+          }
+        }
+        ++table_iter;
+      }
+    }
+  }
+
+  template <typename T, class D>
+  void VisitState(img::ImageStateImpl<T,D>& is) const
+  {
+    assert(false);
+  }
+
+  static String GetAlgorithmName() { return "EntityToDensityRosettaHelper"; }
+
+private:
+
+  ost::mol::alg::DensityType density_type_;
+  ost::mol::EntityView entity_view_;
+  Real resolution_;
+  static AtomScatteringPropsTable scatt_props_table_;
+  static bool scattering_props_table_loaded_;
+};
+
+AtomScatteringPropsTable EntityToDensityRosettaHelperBase::scatt_props_table_ =
+          AtomScatteringPropsTable();
+bool EntityToDensityRosettaHelperBase::scattering_props_table_loaded_ = false;
+
+typedef img::ImageStateConstModIPAlgorithm<EntityToDensityRosettaHelperBase>
+    EntityToDensityRosettaHelper;
+
+
+} // namespace
+
+void EntityToDensityScattering(const mol::EntityView& entity_view,
+                                     img::MapHandle& map,
+                                     Real falloff_start,
+                                     Real falloff_end,
+                                     bool clear_map_flag,
+                                     Real source_wavelength)
+{
+  if(falloff_start<=0.0) throw std::runtime_error("Invalid falloff start");
+  if(falloff_end<=0.0 || falloff_end>falloff_start)
+     throw std::runtime_error("Invalid falloff end");
+
+ geom ::Vec3 rs_sampl = map.GetSpatialSampling();
+  geom ::Vec3 abs_orig = map.GetAbsoluteOrigin();
+  geom::Vec3 map_start = geom::Vec3(abs_orig[0]+map.GetExtent().GetStart()[0]*rs_sampl[0],
+                                    abs_orig[1]+map.GetExtent().GetStart()[1]*rs_sampl[1],
+                                    abs_orig[2]+map.GetExtent().GetStart()[2]*rs_sampl[2]);
+
+  geom::Vec3 map_end = geom::Vec3(abs_orig[0]+map.GetExtent().GetEnd()[0]*rs_sampl[0],
+                                  abs_orig[1]+map.GetExtent().GetEnd()[1]*rs_sampl[1],
+                                  abs_orig[2]+map.GetExtent().GetEnd()[2]*rs_sampl[2]);
+  detail::EntityToDensityHelper e_to_d_helper(entity_view,
+                                              falloff_start,
+                                              falloff_end,
+                                              source_wavelength, map_start,map_end);
+  if (clear_map_flag==true) {
+    img::MapHandle mm=img::CreateImage(img::Extent(map.GetSize(),
+                                       img::Point(0,0)),
+                                       img::COMPLEX,img::HALF_FREQUENCY);
+    // swap newly created map into place
+    mm.SetSpatialSampling(map.GetSpatialSampling());
+    mm.SetAbsoluteOrigin(map.GetAbsoluteOrigin());
+    map.Swap(mm);
+  } else {
+    map.ApplyIP(img::alg::DFT());
+  }
+
+  map.ApplyIP(e_to_d_helper);
+  map.ApplyIP(img::alg::DFT());
+}
+
+
+void EntityToDensityRosetta(const mol::EntityView& entity_view,
+                            img::MapHandle& map,
+                            const DensityType& density_type,
+                            Real resolution,
+                            bool clear_map_flag,
+                            Real source_wavelength)
+
+{
+  if(resolution <=0.0) throw std::runtime_error("Invalid resolution");
+  if (clear_map_flag==true) {
+    img::MapHandle mm=img::CreateImage(img::Extent(img::Point(0,0),
+                                       map.GetSize()));
+    // swap newly created map into place
+    mm.SetSpatialSampling(map.GetSpatialSampling());
+    mm.SetAbsoluteOrigin(map.GetAbsoluteOrigin());
+    map.Swap(mm);
+  }
+
+  detail::EntityToDensityRosettaHelper e_to_d_r_helper
+                                                (entity_view,density_type,
+                                                resolution);
+  map.ApplyIP(e_to_d_r_helper);
+}
+
+
+}}} // ns
+
+
diff --git a/modules/mol/alg/src/entity_to_density.hh b/modules/mol/alg/src/entity_to_density.hh
new file mode 100644
index 000000000..fc9180006
--- /dev/null
+++ b/modules/mol/alg/src/entity_to_density.hh
@@ -0,0 +1,79 @@
+#ifndef OST_ENTITY_TO_DENSITY_HH
+#define OST_ENTITY_TO_DENSITY_HH
+
+#include <ost/mol/entity_view.hh>
+#include <ost/img/map.hh>
+
+#include <ost/mol/alg/module_config.hh>
+
+
+namespace ost { namespace mol { namespace alg {
+
+/// \brief type of density being created by the EntityToDensity function
+enum DensityType
+{
+  HIGH_RESOLUTION,
+  LOW_RESOLUTION
+};
+
+/// \brief create a density representation of an entity in a density map (using electron scattering factors)
+///
+/// This functions creates a density representation of the entity provided by
+/// the user in a density map, in Fourier space using the correct scattering
+/// factors for the elements involved.
+///
+/// The user can also choose if the density map should be cleared of its
+/// previous content before creating the density representation.
+///
+/// The density is generated in Fourier space. In order to
+/// avoid artifacts in the final density representation, the function avoids
+/// sharp frequency cutoffs by applying a Gaussian falloff. The user must
+/// provide the resolutions at which the cutoff should begin and end, as opposed
+/// to a single resolution cutoff value.
+///
+/// This function will only create a density represenation of the entities
+/// (or portion of entities ) that fall within the borders of the map.
+/// The user must take care that this condition is verified for all
+/// entities for which he wants a representation.
+///
+void DLLEXPORT_OST_MOL_ALG EntityToDensityScattering(const mol::EntityView& entity_view,
+                                        img::MapHandle& map,
+                                        Real falloff_start,
+                                        Real falloff_end,
+                                        bool clear_map_flag = false,
+                                        Real source_wavelength = 1.5418);
+
+/// \brief create a density representation of an entity in a density map
+///
+/// This function creates a density representation of the entity provided by
+/// the user in a density map, also provided by the user. The user can choose
+/// the type of density of the output map:
+///
+/// ROSETTA_HIGH_RESOLUTION gaussian spheres in real space to represent
+///                         density, one per atom, see Dimaio et al.,
+///                         Refinement of Protein Structures into Low-Resolution
+///                         Density Maps Using Rosetta. Journal of Molecular
+///                         Biology (2009) pp. 1-10
+/// ROSETTA_LOW_RESOLUTION guassian spheres in real space to represent
+///                        density, one per residue. See reference above. Only
+///                        useful at low resolution
+///
+/// The user can also choose if the density map should be cleared of its
+/// previous content before creating the density representation.
+///
+/// The user must also provide a resolution parameter.
+///
+/// This function will only create a density represenation of the entities
+/// (or portion of entities ) that fall within the borders of the map.
+/// The user must take care that this condition is verified for all
+/// entities for which he wants a representation.
+///
+void DLLEXPORT_OST_MOL_ALG EntityToDensityRosetta(const mol::EntityView& entity_view,
+                                        img::MapHandle& map,
+                                        const DensityType& density_type,
+                                        Real resolution,
+                                        bool clear_map_flag = false,
+                                        Real source_wavelength = 1.5418);
+}}} // ns
+
+#endif // OST_ENTITY_TO_DENSITY
diff --git a/modules/mol/base/doc/editors.rst b/modules/mol/base/doc/editors.rst
index aaed57b35..f224b2e1f 100644
--- a/modules/mol/base/doc/editors.rst
+++ b/modules/mol/base/doc/editors.rst
@@ -1,7 +1,7 @@
 Editors
 ================================================================================
 
-.. currentmodule:: mol
+.. currentmodule:: ost.mol
 
 The structure, topology and connectivity of entities is edited via editors. This 
 includes operations such as changing atom positions, connecting atoms with bonds 
@@ -118,7 +118,7 @@ euclidian space.
      transform.
      
      :param atom: must be a valid atom handle
-     :type  atom: :class:`mol.AtomHandle`
+     :type  atom: :class:`ost.mol.AtomHandle`
      :param pos: The new position
      :type  pos: :class:`geom.Vec3`
      
@@ -129,7 +129,7 @@ euclidian space.
      the original pos.
      
      :param atom: must be a valid atom handle
-     :type  atom: :class:`mol.AtomHandle`
+     :type  atom: :class:`ost.mol.AtomHandle`
      :param pos: The new untransformed position
      :type  pos: :class:`geom.Vec3`
   
diff --git a/modules/mol/base/doc/entity.rst b/modules/mol/base/doc/entity.rst
index 75e5c6fde..1adcd2de7 100644
--- a/modules/mol/base/doc/entity.rst
+++ b/modules/mol/base/doc/entity.rst
@@ -1,7 +1,7 @@
 The Molecular Entity
 ================================================================================
 
-.. currentmodule:: mol
+.. currentmodule:: ost.mol
 
 This document describes the :class:`EntityHandle` and related classes.
 
@@ -10,7 +10,7 @@ This document describes the :class:`EntityHandle` and related classes.
 
    Creates a new entity. The created entity is empty, that is, it does not
    contain any atoms, residues, chains, bonds or torsions. To populate the
-   entity, create a new editor.
+   entity, use an :doc:`editors`.
    
    :returns: The newly created :class:`EntityHandle`
    
diff --git a/modules/mol/base/doc/mol.rst b/modules/mol/base/doc/mol.rst
index e4de24691..a16b21f54 100644
--- a/modules/mol/base/doc/mol.rst
+++ b/modules/mol/base/doc/mol.rst
@@ -1,7 +1,7 @@
-:mod:`mol` -- Molecular structures and surfaces
+:mod:`~ost.mol` -- Molecular structures and surfaces
 ================================================================================
 
-.. module:: mol
+.. module:: ost.mol
    :synopsis: Contains classes and functions to deal with molecular structures
               and surfaces
 
diff --git a/modules/mol/base/pymod/CMakeLists.txt b/modules/mol/base/pymod/CMakeLists.txt
index 590af6909..29c336dca 100644
--- a/modules/mol/base/pymod/CMakeLists.txt
+++ b/modules/mol/base/pymod/CMakeLists.txt
@@ -18,6 +18,7 @@ export_query_view_wrapper.cc
 export_torsion.cc
 export_visitor.cc
 wrap_mol.cc
+export_entity_property_mapper.cc
 )
 
 pymod(NAME mol CPP ${OST_BASE_PYMOD_SOURCES} PY __init__.py)
diff --git a/modules/mol/base/pymod/export_atom.cc b/modules/mol/base/pymod/export_atom.cc
index 83f2adc06..43e7483a7 100644
--- a/modules/mol/base/pymod/export_atom.cc
+++ b/modules/mol/base/pymod/export_atom.cc
@@ -27,7 +27,7 @@ using namespace ost;
 using namespace ost::mol;
 
 #include <ost/export_helper/generic_property_def.hh>
-
+#include <ost/export_helper/vector.hh>
 void export_Atom()
 {
   class_<AtomBase> atom_base("AtomBase", no_init);
@@ -42,8 +42,6 @@ void export_Atom()
     .add_property("qualified_name", &AtomBase::GetQualifiedName)
     .def("IsValid", &AtomBase::IsValid)
     .def(self_ns::str(self))
-    .add_property("hash_code", &AtomBase::GetHashCode)
-    .def("GetHashCode", &AtomBase::GetHashCode)
     .def("GetAtomProps", &AtomBase::GetAtomProps,
          return_value_policy<copy_const_reference>())
     .def("SetAtomProps", &AtomBase::SetAtomProps, args("prop"))
@@ -86,14 +84,17 @@ void export_Atom()
     .add_property("handle", &AtomHandle::GetHandle)
     .add_property("entity", &AtomHandle::GetEntity)
     .def("GetBondPartners", &AtomHandle::GetBondPartners)
+    .def("GetHashCode", &AtomHandle::GetHashCode)    
     .def("FindBondToAtom", &AtomHandle::FindBondToAtom, args("other_atom"))
     .def(self==self)
     .def(self!=self)
     .def("__hash__", &AtomHandle::GetHashCode)
+    .add_property("hash_code", &AtomHandle::GetHashCode)
   ;
 
   class_<AtomHandleList>("AtomHandleList", no_init)
     .def(vector_indexing_suite<AtomHandleList>())
+    .def(ost::VectorAdditions<AtomHandleList>())
   ;
   class_<AtomProp>("AtomProp", init<>())
     .def_readwrite("element", &AtomProp::element)
diff --git a/modules/mol/base/pymod/export_atom_view.cc b/modules/mol/base/pymod/export_atom_view.cc
index af2dd063b..bdee6609d 100644
--- a/modules/mol/base/pymod/export_atom_view.cc
+++ b/modules/mol/base/pymod/export_atom_view.cc
@@ -22,7 +22,7 @@
 using namespace boost::python;
 
 #include <ost/mol/mol.hh>
-
+#include <ost/export_helper/vector.hh>
 using namespace ost;
 using namespace ost::mol;
 
@@ -43,10 +43,14 @@ void export_AtomView()
     .def("GetHandle", &AtomView::GetHandle)
     .def("GetBondCount", &AtomView::GetBondCount)
     .def("GetBondList", &AtomView::GetBondList)
+    .def("GetHashCode", &AtomView::GetHashCode)
+    .def("__hash__", &AtomView::GetHashCode)
+    .add_property("hash_code", &AtomView::GetHashCode)
     .def("GetBondPartners", &AtomView::GetBondPartners)
   ;
   class_<AtomViewList>("AtomViewList", init<>())
     .def(vector_indexing_suite<AtomViewList>())
+    .def(ost::VectorAdditions<AtomViewList>())
   ;
 }
 
diff --git a/modules/mol/base/pymod/export_chain.cc b/modules/mol/base/pymod/export_chain.cc
index 57e717eba..fe2019d3a 100644
--- a/modules/mol/base/pymod/export_chain.cc
+++ b/modules/mol/base/pymod/export_chain.cc
@@ -21,7 +21,7 @@
 using namespace boost::python;
 
 #include <ost/mol/mol.hh>
-
+#include <ost/export_helper/vector.hh>
 using namespace ost;
 using namespace ost::mol;
 #include <ost/export_helper/generic_property_def.hh>
@@ -92,5 +92,6 @@ void export_Chain()
   
   class_<ChainHandleList>("ChainHandleList", no_init)
     .def(vector_indexing_suite<ChainHandleList>())
+    .def(ost::VectorAdditions<ChainHandleList>())    
   ;
 }
diff --git a/modules/mol/base/pymod/export_chain_view.cc b/modules/mol/base/pymod/export_chain_view.cc
index 8de0f77d7..fa8446a50 100644
--- a/modules/mol/base/pymod/export_chain_view.cc
+++ b/modules/mol/base/pymod/export_chain_view.cc
@@ -24,7 +24,7 @@ using namespace boost::python;
 #include <ost/mol/query.hh>
 #include <ost/mol/chain_handle.hh>
 #include <ost/mol/entity_visitor.hh>
-
+#include <ost/export_helper/vector.hh>
 using namespace ost;
 using namespace ost::mol;
 
@@ -58,6 +58,7 @@ void export_ChainView()
 {
   class_<ChainViewList>("ChainViewList", no_init)
     .def(vector_indexing_suite<ChainViewList>())
+    .def(ost::VectorAdditions<ChainViewList>())    
   ;
 
   void (ChainView::* apply1)(EntityVisitor&) = &ChainView::Apply;
diff --git a/modules/mol/base/pymod/export_entity_property_mapper.cc b/modules/mol/base/pymod/export_entity_property_mapper.cc
new file mode 100644
index 000000000..fa271bed8
--- /dev/null
+++ b/modules/mol/base/pymod/export_entity_property_mapper.cc
@@ -0,0 +1,68 @@
+#include <boost/python.hpp>
+
+#include <ost/mol/entity_property_mapper.hh>
+
+using namespace ost;
+using namespace ost::mol;
+using namespace boost::python;
+
+namespace {
+
+
+Real (EntityPropertyMapper::*get_ah_a)(const AtomHandle&) const=&EntityPropertyMapper::Get;
+Real (EntityPropertyMapper::*get_av_a)(const AtomView&) const=&EntityPropertyMapper::Get;
+Real (EntityPropertyMapper::*get_rh_a)(const ResidueHandle&) const=&EntityPropertyMapper::Get;
+Real (EntityPropertyMapper::*get_rv_a)(const ResidueView&) const=&EntityPropertyMapper::Get;
+Real (EntityPropertyMapper::*get_ch_a)(const ChainHandle&) const=&EntityPropertyMapper::Get;
+Real (EntityPropertyMapper::*get_cv_a)(const ChainView&) const=&EntityPropertyMapper::Get;
+
+
+Real (EntityPropertyMapper::*get_ah_b)(const AtomHandle&, Real) const=&EntityPropertyMapper::Get;
+Real (EntityPropertyMapper::*get_av_b)(const AtomView&, Real) const=&EntityPropertyMapper::Get;
+Real (EntityPropertyMapper::*get_rh_b)(const ResidueHandle&, Real) const=&EntityPropertyMapper::Get;
+Real (EntityPropertyMapper::*get_rv_b)(const ResidueView&, Real) const=&EntityPropertyMapper::Get;
+Real (EntityPropertyMapper::*get_ch_b)(const ChainHandle&, Real) const=&EntityPropertyMapper::Get;
+Real (EntityPropertyMapper::*get_cv_b)(const ChainView&, Real) const=&EntityPropertyMapper::Get;
+
+EntityPropertyMapper create_epm(const String& prop_name, char level)
+{
+  switch(level) {
+    case 'A':
+    case 'a':
+      return EntityPropertyMapper(prop_name, Prop::ATOM);
+    case 'R':
+    case 'r':
+      return EntityPropertyMapper(prop_name, Prop::RESIDUE);
+    case 'C':
+    case 'c':
+      return EntityPropertyMapper(prop_name, Prop::CHAIN);
+    case 'U':
+    case 'u':
+      return EntityPropertyMapper(prop_name, Prop::UNSPECIFIED);
+    default:
+      throw std::runtime_error(String("unknown property level '")+level+"'");
+  }
+}
+
+}
+
+void export_EntityPropertyMapper()
+{
+  class_<EntityPropertyMapper>("EntityPropertyMapper", 
+                               init<const String&, 
+                                    Prop::Level>(arg("level")=Prop::UNSPECIFIED))
+    .def("__init__", &create_epm)
+    .def("Get", get_ah_a)
+    .def("Get", get_av_a)
+    .def("Get", get_rh_a)
+    .def("Get", get_rv_a)
+    .def("Get", get_ch_a)
+    .def("Get", get_cv_a)
+    .def("Get", get_ah_b)
+    .def("Get", get_av_b)
+    .def("Get", get_rh_b)
+    .def("Get", get_rv_b)
+    .def("Get", get_ch_b)
+    .def("Get", get_cv_b)
+  ;  
+}
diff --git a/modules/mol/base/pymod/export_residue.cc b/modules/mol/base/pymod/export_residue.cc
index 905c6b515..0c28df652 100644
--- a/modules/mol/base/pymod/export_residue.cc
+++ b/modules/mol/base/pymod/export_residue.cc
@@ -22,7 +22,7 @@
 using namespace boost::python;
 
 #include <ost/mol/mol.hh>
-
+#include <ost/export_helper/vector.hh>
 using namespace ost;
 using namespace ost::mol;
 
@@ -71,6 +71,7 @@ void export_Residue()
     .def(self+int())
     .def(self-int())    
   ;
+  implicitly_convertible<int, ResNum>();
   {
     scope sec_struct_scope=class_<SecStructure>("SecStructure", init<>())
       .def(init<char>())
@@ -174,5 +175,6 @@ void export_Residue()
 
   class_<ResidueHandleList>("ResidueHandleList", no_init)
     .def(vector_indexing_suite<ResidueHandleList>())
+    .def(ost::VectorAdditions<ResidueHandleList>())    
   ;
 }
diff --git a/modules/mol/base/pymod/export_residue_view.cc b/modules/mol/base/pymod/export_residue_view.cc
index 29943f54a..a23bcf88d 100644
--- a/modules/mol/base/pymod/export_residue_view.cc
+++ b/modules/mol/base/pymod/export_residue_view.cc
@@ -22,7 +22,7 @@
 using namespace boost::python;
 
 #include <ost/mol/mol.hh>
-
+#include <ost/export_helper/vector.hh>
 using namespace ost;
 using namespace ost::mol;
 
@@ -48,6 +48,7 @@ void export_ResidueView()
 {
   class_<ResidueViewList>("ResidueViewList", no_init)
     .def(vector_indexing_suite<ResidueViewList>())
+    .def(ost::VectorAdditions<ResidueViewList>()) 
   ;
 
   void (ResidueView::* apply1)(EntityVisitor&) = &ResidueView::Apply;
diff --git a/modules/mol/base/pymod/export_surface.cc b/modules/mol/base/pymod/export_surface.cc
index 71c347e16..fe0d98fa1 100644
--- a/modules/mol/base/pymod/export_surface.cc
+++ b/modules/mol/base/pymod/export_surface.cc
@@ -24,7 +24,6 @@ using namespace boost::python;
 #include <ost/mol/surface_handle.hh>
 #include <ost/mol/surface_builder.hh>
 #include <ost/mol/entity_handle.hh>
-#include <ost/mol/impl/rsurf_impl.hh>
 #include <ost/mol/impl/surface_impl.hh>
 
 using namespace ost;
@@ -37,12 +36,6 @@ SurfaceHandle create1()
   return CreateSurface();
 }
 
-void rsurf_tri_dummy(rsurf::RSurf& rs, float patch_size)
-{
-  impl::SurfaceImplP impl(new impl::SurfaceImpl());
-  rs.Triangulate(impl,patch_size);
-}
-
 void (SurfaceHandle::*attach1)(const EntityHandle&,Real)=&SurfaceHandle::Attach;
 void (SurfaceHandle::*attach2)(const EntityView&,Real)=&SurfaceHandle::Attach;
 
@@ -74,10 +67,4 @@ void export_Surface()
   def("CreateSurface",create1);
 
   def("BuildSurface",BuildSurface);
-
-  class_<rsurf::RSurf,rsurf::RSurfP>("RSurf", init<Real>())
-    .def("AddSphere",&rsurf::RSurf::AddSphere)
-    .def("Build",&rsurf::RSurf::Build)
-    .def("Triangulate",rsurf_tri_dummy)
-    ;
 }
diff --git a/modules/mol/base/pymod/wrap_mol.cc b/modules/mol/base/pymod/wrap_mol.cc
index 82a449f68..ce55b9942 100644
--- a/modules/mol/base/pymod/wrap_mol.cc
+++ b/modules/mol/base/pymod/wrap_mol.cc
@@ -41,6 +41,7 @@ void export_CoordGroup();
 void export_PropertyID();
 void export_BoundingBox();
 void export_QueryViewWrapper();
+void export_EntityPropertyMapper();
 BOOST_PYTHON_MODULE(_mol)
 {
   export_Entity();
@@ -61,7 +62,7 @@ BOOST_PYTHON_MODULE(_mol)
   export_PropertyID();  
   export_BoundingBox();
   export_QueryViewWrapper();
-
+  export_EntityPropertyMapper();
   class_<Transform>("Transform", init<>())
     .def("GetMatrix",&Transform::GetMatrix)
     .def("GetTransposedMatrix",&Transform::GetTransposedMatrix)
diff --git a/modules/mol/base/src/atom_base.cc b/modules/mol/base/src/atom_base.cc
index 8eaff3164..2818844b0 100644
--- a/modules/mol/base/src/atom_base.cc
+++ b/modules/mol/base/src/atom_base.cc
@@ -120,12 +120,6 @@ void AtomBase::CheckValidity() const
     throw InvalidHandle();
 }
 
-long AtomBase::GetHashCode() const 
-{
-  this->CheckValidity();  
-  return reinterpret_cast<long>(Impl().get());
-}
-
 std::ostream& operator<<(std::ostream& os, const AtomBase& atom) 
 {
   if (atom.IsValid()) {
diff --git a/modules/mol/base/src/atom_base.hh b/modules/mol/base/src/atom_base.hh
index 142f1a9db..9777aea71 100644
--- a/modules/mol/base/src/atom_base.hh
+++ b/modules/mol/base/src/atom_base.hh
@@ -153,11 +153,6 @@ public:
   /// \brief get atom implementation
   impl::AtomImplPtr& Impl();
 
-  /// \brief Get unique identifier for atom
-  /// 
-  /// Get hash code that uniquely identifies every atom. The hash code is
-  /// identical for all atom views pointing to a given atom.
-  long GetHashCode() const;  
 protected:
   
   GenericPropContainerImpl* GpImpl();
diff --git a/modules/mol/base/src/atom_handle.cc b/modules/mol/base/src/atom_handle.cc
index 486441683..61c975724 100644
--- a/modules/mol/base/src/atom_handle.cc
+++ b/modules/mol/base/src/atom_handle.cc
@@ -116,6 +116,12 @@ AtomHandle AtomHandle::GetHandle() const
   return *this;
 }
 
+long AtomHandle::GetHashCode() const 
+{
+  this->CheckValidity();  
+  return reinterpret_cast<long>(Impl().get());
+}
+
 }} // ns
 
 
diff --git a/modules/mol/base/src/atom_handle.hh b/modules/mol/base/src/atom_handle.hh
index 7d817f8e1..6ea9094c0 100644
--- a/modules/mol/base/src/atom_handle.hh
+++ b/modules/mol/base/src/atom_handle.hh
@@ -81,6 +81,13 @@ public:
   /// 
   /// Useful for duck-typing in Python and templated code.
   AtomHandle GetHandle() const;
+  
+  /// \brief Get unique identifier for atom
+  /// 
+  /// Get hash code that uniquely identifies every atom. The hash code is
+  /// identical for all atom views pointing to a given atom.
+  long GetHashCode() const;
+  
   bool operator==(const AtomHandle& ref) const;
   bool operator!=(const AtomHandle& ref) const;
 
diff --git a/modules/mol/base/src/atom_view.cc b/modules/mol/base/src/atom_view.cc
index 25518778e..5811a2d55 100644
--- a/modules/mol/base/src/atom_view.cc
+++ b/modules/mol/base/src/atom_view.cc
@@ -115,7 +115,7 @@ mol::AtomViewList AtomView::GetBondPartners() const
   mol::AtomViewList avl;
   mol::BondHandleList::const_iterator i;
   for (i=data_->bonds.begin();i!=data_->bonds.end();++i) {
-    if (i->GetFirst()!=*this) {
+    if (i->GetFirst().GetHandle()!=this->GetHandle()) {
       avl.push_back(this->GetEntity().FindAtom(i->GetFirst()));
     } else {
       avl.push_back(this->GetEntity().FindAtom(i->GetSecond()));
@@ -156,7 +156,13 @@ void AtomView::RemoveBondInternal(const BondHandle& bond)
     data_->bonds.erase(i);    
   }
 }
-  
+
+long AtomView::GetHashCode() const 
+{
+  this->CheckValidity();  
+  return reinterpret_cast<long>(data_.get());
+} 
+
 }} // ns
 
 
diff --git a/modules/mol/base/src/atom_view.hh b/modules/mol/base/src/atom_view.hh
index ad65accc6..a9e2d9937 100644
--- a/modules/mol/base/src/atom_view.hh
+++ b/modules/mol/base/src/atom_view.hh
@@ -69,6 +69,11 @@ public:
   void Apply(EntityVisitor& visitor);
   void Apply(EntityViewVisitor& visitor);
 
+  /// \brief get unique id
+  /// 
+  /// The unique id is the same for all AtomViews pointing to the same atom 
+  /// view data. 
+  long GetHashCode() const;
   bool operator==(const AtomView& rhs) const;
   bool operator!=(const AtomView& rhs) const;
 protected:
diff --git a/modules/mol/base/src/chain_handle.cc b/modules/mol/base/src/chain_handle.cc
index 156eca176..4581eb780 100644
--- a/modules/mol/base/src/chain_handle.cc
+++ b/modules/mol/base/src/chain_handle.cc
@@ -125,17 +125,18 @@ bool ChainHandle::operator!=(const ChainHandle& ref) const
 ResidueHandleIter ChainHandle::ResiduesBegin() const {
   this->CheckValidity();
   impl::ChainImplPtr c=Impl();
-  impl::ChainImplMap::iterator cc=c->GetEntity()->GetChainMap().find(c->GetName());
-  return ResidueHandleIter(cc, c->GetResidueList().begin(), c->GetEntity());
+  impl::ChainImplList::iterator cc=c->GetEntity()->GetChain(this->GetName());
+  return ResidueHandleIter(cc, c->GetResidueList().begin(), 
+                           c->GetEntity());
 }
 
 ResidueHandleIter ChainHandle::ResiduesEnd() const {
   this->CheckValidity();
   impl::ChainImplPtr c=Impl();
-  impl::ChainImplMap::iterator cc=c->GetEntity()->GetChainMap().find(c->GetName());  
-  impl::ChainImplMap::iterator nc=cc; ++nc;
-  if (nc!=c->GetEntity()->GetChainMap().end()) {
-    return ResidueHandleIter(nc, nc->second->GetResidueList().begin(), 
+  impl::ChainImplList::iterator cc=c->GetEntity()->GetChain(this->GetName());
+  impl::ChainImplList::iterator nc=cc; ++nc;
+  if (nc!=c->GetEntity()->GetChainList().end()) {
+    return ResidueHandleIter(nc, (*nc)->GetResidueList().begin(), 
                              c->GetEntity());    
   } else {
     return ResidueHandleIter(cc, c->GetResidueList().end(), 
@@ -151,7 +152,7 @@ AtomHandleIter ChainHandle::AtomsBegin() const
 
     return AtomHandleIter();
   }  
-  impl::ChainImplMap::iterator cc=c->GetEntity()->GetChainMap().find(c->GetName());    
+  impl::ChainImplList::iterator cc=c->GetEntity()->GetChain(this->GetName()); 
   return AtomHandleIter(cc, c->GetResidueList().begin(),
                         c->GetResidueList().front()->GetAtomList().begin(),
                         c->GetEntity(), true);    
@@ -164,10 +165,10 @@ AtomHandleIter ChainHandle::AtomsEnd() const {
   if (c->GetResidueList().empty()) {
     return AtomHandleIter();
   }  
-  impl::ChainImplMap::iterator cc=c->GetEntity()->GetChainMap().find(c->GetName());
-  impl::ChainImplMap::iterator nc=cc; ++nc;
-  impl::ResidueImplList& rc=nc->second->GetResidueList();
-  if (nc!=c->GetEntity()->GetChainMap().end()) {  
+  impl::ChainImplList::iterator cc=c->GetEntity()->GetChain(this->GetName());
+  impl::ChainImplList::iterator nc=cc; ++nc;
+  impl::ResidueImplList& rc=(*nc)->GetResidueList();
+  if (nc!=c->GetEntity()->GetChainList().end()) {  
     return AtomHandleIter(nc, rc.begin(), rc.front()->GetAtomList().begin(),
                           c->GetEntity(), false);
   } else {
diff --git a/modules/mol/base/src/coord_source.cc b/modules/mol/base/src/coord_source.cc
index 9b9f853e3..0afa3597d 100644
--- a/modules/mol/base/src/coord_source.cc
+++ b/modules/mol/base/src/coord_source.cc
@@ -95,7 +95,7 @@ void CoordSource::CaptureInto(int pos)
        e=atoms_.end(); i!=e; ++i) {
     coords.push_back(i->GetPos());
   }
-  if(pos<0 || pos>=GetFrameCount()) {
+  if(pos<0 || pos>=static_cast<int>(this->GetFrameCount())) {
     this->AddFrame(coords);
   } else {
     this->InsertFrame(pos,coords);
diff --git a/modules/mol/base/src/entity_handle.cc b/modules/mol/base/src/entity_handle.cc
index b0ac01f09..8686df88c 100644
--- a/modules/mol/base/src/entity_handle.cc
+++ b/modules/mol/base/src/entity_handle.cc
@@ -257,48 +257,48 @@ AtomHandle EntityHandle::FindAtom(const String& chain_name,
 
 ResidueHandleIter EntityHandle::ResiduesBegin() const {
   this->CheckValidity();
-  if (Impl()->GetChainMap().empty()) {
+  if (Impl()->GetChainList().empty()) {
     return ResidueHandleIter();
   }
   impl::EntityImplPtr i=Impl();
-  impl::ChainImplPtr chain=i->GetChainMap().begin()->second;
-  return ResidueHandleIter(i->GetChainMap().begin(),
+  impl::ChainImplPtr chain=i->GetChainList().front();
+  return ResidueHandleIter(i->GetChainList().begin(),
                            chain->GetResidueList().begin(), i);
 }
 
 ResidueHandleIter EntityHandle::ResiduesEnd() const {
   this->CheckValidity();
-  if (Impl()->GetChainMap().empty()) {
+  if (Impl()->GetChainList().empty()) {
     return ResidueHandleIter();
   }
   impl::EntityImplPtr i=Impl();
-  impl::ChainImplPtr chain=i->GetChainMap().rbegin()->second;
-  return ResidueHandleIter(i->GetChainMap().end(),
+  impl::ChainImplPtr chain=i->GetChainList().back();
+  return ResidueHandleIter(i->GetChainList().end(),
                            chain->GetResidueList().end(), i);
 }
 
 ChainHandleIter EntityHandle::ChainsBegin() const {
   this->CheckValidity();
-  return ChainHandleIter(Impl()->GetChainMap().begin());
+  return ChainHandleIter(Impl()->GetChainList().begin());
 }
 
 
 ChainHandleIter EntityHandle::ChainsEnd() const {
-  return ChainHandleIter(Impl()->GetChainMap().end());
+  return ChainHandleIter(Impl()->GetChainList().end());
 }
 
 
 AtomHandleIter EntityHandle::AtomsBegin() const {
   this->CheckValidity();
   impl::EntityImplPtr ent=Impl();
-  if (ent->GetChainMap().empty()) {
+  if (ent->GetChainList().empty()) {
     return AtomHandleIter();
   }
-  impl::ResidueImplList& r=ent->GetChainMap().begin()->second->GetResidueList();
+  impl::ResidueImplList& r=ent->GetChainList().front()->GetResidueList();
   if (r.empty()) {
     return AtomHandleIter();
   }
-  return AtomHandleIter(ent->GetChainMap().begin(), r.begin(),
+  return AtomHandleIter(ent->GetChainList().begin(), r.begin(),
                         r.front()->GetAtomList().begin(), ent, true);
 }
 
@@ -306,14 +306,14 @@ AtomHandleIter EntityHandle::AtomsEnd() const
 {
   this->CheckValidity();
   impl::EntityImplPtr ent=Impl();
-  if (ent->GetChainMap().empty()) {
+  if (ent->GetChainList().empty()) {
     return AtomHandleIter();
   }
-  impl::ResidueImplList& r=ent->GetChainMap().rbegin()->second->GetResidueList();
+  impl::ResidueImplList& r=ent->GetChainList().back()->GetResidueList();
   if (r.empty()) {
     return AtomHandleIter();
   }
-  return AtomHandleIter(ent->GetChainMap().end(), r.end(),
+  return AtomHandleIter(ent->GetChainList().end(), r.end(),
                         r.back()->GetAtomList().end(), ent, false);
 }
 
diff --git a/modules/mol/base/src/entity_view.cc b/modules/mol/base/src/entity_view.cc
index 34f7d5064..a3819e102 100644
--- a/modules/mol/base/src/entity_view.cc
+++ b/modules/mol/base/src/entity_view.cc
@@ -76,9 +76,9 @@ EntityView::EntityView(const EntityHandle& entity,
                        ViewAddFlags flags)
   : EntityBase(entity.Impl()), data_(new EntityViewData()) {
   if (flags & ViewAddFlag::INCLUDE_CHAINS) {
-    impl::ChainImplMap::const_iterator i=entity.Impl()->GetChainMap().begin();
-    for (; i!=entity.Impl()->GetChainMap().end(); ++i) {
-      this->AddChain(ChainHandle(i->second), flags);
+    impl::ChainImplList::const_iterator i=entity.Impl()->GetChainList().begin();
+    for (; i!=entity.Impl()->GetChainList().end(); ++i) {
+      this->AddChain(ChainHandle(*i), flags);
     }
   }
 }
diff --git a/modules/mol/base/src/impl/CMakeLists.txt b/modules/mol/base/src/impl/CMakeLists.txt
index c398ff177..3de4864e7 100644
--- a/modules/mol/base/src/impl/CMakeLists.txt
+++ b/modules/mol/base/src/impl/CMakeLists.txt
@@ -9,7 +9,6 @@ query_ast.cc
 query_impl.cc
 residue_impl.cc
 surface_impl.cc
-rsurf_impl.cc
 torsion_impl.cc
 PARENT_SCOPE
 )
@@ -34,7 +33,6 @@ residue_impl.hh
 residue_impl_fw.hh
 surface_impl.hh
 surface_impl_fw.hh
-rsurf_impl.hh
 torsion_impl.hh
 torsion_impl_fw.hh
 PARENT_SCOPE
diff --git a/modules/mol/base/src/impl/chain_impl_fw.hh b/modules/mol/base/src/impl/chain_impl_fw.hh
index 00f22561b..2ba9c725d 100644
--- a/modules/mol/base/src/impl/chain_impl_fw.hh
+++ b/modules/mol/base/src/impl/chain_impl_fw.hh
@@ -28,7 +28,6 @@ namespace ost { namespace mol { namespace impl {
 class ChainImpl;
 typedef boost::shared_ptr<ChainImpl> ChainImplPtr;
 typedef boost::weak_ptr<ChainImpl> ChainImplW;
-typedef std::list<ChainImplPtr> ChainImplList;
 
 }}} // ns
 
diff --git a/modules/mol/base/src/impl/entity_impl.cc b/modules/mol/base/src/impl/entity_impl.cc
index 29fdad970..c7eb10163 100644
--- a/modules/mol/base/src/impl/entity_impl.cc
+++ b/modules/mol/base/src/impl/entity_impl.cc
@@ -64,7 +64,7 @@ namespace ost { namespace mol { namespace impl {
 
 EntityImpl::EntityImpl():
   atom_map_(),
-  chain_map_(),
+  chain_list_(),
   connector_map_(),
   torsion_map_(),
   transformation_matrix_(),
@@ -104,9 +104,9 @@ mol::BondHandleList EntityImpl::GetBondList() const
 int EntityImpl::GetResidueCount() const 
 {
   int count=0;
-  for (ChainImplMap::const_iterator i=chain_map_.begin(), 
-       e=chain_map_.end(); i!=e; ++i) {
-    count+=i->second->GetResidueCount();
+  for (ChainImplList::const_iterator i=chain_list_.begin(), 
+       e=chain_list_.end(); i!=e; ++i) {
+    count+=(*i)->GetResidueCount();
   }
   return count;
 }
@@ -133,9 +133,9 @@ ChainImplPtr EntityImpl::InsertChain(const ChainImplPtr& chain)
 
 void EntityImpl::ReplicateHierarchy(EntityImplPtr dest)
 {
-  for (ChainImplMap::const_iterator i=chain_map_.begin(), 
-       e1=chain_map_.end(); i!=e1; ++i) {
-    ChainImplPtr src_chain=i->second;
+  for (ChainImplList::const_iterator i=chain_list_.begin(), 
+       e1=chain_list_.end(); i!=e1; ++i) {
+    ChainImplPtr src_chain=*i;
     ChainImplPtr dst_chain=dest->InsertChain(src_chain);
     // copy generic properties
     dst_chain->Assign(*src_chain.get());
@@ -176,10 +176,10 @@ AtomImplPtr lookup_atom(const AtomImplPtr& atom, EntityImplPtr dest,
 
 void EntityImpl::DoCopyBondsAndTorsions(EntityImplPtr dest)
 {
-  for (ChainImplMap::const_iterator i=chain_map_.begin(), 
-       i2=dest->chain_map_.begin(), e1=chain_map_.end(); i!=e1; ++i, ++i2) {
-    ChainImplPtr src_chain=i->second;
-    ChainImplPtr dst_chain=i2->second;
+  for (ChainImplList::const_iterator i=chain_list_.begin(), 
+       i2=dest->chain_list_.begin(), e1=chain_list_.end(); i!=e1; ++i, ++i2) {
+    ChainImplPtr src_chain=*i;
+    ChainImplPtr dst_chain=*i2;
     for (ResidueImplList::iterator j=src_chain->GetResidueList().begin(),
          j2=dst_chain->GetResidueList().begin(),
          e2=src_chain->GetResidueList().end(); j!=e2; ++j, ++j2) {
@@ -236,7 +236,7 @@ void EntityImpl::DoCopy(EntityImplPtr dest)
 
 int EntityImpl::GetChainCount() const 
 {
-  return static_cast<int>(chain_map_.size());
+  return static_cast<int>(chain_list_.size());
 }
 
 const geom::Mat4& EntityImpl::GetTransfMatrix() const
@@ -384,17 +384,19 @@ ResidueImplPtr EntityImpl::CreateResidue(const ChainImplPtr& cp,
 
 ChainImplPtr EntityImpl::InsertChain(const String& cname)
 {
-  ChainImplMap::iterator i=chain_map_.find(cname);
-  if (i!=chain_map_.end()) {
-    throw IntegrityError("Can't insert chain. A chain with name '"+cname+
-                         "' already exists");
+  for (ChainImplList::iterator 
+       i=chain_list_.begin(), e=chain_list_.end(); i!=e; ++i) {
+      if ((*i)->GetName()==cname) {
+        throw IntegrityError("Can't insert chain. A chain with name '"+cname+
+                             "' already exists");
+      }
   }
 #if MAKE_SHARED_AVAILABLE
   ChainImplPtr cp=boost::make_shared<ChainImpl>(shared_from_this(), cname);
 #else
   ChainImplPtr cp(new ChainImpl(shared_from_this(), cname));
 #endif
-  chain_map_.insert(ChainImplMap::value_type(cp->GetName(),cp));
+  chain_list_.push_back(cp);
   return cp;
 }
 
@@ -767,8 +769,9 @@ void EntityImpl::Apply(EntityVisitor& v)
 {
   LOG_TRACE("visitor @" << &v << " visiting entity impl @" << this << std::endl);
   v.OnEntry();
-  for(ChainImplMap::iterator it = chain_map_.begin();it!=chain_map_.end();++it) {
-    it->second->Apply(v);
+  for(ChainImplList::iterator 
+      it = chain_list_.begin();it!=chain_list_.end();++it) {
+    (*it)->Apply(v);
   }
 
   for(ConnectorImplMap::iterator it = connector_map_.begin();it!=connector_map_.end();++it) {
@@ -821,7 +824,7 @@ void EntityImpl::NotifyObserver()
 void EntityImpl::Swap(EntityImpl& impl)
 {
   atom_map_.swap(impl.atom_map_);
-  chain_map_.swap(impl.chain_map_);
+  chain_list_.swap(impl.chain_list_);
   connector_map_.swap(impl.connector_map_);
   torsion_map_.swap(impl.torsion_map_);
   std::swap(transformation_matrix_,impl.transformation_matrix_);
@@ -830,15 +833,6 @@ void EntityImpl::Swap(EntityImpl& impl)
   observer_map_.swap(impl.observer_map_);
 }
 
-ChainImplList EntityImpl::GetChainList() const {
-  ChainImplList cl;
-  ChainImplMap::const_iterator i;
-  for (i=chain_map_.begin(); i!=chain_map_.end(); ++i) {
-    cl.push_back(i->second);
-  }
-  return cl;
-}
-
 
 TorsionImplP EntityImpl::FindTorsion(const AtomImplPtr& a1,
                                      const AtomImplPtr& a2,
@@ -895,19 +889,15 @@ EntityView EntityImpl::do_selection(const EntityHandle& eh,
   EntityHandle myself(const_cast<impl::EntityImpl*>(this)->shared_from_this());
   QueryState qs(query.CreateQueryState(myself));
   LOGN_DUMP("entering chain loop");
-  for (ChainImplMap::const_iterator ch_it = chain_map_.begin();
-       ch_it!=chain_map_.end();++ch_it) {
-    if(!ch_it->second) {
-      LOGN_DUMP("found invalid chain shared_ptr");
-      continue;
-    }
-    LOGN_DUMP("checking chain " << ch_it->second->GetName());
+  for (ChainImplList::const_iterator 
+       ch_it=chain_list_.begin(); ch_it!=chain_list_.end();++ch_it) {
+    LOGN_DUMP("checking chain " << (*ch_it)->GetName());
     c_added = false;
-    tribool c = always_true ? tribool(true) : qs.EvalChain(ch_it->second);
+    tribool c = always_true ? tribool(true) : qs.EvalChain(*ch_it);
     if (c == true) {
       LOGN_DUMP("chain is selected");
       // Include all residues
-      const ChainImplPtr& ci=ch_it->second;
+      const ChainImplPtr& ci=*ch_it;
       ++chain_count;
       ChainView chain=view.AddChain(ci);
       ResidueImplList::const_iterator re_it = ci->GetResidueList().begin();
@@ -930,7 +920,7 @@ EntityView EntityImpl::do_selection(const EntityHandle& eh,
     } else if (indeterminate(c)) {
       // Test residues
       r_added = false;
-      const ChainImplPtr& ci = ch_it->second;
+      const ChainImplPtr& ci = *ch_it;
 
       ChainView chain;
       ResidueImplList::const_iterator re_it = ci->GetResidueList().begin();
@@ -1042,10 +1032,10 @@ EntityView EntityImpl::CreateFullView(const EntityHandle& h) const
 }
 
 ChainImplPtr EntityImpl::FindChain(const String& name) const {
-  ChainImplMap::const_iterator i;
-  for(i=chain_map_.begin(); i!=chain_map_.end();++i) {
-    if (i->second->GetName()==name)
-      return i->second;
+  ChainImplList::const_iterator i;
+  for(i=chain_list_.begin(); i!=chain_list_.end();++i) {
+    if ((*i)->GetName()==name)
+      return *i;
   }
   return ChainImplPtr();
 }
@@ -1078,7 +1068,7 @@ TorsionImplMap& EntityImpl::GetTorsionMap() {
 void EntityImpl::DeleteChain(const ChainImplPtr& chain) {
   if (chain && chain->GetEntity().get()==this) {
     chain->DeleteAllResidues();
-    chain_map_.erase(chain->GetName());
+    chain_list_.erase(this->GetChain(chain->GetName()));
   }
 }
 
@@ -1191,24 +1181,26 @@ void EntityImpl::DecICSEditorCount()
   }
 }
 
+impl::ChainImplList::iterator EntityImpl::GetChain(const String& name)
+{
+  impl::ChainImplList& cc=this->GetChainList();
+  for (impl::ChainImplList::iterator i=cc.begin(), e=cc.end(); i!=e; ++i) {
+    if ((*i)->GetName()==name) {
+      return i;
+    }
+  }
+  return  cc.end();
+}
 void EntityImpl::RenameChain(ChainImplPtr chain, const String& new_name)
 {
-  ChainImplMap::iterator i, j;
-  j=chain_map_.find(new_name);
-
-  if (j!=chain_map_.end() && j->second!=chain) {
+  ChainImplList::iterator i;
+  ChainImplPtr  ch=this->FindChain(new_name);
+  if (ch) {
     throw IntegrityError("unable to rename chain '"+chain->GetName()+
                          "' to '"+new_name+"', since there is already a chain "
                          "with that name");
   }
-  for(i=chain_map_.begin(); i!=chain_map_.end();++i) {
-    if (i->second==chain) {
-      chain_map_.erase(i);
-      chain_map_.insert(std::make_pair(new_name, chain));
-      chain->SetName(new_name);
-      break;
-    }
-  }
+  chain->SetName(new_name);
 }
 
 void EntityImpl::UpdateTransformedPos(){
diff --git a/modules/mol/base/src/impl/entity_impl.hh b/modules/mol/base/src/impl/entity_impl.hh
index 63504c749..81f533bf0 100644
--- a/modules/mol/base/src/impl/entity_impl.hh
+++ b/modules/mol/base/src/impl/entity_impl.hh
@@ -56,7 +56,7 @@ typedef std::map<AtomImpl*,AtomImplPtr> AtomImplMap;
 /// \internal
 typedef std::map<ResidueImpl*,ResidueImplPtr> ResidueImplMap;
 /// \internal
-typedef std::map<String,ChainImplPtr> ChainImplMap;
+typedef std::vector<ChainImplPtr> ChainImplList;
 /// \internal
 typedef std::map<ConnectorImpl*,ConnectorImplP> ConnectorImplMap;
 /// \internal
@@ -201,10 +201,9 @@ public:
 
   bool IsTransfIdentity() const;
 
-  ChainImplList GetChainList() const;
+  const ChainImplList& GetChainList() const { return chain_list_; }
 
-  ChainImplMap& GetChainMap() {return chain_map_; }
-  const ChainImplMap& GetChainMap() const {return chain_map_; }
+  ChainImplList& GetChainList() { return chain_list_; }
 
   void DeleteFromConnMap(const ConnectorImplP& conn);
 
@@ -241,6 +240,8 @@ public:
 
   const String& GetName() const;
 
+  impl::ChainImplList::iterator GetChain(const String& name);
+
   void SetName(const String& ent_name);
 
 private:
@@ -251,7 +252,7 @@ private:
   void DoCopyBondsAndTorsions(EntityImplPtr dest);
 
   AtomImplMap atom_map_;
-  ChainImplMap chain_map_;
+  ChainImplList chain_list_;
   ConnectorImplMap connector_map_;
   TorsionImplMap torsion_map_;
 
diff --git a/modules/mol/base/src/impl/rsurf_impl.cc b/modules/mol/base/src/impl/rsurf_impl.cc
deleted file mode 100644
index 283671fdf..000000000
--- a/modules/mol/base/src/impl/rsurf_impl.cc
+++ /dev/null
@@ -1,1090 +0,0 @@
-//------------------------------------------------------------------------------
-// This file is part of the OpenStructure project <www.openstructure.org>
-//
-// Copyright (C) 2008-2010 by the OpenStructure authors
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License as published by the Free
-// Software Foundation; either version 3.0 of the License, or (at your option)
-// any later version.
-// This library is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
-// details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this library; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-//------------------------------------------------------------------------------
-/*
-  Author: Ansgar Philippsen
-*/
-
-/*
-  parallelization notes:
-
-  during the build round, ie the recursive travel along
-  the surface to identify the reduced surface points, the
-  majority of calls depends on the previous one, and the
-  core algorithm is a recursive traversal; it is unclear
-  how to add parallelization to this type of logic.
-
-  during the triangulization, the creation of the patches,
-  the saddles and the sphere caps are in their internal
-  loop independent from each other; the only restriction
-  in terms of sequence is that the patches must be complete
-  before the saddles are build, and the patches must be
-  complete prior to the sphere caps. 
-
-*/
-
-#include <cmath>
-
-#include <ost/mol/entity_view.hh>
-#include <ost/mol/impl/rsurf_impl.hh>
-#include <ost/mol/impl/surface_impl.hh>
-
-#include <ost/geom/geom.hh>
-#include <ost/log.hh>
-
-namespace ost { namespace mol { namespace rsurf {
-
-using namespace geom;
-
-// almost copy from gfx... bad
-// TODO: refactor to geom
-void build_sphere(int level,
-                  std::vector<Vec3>& vlist,
-                  std::vector<uint>& ilist)
-{
-  vlist.clear();
-  ilist.clear();
-  unsigned int step1 = level*4;
-  unsigned int step2 = level*2;
-  Real fact1 = M_PI*2.0/static_cast<Real>(step1);
-  Real fact2 = M_PI/static_cast<Real>(step2);
-  
-  vlist.push_back(geom::Vec3(0.0,1.0,0.0));
-  for(unsigned int i=0;i<step1;++i) {
-    for(unsigned int k=1;k<step2;++k) {
-      Real ii = M_PI+fact1*static_cast<Real>(i);
-      Real kk = fact2*static_cast<Real>(k);
-      vlist.push_back(geom::Vec3(sin(kk)*cos(ii), cos(kk), sin(kk)*sin(ii)));
-    }
-  }
-  vlist.push_back(geom::Vec3(0.0,-1.0,0.0));
-  
-  unsigned int point_count=vlist.size();
-  
-  // top
-  unsigned int j=1;
-  for(unsigned int i=0;i<step1;++i) {
-    unsigned int k=i+1;
-    k%=step1;
-    ilist.push_back(0);
-    ilist.push_back(k*(step2-1)+j);
-    ilist.push_back(i*(step2-1)+j);
-  }
-  
-  // bottom
-  j=step2-1;
-  for(unsigned int i=0;i<step1;++i) {
-    unsigned int k=i+1;
-    k%=step1;
-    ilist.push_back(point_count-1);
-    ilist.push_back(i*(step2-1)+j);
-    ilist.push_back(k*(step2-1)+j);
-  }  
-  
-  // middle
-  for(unsigned int i=0;i<step1;++i) {
-    unsigned int k=i+1;
-    k%=step1;
-    for(unsigned j=1;j<step2-1;++j) {
-      unsigned l=j+1;
-      l%=(step2);
-      // add 2 triangles, counterclockwise
-      unsigned int p1=i*(step2-1)+j;
-      unsigned int p2=i*(step2-1)+l;
-      unsigned int p3=k*(step2-1)+j;
-      unsigned int p4=k*(step2-1)+l;
-      ilist.push_back(p1);
-      ilist.push_back(p3);
-      ilist.push_back(p2);
-      ilist.push_back(p2);
-      ilist.push_back(p3);
-      ilist.push_back(p4);
-    }
-  }
-}
-
-    
-Arc::Arc()
-{}
-
-Arc::Arc(const SphereP& h, const SphereP& k, const SphereP& s):
-  H(h), K(k), S(s), T()
-{
-  Vec3 o=h->pos;
-  Vec3 d=o-k->pos;
-  Vec3 p=s->pos;
-
-  Real r = (Dot(d,p)-Dot(d,o))/Dot(d,d);
-  axis = Normalize(d);
-  fixpoint = o+r*d;
-  sdir = Normalize(p-fixpoint);
-  tdir=Vec3(0,0,0);
-
-  // transformation matrix into normalized system, for calc_phi
-  Vec3 orth = Normalize(Cross(axis,sdir));
-  xmat = Mat3(sdir[0],sdir[1],sdir[2],
-              orth[0],orth[1],orth[2],
-              axis[0],axis[1],axis[2]);
-
-  LOGN_DUMP("new arc");
-  LOGN_DUMP(" " << H->name << " " << K->name);
-  LOGN_DUMP("  ax=" << axis << " fp=" << fixpoint << " sd=" << sdir << "  ax.sd=" << Dot(axis,sdir));
-}
-
-void Arc::SetT(const SphereP& t)
-{
-  T=t;
-  tdir=Normalize(t->pos-fixpoint);
-}
-
-Tet::Tet(const SphereP& a, const SphereP& b, const SphereP& c, const Sphere& s):
-  A(a), B(b), C(c), S(new Sphere(s))
-{
-  init();
-}
-
-Tet::Tet(const SphereP& a, const SphereP& b, const SphereP& c, const SphereP& s):
-  A(a), B(b), C(c), S(s)
-{
-  init();
-}
-
-void Tet::init()
-{
-  LOGN_DUMP("new tet");
-  LOGN_DUMP(" " << A->name << " " << B->name << " " << C->name);
-  LOGN_DUMP(" " << S->pos);
-  LOGN_DUMP(" a-s: " << Length(A->pos-S->pos) << " " << A->rad+S->rad);
-  LOGN_DUMP(" b-s: " << Length(B->pos-S->pos) << " " << B->rad+S->rad);
-  LOGN_DUMP(" c-s: " << Length(C->pos-S->pos) << " " << C->rad+S->rad);
-  Real ps = Dot(Cross(A->pos-B->pos,C->pos-B->pos),S->pos-(A->pos+B->pos+C->pos)/3.0);
-  LOGN_DUMP(" p.s: " << ps );
-  if(ps<0.0) {
-    LOGN_DUMP(" swapping B/C for correct parity");
-    std::swap(B,C);
-    parity_swap=true;
-  } else {
-    parity_swap=false;
-  }
-  cA=S->pos+(S->rad/(S->rad+A->rad))*(A->pos-S->pos);
-  cB=S->pos+(S->rad/(S->rad+B->rad))*(B->pos-S->pos);
-  cC=S->pos+(S->rad/(S->rad+C->rad))*(C->pos-S->pos);
-}
-
-ArcP Tet::GetArc(const SphereP& h, const SphereP& k)
-{
-  if(U->H==h && U->K==k) return U;
-  else if(U->H==k && U->K==h) return U;
-  else if(V->H==h && V->K==k) return V;
-  else if(V->H==k && V->K==h) return V;
-  else if(W->H==h && W->K==k) return W;
-  else if(W->H==k && W->K==h) return W;
-  return ArcP();
-}
-
-
-RSurf::RSurf(Real probe_radius):
-  sphere_list_(),
-  arc_list_(),
-  tet_list_(),
-  probe_radius_(probe_radius),
-  max_rad_(0.0),
-  spat_org_(probe_radius_*2.0)
-{}
-
-void RSurf::AddSphere(const Vec3& pos, Real rad, const String& name)
-{
-  sphere_list_.push_back(SphereP(new Sphere(pos,rad)));
-  sphere_list_.back()->name=name;
-  spat_org_.Add(sphere_list_.back(),pos);
-  max_rad_=std::max(max_rad_,rad);
-}
-
-namespace {
-bool comp(const Vec3& p1, const Vec3& p2)
-{
-  return p1[2]!=p2[2] ? p1[2]<p2[2] : (p1[1]!=p2[1] ? p1[1]<p2[1] : p1[0]<p2[0]);
-}
-}
-
-void RSurf::Build()
-{
-  LOGN_DUMP("entering RSurf::Build");
-  for(SphereList::iterator it=sphere_list_.begin();it!=sphere_list_.end();++it) {
-    LOGN_DUMP("sphere " << it->get() << " @ " << (*it)->pos);
-  }
-
-  // find sphere with lowest extension in order z,y,x
-  SphereP best_a=*(sphere_list_.begin());
-  Vec3 best_pos=best_a->pos-Vec3(best_a->rad,best_a->rad,best_a->rad);
-  for(SphereList::iterator it=sphere_list_.begin();it!=sphere_list_.end();++it) {
-    // radius corrected
-    Vec3 pp=(*it)->pos-Vec3((*it)->rad,(*it)->rad,(*it)->rad);
-    if(comp(pp,best_pos)) {
-      best_a=*it;
-      best_pos=pp;
-    }
-  }
-
-  // a temporary solvent sphere, only touching best_a
-  SphereP temp_s(new Sphere(best_a->pos-Vec3(0,0,best_a->rad+probe_radius_),probe_radius_));
-  // a temporary arc to find the second starting sphere
-  ArcP temp_arc(new Arc());
-  temp_arc->S=temp_s;
-  temp_arc->axis = Vec3(-1,0,0);
-  temp_arc->fixpoint = best_a->pos;
-  temp_arc->sdir = Vec3(0,0,-1);
-  Vec3 orth = Normalize(Cross(temp_arc->axis,temp_arc->sdir));
-  temp_arc->xmat = Mat3(temp_arc->sdir[0],temp_arc->sdir[1],temp_arc->sdir[2],
-                        orth[0],orth[1],orth[2],
-                        temp_arc->axis[0],temp_arc->axis[1],temp_arc->axis[2]);
-
-  // find best second sphere - almost identical to find_best_tet()
-  SphereList clist = get_nearest_spheres(best_a->pos, best_a,best_a);
-  Real best_phi = 7.0;
-  SphereP best_b;
-
-  for(SphereList::const_iterator it=clist.begin();it!=clist.end();++it) {
-    Real phi = calc_phi(temp_arc,*it,false);
-    if(phi>=0.0 && phi<best_phi) {
-      best_phi = phi;
-      best_b = *it;
-    }
-  }
-
-  if(!best_b) {
-    LOGN_MESSAGE("singular sphere detected, no reduced surface build");
-    return;
-  }
-
-  // rotate solvent around axis to get updated pos
-  temp_s->pos = AxisRotation(temp_arc->axis,best_phi)*
-    (temp_s->pos-temp_arc->fixpoint)+
-    temp_arc->fixpoint;
-
-  // now find third sphere with updated temporary arc - again similar to find_best_tet()
-  temp_arc = ArcP(new Arc(best_a,best_b,temp_s));
-
-  clist = get_nearest_spheres(temp_arc->fixpoint,best_a,best_b);
-  best_phi = 7.0;
-  SphereP best_c;
-
-  for(SphereList::const_iterator it=clist.begin();it!=clist.end();++it) {
-    Real phi = calc_phi(temp_arc,*it,false);
-    if(phi>=0.0 && phi<best_phi) {
-      best_phi = phi;
-      best_c = *it;
-    }
-  }
-
-  if(!best_c) {
-    LOGN_MESSAGE("singular arc detected, no reduced surface build");
-    return;
-  }
-
-  temp_s->pos = AxisRotation(temp_arc->axis,best_phi)*
-    (temp_s->pos-temp_arc->fixpoint)+
-    temp_arc->fixpoint;
-
-  // finally assemble first tet
-  TetP ntet(new Tet(best_a, best_b, best_c,temp_s));
-  tet_list_.push_back(ntet);
-  // initiate the recursive traversal along the three first arcs
-  LOGN_DUMP("starting recursive arc traversal");
-  ntet->U = ArcP(new Arc(ntet->A, ntet->B, ntet->S));
-  ntet->U->A = ntet;
-  ntet->V = ArcP(new Arc(ntet->B, ntet->C, ntet->S));
-  ntet->V->A = ntet;
-  ntet->W = ArcP(new Arc(ntet->C, ntet->A, ntet->S));
-  ntet->W->A = ntet;
-  // note: creation of all three prior to traversal is necessary!
-  traverse_arc(ntet,ntet->U,ntet->C);
-  traverse_arc(ntet,ntet->V,ntet->A);
-  traverse_arc(ntet,ntet->W,ntet->B);
-
-  LOGN_DUMP("build " << tet_list_.size() << " tets and " << arc_list_.size() << " arcs");
-
-  for(ArcList::const_iterator it=arc_list_.begin();it!=arc_list_.end();++it) {
-    if(!(*it)->S) LOGN_VERBOSE("invalid arc detected, null S: " << (*it)->H->name << " " << (*it)->K->name);
-    if(!(*it)->T) LOGN_VERBOSE("invalid arc detected, null T: " << (*it)->H->name << " " << (*it)->K->name);
-  }
-}
-
-void RSurf::traverse_arc(TetP tet, ArcP& arc, SphereP c)
-{
-  if(tet->S!=arc->S) {
-    LOGN_VERBOSE("unexpected error during arc traversal: tet->S != arc->S; aborting arc traversal (" <<arc->H->name << "," << arc->K->name << ")");
-    return;
-  }
-  // find the closest contact point when traversing the arc around [ab],
-  // away from c, and return as a tet
-  std::pair<TetP,bool> ret = find_best_tet(arc,c);
-  TetP ntet=ret.first;
-
- if(!ntet) {
-    LOGN_VERBOSE("unexpected failure during find_best_tet(); aborting arc traversal (" <<arc->H->name << "," << arc->K->name << ")");
-    return;
-  }
-
-  // dest tet already exists
-  if(ret.second) {
-    // grab already allocated arc from tet
-    ArcP narc = ntet->GetArc(arc->H,arc->K);
-    if(narc) {
-      // replace source arc with existing one
-      arc=narc;
-      // close this arc if necessary
-      if(!narc->T) {
-        narc->SetT(tet->S);
-        narc->B=tet;
-        // and add to overall list
-        arc_list_.push_back(narc);
-      }
-    } else {
-      LOGN_VERBOSE("unexpected missing arc in existing tet");
-    }
-
-    return; // existing tet: no reason to continue traversal
-  }
-
-
-  // given the new tet, handle current arc
-  ntet->U = arc;
-  arc->SetT(ntet->S);
-  arc->B=ntet;
-  arc_list_.push_back(arc);
-
-  if(ntet->parity_swap) {
-    // B and C were swapped
-    ntet->V = ArcP(new Arc(ntet->C, ntet->B, ntet->S));
-    ntet->V->A = ntet;
-    ntet->W = ArcP(new Arc(ntet->B, ntet->A, ntet->S));
-    ntet->W->A = ntet;
-    traverse_arc(ntet,ntet->V,ntet->A);
-    traverse_arc(ntet,ntet->W,ntet->C);
-  } else {
-    ntet->V = ArcP(new Arc(ntet->B, ntet->C, ntet->S));
-    ntet->V->A = ntet;
-    ntet->W = ArcP(new Arc(ntet->C, ntet->A, ntet->S));
-    ntet->W->A = ntet;
-    traverse_arc(ntet,ntet->V,ntet->A);
-    traverse_arc(ntet,ntet->W,ntet->B);
-  }
-
-}
-
-std::pair<TetP,bool> RSurf::get_tet(SphereP a, SphereP b, SphereP c, const Sphere& s, bool create)
-{
-  // TODO: this could use a hash table instead of a list for faster lookup
-  for(TetList::const_iterator it=tet_list_.begin();it!=tet_list_.end();++it) {
-    Tet& tet=*(*it);
-    // only compare same parity
-    if(tet.parity_swap) {
-      if((tet.A==a && tet.C==b && tet.B==c) ||
-         (tet.A==c && tet.C==a && tet.B==b) ||
-         (tet.A==b && tet.C==c && tet.B==a)) {
-        return std::make_pair(*it,true);
-      }
-    } else {
-      if((tet.A==a && tet.B==b && tet.C==c) ||
-         (tet.A==c && tet.B==a && tet.C==b) ||
-         (tet.A==b && tet.B==c && tet.C==a)) {
-        return std::make_pair(*it,true);
-      }
-    }
-  }
-  if(create) {
-    TetP tet(new Tet(a,b,c,s));
-    tet_list_.push_back(tet);
-    return std::make_pair(tet,false);
-  }
-  return std::make_pair(TetP(),false);
-}
-
-std::pair<TetP,bool> RSurf::find_best_tet(ArcP arc, SphereP c)
-{
-  SphereList clist = get_nearest_spheres(arc->fixpoint,arc->H,arc->K);
-  Real best_phi = 7.0;
-  SphereP best_c;
-
-  if(clist.empty()) {
-    LOGN_VERBOSE("unexpected zero length sphere list in rsurf::find_best_tet()");
-    return std::make_pair(TetP(),true);
-  }
-  for(SphereList::const_iterator it=clist.begin();it!=clist.end();++it) {
-    Real phi = calc_phi(arc,*it,true);
-    if(phi<best_phi) {
-      if(phi<1e-8 && (*it)==c) continue;
-      best_phi = phi;
-      best_c = *it;
-    }
-  }
-
-  if(!best_c) {
-    LOGN_VERBOSE("unexpected missing best_c in rsurf::find_best_tet()");
-    return std::make_pair(TetP(),true);
-  }
-
-  // rotate solvent around axis to get new pos
-  arc->phi=best_phi;
-  Vec3 new_pos = AxisRotation(arc->axis,best_phi)*(arc->S->pos-arc->fixpoint)+arc->fixpoint;
-  arc->mid = AxisRotation(arc->axis,0.5*best_phi)*(arc->S->pos-arc->fixpoint)+arc->fixpoint;
-
-  // switch HK order for correct parity
-  // (actually, this is questionable and in fact verified in tet ctor)
-  return get_tet(arc->K,arc->H,best_c,Sphere(new_pos, probe_radius_),true);
-}
-
-SphereList RSurf::get_nearest_spheres(const Vec3& pos, SphereP a, SphereP b)
-{
-  SphereList nrvo;
-  SpatOrg::ItemList slist = spat_org_.FindWithin(pos,2.0*(probe_radius_+max_rad_));
-  for(SpatOrg::ItemList::const_iterator it=slist.begin();it!=slist.end();++it) {
-    if(*it!=a && *it!=b) nrvo.push_back(*it);
-  } 
-  return nrvo;
-}
-
-Real RSurf::calc_phi(ArcP arc, SphereP x, bool prune_zero)
-{
-  // calculate angle phi around axis given by ab, when 
-  // starting from s at zero, and touching x upon rotating
-  
-  Vec3 p = arc->xmat*(x->pos-arc->fixpoint);
-
-  Real r = Length(arc->S->pos-arc->fixpoint);
-  Real r2 = r*r;
-  Real x2 = p[0]*p[0];
-  Real y2 = p[1]*p[1];
-  Real z2 = p[2]*p[2];
-  Real d = probe_radius_+x->rad;
-  Real d2 = d*d;
-
-  Real phi1 = 7.0;
-  Real phi2 = 7.0;
-
-  if(std::abs(p[0])<1e-8) {
-
-    Real c4 = 1.0/(2.0*y2);
-    Real c5 = p[1]*(r2-d2+y2+z2);
-    Real ys1 = c4*c5;
-
-    phi1 = atan2(ys1,Real(0.0));
-    phi2 = phi1;
-
-  } else {
-
-    Real c0 = -d2+x2+y2+z2;
-    Real c1 = -x2*(r2*r2-2.0*r2*(d2+x2+y2-z2)+c0*c0);
-    if(c1<0.0) {
-      if(std::abs(c1)<1e-5) {
-        c1=0.0;
-      } else {
-        return 7.0;
-      }
-    }
-    c1 = sqrt(c1);
-    Real c2 = 1.0/(2.0*p[0]*(x2+y2));
-    Real c3 = x2*(r2-d2+x2+y2+z2);
-    Real xs1 = c2*(c3-p[1]*c1);
-    Real xs2 = c2*(c3+p[1]*c1);
-    Real c4 = 1.0/(2.0*(x2+y2));
-    Real c5 = p[1]*(r2-d2+x2+y2+z2);
-    Real ys1 = c4*(c5+c1);
-    Real ys2 = c4*(c5-c1);
-
-    phi1 = atan2(ys1,xs1);
-    phi2 = atan2(ys2,xs2);
-  }
-
-  if(phi1<0.0) phi1+=2.0*M_PI;
-  if(phi2<0.0) phi2+=2.0*M_PI;
-  if(prune_zero) {
-    if(phi1<1e-8) phi1=7.0;
-    if(phi2<1e-8) phi2=7.0;
-  }
-
-  return std::min(phi1,phi2);
-}
-
-
-////////////////////////////////
-// Triangulation stuff
-////////////////////////////////
-
-namespace { 
-
-// all helper functions are in namespace anon
-
-// split given list into two at position p (which is excluded)
-void split_edge(const EdgePointList& in, unsigned int p, EdgePointList& o1, EdgePointList& o2)
-{
-  for(unsigned int i=0;i<p;++i) {
-    o1.push_back(in[i]);
-  }
-  for(unsigned int i=p+1;i<in.size();++i) {
-    o2.push_back(in[i]);
-  }
-}
-
-// build edges on great arc between e1 and e2, _not_ including these two points
-EdgePointList build_edge(const EdgePoint& e1, const EdgePoint& e2, 
-                         const Vec3& ori, Real patch, Real mult, 
-                         impl::SurfaceImplP& surf,int type)
-{
-  Vec3 d1 = e1.pos-ori;
-  Real rad = Length(d1);
-  Vec3 n1=Normalize(d1);
-  Vec3 n2=Normalize(e2.pos-ori);
-
-  Vec3 ax=Normalize(Cross(n1,n2));
-  Real phi=acos(Dot(n1,n2));
-  int step=static_cast<int>(floor(rad*phi/patch));
-  Real delta_phi=phi/static_cast<Real>(step);
-
-  EdgePointList e12;
-
-  for(int k=1;k<step;++k) {
-    Vec3 dd = AxisRotation(ax,static_cast<Real>(k)*delta_phi)*d1;
-    Vec3 nn = Normalize(mult*dd);
-    Vec3 vv = dd+ori;
-    e12.push_back(EdgePoint(surf->AddVertex(SurfaceVertex(vv,nn,type)),vv,nn));
-  }
-
-  return e12;
-}
-
-// variant to above, with explicit step size
-EdgePointList build_edge(const EdgePoint& e1, const EdgePoint& e2, 
-                         const Vec3& ori, int step, Real mult,
-                         impl::SurfaceImplP& surf, int type)
-{
-  EdgePointList e12;
-
-  if(step==0) return e12;
-
-  Vec3 d1 = e1.pos-ori;
-  Vec3 n1=Normalize(d1);
-  Vec3 n2=Normalize(e2.pos-ori);
-
-  Vec3 ax=Normalize(Cross(n1,n2));
-  Real phi=acos(Dot(n1,n2));
-  Real delta_phi=phi/static_cast<Real>(step);
-
-  for(int k=1;k<step;++k) {
-    Vec3 dd = AxisRotation(ax,static_cast<Real>(k)*delta_phi)*d1;
-    Vec3 nn = Normalize(mult*dd);
-    Vec3 vv = dd+ori;
-    e12.push_back(EdgePoint(surf->AddVertex(SurfaceVertex(vv,nn,type)),vv,nn));
-  }
-
-  return e12;
-}
-
-EdgePointList revert_epl(const EdgePointList& epl)
-{
-  EdgePointList nrvo(epl.size());
-  std::reverse_copy(epl.begin(),epl.end(),nrvo.begin());
-  return nrvo;
-}
-    
-/*
-  general scheme for subdivisioning
-  (e=corner, l=edge, p=new point, x=new edge)
-
-              e2
-       ^      /\                  /\
-      /      /b \             x2 /  \ x3
-    l12  p3 /____\ p1 l23       /_x7_\
-           /\ d  /\    \       /\    /\
-          /a \  /c \   `'   x1/  x9 x8 \ x4
-         /    \/    \        /    \/    \
-      e1 ------------ e3     ------------
-              p2               x6     x5 
-          <-  l31
-
-  special cases are implemented when one or two
-  edges contain no more points
-*/
-
-#define SUBDIVIDE_ONEZERO(E1,E2,E3,L1,L2,L3)      \
-    EdgePointList x2(L2.size()-1);                \
-    std::copy(&L2[1],&L2[L2.size()],&x2[0]);      \
-    EdgePointList x3(L3.size()-1);                \
-    std::copy(&L3[0],&L3[L3.size()-1],&x3[0]);    \
-    surf->AddTri(E2.id, E1.id, L2[0].id);         \
-    surf->AddTri(L2[0].id, E1.id, L3.back().id);  \
-    subdivide(L3.back(),L2[0],E3,L1,x2,x3,ori,patch,mult,surf,type);
-
-
-#define SUBDIVIDE_TWOZERO(E1,E2,E3,L1)            \
-    surf->AddTri(L1[0].id,E1.id,E3.id);           \
-    for(unsigned int ii=0;ii<L1.size()-1;++ii) {  \
-      surf->AddTri(L1[ii+1].id,L1[ii].id,E3.id);  \
-    }                                             \
-    surf->AddTri(E2.id,L1.back().id,E3.id);
-
-void subdivide(const EdgePoint& e1, const EdgePoint& e2, const EdgePoint& e3,
-               const EdgePointList& l12, 
-               const EdgePointList& l23, 
-               const EdgePointList& l31,
-               const Vec3& ori, Real patch, Real mult,
-               impl::SurfaceImplP& surf, int type)
-{
-  if(l12.empty() && l23.empty() && l31.empty()) {
-    surf->AddTri(e2.id,e1.id,e3.id);
-  } else if(l12.empty() && !l23.empty() && !l31.empty()) {
-    SUBDIVIDE_ONEZERO(e1,e2,e3,l12,l23,l31);
-  } else if(!l12.empty() && l23.empty() && !l31.empty()) {
-    SUBDIVIDE_ONEZERO(e2,e3,e1,l23,l31,l12);
-  } else if(!l12.empty() && !l23.empty() && l31.empty()) {
-    SUBDIVIDE_ONEZERO(e3,e1,e2,l31,l12,l23);
-  } else if(l12.empty() && l23.empty() && !l31.empty()) {
-    SUBDIVIDE_TWOZERO(e3,e1,e2,l31);
-  } else if(l12.empty() && !l23.empty() && l31.empty()) {
-    SUBDIVIDE_TWOZERO(e2,e3,e1,l23);
-  } else if(!l12.empty() && l23.empty() && l31.empty()) {
-    SUBDIVIDE_TWOZERO(e1,e2,e3,l12);
-  } else {
-
-    unsigned int cp1=(l23.size()+1)/2-1;
-    unsigned int cp2=(l31.size()+1)/2-1;
-    unsigned int cp3=(l12.size()+1)/2-1;
-    
-    EdgePoint p1 = l23[cp1];
-    EdgePoint p2 = l31[cp2];
-    EdgePoint p3 = l12[cp3];
-    
-    EdgePointList x1,x2,x3,x4,x5,x6;
-    
-    // new outer edges
-    split_edge(l12,cp3,x1,x2);
-    split_edge(l23,cp1,x3,x4);
-    split_edge(l31,cp2,x5,x6); 
-    
-#if 0
-    EdgePointList x7 = build_edge(p1,p3,ori,patch,mult,surf,type);
-    EdgePointList x8 = build_edge(p2,p1,ori,patch,mult,surf,type);
-    EdgePointList x9 = build_edge(p3,p2,ori,patch,mult,surf,type);
-#else
-    EdgePointList x7 = build_edge(p1,p3,ori,(int)((x2.size()+x3.size())/2),mult,surf,type);
-    EdgePointList x8 = build_edge(p2,p1,ori,(int)((x4.size()+x5.size())/2),mult,surf,type);
-    EdgePointList x9 = build_edge(p3,p2,ori,(int)((x1.size()+x6.size())/2),mult,surf,type);
-#endif
-    
-    subdivide(e1,p3,p2,x1,x9,x6,ori,patch,mult,surf,type);
-    subdivide(p3,e2,p1,x2,x3,x7,ori,patch,mult,surf,type);
-    subdivide(p2,p1,e3,x8,x4,x5,ori,patch,mult,surf,type);
-    subdivide(p1,p2,p3,revert_epl(x8),revert_epl(x9),revert_epl(x7),ori,patch,mult,surf,type);
-  }
-}
-
-struct EdgePointList3 {
-  EdgePointList l1,l2,l3;
-};
-
-EdgePointList3 build_patch(const Tet& tet, Real patch, Real mult,
-                           impl::SurfaceImplP& surf)
-{
-  Vec3 ori=tet.S->pos;
-  Vec3 n1=-Normalize(tet.cA-ori);
-  EdgePoint e1(surf->AddVertex(SurfaceVertex(tet.cA,n1,1)),tet.cA,n1);
-  Vec3 n2=-Normalize(tet.cB-ori);
-  EdgePoint e2(surf->AddVertex(SurfaceVertex(tet.cB,n2,1)),tet.cB,n2);
-  Vec3 n3=-Normalize(tet.cC-ori);
-  EdgePoint e3(surf->AddVertex(SurfaceVertex(tet.cC,n3,1)),tet.cC,n3);
-
-#if 1
-  EdgePointList l12 = build_edge(e1,e2,ori,(int)tet.U->step,mult,surf,1);
-  EdgePointList l23 = build_edge(e2,e3,ori,(int)tet.V->step,mult,surf,1);
-  EdgePointList l31 = build_edge(e3,e1,ori,(int)tet.W->step,mult,surf,1);
-#else
-  EdgePointList l12 = build_edge(e1,e2,ori,patch,mult,surf,1);
-  EdgePointList l23 = build_edge(e2,e3,ori,patch,mult,surf,1);
-  EdgePointList l31 = build_edge(e3,e1,ori,patch,mult,surf,1);
-#endif
-
-  subdivide(e1,e2,e3,l12,l23,l31,ori,patch,mult,surf,1);
-
-  l12.insert(l12.begin(),e1);
-  l12.push_back(e2);
-  l23.insert(l23.begin(),e2);
-  l23.push_back(e3);
-  l31.insert(l31.begin(),e3);
-  l31.push_back(e1);
-
-  EdgePointList3 epl3={l12,l23,l31};
-  return epl3;
-}
-
-void build_saddle(ArcP& arcp, Real patch, impl::SurfaceImplP& surf)
-{
-  Arc& arc = *arcp;
-  if(arc.eplS.empty() || arc.eplT.empty()) {
-    LOGN_VERBOSE("unexpected empty arc EdgePointList");
-    return;
-  } 
-  if(arc.eplS.size()!=arc.eplT.size()) {
-    LOGN_VERBOSE("unexpected size missmatch in arc EdgePointLists (" << arc.H->name << "," << arc.K->name << ")");
-    return;
-  }
-
-  std::vector<EdgePointList> epll(arc.eplS.size());
-
-  int step=static_cast<int>(floor(arc.H->rad*arc.phi/patch));
-  Real delta_phi = arc.phi/static_cast<Real>(step);
-
-  // initialize first component of each convex running edge list
-  // is equivalent to step zero
-  for(unsigned int k=0;k<arc.eplS.size();++k) {
-    epll[k].push_back(arc.eplS[k]);
-  }
-
-  // outer loop goes over the convex part of saddle
-  for(int c=1;c<step;++c) {
-    Mat3 vmat=AxisRotation(arc.axis,static_cast<Real>(c)*delta_phi);
-    // inner loop goes over concave part
-    for(unsigned int k=0;k<arc.eplS.size();++k) {
-      // this is the direction vector which is rotated around the arc axis
-      Vec3 p0 = arc.eplS[k].pos-arc.fixpoint;
-      Vec3 p1 = vmat*p0+arc.fixpoint;
-      // the normal is retrieved from a previous calculation
-      Vec3 n1 = vmat*arc.eplS[k].norm;
-      epll[k].push_back(EdgePoint(surf->AddVertex(SurfaceVertex(p1,n1,2)),p1,n1));
-    }
-  }
-
-  // this should be equivalent to the above rotation for c==step...
-  for(unsigned int k=0;k<arc.eplS.size();++k) {
-    epll[k].push_back(arc.eplT[k]);
-  }
-
-  // now that all vertices are created, assign triangles
-  for(unsigned int k=0;k<arc.eplS.size()-1;++k) {
-    for(unsigned int c=0;c<epll[k].size()-1;++c) {
-      surf->AddTri(epll[k+1][c+1].id,
-                   epll[k][c+1].id,
-                   epll[k][c].id);
-      surf->AddTri(epll[k+1][c].id,
-                   epll[k+1][c+1].id,
-                   epll[k][c].id);
-    }
-  }
-
-  // book-keeping for the spheres
-  ArcDirEntry adeH,adeK;
-  adeH.v=arc.eplS.front();
-  adeH.w=arc.eplT.front();
-  adeH.arc=arcp;
-  adeH.inv_arc=false;
-  adeK.v=arc.eplT.back();
-  adeK.w=arc.eplS.back();
-  adeK.arc=arcp;
-  adeK.inv_arc=true;
-  for(int c=0;c<step;++c) {
-    adeH.epl.push_back(epll.front()[c]);
-    adeK.epl.push_back(epll.back()[step-c-1]);
-  }
-
-  arc.H->arc_list.push_back(adeH);
-  arc.K->arc_list.push_back(adeK);
-}
-
-void fix_arc_list(ArcDirDeque& elist)
-{
-  for(uint a=0;a<elist.size()-1;++a) {
-    for(uint b=a+1;b<elist.size();++b) {
-      if(elist[a].v.id != elist[b].v.id) {
-        if(Length(elist[a].v.pos-elist[b].v.pos)<1.0e-4) {
-          elist[b].v.id = elist[a].v.id;
-        }
-      }
-      if(elist[a].v.id != elist[b].w.id) {
-        if(Length(elist[a].v.pos-elist[b].w.pos)<1.0e-4) {
-          elist[b].w.id = elist[a].v.id;
-        }
-      }
-      if(elist[a].w.id != elist[b].v.id) {
-        if(Length(elist[a].w.pos-elist[b].v.pos)<1.0e-4) {
-          elist[b].v.id = elist[a].w.id;
-        }
-      }
-      if(elist[a].w.id != elist[b].w.id) {
-        if(Length(elist[a].w.pos-elist[b].w.pos)<1.0e-4) {
-          elist[b].w.id = elist[a].w.id;
-        }
-      }
-    }
-  }
-}
-
-
-std::vector<ArcDirDeque> sort_arc_list(ArcDirDeque arc_list,
-                                       std::vector<Vec3>& topsumlist,
-                                       Sphere& sp)
-{
-  std::vector<ArcDirDeque> elistlist;
-  while(!arc_list.empty()) {
-    bool used=false;
-    for(ArcDirDeque::iterator ait=arc_list.begin();ait!=arc_list.end();++ait) {
-      for(uint l=0;l<elistlist.size();++l) {
-        if(ait->v.id == elistlist[l].back().w.id) {
-          elistlist[l].push_back(*ait);
-          arc_list.erase(ait);
-          used=true;
-        } else if(ait->w.id == elistlist[l].front().v.id) {
-          elistlist[l].push_front(*ait);
-          arc_list.erase(ait);
-          used=true;
-        }
-        if(used) {
-          topsumlist[l]+=(ait->arc->mid-sp.pos)*ait->arc->phi;
-          break;
-        }
-      }
-      if(used) break;
-    }
-    if(!used) {
-      elistlist.push_back(ArcDirDeque());
-      elistlist.back().push_back(arc_list.back());
-      topsumlist.push_back((arc_list.back().arc->mid-sp.pos)*arc_list.back().arc->phi);
-      arc_list.pop_back();
-    }
-  }
-  return elistlist;
-}
-
-
-struct PolarMap
-{
-  struct Entry {
-    Real theta, phi;
-    uint id;
-  };
-
-  typedef std::vector<Entry> EntryList;
-
-  PolarMap(): theta_off(0.0), phi_off(0.0) {}
-  void Add(const Vec3& v, uint id) {
-    Real l = Length(v);
-    Real theta=atan2(v[0],v[2]);
-    Real phi=acos(v[1]/l);
-    Real theta1=theta+theta_off;
-    Real phi1=phi+phi_off;
-
-    if(!entry_list.empty()) {
-      Real theta0=entry_list.back().theta;
-      Real phi0=entry_list.back().phi;
-
-      /*Real theta2=theta1;
-      Real phi2=phi1;*/
-      if(theta1-theta0>M_PI) {
-        theta1-=2.0*M_PI;
-        theta_off=-2.0*M_PI;
-      } else if(theta1-theta0<-M_PI) {
-        theta1+=2.0*M_PI;
-        theta_off+=2.0*M_PI;
-      }
-      if(phi1-phi0>M_PI_2) {
-        phi1-=M_PI;
-        phi_off=-M_PI;
-      } else if(phi1-phi0<-M_PI_2) {
-        phi1+=M_PI;
-        phi_off+=M_PI;
-      }
-
-      theta_min=std::min(theta_min,theta1);
-      theta_max=std::max(theta_max,theta1);
-      phi_min=std::min(phi_min,phi1);
-      phi_max=std::max(phi_max,phi1);
-
-    } else {
-      theta_min=theta1;
-      theta_max=theta1;
-      phi_min=phi1;
-      phi_max=phi1;
-    }
-    Entry e={theta1,phi1,id};
-    entry_list.push_back(e);
-  }
-
-  Real theta_off,phi_off;
-  Real theta_min,theta_max;
-  Real phi_min,phi_max;
-  EntryList entry_list;
-};
-
-struct CapEdgeEntry {
-  CapEdgeEntry() {}
-  CapEdgeEntry(uint i, Real t, Real p): eid(i), theta(t), phi(p) {}
-  uint eid;
-  Real theta, phi;
-};
-
-typedef std::vector<CapEdgeEntry> CapEdgeList;
-
-struct CapVecEntry {
-};
-
-typedef std::vector<CapVecEntry> CapVecList;
-
-void build_cap(Sphere& sp, Real patch, impl::SurfaceImplP& surf)
-{
-  // assemble sorted lists of spheres and edge-point-lists
-  std::vector<Vec3> topsumlist;
-  std::vector<ArcDirDeque> alistlist = sort_arc_list(sp.arc_list,topsumlist,sp);
-  
-  sp.arc_list_list=alistlist;
-
-  bool check=true;
-  // for each independent list, build cap
-  for(uint l=0;l<alistlist.size();++l) {
-    ArcDirDeque& alist = alistlist[l];
-    if(alist.front().v.id != alist.back().w.id) {
-      check=false;
-      break;
-    }
-  }
-  if(!check) {
-    LOGN_DEBUG("non-circular arc-dir list found, attempting fix");
-    ArcDirDeque tmp_list=sp.arc_list;
-    fix_arc_list(tmp_list);
-    topsumlist.clear();
-    alistlist = sort_arc_list(tmp_list,topsumlist,sp);
-    sp.arc_list_list=alistlist;
-  }
-
-  sp.top_list.resize(alistlist.size());
-
-  std::vector<Vec3> vlist;
-  std::vector<uint> ilist;
-  build_sphere(4,vlist,ilist);
-
-  for(uint l=0;l<alistlist.size();++l) {
-    ArcDirDeque& alist = alistlist[l];
-    if(alist.front().v.id != alist.back().w.id) {
-      LOGN_VERBOSE("unexpected non-circular arc-dir list for [" << sp.name << "]");
-      continue;
-    }
-
-    // generate the top position
-    Vec3 sum1;
-    Vec3 sum2;
-    Vec3 prev;
-    float plan=0.0;
-    for(uint i=0;i<alist.size();++i) {
-      uint j = (i-1+alist.size())%alist.size();
-      uint k = (i+1)%alist.size();
-      sum1+=(alist[i].arc->mid-sp.pos)*alist[i].arc->phi;
-      Vec3 d0 = alist[i].arc->S->pos-sp.pos;
-      Vec3 d1 = alist[i].arc->mid-sp.pos;
-      Vec3 d2 = alist[i].arc->T->pos-sp.pos;
-      
-      Vec3 p0 = sp.pos+sp.rad*(d0)/(sp.rad+alist[i].arc->S->rad);
-      Vec3 p1 = sp.pos+sp.rad*(d1)/(sp.rad+alist[i].arc->S->rad);
-      Vec3 p2 = sp.pos+sp.rad*(d2)/(sp.rad+alist[i].arc->S->rad);
-      Vec3 c0 = Normalize(Cross(Normalize(alist[i].w.pos-alist[i].v.pos),
-                                Normalize(alist[k].w.pos-alist[k].v.pos))+
-                          Cross(Normalize(alist[j].w.pos-alist[j].v.pos),
-                                Normalize(alist[i].w.pos-alist[i].v.pos)));
-      if(i>0) {
-        plan+=Dot(prev,Normalize(d1));
-      }
-      prev=Normalize(d1);
-      sum2+=c0*alist[i].arc->phi;
-    }
-    Real f = plan/static_cast<Real>(alist.size());
-    // this is a combination of two algorithms, weighted by planarity
-    Vec3 topn = Normalize(f*sum1+(1.0-f)*sum2);
-    Vec3 topv = sp.pos+sp.rad*topn;
-
-    sp.top_list[l]=topv;
-
-    // now for the actual cap
-
-    PolarMap polar_map;
-    for(ArcDirDeque::const_iterator ait=alist.begin();ait!=alist.end();++ait) {
-      std::cerr << ait->v.id << std::endl;
-      for(EdgePointList::const_iterator eit=ait->epl.begin();eit!=ait->epl.end();++eit) {
-        polar_map.Add(eit->pos-sp.pos,eit->id);
-      }
-    }
-    if(polar_map.entry_list.empty()) continue;
-    polar_map.entry_list.push_back(polar_map.entry_list.front());
-
-    for(uint i=0;i<polar_map.entry_list.size();++i) {
-      PolarMap::Entry& e = polar_map.entry_list[i];
-      std::cerr << i+1 << " " << (e.theta-polar_map.theta_min)*57.3 << " " << (e.phi+(M_PI-polar_map.phi_max))*57.3 << std::endl;
-    }
-
-  }
-}
-
-} // ns
-  
-void RSurf::Triangulate(impl::SurfaceImplP& surface, Real patch_size)
-{
-  for(ArcList::iterator it=arc_list_.begin();it!=arc_list_.end();++it) {
-    Arc& arc = *(*it);
-    Real da=arc.H->rad+probe_radius_;
-    Real db=arc.K->rad+probe_radius_;
-    Real dc=Length(arc.H->pos-arc.K->pos);
-    Real cosphi = -0.5*(dc*dc-da*da-db*db)/(da*db);
-    cosphi = std::min(Real(1.0),std::max(Real(-1.0),cosphi));
-    arc.step = static_cast<int>(floor(acos(cosphi)*probe_radius_/patch_size));
-  }
-
-  for(TetList::const_iterator it=tet_list_.begin();it!=tet_list_.end();++it) {
-    Tet& tet=*(*it);
-    // make S sphere concave patch
-    EdgePointList3 epl3=build_patch(tet, patch_size, -1.0, surface);
-
-    // assign stored edgepointlists
-    if(tet.U->S==tet.S) {
-      tet.U->eplS=epl3.l1;
-    } else if(tet.U->T==tet.S) {
-      tet.U->eplT=revert_epl(epl3.l1);
-    }
-    if(tet.V->S==tet.S) {
-      tet.V->eplS=epl3.l2;
-    } else if(tet.V->T==tet.S) {
-      tet.V->eplT=revert_epl(epl3.l2);
-    }
-    if(tet.W->S==tet.S) {
-      tet.W->eplS=epl3.l3;
-    } else if(tet.W->T==tet.S) {
-      tet.W->eplT=revert_epl(epl3.l3);
-    }
-  }
-
-  for(ArcList::iterator it=arc_list_.begin();it!=arc_list_.end();++it) {
-    build_saddle(*it,patch_size,surface);
-  }
-
-  for(SphereList::const_iterator it=sphere_list_.begin();it!=sphere_list_.end();++it) {
-    if((*it)->arc_list.empty()) continue;
-    build_cap(*(*it),patch_size,surface);
-  }
-
-  std::vector<SurfaceVertexID> vlist = surface->GetVertexIDList();
-  std::vector<SurfaceTriID> tlist = surface->GetTriIDList();
-  LOGN_VERBOSE("added " << vlist.size() << " vertices and " << tlist.size() << " tris");
-}
-
-
-}}} // ns
diff --git a/modules/mol/base/src/impl/rsurf_impl.hh b/modules/mol/base/src/impl/rsurf_impl.hh
deleted file mode 100644
index 5f7755afe..000000000
--- a/modules/mol/base/src/impl/rsurf_impl.hh
+++ /dev/null
@@ -1,207 +0,0 @@
-//------------------------------------------------------------------------------
-// This file is part of the OpenStructure project <www.openstructure.org>
-//
-// Copyright (C) 2008-2010 by the OpenStructure authors
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License as published by the Free
-// Software Foundation; either version 3.0 of the License, or (at your option)
-// any later version.
-// This library is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
-// details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this library; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-//------------------------------------------------------------------------------
-#ifndef OST_SURFACE_IMPL_RSURF_HH
-#define OST_SURFACE_IMPL_RSURF_HH
-
-/*
-  A fast reduced surface implementation to generate molecular surfaces
-  
-  The concept of a reduced surface was introduced by M Sanner et al, 1984
-
-  Author: Ansgar Philippsen
-*/
-
-#include <vector>
-#include <deque>
-
-#include <boost/shared_ptr.hpp>
-
-#include <ost/geom/geom.hh>
-#include <ost/mol/spatial_organizer.hh>
-#include "surface_impl_fw.hh"
-#include <ost/mol/surface_prop.hh>
-
-namespace ost { namespace mol { namespace rsurf {
-
-// helper types for triangulation
-// \internal
-struct EdgePoint
-{
-  EdgePoint(): id(0),pos() {}
-  EdgePoint(SurfaceVertexID i, const geom::Vec3& p, const geom::Vec3& n): 
-    id(i), pos(p), norm(n) {}
-  SurfaceVertexID id;
-  geom::Vec3 pos,norm;
-};
-
-/// \internal
-typedef std::vector<EdgePoint> EdgePointList;
-
-// required before sphere
-/// \internal
-struct Arc;
-
-/// \internal
-typedef boost::shared_ptr<Arc> ArcP;
-
-/// \internal
-typedef std::vector<ArcP> ArcList;
-
-/// \internal
-struct ArcDirEntry {
-  EdgePointList epl;
-  EdgePoint v,w;
-  ArcP arc;
-  bool inv_arc;
-};
-
-/// \internal
-typedef std::deque<ArcDirEntry> ArcDirDeque;
-
-// basic sphere
-struct Sphere {
-  Sphere(const geom::Vec3& p, Real r): pos(p), rad(r) {}
-  geom::Vec3 pos;
-  Real rad;
-  String name;
-  ArcDirDeque arc_list;
-  std::vector<geom::Vec3> top_list;
-  std::vector<ArcDirDeque> arc_list_list;
-};
-  
-typedef boost::shared_ptr<Sphere> SphereP;
-typedef std::vector<SphereP> SphereList;
-
-struct Tet;
-typedef boost::shared_ptr<Tet> TetP;
-
-
-// arc that bridges two tets
-/*
-  the orientation of H,K,S,T is such that the rotation of S
-  around the HK axis towards T is positive right handed:
-
-    S  T   (S is in front, T in back)
-     \/
-   K----H
-
-   i.e. for HK=Vec3(0,0,1) and S=Vec3(1,0,0), a 90deg
-   positive rotation results in Vec3(0,1,0)
- 
-*/
-struct Arc {
-  Arc();
-  Arc(const SphereP& h, const SphereP& k, const SphereP& s);
-  void SetT(const SphereP& t);
-
-  SphereP H,K;         // the two sphere that form the axis
-  SphereP S,T;         // the start and end solvent sphere
-  geom::Vec3 axis;     // normalized axis from H to K
-  geom::Vec3 fixpoint; // point on axis where sdir and tdir start
-  geom::Vec3 sdir;     // direction normal from axis to S
-  geom::Vec3 tdir;     // direction normal from axis to T
-  Real phi;          // angle from S to T
-  geom::Mat3 xmat;     // transformation matrix needed during traversal
-  geom::Vec3 mid;
-  EdgePointList eplS, eplT; // book-keeping for the triangulation
-  TetP A,B;
-  uint step;           // sync edge stepsize for triangulation
-};
-  
-
-// the constellation of three spheres with a locked solvent sphere
-/*
-  when viewed with the solvent sphere in front of the abc triplet,
-  [ABC] are arranged clockwise
-*/
-struct Tet {
-  // use already determined sphere
-  Tet(const SphereP& a, const SphereP& b, const SphereP& c, const Sphere& s);
-  // use existing S
-  Tet(const SphereP& a, const SphereP& b, const SphereP& c, const SphereP& s);
-
-  ArcP GetArc(const SphereP& h, const SphereP& k);
-
-  SphereP A,B,C,S;
-  ArcP U,V,W;
-
-  geom::Vec3 cA,cB,cC; // contact points of S with A,B and C
-
-  bool parity_swap;
-
-  void init();
-};
-  
-typedef std::vector<TetP> TetList;
-
-// spatial organizer for optimized search
-typedef SpatialOrganizer<SphereP> SpatOrg;
-
-class DLLEXPORT_OST_MOL RSurf
-{
-public:
-  // ctor
-  RSurf(Real probe_radius);
-
-  void AddSphere(const geom::Vec3& pos, Real rad, const String& name);
-
-  // construct reduced surface from spheres
-  void Build();
-
-  // triangulate rsurf and thereby build full molecular surface
-  void Triangulate(impl::SurfaceImplP& surface, Real patch_size);
-
-  // return probe radius
-  Real GetProbeRadius() const {return probe_radius_;}
-
-  // internal use
-  ArcList GetArcList() const {return arc_list_;}
-  // internal use
-  TetList GetTetList() const {return tet_list_;}
-  // internal use
-  SphereList GetSphereList() const {return sphere_list_;}
-
-private:
-
-  // main recursive routine
-  void traverse_arc(TetP tet, ArcP& arc, SphereP c);
-
-  // get tet from list, optionally creating it if necessary
-  // the solvent s is either used as a parity check, or as the new sphere
-  std::pair<TetP,bool> get_tet(SphereP a, SphereP b, SphereP c, const Sphere& s, bool create);
-
-  // find best tet for an arc traversal
-  std::pair<TetP,bool> find_best_tet(ArcP arc, SphereP c);
-
-  SphereList get_nearest_spheres(const geom::Vec3& pos, SphereP a, SphereP b);
-
-  Real calc_phi(ArcP arc, SphereP x, bool prune_zero);
-
-  SphereList sphere_list_;
-  ArcList arc_list_;
-  TetList tet_list_;
-  Real probe_radius_;
-  Real max_rad_;
-  SpatOrg spat_org_;
-};
-
-
-}}} // ns
-
-#endif
diff --git a/modules/mol/base/src/impl/surface_impl.hh b/modules/mol/base/src/impl/surface_impl.hh
index 4a577806c..78fd1ea57 100644
--- a/modules/mol/base/src/impl/surface_impl.hh
+++ b/modules/mol/base/src/impl/surface_impl.hh
@@ -37,8 +37,6 @@ class DLLEXPORT_OST_MOL SurfaceImpl {
   typedef std::vector<SurfaceVertex> VertexList;
   typedef std::vector<SurfaceTri> FaceList;
 
-  friend class ::ost::mol::rsurf::RSurf;
-
 public:
   SurfaceImpl();
 
diff --git a/modules/mol/base/src/impl/surface_impl_fw.hh b/modules/mol/base/src/impl/surface_impl_fw.hh
index c5b9007b5..dac23ce74 100644
--- a/modules/mol/base/src/impl/surface_impl_fw.hh
+++ b/modules/mol/base/src/impl/surface_impl_fw.hh
@@ -28,14 +28,4 @@ typedef boost::shared_ptr<SurfaceImpl> SurfaceImplP;
 
 }}} // ns
 
-namespace ost { namespace mol { namespace rsurf {
-
-/// \internal
-class RSurf;
-
-/// \internal
-typedef boost::shared_ptr<RSurf> RSurfP;
-
-}}} // ns
-
 #endif
diff --git a/modules/mol/base/src/iterator.cc b/modules/mol/base/src/iterator.cc
index 26fc51644..74ff90c65 100644
--- a/modules/mol/base/src/iterator.cc
+++ b/modules/mol/base/src/iterator.cc
@@ -28,21 +28,21 @@ namespace ost { namespace mol {
 
 ResidueHandleIter& ResidueHandleIter::operator++() {
   ++cur_res_;
-  if (cur_res_==cur_chain_->second->GetResidueList().end()) {
+  if (cur_res_==(*cur_chain_)->GetResidueList().end()) {
     // we have to skip over empty chains otherwise we end up pointing to an 
     // invalid residue.
     do {
       ++cur_chain_;
-      if (ent_->GetChainMap().end()==cur_chain_) {
+      if (ent_->GetChainList().end()==cur_chain_) {
         break;        
       }
-      cur_res_=cur_chain_->second->GetResidueList().begin();
-    } while (cur_chain_->second->GetResidueList().empty());
+      cur_res_=(*cur_chain_)->GetResidueList().begin();
+    } while ((*cur_chain_)->GetResidueList().empty());
   }        
   return *this;
 }
 
-ResidueHandleIter::ResidueHandleIter(impl::ChainImplMap::iterator chain_it, 
+ResidueHandleIter::ResidueHandleIter(impl::ChainImplList::iterator chain_it, 
                                      impl::ResidueImplList::iterator res_it,
                                      impl::EntityImplPtr ent) 
  : cur_chain_(chain_it), cur_res_(res_it),
@@ -99,7 +99,7 @@ AtomHandleIter::AtomHandleIter()
 #endif
 {}  
 
-AtomHandleIter::AtomHandleIter(impl::ChainImplMap::iterator chain_it,
+AtomHandleIter::AtomHandleIter(impl::ChainImplList::iterator chain_it,
                                impl::ResidueImplList::iterator res_it,
                                impl::AtomImplList::iterator atom_it,
                                impl::EntityImplPtr ent, bool skip_empty)
@@ -122,19 +122,19 @@ void AtomHandleIter::SkipEmpty()
     // pointing to an invalid atom.
     do {
       ++cur_res_;
-      if (cur_chain_->second->GetResidueList().end()==cur_res_) {
+      if ((*cur_chain_)->GetResidueList().end()==cur_res_) {
         do {
           ++cur_chain_;
-          if (ent_->GetChainMap().end()==cur_chain_) {
+          if (ent_->GetChainList().end()==cur_chain_) {
             return;
           }
 
-          cur_res_=cur_chain_->second->GetResidueList().begin();
-          if (!cur_chain_->second->GetResidueList().empty())          
+          cur_res_=(*cur_chain_)->GetResidueList().begin();
+          if (!(*cur_chain_)->GetResidueList().empty())          
             cur_atom_=(*cur_res_)->GetAtomList().begin();
           else
             cur_atom_=impl::AtomImplList::iterator();
-        } while (cur_chain_->second->GetResidueList().empty());
+        } while ((*cur_chain_)->GetResidueList().empty());
       } else {
         cur_atom_=(*cur_res_)->GetAtomList().begin();
       }
diff --git a/modules/mol/base/src/iterator.hh b/modules/mol/base/src/iterator.hh
index 4d75aec8b..7bbbe4839 100644
--- a/modules/mol/base/src/iterator.hh
+++ b/modules/mol/base/src/iterator.hh
@@ -80,17 +80,17 @@ private:
 
 namespace impl {
   // forward declearation of chain impl map.
-  typedef std::map<String, ChainImplPtr> ChainImplMap;
+  typedef std::vector<ChainImplPtr> ChainImplList;
 }
 class DLLEXPORT_OST_MOL ChainHandleIter : public std::iterator<std::forward_iterator_tag, 
                                              ChainHandle> {
 public: // internally used constructors
-  ChainHandleIter(impl::ChainImplMap::iterator chain_it)  
+  ChainHandleIter(impl::ChainImplList::iterator chain_it)  
     : cur_(chain_it) {    
   }
 public:
   ChainHandle operator*() {
-    return ChainHandle(cur_->second);
+    return ChainHandle(*cur_);
   }
   
   ChainHandleIter& operator++() {
@@ -106,7 +106,7 @@ public:
     return !this->operator==(rhs);
   }
 private:
-  impl::ChainImplMap::iterator cur_;
+  impl::ChainImplList::iterator cur_;
 };
 
 class DLLEXPORT_OST_MOL ResidueHandleIter : public std::iterator<std::forward_iterator_tag,
@@ -114,7 +114,7 @@ class DLLEXPORT_OST_MOL ResidueHandleIter : public std::iterator<std::forward_it
 public:
   ResidueHandleIter() {    
   }
-  ResidueHandleIter(impl::ChainImplMap::iterator chain_it, 
+  ResidueHandleIter(impl::ChainImplList::iterator chain_it, 
                     impl::ResidueImplList::iterator res_it,
                     impl::EntityImplPtr ent);
   bool operator==(const ResidueHandleIter& rhs) const {
@@ -133,7 +133,7 @@ public:
   ResidueHandle operator*();
   
 private:
-  impl::ChainImplMap::iterator cur_chain_;
+  impl::ChainImplList::iterator cur_chain_;
   impl::ResidueImplList::iterator cur_res_;
   impl::EntityImplPtr  ent_;
 };
@@ -174,7 +174,7 @@ class DLLEXPORT_OST_MOL AtomHandleIter : public std::iterator<std::forward_itera
 public:
   AtomHandleIter(); 
 
-  AtomHandleIter(impl::ChainImplMap::iterator chain_it,
+  AtomHandleIter(impl::ChainImplList::iterator chain_it,
                  impl::ResidueImplList::iterator res_it,
                  impl::AtomImplList::iterator atom_it,
                  impl::EntityImplPtr ent, bool skip_empty);
@@ -195,7 +195,7 @@ public:
   AtomHandle operator*();
 private:
   void SkipEmpty();
-  impl::ChainImplMap::iterator cur_chain_;
+  impl::ChainImplList::iterator cur_chain_;
   impl::ResidueImplList::iterator cur_res_;
   impl::AtomImplList::iterator cur_atom_;
   impl::EntityImplPtr  ent_;
diff --git a/modules/mol/base/src/residue_handle.cc b/modules/mol/base/src/residue_handle.cc
index b66c83250..bfc57c194 100644
--- a/modules/mol/base/src/residue_handle.cc
+++ b/modules/mol/base/src/residue_handle.cc
@@ -181,7 +181,7 @@ AtomHandleIter ResidueHandle::AtomsBegin() const
   impl::ResidueImplPtr r=Impl();
   int index=this->GetIndex();
   impl::ChainImplPtr c=r->GetChain();
-  impl::ChainImplMap::iterator cc=r->GetEntity()->GetChainMap().find(c->GetName());
+  impl::ChainImplList::iterator cc=r->GetEntity()->GetChain(c->GetName());
   return AtomHandleIter(cc, c->GetResidueList().begin()+index,
                         r->GetAtomList().begin(), r->GetEntity(), true);
 }
@@ -192,7 +192,7 @@ AtomHandleIter ResidueHandle::AtomsEnd() const
   impl::ResidueImplPtr r=Impl();
   int index=this->GetIndex();
   impl::ChainImplPtr c=r->GetChain();
-  impl::ChainImplMap::iterator cc=r->GetEntity()->GetChainMap().find(c->GetName());
+  impl::ChainImplList::iterator cc=r->GetEntity()->GetChain(c->GetName());
   if (c->GetResidueList().begin()+index+1==c->GetResidueList().end()) {
     return AtomHandleIter(cc, c->GetResidueList().begin()+index,
                           r->GetAtomList().end(), r->GetEntity(), false);
diff --git a/modules/mol/base/src/residue_view.cc b/modules/mol/base/src/residue_view.cc
index b9cc9b8b7..72c5ff76f 100644
--- a/modules/mol/base/src/residue_view.cc
+++ b/modules/mol/base/src/residue_view.cc
@@ -208,9 +208,9 @@ double ResidueView::GetMass() const
 geom::Vec3 ResidueView::GetGeometricStart() const 
 {
   this->CheckValidity();
-  geom::Vec3 minimum(std::numeric_limits<double>::max(),
-                     std::numeric_limits<double>::max(),
-                     std::numeric_limits<double>::max());
+  geom::Vec3 minimum(std::numeric_limits<Real>::max(),
+                     std::numeric_limits<Real>::max(),
+                     std::numeric_limits<Real>::max());
   AtomViewList::const_iterator i;
   for (i=data_->atoms.begin(); i!=data_->atoms.end(); ++i) {
     minimum=geom::Min(minimum, (*i).GetPos());
@@ -221,9 +221,9 @@ geom::Vec3 ResidueView::GetGeometricStart() const
 geom::Vec3 ResidueView::GetGeometricEnd() const 
 {
   this->CheckValidity();
-  geom::Vec3 maximum(-std::numeric_limits<double>::max(),
-                     -std::numeric_limits<double>::max(),
-                     -std::numeric_limits<double>::max());
+  geom::Vec3 maximum(-std::numeric_limits<Real>::max(),
+                     -std::numeric_limits<Real>::max(),
+                     -std::numeric_limits<Real>::max());
   AtomViewList::const_iterator i;
   for (i=data_->atoms.begin(); i!=data_->atoms.end(); ++i) {
     maximum=geom::Max(maximum, (*i).GetPos());
diff --git a/modules/mol/base/src/surface.hh b/modules/mol/base/src/surface.hh
index 5e9e848d3..97e1bacec 100644
--- a/modules/mol/base/src/surface.hh
+++ b/modules/mol/base/src/surface.hh
@@ -21,6 +21,5 @@
 
 #include <ost/mol/surface_handle.hh>
 #include <ost/mol/impl/surface_impl.hh>
-#include <ost/mol/impl/rsurf_impl.hh>
 
 #endif
diff --git a/modules/mol/base/src/surface_builder.cc b/modules/mol/base/src/surface_builder.cc
index 75214f3de..4fd1a97e4 100644
--- a/modules/mol/base/src/surface_builder.cc
+++ b/modules/mol/base/src/surface_builder.cc
@@ -18,10 +18,9 @@
 //------------------------------------------------------------------------------
 #include "surface_builder.hh"
 
-#include "surface_handle.hh"
-#include <ost/mol/impl/surface_impl.hh>
-#include <ost/mol/impl/rsurf_impl.hh>
+#include <ost/log.hh>
 
+#include "surface_handle.hh"
 #include "entity_view.hh"
 #include "iterator.hh"
 
@@ -29,18 +28,8 @@ namespace ost { namespace mol {
 
 SurfaceHandle BuildSurface(const EntityView& ev, Real probe_radius, Real patch_size)
 {
-  rsurf::RSurf rsurf(probe_radius);
-
-  for(AtomViewIter it=ev.AtomsBegin();it!=ev.AtomsEnd();++it) {
-    rsurf.AddSphere((*it).GetPos(),(*it).GetAtomProps().radius,(*it).GetQualifiedName());
-  }
-
-  rsurf.Build();
-
-  impl::SurfaceImplP impl(new impl::SurfaceImpl());
-  rsurf.Triangulate(impl,patch_size);
-
-  return SurfaceHandle(impl);
+  LOGN_ERROR("not yet implemented");
+  return SurfaceHandle();
 }
 
 }}
diff --git a/modules/mol/base/src/surface_handle.cc b/modules/mol/base/src/surface_handle.cc
index 06f920b88..6d1e82e64 100644
--- a/modules/mol/base/src/surface_handle.cc
+++ b/modules/mol/base/src/surface_handle.cc
@@ -28,6 +28,10 @@ SurfaceHandle CreateSurface()
 }
 
 
+SurfaceHandle::SurfaceHandle():
+  impl_()
+{}
+
 SurfaceHandle::SurfaceHandle(const impl::SurfaceImplP& p):
   impl_(p)
 {}
diff --git a/modules/mol/base/src/surface_handle.hh b/modules/mol/base/src/surface_handle.hh
index 1802afd5b..bfc48f5e0 100644
--- a/modules/mol/base/src/surface_handle.hh
+++ b/modules/mol/base/src/surface_handle.hh
@@ -38,6 +38,9 @@ typedef std::vector<SurfaceVertexID> SurfaceVertexIDList;
 // molecular surface
 class DLLEXPORT_OST_MOL SurfaceHandle {
 public:
+  // creates invalid handle
+  SurfaceHandle();
+  
   // internally used ctor
   SurfaceHandle(const impl::SurfaceImplP& p);
 
diff --git a/modules/mol/base/tests/test_view.cc b/modules/mol/base/tests/test_view.cc
index 33bda815d..26399e10e 100644
--- a/modules/mol/base/tests/test_view.cc
+++ b/modules/mol/base/tests/test_view.cc
@@ -77,6 +77,17 @@ BOOST_AUTO_TEST_CASE(gen_full_view)
   BOOST_CHECK_EQUAL(avl[1].GetBondCount(),2);
   BOOST_CHECK_EQUAL(avl[2].GetBondCount(),2);
   BOOST_CHECK_EQUAL(avl[3].GetBondCount(),1);
+  
+  mol::AtomView av1=avl[0];
+  mol::AtomView av2=avl[1];
+  
+  BOOST_CHECK(av1!=av2);
+  BOOST_CHECK(av1.GetHashCode()!=av2.GetHashCode());
+  BOOST_CHECK(av1.GetHandle().GetHashCode()!=av1.GetHashCode());
+  
+  mol::AtomView av3=av1;
+  BOOST_CHECK(av1==av3);
+  BOOST_CHECK_EQUAL(av1.GetHashCode(), av3.GetHashCode());  
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/modules/qa/src/index.hh b/modules/qa/src/index.hh
index 2f67aea95..f2744aa26 100644
--- a/modules/qa/src/index.hh
+++ b/modules/qa/src/index.hh
@@ -40,7 +40,7 @@ public:
     memcpy(data_, rhs.data_, sizeof(uint32_t[D]));
   }
   IndexBase() {
-    memset(data_, sizeof(uint32_t[D]), 0);
+    memset(data_, 0, sizeof(uint32_t[D]));
   }
   IndexBase& operator=(const IndexBase& rhs) {
     memcpy(data_, rhs.data_, sizeof(uint32_t[D]));
diff --git a/modules/seq/alg/pymod/CMakeLists.txt b/modules/seq/alg/pymod/CMakeLists.txt
index 22db6f7e8..93dd1b348 100644
--- a/modules/seq/alg/pymod/CMakeLists.txt
+++ b/modules/seq/alg/pymod/CMakeLists.txt
@@ -5,4 +5,4 @@ set(OST_SEQ_ALG_PYMOD_SOURCES
 
 pymod(NAME seq_alg OUTPUT_DIR ost/seq/alg 
       CPP ${OST_SEQ_ALG_PYMOD_SOURCES}
-      PY __init__.py)
+      PY __init__.py mat.py)
diff --git a/modules/seq/alg/pymod/__init__.py b/modules/seq/alg/pymod/__init__.py
index 22aa0c863..5d4730f17 100644
--- a/modules/seq/alg/pymod/__init__.py
+++ b/modules/seq/alg/pymod/__init__.py
@@ -1 +1,5 @@
-from _seq_alg import *
\ No newline at end of file
+from _seq_alg import *
+from ost.seq.alg.mat import *
+
+    
+  
\ No newline at end of file
diff --git a/modules/seq/alg/pymod/mat.py b/modules/seq/alg/pymod/mat.py
new file mode 100644
index 000000000..65152f045
--- /dev/null
+++ b/modules/seq/alg/pymod/mat.py
@@ -0,0 +1,45 @@
+from ost.seq.alg import SubstWeightMatrix
+
+def _InitMatrix(data):
+  """
+  Initialise a new substitution weight matrix with the weights in data. data
+  must be a 24x24 array of ints.
+  """
+  mat=SubstWeightMatrix()
+  # string of valid amino acid one letter codes
+  chars='ABCDEFGHIKLMNPQRSTVWXYZ'
+  for i, row in enumerate(data):
+    for j, weight in enumerate(row):
+      mat.SetWeight(chars[i], chars[j], weight)
+  return mat
+      
+  
+_RAW_BLOSUM62_DATA=(  
+  (4,-2,0,-2,-1,-2,0,-2,-1,-1,-1,-1,-2,-1,-1,-1,1,0,0,-3,-1,-2),
+  (-2,6,-3,6,2,-3,-1,-1,-3,-1,-4,-3,1,-1,0,-2,0,-1,-3,-4,-1,-3),
+  (0,-3,9,-3,-4,-2,-3,-3,-1,-3,-1,-1,-3,-3,-3,-3,-1,-1,-1,-2,-1,-2),
+  (-2,6,-3,6,2,-3,-1,-1,-3,-1,-4,-3,1,-1,0,-2,0,-1,-3,-4,-1,-3),
+  (-1,2,-4,2,5,-3,-2,0,-3,1,-3,-2,0,-1,2,0,0,-1,-2,-3,-1,-2),
+  (-2,-3,-2,-3,-3,6,-3,-1,0,-3,0,0,-3,-4,-3,-3,-2,-2,-1,1,-1,3),
+  (0,-1,-3,-1,-2,-3,6,-2,-4,-2,-4,-3,0,-2,-2,-2,0,-2,-3,-2,-1,-3),
+  (-2,-1,-3,-1,0,-1,-2,8,-3,-1,-3,-2,1,-2,0,0,-1,-2,-3,-2,-1,2),
+  (-1,-3,-1,-3,-3,0,-4,-3,4,-3,2,1,-3,-3,-3,-3,-2,-1,3,-3,-1,-1),
+  (-1,-1,-3,-1,1,-3,-2,-1,-3,5,-2,-1,0,-1,1,2,0,-1,-2,-3,-1,-2),
+  (-1,-4,-1,-4,-3,0,-4,-3,2,-2,4,2,-3,-3,-2,-2,-2,-1,1,-2,-1,-1),
+  (-1,-3,-1,-3,-2,0,-3,-2,1,-1,2,5,-2,-2,0,-1,-1,-1,1,-1,-1,-1),
+  (-2,1,-3,1,0,-3,0,1,-3,0,-3,-2,6,-2,0,0,1,0,-3,-4,-1,-2),
+  (-1,-1,-3,-1,-1,-4,-2,-2,-3,-1,-3,-2,-2,7,-1,-2,-1,-1,-2,-4,-1,-3),
+  (-1,0,-3,0,2,-3,-2,0,-3,1,-2,0,0,-1,5,1,0,-1,-2,-2,-1,-1),
+  (-1,-2,-3,-2,0,-3,-2,0,-3,2,-2,-1,0,-2,1,5,-1,-1,-3,-3,-1,-2),
+  (1,0,-1,0,0,-2,0,-1,-2,0,-2,-1,1,-1,0,-1,4,1,-2,-3,-1,-2),
+  (0,-1,-1,-1,-1,-2,-2,-2,-1,-1,-1,-1,0,-1,-1,-1,1,5,0,-2,-1,-2),
+  (0,-3,-1,-3,-2,-1,-3,-3,3,-2,1,1,-3,-2,-2,-3,-2,0,4,-3,-1,-1),
+  (-3,-4,-2,-4,-3,1,-2,-2,-3,-3,-2,-1,-4,-4,-2,-3,-3,-2,-3,11,-1,2),
+  (-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1),
+  (-2,-3,-2,-3,-2,3,-3,2,-1,-2,-1,-1,-2,-3,-1,-2,-2,-2,-1,2,-1,7),
+  (-1,2,-4,2,5,-3,-2,0,-3,1,-3,-2,0,-1,2,0,0,-1,-2,-3,-1,-2),
+)
+
+BLOSUM62=_InitMatrix(_RAW_BLOSUM62_DATA)
+
+__all__=['BLOSUM62']
\ No newline at end of file
diff --git a/modules/seq/alg/pymod/wrap_seq_alg.cc b/modules/seq/alg/pymod/wrap_seq_alg.cc
index d4c4462c8..561d0379c 100644
--- a/modules/seq/alg/pymod/wrap_seq_alg.cc
+++ b/modules/seq/alg/pymod/wrap_seq_alg.cc
@@ -22,7 +22,7 @@
 #include <ost/seq/alg/merge_pairwise_alignments.hh>
 #include <ost/seq/alg/sequence_identity.hh>
 #include <ost/seq/alg/ins_del.hh>
-
+#include <ost/seq/alg/conservation.hh>
 using namespace boost::python;
 using namespace ost::seq;
 using namespace ost::seq::alg;
@@ -47,5 +47,6 @@ BOOST_PYTHON_MODULE(_seq_alg)
     .def("GetInsertions", &InsDel::GetInsertions)
   ;
   def("MergePairwiseAlignments", &MergePairwiseAlignments);
+  def("Conservation", &Conservation, (arg("assign")=true, arg("prop_name")="cons"));
   export_Align();  
 }
diff --git a/modules/seq/alg/src/CMakeLists.txt b/modules/seq/alg/src/CMakeLists.txt
index ae43bd38d..5f3cac427 100644
--- a/modules/seq/alg/src/CMakeLists.txt
+++ b/modules/seq/alg/src/CMakeLists.txt
@@ -7,6 +7,7 @@ local_align.hh
 alignment_opts.hh
 global_align.hh
 merge_pairwise_alignments.hh
+conservation.hh
 )
 
 set(OST_SEQ_ALG_SOURCES
@@ -16,6 +17,7 @@ sequence_identity.cc
 ins_del.cc
 subst_weight_matrix.cc
 local_align.cc
+conservation.cc
 )
 
 module(NAME seq_alg HEADER_OUTPUT_DIR ost/seq/alg SOURCES ${OST_SEQ_ALG_SOURCES}
diff --git a/modules/seq/alg/src/conservation.cc b/modules/seq/alg/src/conservation.cc
new file mode 100644
index 000000000..e5a0df71d
--- /dev/null
+++ b/modules/seq/alg/src/conservation.cc
@@ -0,0 +1,132 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+#include <ost/seq/aligned_column.hh>
+#include <ost/seq/alignment_handle.hh>
+#include <ost/seq/alg/conservation.hh>
+
+namespace ost { namespace seq { namespace alg {
+
+// taken from Armon et al., J. Mol. Biol. (2001) 307, 447-463
+static float CHEM_DISSIM[][24]={
+  {0.00, 1.33, 1.39, 2.22, 1.84, 1.45, 2.48, 3.26, 2.83, 3.48, 2.56, 3.27, 3.06, 
+   0.86, 1.65, 1.63, 1.46, 2.24, 2.38, 3.34, 6.00, 6.00, 2.87, 3.15},
+  {0.00, 0.06, 0.97, 0.56, 0.87, 1.92, 2.48, 1.80, 2.40, 2.15, 2.94, 2.90, 1.79, 
+   2.70, 2.62, 2.36, 3.17, 3.12, 4.17, 6.00, 6.00, 2.20, 2.10,-1.00},
+  {0.00, 0.91, 0.51, 0.90, 1.92, 2.46, 1.78, 2.37, 2.78, 3.54, 3.58, 2.76, 3.67, 
+   3.60, 3.34, 4.14, 4.08, 5.13, 6.00, 6.00, 2.19, 2.08,-1.00,-1.00},
+  {0.00, 0.85, 1.70, 2.48, 2.78, 1.96, 2.37, 2.78, 3.54, 3.58, 2.76, 3.67, 3.60, 
+   3.34, 4.14, 4.08, 5.13, 6.00, 6.00, 2.63, 2.17,-1.00,-1.00,-1.00},
+  {0.00, 0.89, 1.65, 2.06, 1.31, 1.87, 1.94, 2.71, 2.74, 2.15, 3.04, 2.95, 2.67, 
+   3.45, 3.33, 4.38, 6.00, 6.00, 1.85, 1.59,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 1.12, 1.83, 1.40, 2.05, 1.32, 2.10, 3.03, 1.42, 2.25, 2.14, 1.86, 2.60, 
+   2.45, 3.50, 6.00, 6.00, 1.47, 1.73,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 0.84, 0.99, 1.47, 0.32, 1.06, 1.30, 2.13, 2.70, 2.57, 2.30, 2.81, 2.48, 
+   3.42, 6.00, 6.00, 0.42, 1.23,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 0.85, 0.90, 0.96, 1.14, 1.45, 2.97, 3.53, 3.39, 3.13, 3.59, 3.22, 4.08, 
+   6.00, 6.00, 0.42, 0.88,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 0.65, 1.29, 1.84, 2.04, 2.76, 3.49, 3.37, 3.08, 3.70, 3.42, 4.39, 6.00, 
+   6.00, 0.92, 0.33,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 1.72, 2.05, 2.34, 3.40, 4.10, 3.98, 3.69, 4.27, 3.95, 4.88, 6.00, 6.00, 
+   1.18, 0.33,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 0.79, 0.82, 2.11, 2.59, 2.45, 2.19, 2.63, 2.27, 3.16, 6.00, 6.00, 0.64, 
+   1.51,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 0.40, 2.70, 2.98, 2.84, 2.63, 2.85, 2.42, 3.11, 6.00, 6.00, 1.10, 1.95,
+  -1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 2.43, 2.62, 2.49, 2.29, 2.47, 2.02, 2.72, 6.00, 6.00, 1.29, 2.19,-1.00,
+  -1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 0.91, 0.85, 0.62, 1.43, 1.52, 2.51, 6.00, 6.00, 2.55, 3.08,-1.00,-1.00,
+  -1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 0.14, 0.41, 0.63, 0.94, 1.73, 6.00, 6.00, 3.11, 3.80,-1.00,-1.00,-1.00,
+  -1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 0.29, 0.61, 0.86, 1.72, 6.00, 6.00, 2.98, 3.68,-1.00,-1.00,-1.00,-1.00,
+  -1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 0.82, 0.93, 1.89, 6.00, 6.00, 2.71, 3.39,-1.00,-1.00,-1.00,-1.00,-1.00,
+  -1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 0.48, 0.11, 6.00, 6.00, 3.20, 3.99,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,
+  -1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 1.06, 6.00, 6.00, 2.85, 3.67,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,
+  -1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 6.00, 6.00, 3.75, 4.64,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,
+  -1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.50, 6.00, 6.00, 6.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,
+  -1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 6.00, 6.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,
+  -1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00, 1.05,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,
+  -1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00},
+  {0.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,
+  -1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00,-1.00}
+};
+
+float PhysicoChemicalDissim(char c1, char c2)
+{
+  static int indices[]={2, 23, 0, 9, 7, 17, 3, 10, 15, -1, 
+             11, 14, 16, 8, -1, 1, 6, 12, 4, 5, 
+             -1, 13, 19, 21, 18, 22};
+  int idx_a=(c1=='-' || c1<'A' || c1>'Z') ? 20 : indices[c1-'A'];
+  int idx_b=(c2=='-' || c2<'A' || c2>'Z') ? 20 : indices[c2-'A'];  
+  assert(idx_a>=0);
+  assert(idx_b>=0);
+  if (idx_a<0) {
+    idx_a=20;
+  }
+  if (idx_b<0) {
+    idx_b=20;
+  }
+  float s=0.0;
+  if (idx_a>idx_b)
+    s=CHEM_DISSIM[idx_b][idx_a-idx_b];
+  else
+    s=CHEM_DISSIM[idx_a][idx_b-idx_a];
+  assert(s>=0.0);
+  return s;
+}
+
+std::vector<Real> Conservation(const AlignmentHandle& aln, bool assign, 
+                               const String& prop)
+{
+  std::vector<Real> cons(aln.GetLength(), 0.0);
+  int comb=aln.GetCount()*(aln.GetCount()-1)/2;
+  for (int col=0; col<aln.GetLength(); ++col) {
+    float score=0.0;
+    AlignedColumn c=aln[col];
+    for (int i=0; i<aln.GetCount(); ++i) {
+      for (int j=i+1; j<aln.GetCount(); ++j) {
+        score+=PhysicoChemicalDissim(c[i], c[j]);
+      }
+    }
+    score=1.0-score/(6.0*comb);
+    cons[col]=score;
+    if (assign) {
+      for (int i=0; i<aln.GetCount(); ++i) {
+        if (c[i]!='-') {
+          mol::ResidueView r=c.GetResidue(i);
+          if (r.IsValid()) {
+            r.SetFloatProp(prop, score);
+          }
+        }
+      }
+    }
+  }
+  return cons;
+}
+
+}}}
+
diff --git a/modules/seq/alg/src/conservation.hh b/modules/seq/alg/src/conservation.hh
new file mode 100644
index 000000000..b1375c4a2
--- /dev/null
+++ b/modules/seq/alg/src/conservation.hh
@@ -0,0 +1,43 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+
+#include <ost/seq/alignment_handle.hh>
+#include <ost/seq/alg/module_config.hh>
+
+/*
+  Authors: Marco Biasini
+ */
+namespace ost { namespace seq { namespace alg {
+
+/// \brief Calculates conservation scores for each column in the alignment. 
+/// 
+/// The conservation score is a value between 0 and 1. The bigger the number 
+/// the more conserved the aligned residues are. 
+/// 
+/// \p assign If true, the conservation scores are assigned to attached 
+///     residues. The name of the property can be changed with the prop_name 
+///     parameter. Useful when coloring entities based on sequence conservation.
+/// \p prop_name The property name for assigning the conservation to 
+///     attached residues. Defaults to 'cons'.
+/// 
+std::vector<Real> DLLEXPORT_OST_SEQ_ALG Conservation(const AlignmentHandle& aln,
+                                             bool assign=true,
+                                             const String& prop_name="cons");
+}}}
+
diff --git a/modules/seq/base/doc/seq.rst b/modules/seq/base/doc/seq.rst
new file mode 100644
index 000000000..7deafe22e
--- /dev/null
+++ b/modules/seq/base/doc/seq.rst
@@ -0,0 +1,350 @@
+:mod:`~ost.seq` -- Sequences and Alignments
+================================================================================
+
+.. module:: ost.seq
+   :synopsis: Contains classes and functions to deal with sequences and 
+              alignments
+
+The :mod:`seq` module helps you working with sequence data of various kinds. It 
+has classes for :class:`single sequences <SequenceHandle>`, :class:`lists of 
+sequences <SequenceList>` and :class:`alignments <AlignmentHandle>` of two or
+more sequences. 
+
+
+.. _attaching-views:
+
+Attaching Structures to Sequences
+--------------------------------------------------------------------------------
+
+
+Being a structural biology framework, it is not surprising that the sequence 
+classes have been designed to work together with structural data. Each sequence 
+can have an attached :class:`~mol.EntityView` allowing for fast mapping between 
+residues in the entity view and position in the sequence. 
+
+.. _sequence-offset:
+
+Sequence Offset
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When using sequences and structures together, often the start of the structure 
+and the beginning of the sequence do not fall together. In the following case, 
+the alignment of sequences B and C only covers a subpart of structure A::
+
+  A acefghiklmnpqrstuvwy
+  B     ghiklm
+  C     123-45
+  
+We would now like to know which residue in protein A is aligned to which residue 
+in sequence C. This is achieved by setting the sequence offset of sequence C to 
+4. In essence, the sequence offset influences all the mapping operations from 
+position in the sequence to residue index and vice versa. By default, the 
+sequence offset is 0.
+
+Loading and Saving Sequences and Alignments
+--------------------------------------------------------------------------------
+
+The :mod:`io` module supports input and output of common sequence formats. 
+Single  sequences can be loaded from disk with :func:`io.LoadSequence`,
+alignments are loaded with :func:`io.LoadAlignment` and lists of sequences are loaded with :func:`io.LoadSequenceList`. In addition to the file based input 
+methods, sequences can also be loaded from a string:
+
+.. code-block:: python
+
+  seq_string='''>sequence
+  abcdefghiklmnop'''
+  s=io.LoadSequenceFromString(seq_string, 'fasta')
+  print s.name, s # will print "sequence abcdefghiklmnop"
+  
+Note that, in that case specifying the format is mandatory.
+
+The SequenceHandle
+--------------------------------------------------------------------------------
+
+.. function:: CreateSequence(name, sequence)
+
+  Create a new :class:`SequenceHandle` with the given name and sequence. 
+  
+  :param name: name of the sequence
+  :type  name: str
+  :param sequence: String of characters representing the sequence. Only   
+       alphanumerical characters and '-' are allowed.
+  :type sequence: str
+  :raises InvalidSequence: When the sequence string contains forbidden
+       characters, that is anything that is not alphanumeric or a hyphen.
+
+.. class:: SequenceHandle
+
+  Represents a sequence. New instances are created with :func:`CreateSequence`.
+  
+  .. method:: GetPos(residue_index)
+  
+    Get position of residue with index in sequence. This is best illustrated in 
+    the following example:
+    
+    .. code-block:: python
+      
+      s=seq.CreateSequence("A", "abc---def")
+      print s.GetPos(1) # prints 1
+      print s.GetPos(3) # prints 6
+    
+    The reverse mapping, that is from position in the sequence to residue index 
+    can be achieved with :meth:`GetResidueIndex`.
+  
+  .. method:: GetResidueIndex(pos)
+     
+    Get residue index of character at given position. This method is the
+    inverse of :meth:`GetPos`. If the sequence contains a gap at that position,
+    an :exc:`Error` is raised.
+    
+    .. code-block:: python
+      
+      s=seq.CreateSequence("A", "abc--def")
+      print s.GetResidueIndex(1) # prints 1
+      print s.GetResidueIndex(6) # prints 4
+      # the following line raises an exception of type
+      # Error with the message "requested position contains 
+      # a gap"
+      print s.GetResidueIndex(3)
+
+  .. method:: GetLastNonGap()
+     
+    Get position of last non-gap character in sequence. In case of an empty
+    sequence, or, a sequence only consisting of hyphens, -1 is returned
+     
+  .. method:: GetFirstNonGap()
+  
+    Get position of first non-gap character in sequence. In case of an empty
+    sequence, or, a sequence only consisting of hyphens, -1 is returned.
+
+  .. method:: AttachView(view)
+              AttachView(view, [chain_name])
+    
+    Attach an :class:`~mol.EntityView` to sequence. The first signature requires
+    that the view contains one chain. If not, an :exc:`IntegrityError` is
+    raised. The second signature will select the chain with the given name. If 
+    no such chain exists, an :exc:`IntegrityError` is raised.
+    
+  .. method:: HasAttachedView()
+  
+    Returns True when the sequence has a view attached, False if not.
+    
+  .. method:: GetAttachedView()
+  
+    Returns the attached :class:`~mol.EntityView`, or an invalid
+    :class:`~mol.EntityView` if no view has been attached. Also available as 
+    the property :attr:`attached_view`.
+    
+  .. method:: GetName()
+  
+    Returns the name of the sequence. Also available as the property
+    :attr:`name`
+  
+  .. method:: SetSequenceOffset()
+  
+    Set the :ref:`sequence offset <sequence-offset>`. By default, the offset is
+    0. Also available as the property :attr:`sequence_offset`.
+    
+  .. method:: GetSequenceOffset()
+    
+    Returns the :ref:`sequence offset <sequence-offset>`. Also available as
+    :attr:`sequence_offset`.
+    
+    
+  .. method:: GetGaplessString()
+     
+    Returns a string version of this sequence with all hyphens removed. Also
+    available as the property :attr:`gapless_string`.
+     
+   
+  .. method:: SetName()
+  
+    Set name of the sequence. Also available as the property :attr:`name`.
+  
+  .. attribute:: gapless_string
+     
+    Shorthand for :meth:`GetGaplessString()`
+     
+  .. attribute:: name
+  
+    Shorthand for :meth:`GetName`/:meth:`SetName`
+  
+  .. attribute:: attached_view
+  
+    Shorthand for :meth:`GetAttachedView`.
+
+  .. attribute:: sequence_offset
+  
+    Shorthand for :meth:`GetSequenceOffset`/:meth:`SetSequenceOffset`
+
+  .. method:: __len__()
+    
+    Returns the length of the sequence (including insertions and deletions)
+    
+  .. method:: __str__()
+
+    Returns the sequence as a string.
+
+
+The SequenceList    
+--------------------------------------------------------------------------------
+
+.. class:: SequenceList
+
+  Represents a list of sequences. The class provides a row-based interface. New
+  instances are created with :func:`CreateSequenceList`.
+
+
+The AlignmentHandle   
+--------------------------------------------------------------------------------
+
+The :class:`AlignmentHandle` represents a list of aligned sequences. In
+constrast to :class:`SequenceList`, an alignment requires all sequences to be of 
+the same length. New instances of alignments are created with 
+:func:`CreateAlignment` and :func:`AlignmentFromSequenceList`.
+
+Typically sequence alignments are used column-based, i.e by looking at an  
+aligned columns in the sequence alignment. To get a row-based (sequence) view
+on the sequence list, use :meth:`GetSequenceList()`. 
+
+All functions that operate on an alignment will again produce a valid alignment. 
+This mean that it is not possible to change the length of one sequence, without  
+adjusting the other sequences, too.
+
+The following example shows how to iterate over the columns and sequences of
+an alignment:
+
+.. code-block:: python
+
+  aln=io.LoadAlignment('aln.fasta')
+  # iterate over the columns
+  for col in aln:
+    print col
+
+  # iterate over the sequences
+  for s in aln.sequences:
+    print s
+
+.. function:: CreateAlignment()
+
+  Creates and returns a new :class:`AlignmentHandle` with no sequences.
+  
+.. function:: AlignmentFromSequenceList(sequences)
+  
+  Create a new alignment from the given list of sequences
+  
+  :param sequences: the list of sequences
+  :type sequences: :class:`ConstSequenceList`
+  
+  :raises: :exc:`InvalidAlignment` if the sequences do not have the same length.
+
+.. class:: AlignmentHandle
+  
+  .. note:: 
+  
+    Several of these methods just forward calls to the sequence. For more 
+    detailed information, have a look at the :class:`SequenceHandle`
+    documentation.
+  
+  .. method:: GetSequence(index)
+  
+    Returns the sequence at the given index, raising an IndexError when trying
+    to access an inexistent sequence.
+    
+  .. method:: GetSequenceList()
+  
+    Returns a list of all sequence of the alignment.
+    
+  .. method:: GetLength()
+  
+    Returns the length of the alignment.
+    
+  .. method:: GetCount()
+  
+    Returns the number of sequences in the alignment.
+  
+  
+  .. method:: ToString(width=80)
+  
+    Returns a formatted string version of the alignment. The sequences are 
+    split into smaller parts to fit into the number columns specified. 
+    
+    .. code-block:: python
+    
+      aln=seq.CreateAlignment()
+      aln.AddSequence(seq.CreateSequence("A", "abcdefghik"))
+      aln.AddSequence(seq.CreateSequence("B", "1234567890"))
+      # The following command will print the output given below
+      print aln.ToString(7)
+      # A abcde
+      # B 12345
+      #
+      # A fghik
+      # B 67890
+
+  .. method:: FindSequence(name)
+  
+    Find sequence with given name. If the alignment contains several sequences
+    with the same name, the first sequence is returned.
+    
+  .. method:: SetSequenceName(seq_index, name)
+  
+    Set the name of the sequence at index `seq_index` to name
+    
+  .. method:: SetSequenceOffset(seq_index, offset)
+  
+    Set the sequence offset of sequence at index `seq_index`
+    
+  .. method:: Copy()
+    
+    Create a deep copy of the alignment
+
+  .. method:: GetPos(seq_index, res_index)
+    
+    Get position of residue with index equal to `res_index` in sequence at index
+    `seq_index`.
+    
+  .. method:: GetResidueIndex(seq_index, pos)
+  
+    Get residue index of residue at position `pos` in sequence at index
+    `seq_index`.
+  
+  .. method:: AttachView(seq_index, view)
+              AttachView(seq_index, view, chain_name)
+    
+    Attach the given view to the sequence at index `seq_index`.
+    
+  .. method:: Cut(start, end)
+  
+    Removes the columns in the half-closed interval `start`, `end` from the
+    alignment.
+    
+    .. code-block:: python
+    
+      aln=seq.CreateAlignment()
+      aln.AddSequence(seq.CreateSequence("A", "abcd---hik"))
+      aln.AddSequence(seq.CreateSequence("B", "1234567890"))
+      aln.Cut(4, 7)
+      
+      print aln.ToString(80)
+      # will print
+      # A abcdhik
+      # B 1234890
+   
+  .. method:: Replace(new_region, start, end)
+  
+    Replace the columns in the half-closed interval `start`, `end` with the
+    columns in `new_region`.
+    
+    :param new_region: The region to be inserted
+    :type new_region: :class:`AlignedRegion` or :class:`AlignmentHandle`
+  
+  
+  .. method:: ShiftRegion(start, end, amount, master=-1)
+  
+    Shift columns in the half-closed interval `start`, `end`. If amount is a
+    positive number, the columns are shifted to the right, if negative, the 
+    columns are shifted to the left.
+    
+    If master is set to -1, all sequences in the region are affected, otherwise 
+    only the sequence at index equal to master is shifted.
diff --git a/modules/seq/base/pymod/__init__.py b/modules/seq/base/pymod/__init__.py
index 6b92feb56..0bc8f1b30 100644
--- a/modules/seq/base/pymod/__init__.py
+++ b/modules/seq/base/pymod/__init__.py
@@ -16,100 +16,4 @@
 # along with this library; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 #------------------------------------------------------------------------------
-from _seq import *
-from ost import mol
-
-def ViewsFromAlignment(multi_seq_ali, ent_a, ent_b, include_atoms=True):
-  seq_a=multi_seq_ali.GetSequence(0)
-  seq_b=multi_seq_ali.GetSequence(1)
-
-  # set offset according to ent_a and ent_b
-
-
-  return ViewsFromSequences(seq_a, seq_b, ent_a, ent_b, include_atoms)
-
-def ViewsFromSequences(seq_a, seq_b, ent_a=None, ent_b=None,
-                       include_atoms=True):
-  ent_a=ent_a or seq_a.attached_view
-  ent_b=ent_b or seq_b.attached_view
-  if ent_a.chain_count>1:
-   raise RuntimeError("first entity contains more than one chain")
-  if ent_b.chain_count>1:
-   raise RuntimeError("second entity contains more than one chain")
-  is_ha=isinstance(ent_a, mol.EntityHandle)
-  is_hb=isinstance(ent_b, mol.EntityHandle)
-
-  ev_a= is_ha and ent_a.CreateEmptyView() or ent_a.handle.CreateEmptyView()
-  ev_b= is_hb and ent_b.CreateEmptyView() or ent_b.handle.CreateEmptyView()
-
-  flags=include_atoms and mol.ViewAddFlag.INCLUDE_ATOMS or 0
-  # get all residues
-  res_a=ent_a.residues
-  res_b=ent_b.residues
-
-  # map sequence onto
-  s1 = seq_a.gapless_string
-  s2 = seq_b.gapless_string
-
-  # get sequence of ent1
-  seq_ent_a = ""
-  seq_ent_b= ""
-
-  sub_a = ent_a.Select("peptide = 1")
-  sub_b = ent_b.Select("peptide = 1")
-  for res1 in sub_a.residues:
-      seq_ent_a = "%s%s" % (seq_ent_a, res1.one_letter_code)
-
-  seq_ent_b = ""
-  for res2 in sub_b.residues:
-      seq_ent_b = "%s%s" % (seq_ent_b, res2.one_letter_code)
-
-  #~ print seq_ent_a
-  #~ print s1
-
-  #~ print seq_ent_a
-  #~ print s1
-  off_a = seq_ent_a.index(s1)
-  off_b = seq_ent_b.index(s2)
-
-  #off_a=seq_a.GetSequenceOffset()
-  #off_b=seq_b.GetSequenceOffset()
-
-
-  index_a, index_b=(0, 0)
-  done=False
-
-  align_index = 0
-
-  # iterate over residues
-  while index_a<seq_a.GetLength() and index_b<seq_b.GetLength():
-      # print 'index',index_a, seq_a.GetLength(), index_b, seq_b.GetLength()
-   while seq_a.GetOneLetterCode(index_a)=='-':
-     index_a+=1
-     if seq_a.GetLength()<index_a:
-       done=True
-       break
-   while seq_b.GetOneLetterCode(index_b)=='-':
-     index_b+=1
-     if seq_b.GetLength()<index_b:
-       done=True
-       break
-   if done or len(res_a)<=off_a+index_b or len(res_b)<=off_b+index_a:
-     break
-   ra=res_a[off_a+index_b]
-   rb=res_b[off_b+index_a]
-   #ra = res_a[index_b]
-   #rb = res_a[index_a]
-   #~ print "set align_index %d for %s %s" % (align_index, ra, rb)
-   #ra.SetIntProp("align_index",align_index)
-   #rb.SetIntProp("align_index",align_index)
-   align_index += 1
-   ev_a.AddResidue(is_ha and ra or ra.handle, flags)
-   ev_b.AddResidue(is_hb and rb or rb.handle, flags)
-   index_a+=1
-   index_b+=1
-   eda=ev_a.handle.RequestXCSEditor()
-   eda.RenameChain(ent_a.chains[0].handle,ent_a.chains[0].name)
-   edb=ev_b.handle.RequestXCSEditor()
-   edb.RenameChain(ent_b.chains[0].handle, ent_b.chains[0].name)
-  return ev_a, ev_b
+from _seq import *
\ No newline at end of file
diff --git a/modules/seq/base/pymod/const_seq_list_export_def.hh b/modules/seq/base/pymod/const_seq_list_export_def.hh
index 4c8a27068..baba81158 100644
--- a/modules/seq/base/pymod/const_seq_list_export_def.hh
+++ b/modules/seq/base/pymod/const_seq_list_export_def.hh
@@ -23,11 +23,11 @@
   .def("AddSequence", &C::AddSequence)                                         \
   .def("GetMaxLength", &C::GetMaxLength)                                       \
   .def("GetMinLength", &C::GetMinLength)                                       \
+  .def("IsValid", &C::IsValid)                                                 \
   .def("Take", &C::Take)                                                       \
-  .def("Slice", &C::Slice)                                                   \
+  .def("Slice", &C::Slice)                                                     \
   .def("SequencesHaveEqualLength",                                             \
        &C::SequencesHaveEqualLength)                                           \
   .def("__getitem__", &C::operator[])                                          \
-  .def("__iter__", iterator<C>())                                              \
   .def("__len__", &C::GetCount)
 
diff --git a/modules/seq/base/pymod/export_sequence.cc b/modules/seq/base/pymod/export_sequence.cc
index 581c5494c..ee33b6125 100644
--- a/modules/seq/base/pymod/export_sequence.cc
+++ b/modules/seq/base/pymod/export_sequence.cc
@@ -20,8 +20,9 @@
 #include <boost/python/slice.hpp>
 #include <boost/python/register_ptr_to_python.hpp>
 #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
-using namespace boost::python;
 
+
+#include <ost/export_helper/pair_to_tuple_conv.hh>
 #include <ost/generic_property.hh>
 #include <ost/export_helper/generic_property_def.hh>
 #include <ost/info/info.hh>
@@ -31,11 +32,12 @@ using namespace boost::python;
 #include <ost/seq/sequence_op.hh>
 #include <ost/seq/sequence_list.hh>
 #include <ost/seq/aligned_region.hh>
+#include <ost/seq/views_from_sequences.hh>
 #include "const_seq_list_export_def.hh"
 
 using namespace ost;
 using namespace ost::seq;
-
+using namespace boost::python;
 namespace {
 
 void (SequenceHandle::*attach_one)(const mol::EntityView&)=&SequenceHandle::AttachView;
@@ -102,8 +104,9 @@ struct RevRegionRangeIter {
     if (b_==e_) {
       boost::python::objects::stop_iteration_error();
     }
-    AlignedColumn col=*e_;
     --e_;
+    AlignedColumn col=*e_;
+
     return col;
   }
 private:
@@ -131,6 +134,55 @@ private:
   AlignedColumnIterator e_;
 };
 
+struct ConstSeqListIter {
+  ConstSeqListIter(ConstSequenceList& list):
+    l_(list), b_(l_.begin()), e_(l_.end())
+  { }
+
+  ConstSequenceHandle next()
+  {
+    if (b_==e_) {
+      boost::python::objects::stop_iteration_error();
+    }
+    ConstSequenceHandle s=*b_;  
+    ++b_;
+    return s;
+  }
+private:
+  ConstSequenceList           l_;
+  ConstSequenceList::iterator b_;
+  ConstSequenceList::iterator e_;
+};
+
+struct SeqListIter {
+  SeqListIter(SequenceList& list):
+    l_(list), b_(l_.begin()), e_(l_.end())
+  { }
+
+  SequenceHandle next()
+  {
+    if (b_==e_) {
+      boost::python::objects::stop_iteration_error();
+    }
+    SequenceHandle s=*b_;
+    ++b_;
+    return s;
+  }
+private:
+  SequenceList           l_;
+  SequenceList::iterator b_;
+  SequenceList::iterator e_;
+};
+
+ConstSeqListIter iter_cs(ConstSequenceList& sl) 
+{
+  return ConstSeqListIter(sl);
+}
+
+SeqListIter iter_sl(SequenceList& sl) 
+{
+  return SeqListIter(sl);
+}
 
 RegionRangeIter iter_range1(AlignmentHandle& aln)
 {
@@ -142,7 +194,7 @@ RegionRangeIter iter_range2(AlignedRegion& aln_region)
   return RegionRangeIter(aln_region.begin(), aln_region.end());
 }
 
-RevRegionRangeIter iter_range3(AlignedRegion& aln_region)
+RevRegionRangeIter iter_range_rev(AlignedRegion& aln_region)
 {
   return RevRegionRangeIter(aln_region.begin(), aln_region.end());
 }
@@ -159,6 +211,7 @@ void const_seq_handle_def(O& bp_class)
     .def("__getitem__", &C::GetOneLetterCode)
     .def("GetSequenceOffset", &C::GetSequenceOffset)
     .def("Copy", &C::Copy)
+    .def("IsValid", &C::IsValid)
     .def("GetFirstNonGap", &C::GetFirstNonGap)
     .def("GetLastNonGap", &C::GetLastNonGap)
     .add_property("first_non_gap", &C::GetFirstNonGap)
@@ -226,6 +279,12 @@ void export_sequence()
     class_<RevRegionRangeIter>("RevRegionRangeIter", no_init)
     .def("next", &RevRegionRangeIter::next)
   ;
+  class_<ConstSeqListIter>("ConstSeqListIter", no_init)
+    .def("next", &ConstSeqListIter::next)
+  ;
+  class_<SeqListIter>("SeqListIter", no_init)
+    .def("next", &SeqListIter::next)
+  ;
   class_<AlignmentHandle>("AlignmentHandle", init<>())
     .def("GetCount", &AlignmentHandle::GetCount)
     .add_property("sequence_count", &AlignmentHandle::GetCount)
@@ -250,11 +309,13 @@ void export_sequence()
     .add_property("sequences", &AlignmentHandle::GetSequences)
     .def("SetSequenceName",  &AlignmentHandle::SetSequenceName)
     .def("SetSequenceOffset", &AlignmentHandle::SetSequenceOffset)
+    .def("GetSequenceOffset", &AlignmentHandle::GetSequenceOffset)
   ;
   class_<AlignedColumn>("AlignedColumn", no_init)
     .def("GetIndex", &AlignedColumn::GetIndex)
     .def("__getitem__", &AlignedColumn::operator[])
     .def("GetRowCount", &AlignedColumn::GetRowCount)
+    .def("GetResidue", &AlignedColumn::GetResidue)
     .def(self_ns::str(self))
   ;
   class_<AlignedRegion>("AlignedRegion", no_init)
@@ -273,27 +334,34 @@ void export_sequence()
     .def("__getitem__", &AlignedRegion::operator[])
     .def("__len__", &AlignedRegion::GetLength)
     .def("__iter__", iter_range2)
-    //~ .def("__iter__", iter_range3)
+    //~ .def("__reversed__", iter_range_rev)
     .add_property("start", &AlignedRegion::GetStart)
     .add_property("end", &AlignedRegion::GetEnd)
   ;
   class_<ConstSequenceList>("ConstSequenceList", init<>())
     CONST_SEQ_LIST_DEF(ConstSequenceList)
     .def("__getitem__", &do_slice_a)
+    .def("__iter__", &iter_cs)    
   ;
   class_<SequenceList>("SequenceList", init<>())
     CONST_SEQ_LIST_DEF(SequenceList)
     .def("__getitem__", &do_slice_b)
+    .def("__iter__", &iter_sl)
   ;
   class_<AlignmentList>("AlignmentList", init<>())
     .def(vector_indexing_suite<AlignmentList>())
     .def("__getitem__", &do_slice_b)
   ;
   implicitly_convertible<SequenceList, ConstSequenceList>();
+  to_python_converter<std::pair<mol::EntityView, mol::EntityView>, 
+                      PairToTupleConverter<mol::EntityView, mol::EntityView> >();
   def("CreateSequenceList", &CreateSequenceList);
   def("SequenceFromChain", seq_from_chain_a);
   def("SequenceFromChain", seq_from_chain_b);
   def("SequenceToInfo", &SequenceToInfo);
+  def("ViewsFromSequences", &ViewsFromSequences, (arg("seq1"), arg("seq2")));
+  def("ViewsFromAlignment", &ViewsFromAlignment, 
+      (arg("aln"), arg("index1")=0, arg("index2")=1));
   def("SequenceListToInfo", &SequenceListToInfo);
   def("SequenceFromInfo", &SequenceFromInfo);
   def("CreateAlignment", &CreateAlignment);
diff --git a/modules/seq/base/src/CMakeLists.txt b/modules/seq/base/src/CMakeLists.txt
index 3cd12d19a..9a7015bda 100644
--- a/modules/seq/base/src/CMakeLists.txt
+++ b/modules/seq/base/src/CMakeLists.txt
@@ -15,6 +15,7 @@ aligned_region.hh
 aligned_column.hh
 aligned_column_iterator.hh
 invalid_sequence.hh
+views_from_sequences.hh
 )
 
 set(OST_SEQ_SOURCES
@@ -26,6 +27,7 @@ aligned_column.cc
 sequence_list.cc
 alignment_handle.cc
 sequence_op.cc
+views_from_sequences.cc
 )
 module(NAME seq SOURCES ${OST_SEQ_SOURCES} 
        HEADERS ${OST_SEQ_IMPL_HEADERS} IN_DIR impl
diff --git a/modules/seq/base/src/aligned_column.cc b/modules/seq/base/src/aligned_column.cc
index 8f5f1081c..e07e828b5 100644
--- a/modules/seq/base/src/aligned_column.cc
+++ b/modules/seq/base/src/aligned_column.cc
@@ -38,16 +38,19 @@ int AlignedColumn::GetIndex() const
 
 char AlignedColumn::operator[](int row) const
 {
+  this->CheckRowValidity(row);
   return aln_.GetOneLetterCode(row, index_);
 }
 
 int AlignedColumn::GetResidueIndex(int row) const
 {
+  this->CheckRowValidity(row);
   return aln_.GetResidueIndex(row, index_);
 }
 
 mol::ResidueView AlignedColumn::GetResidue(int row) const
 {
+  this->CheckRowValidity(row);
   return aln_.GetResidue(row, index_);
 }
 
@@ -64,4 +67,12 @@ int AlignedColumn::GetRowCount() const
   return aln_.GetCount();
 }
 
+void AlignedColumn::CheckRowValidity(int row) const
+{
+  if(row<0 || row>=this->GetRowCount()){
+    throw std::out_of_range("Row out of bounds");
+  }
+}
+
+
 }}
diff --git a/modules/seq/base/src/aligned_column.hh b/modules/seq/base/src/aligned_column.hh
index 2ea6e5cca..75bdf6fd3 100644
--- a/modules/seq/base/src/aligned_column.hh
+++ b/modules/seq/base/src/aligned_column.hh
@@ -55,6 +55,8 @@ public:
   /// \sa AlignmentHandle::GetResidue()
   mol::ResidueView GetResidue(int row) const;
 private:
+  void CheckRowValidity(int row) const;
+
   AlignmentHandle aln_;
   int             index_;
 };
diff --git a/modules/seq/base/src/aligned_region.cc b/modules/seq/base/src/aligned_region.cc
index decb966ef..fc4a3c6d6 100644
--- a/modules/seq/base/src/aligned_region.cc
+++ b/modules/seq/base/src/aligned_region.cc
@@ -94,7 +94,11 @@ AlignedColumnIterator AlignedRegion::end()
 
 AlignedColumn AlignedRegion::operator[](int index) const
 {
-  return AlignedColumn(aln_, start_+index);
+  int col_index = start_+index;
+  if(col_index<start_ || col_index>=end_){
+    throw std::out_of_range("Index out of region");
+  }
+  return AlignedColumn(aln_, col_index);
 }
 
 bool AlignedRegion::operator==(const AlignedRegion& rhs) const
@@ -115,6 +119,9 @@ int AlignedRegion::GetMaster() const
 
 void AlignedRegion::SetMaster(int master)
 {
+  if(master < -1 || master >= aln_.GetCount()){
+    throw IntegrityError("Master out of bounds");
+  }
   master_=master;
 }
 
diff --git a/modules/seq/base/src/alignment_handle.cc b/modules/seq/base/src/alignment_handle.cc
index 48bb07af5..d4611b562 100644
--- a/modules/seq/base/src/alignment_handle.cc
+++ b/modules/seq/base/src/alignment_handle.cc
@@ -62,9 +62,9 @@ int AlignmentHandle::GetResidueIndex(int seq_index, int pos) const
 void AlignmentHandle::AddSequence(const ConstSequenceHandle& sequence)
 {
   this->CheckValidity();
-  if (impl_->GetCount()>0 && 
-      impl_->GetSequence(0)->GetLength()!=sequence.GetLength()) {
-    throw InvalidAlignment();
+  if (!sequence.IsValid() || (impl_->GetCount()>0 &&
+      impl_->GetSequence(0)->GetLength()!=sequence.GetLength())) {
+    throw InvalidSequence();
   }
   return impl_->AddSequence(sequence.Impl());
 }
@@ -124,7 +124,7 @@ int AlignmentHandle::GetCount() const
 
 AlignmentHandle AlignmentFromSequenceList(const SequenceList& seq_list)
 {
-  if (seq_list.SequencesHaveEqualLength()) {
+  if (seq_list.IsValid() && seq_list.SequencesHaveEqualLength()) {
     return AlignmentHandle(seq_list.Impl());
   }
   throw InvalidAlignment();
@@ -143,7 +143,7 @@ void AlignmentHandle::AttachView(int seq_index, const mol::EntityView& view)
   impl_->GetSequence(seq_index)->AttachView(view);
 }
 
-void AlignmentHandle::AttachView(int seq_index, const mol::EntityView& view, 
+void AlignmentHandle::AttachView(int seq_index, const mol::EntityView& view,
                                  const String& chain_name)
 {
   this->CheckValidity();
@@ -160,7 +160,7 @@ ConstSequenceHandle AlignmentHandle::FindSequence(const String& name) const
 void AlignmentHandle::Cut(int start, int end)
 {
   this->CheckValidity();
-  for (impl::SequenceListImpl::Iterator i=impl_->Begin(), 
+  for (impl::SequenceListImpl::Iterator i=impl_->Begin(),
        e=impl_->End(); i!=e; ++i) {
     (*i)->Cut(start, end-start);
   }
@@ -170,28 +170,33 @@ void AlignmentHandle::Replace(const AlignedRegion& aln_r, int start, int end){
   this->CheckValidity();
   //check that alignment handle and aligned region contain same number of sequences
   if (impl_->GetCount() != aln_r.GetAlignmentHandle().GetCount()) {
-    throw IntegrityError("alignment handle and aligned region are required "\
-                         "to share the same number of sequences");
+    throw IntegrityError("alignment handle and aligned region are required "
+                         "to have the same number of sequences");
   }
-  int aln_rStart=aln_r.GetStart();
-  int aln_rEnd=aln_r.GetEnd();
+  int aln_r_start=aln_r.GetStart();
+  int aln_r_length=aln_r.GetLength();
   AlignmentHandle aln=aln_r.GetAlignmentHandle();
   //iterate over sequences and replace part of sequences with the substrings
   //from aligned region
   for (int i=0;i<impl_->GetCount() ;++i) {
-    this->GetSequence(i).Impl()->Replace(aln.GetSequence(i).GetString().substr(aln_rStart,aln_rEnd), start, end);
+    String s=aln.GetSequence(i).GetString().substr(aln_r_start, aln_r_length);
+    this->GetSequence(i).Impl()->Replace(s, start, end);
   }
 }
 
-void AlignmentHandle::ShiftRegion(int start, int end, int amount, 
+void AlignmentHandle::ShiftRegion(int start, int end, int amount,
                                   int master)
 {
   this->CheckValidity();
   int cnt=0;
-  for (impl::SequenceListImpl::Iterator i=impl_->Begin(), 
-       e=impl_->End(); i!=e; ++i, ++cnt) {
-    if (master==-1 || cnt==master) {
-      (*i)->ShiftRegion(start, end, amount);
+  if(master!=-1){
+    impl::SequenceImplPtr handle = this->GetSequence(master).Impl();
+    handle->ShiftRegion(start, end, amount);
+  }
+  else{
+    for (impl::SequenceListImpl::Iterator i=impl_->Begin(),
+         e=impl_->End(); i!=e; ++i, ++cnt) {
+        (*i)->ShiftRegion(start, end, amount);
     }
   }
 }
@@ -199,6 +204,9 @@ void AlignmentHandle::ShiftRegion(int start, int end, int amount,
 AlignedRegion AlignmentHandle::MakeRegion(int start, int n, int master) const
 {
   this->CheckValidity();
+  if((start<0 )||( n < 0 )|| ((start + n) > this->GetLength())){
+    throw std::out_of_range("invalid region");
+  }
   return AlignedRegion(*this, start, start+n, master);
 }
 
@@ -216,7 +224,7 @@ char AlignmentHandle::GetOneLetterCode(int seq_index, int pos) const
 
 AlignedColumnIterator AlignmentHandle::begin() const
 {
-  // no need to check for validity here  
+  // no need to check for validity here
   return AlignedColumnIterator(*this, 0, this->GetLength());
 }
 
@@ -244,4 +252,9 @@ void AlignmentHandle::SetSequenceOffset(int seq_index, int offset)
   impl_->GetSequence(seq_index)->SetSequenceOffset(offset);
 }
 
+int AlignmentHandle::GetSequenceOffset(int seq_index)
+{
+  this->CheckValidity();
+  return impl_->GetSequence(seq_index)->GetSequenceOffset();
+}
 }}
diff --git a/modules/seq/base/src/alignment_handle.hh b/modules/seq/base/src/alignment_handle.hh
index 7e6ba8567..998618b52 100644
--- a/modules/seq/base/src/alignment_handle.hh
+++ b/modules/seq/base/src/alignment_handle.hh
@@ -35,27 +35,27 @@ class AlignedRegion;
 class AlignedColumn;
 class AlignedColumnIterator;
 
-/// \brief representation of a multiple sequence alignemnt consisting of two or 
+/// \brief representation of a multiple sequence alignemnt consisting of two or
 ///     more sequences
 ///
-/// A sequence alignment consists of two or more sequences. The number of 
-/// sequences in the alignment can be obtained by #GetCount(). 
+/// A sequence alignment consists of two or more sequences. The number of
+/// sequences in the alignment can be obtained by #GetCount().
 /// All sequences are of length #GetLength().
-/// 
-/// Typically sequence alignments are used column-based, i.e by looking at an 
-/// aligned columns in the sequence alignment. To get a row-based (sequence) 
-/// view on the sequence list, use AlignmentHandle::GetSequenceList(). For an 
+///
+/// Typically sequence alignments are used column-based, i.e by looking at an
+/// aligned columns in the sequence alignment. To get a row-based (sequence)
+/// view on the sequence list, use AlignmentHandle::GetSequenceList(). For an
 /// overview of how to use the sequence module, see \ref module_seq "here"
-/// 
-/// All operators that operate on an alignment will again  produce a valid 
-/// alignment. This mean that it is not possible to change the length of one 
+///
+/// All operators that operate on an alignment will again  produce a valid
+/// alignment. This mean that it is not possible to change the length of one
 /// sequence, without  adjusting the other sequences, too.
 class DLLEXPORT_OST_SEQ AlignmentHandle {
 public:
 
   typedef AlignedColumnIterator iterator;
   AlignmentHandle();
-  
+
   /// \brief  Get position in sequence with index seq_index that corresponds to
   ///         the given residue index.
   ///
@@ -68,19 +68,19 @@ public:
   int GetResidueIndex(int seq_index, int pos) const;
 
   mol::ResidueView GetResidue(int seq_index, int pos) const;
-  
+
   char GetOneLetterCode(int seq_index, int pos) const;
-  
+
   /// \brief     Add new sequence to multiple sequence alignment.
-  /// 
-  /// If the sequence length does not match with the length of the other 
+  ///
+  /// If the sequence length does not match with the length of the other
   /// sequences in the alignment, an InvalidSequence() exception is thrown.
   void AddSequence(const ConstSequenceHandle& sequence);
 
   /// \brief     Get sequence with given index.
   /// \return    sequence or invalid handle if the index is out of bounds
-  ConstSequenceHandle GetSequence(int seq_id) const; 
-  
+  ConstSequenceHandle GetSequence(int seq_id) const;
+
   /// \brief   Convert multiple sequence alignment to string.
   String ToString(int width=80) const;
 
@@ -88,87 +88,87 @@ public:
   int GetLength() const;
 
   /// \brief deep-copy multi sequence alignment
-  AlignmentHandle Copy() const;  
-  
+  AlignmentHandle Copy() const;
+
   /// \brief find sequence by name.
-  /// 
-  /// If several sequences have the same name, the first matching sequence will 
+  ///
+  /// If several sequences have the same name, the first matching sequence will
   /// be returned.
   ConstSequenceHandle FindSequence(const String& name) const;
-  
+
   /// \brief attach view to given sequence
   /// \sa SequenceHandle::AttachView(const mol::EntityView&)
   void AttachView(int seq_index, const mol::EntityView& view);
-  
+
   /// \brief attach view to given sequence
-  /// \sa SequenceHandle::AttachView(const mol::EntityView&, const String&)  
-  void AttachView(int seq_index, const mol::EntityView& view, 
+  /// \sa SequenceHandle::AttachView(const mol::EntityView&, const String&)
+  void AttachView(int seq_index, const mol::EntityView& view,
                   const String& chain_name);
-                  
+
   /// \brief set name of sequence
   void SetSequenceName(int seq_index, const String& name);
-  
-  void SetSequenceOffset(int seq_index, int offset);
+
+  void SetSequenceOffset(int seq_index, int offset); 
+  int  GetSequenceOffset(int seq_index);
   /// \brief Get list of sequences (read-only)
   ConstSequenceList GetSequences() const;
-  
+
   /// \brief create an aligned region.
-  /// 
+  ///
   /// \param start is the index of the first column
   /// \param n is the length of the sequence
-  /// \param master is the reference system for operations such as shifting. 
-  ///      If set to -1, no master sequence is defined and the operations will 
+  /// \param master is the reference system for operations such as shifting.
+  ///      If set to -1, no master sequence is defined and the operations will
   ///      affect all sequences
-  /// 
-  /// This method does not throw any exceptions, even if the aligned region is 
-  /// out of bounds.
+  ///
+  /// If the aligned region is out of bounds, a std::out_of_bounds exeception will be thrown.
   AlignedRegion MakeRegion(int start, int n, int master=-1) const;
-  
+
   /// \brief get number of sequences in alignment
   int GetCount() const;
-  
+
   bool operator==(const AlignmentHandle& rhs) const;
-  bool operator!=(const AlignmentHandle& rhs) const;  
-  
+  bool operator!=(const AlignmentHandle& rhs) const;
+
   /// \brief get aligned column at index
-  /// 
-  /// This method does not throw any exception. Upon accessing methods of the 
-  /// aligned column, exceptions might be thrown when the index is out of 
+  ///
+  /// This method does not throw any exception. Upon accessing methods of the
+  /// aligned column, exceptions might be thrown when the index is out of
   /// bounds.
   AlignedColumn operator[](int index) const;
-  
-  AlignmentHandle(const impl::SequenceListImplPtr& impl);  
-  
+
+  AlignmentHandle(const impl::SequenceListImplPtr& impl);
+
   /// \brief cut out half-closed interval start, end
   void Cut(int start, int end);
-  
+
   ///\brief Replace part of an alignment
   void Replace(const AlignedRegion& rhs, int start, int end);
   /// \brief shift half-closed interval by amount
-  /// 
+  ///
   /// if master is -1, all sequences of the alignment will be shifted. Otherwise
   /// only the sequence with given index is affected.
   void ShiftRegion(int start, int end, int amount, int master=-1);
-  
+
   /// \brief Column iterator start-point
   iterator begin() const;
   /// \brief Column iterator end-point
   iterator end() const;
-  
+
 private:
   void CheckValidity() const;
-  impl::SequenceListImplPtr impl_; 
+  impl::SequenceListImplPtr impl_;
 };
 
 AlignmentHandle DLLEXPORT_OST_SEQ CreateAlignment();
 
 /// \brief convert alignment from sequence list
-/// 
-/// If the sequences in the SequenceList have different lengths, an 
+///
+/// If the sequences in the SequenceList have different lengths, an
 /// InvalidAlignment exception is thrown.
-/// 
+///
 /// \return alignment consisting of the sequences in seq_list.
-AlignmentHandle DLLEXPORT_OST_SEQ 
+AlignmentHandle DLLEXPORT_OST_SEQ
 AlignmentFromSequenceList(const SequenceList& seq_list);
 
 typedef std::vector<AlignmentHandle> AlignmentList;
diff --git a/modules/seq/base/src/impl/sequence_impl.cc b/modules/seq/base/src/impl/sequence_impl.cc
index 69fd3f42f..06edaf5d5 100644
--- a/modules/seq/base/src/impl/sequence_impl.cc
+++ b/modules/seq/base/src/impl/sequence_impl.cc
@@ -63,8 +63,13 @@ SequenceImplPtr SequenceImpl::FromString(const String& seq_name,
 
 void SequenceImpl::SetString(const String& seq)
 {
-  seq_string_=seq;
-  this->ShiftsFromSequence();
+  if (SequenceImpl::IsSequenceStringSane(seq)) {
+    seq_string_=seq;
+    this->ShiftsFromSequence();
+  }
+  else {
+    throw InvalidSequence();
+  }
 }
 
 SequenceImpl::SequenceImpl(const String& seq_name,
@@ -165,6 +170,8 @@ int SequenceImpl::GetLength() const {
 
 char SequenceImpl::GetOneLetterCode(int position) const
 {
+  if (position<0 || position>=static_cast<int>(seq_string_.length()))
+    throw Error("Position is not covered in sequence");
   return seq_string_[position];
 }
 
@@ -207,7 +214,7 @@ void SequenceImpl::AttachView(const mol::EntityView& view)
 {
   static const char* msg="Expected 1 chain, but %d chains found";
   attached_view_=view;
-  if (attached_view_.GetChainCount()!=1) {
+  if (view.IsValid() && attached_view_.GetChainCount()!=1) {
     throw IntegrityError(str(format(msg) % attached_view_.GetChainCount()));
   }
 }
@@ -273,6 +280,9 @@ void SequenceImpl::Replace(const String& str,int start, int end)
 
 void SequenceImpl::ShiftRegion(int start, int end, int amount)
 {
+  if(start > end || start + amount < 0 || end + amount > this->GetLength()){
+    throw std::out_of_range("ShiftRegion: invalid region");
+  }
   String str1=seq_string_.substr(start, end-start);
   if (amount<0) {
     String str2=seq_string_.substr(start+amount, -amount);
diff --git a/modules/seq/base/src/impl/sequence_list_impl.hh b/modules/seq/base/src/impl/sequence_list_impl.hh
index 0911aa9b8..93bc07035 100644
--- a/modules/seq/base/src/impl/sequence_list_impl.hh
+++ b/modules/seq/base/src/impl/sequence_list_impl.hh
@@ -41,12 +41,21 @@ public:
   /// \brief get number of sequences in list
   int GetCount() const { return list_.size(); }
   
-  SequenceImplPtr& GetSequence(int i) 
-  { 
-    return list_[i]; 
+  SequenceImplPtr& GetSequence(int i) {
+    unsigned int index = static_cast<unsigned int>(i);
+    if (index<list_.size()) {
+      return list_[index];
+    }
+    throw Error("Index not covered SequenceList");
   }
   
-  const SequenceImplPtr& GetSequence(int i) const { return list_[i]; }  
+  const SequenceImplPtr& GetSequence(unsigned int i) const {
+    unsigned int index = static_cast<unsigned int>(i);
+    if (index<list_.size()) {
+      return list_[index];
+    }
+    throw Error("Index not covered SequenceList");
+  }
   
   int GetPos(int seq_index, int residue_index) const;
 
diff --git a/modules/seq/base/src/sequence_handle.cc b/modules/seq/base/src/sequence_handle.cc
index eeb3d1acb..a7f5347e1 100644
--- a/modules/seq/base/src/sequence_handle.cc
+++ b/modules/seq/base/src/sequence_handle.cc
@@ -51,6 +51,11 @@ bool ConstSequenceHandle::operator!=(const ConstSequenceHandle& rhs) const
   return impl_!=rhs.impl_;
 }
 
+char ConstSequenceHandle::operator[](int index) const
+{
+  this->CheckValidity();
+  return this->GetOneLetterCode(index);
+}
 
 void ConstSequenceHandle::CheckValidity() const
 {
diff --git a/modules/seq/base/src/sequence_handle.hh b/modules/seq/base/src/sequence_handle.hh
index ad4d294e3..de03a505b 100644
--- a/modules/seq/base/src/sequence_handle.hh
+++ b/modules/seq/base/src/sequence_handle.hh
@@ -116,6 +116,8 @@ public:
   bool operator==(const ConstSequenceHandle& rhs) const;
   bool operator!=(const ConstSequenceHandle& rhs) const;  
   
+  char operator[](int index) const;
+  
   /// \brief whether the sequence is valid
   bool IsValid() const;
   /// \internal
diff --git a/modules/seq/base/src/views_from_sequences.cc b/modules/seq/base/src/views_from_sequences.cc
new file mode 100644
index 000000000..7ab0ff1f6
--- /dev/null
+++ b/modules/seq/base/src/views_from_sequences.cc
@@ -0,0 +1,87 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#include <ost/integrity_error.hh>
+#include <ost/seq/views_from_sequences.hh>
+
+namespace ost { namespace seq {
+
+namespace {
+
+bool skip_gaps(const ConstSequenceHandle& seq1, 
+               const ConstSequenceHandle& seq2, int& pos, 
+               int& index_a, int& index_b)
+{
+  while (seq1.GetLength()>pos) {
+    if (seq1[pos]=='-') {
+      if (seq2[pos]!='-') {
+        index_b+=1;
+      }
+    } else if (seq2[pos]=='-') {
+      index_a+=1;
+    } else {
+      return true;
+    }
+    pos+=1;
+  }
+  return false;
+}
+
+}
+
+std::pair<mol::EntityView, mol::EntityView> 
+ViewsFromSequences(const ConstSequenceHandle& seq1, 
+                   const ConstSequenceHandle& seq2)
+{
+  if (seq1.GetLength()!=seq2.GetLength()) {
+    throw IntegrityError("Sequence lengths do not match");
+  }
+  if (!seq1.HasAttachedView()) {
+    throw IntegrityError("First sequence does not have an attached view");
+  }
+  if (!seq2.HasAttachedView()) {
+    throw IntegrityError("Second sequence does not have an attached view");
+  }
+  mol::EntityView src_a=seq1.GetAttachedView();
+  mol::EntityView src_b=seq2.GetAttachedView();
+  
+  mol::EntityView dst_a=src_a.CreateEmptyView();
+  mol::EntityView dst_b=src_b.CreateEmptyView();
+  mol::ResidueViewList res_a=src_a.GetResidueList();
+  mol::ResidueViewList res_b=src_b.GetResidueList();  
+  int pos=0, index_a=0, index_b=0;
+  while (skip_gaps(seq1, seq2, pos, index_a, index_b)) {
+    dst_a.AddResidue(res_a.at(seq1.GetSequenceOffset()+index_a), 
+                     mol::ViewAddFlag::INCLUDE_ATOMS);
+    dst_b.AddResidue(res_b.at(seq2.GetSequenceOffset()+index_b), 
+                     mol::ViewAddFlag::INCLUDE_ATOMS);
+    pos+=1;
+    index_a+=1;
+    index_b+=1;
+  }
+  return std::make_pair(dst_a, dst_b);
+}
+
+
+std::pair<mol::EntityView, mol::EntityView> 
+ViewsFromAlignment(const AlignmentHandle& aln, int index1, int index2)
+{
+  return ViewsFromSequences(aln.GetSequence(index1), aln.GetSequence(index2));
+}
+
+}}
diff --git a/modules/seq/base/src/views_from_sequences.hh b/modules/seq/base/src/views_from_sequences.hh
new file mode 100644
index 000000000..1a46965b1
--- /dev/null
+++ b/modules/seq/base/src/views_from_sequences.hh
@@ -0,0 +1,36 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#ifndef OST_SEQ_VIEWS_FROM_SEQUENCES_HH
+#define OST_SEQ_VIEWS_FROM_SEQUENCES_HH
+
+#include <ost/seq/module_config.hh>
+#include <ost/seq/alignment_handle.hh>
+
+namespace ost { namespace seq {
+
+std::pair<mol::EntityView, mol::EntityView> DLLEXPORT_OST_SEQ 
+ViewsFromSequences(const ConstSequenceHandle& seq1, 
+                   const ConstSequenceHandle& seq2);
+
+std::pair<mol::EntityView, mol::EntityView> DLLEXPORT_OST_SEQ
+ViewsFromAlignment(const AlignmentHandle& aln, int index1=0, int index2=1);
+  
+}}
+
+#endif
diff --git a/modules/seq/base/tests/CMakeLists.txt b/modules/seq/base/tests/CMakeLists.txt
index cb7025d94..528cb936d 100644
--- a/modules/seq/base/tests/CMakeLists.txt
+++ b/modules/seq/base/tests/CMakeLists.txt
@@ -1,5 +1,9 @@
 set(OST_SEQ_UNIT_TESTS
+  test_seq.py
   test_sequence.cc
+  test_aligned_column.cc
+  test_aligned_region.cc
+  test_alignment.cc
   tests.cc
 )
 
diff --git a/modules/seq/base/tests/test_aligned_column.cc b/modules/seq/base/tests/test_aligned_column.cc
new file mode 100644
index 000000000..f76573df3
--- /dev/null
+++ b/modules/seq/base/tests/test_aligned_column.cc
@@ -0,0 +1,133 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#define BOOST_TEST_DYN_LINK
+#include <boost/test/unit_test.hpp>
+
+#include <ost/mol/mol.hh>
+
+#include <ost/invalid_handle.hh>
+#include <ost/integrity_error.hh>
+
+#include <ost/mol/mol.hh>
+#include <ost/seq/alignment_handle.hh>
+#include <ost/seq/aligned_region.hh>
+#include <ost/seq/aligned_column.hh>
+#include <ost/seq/sequence_handle.hh>
+#include <ost/seq/sequence_list.hh>
+#include <ost/seq/impl/sequence_list_impl.hh>
+#include <ost/seq/impl/sequence_impl.hh>
+#include <ost/seq/sequence_list.hh>
+
+using namespace ost;
+using namespace ost::seq;
+using namespace ost::mol;
+
+
+struct Fixture {
+  Fixture() {
+    eh = CreateEntity();
+    eh.SetName("TestEntity");
+    XCSEditor e=eh.RequestXCSEditor();
+    chain = e.InsertChain("A");
+    res1 = e.AppendResidue(chain, "ARG");
+    e.InsertAtom(res1, "CA",geom::Vec3(1,0,0));
+    res2 = e.AppendResidue(chain, "ARG");
+    e.InsertAtom(res2, "CA",geom::Vec3(0,1,0));
+    res3 = e.AppendResidue(chain, "ARG");
+    e.InsertAtom(res3, "CA",geom::Vec3(0,0,1));
+  }
+  EntityHandle eh;
+  ChainHandle  chain;
+  ResidueHandle res1;
+  ResidueHandle res2;
+  ResidueHandle res3;
+};
+
+BOOST_AUTO_TEST_SUITE( aligned_column )
+
+BOOST_AUTO_TEST_CASE(aligned_column_triv)
+{
+  AlignedColumn ac =AlignedColumn();
+  BOOST_CHECK_THROW(ac[0], InvalidHandle);
+
+  AlignmentHandle a = CreateAlignment();
+  SequenceHandle seq1 = CreateSequence("S1","ab-cdef");
+  SequenceHandle seq2 = CreateSequence("S2","ghijk-l");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  AlignedRegion ar = AlignedRegion(a,1,3,1);
+  ac = ar[0];
+
+  BOOST_CHECK_EQUAL(ac.GetIndex(), 1);
+  ac = ar[1];
+  BOOST_CHECK_EQUAL(ac.GetIndex(), 2);
+  BOOST_CHECK_THROW(ar[2], std::out_of_range);
+  BOOST_CHECK_THROW(ar[-1], std::out_of_range);
+
+  AlignedColumn ac_test = AlignedColumn(a,2);
+  char c = ac[0];
+  BOOST_CHECK_EQUAL(c, ac_test[0]);
+  BOOST_CHECK_EQUAL(c, '-');
+  c = ac[1];
+  BOOST_CHECK_EQUAL(c, ac_test[1]);
+  BOOST_CHECK_EQUAL(c, 'i');
+}
+
+BOOST_AUTO_TEST_CASE(aligned_get_residue)
+{
+  Fixture f;
+  EntityView v1 = f.eh.CreateFullView();
+  EntityView v2 = f.eh.CreateFullView();
+
+  AlignmentHandle a = CreateAlignment();
+  SequenceHandle seq1 = CreateSequence("S1","ab-cdef");
+  SequenceHandle seq2 = CreateSequence("S2","ghijk-l");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  a.AttachView(0,v1);
+  a.AttachView(1,v2);
+  AlignedRegion ar = AlignedRegion(a,1,3,1);
+  AlignedColumn ac = ar[0];
+  BOOST_CHECK_EQUAL(f.res2,ac.GetResidue(0));
+  ac = ar[1];
+  BOOST_CHECK_EQUAL(f.res2,ac.GetResidue(1));
+  BOOST_CHECK_THROW(ac.GetResidue(2),std::out_of_range);
+  BOOST_CHECK_THROW(ac.GetResidue(-1),std::out_of_range);
+}
+
+BOOST_AUTO_TEST_CASE(aligned_get_residue_index)
+{
+  AlignmentHandle a = CreateAlignment();
+  SequenceHandle seq1 = CreateSequence("S1","ab-cdef");
+  SequenceHandle seq2 = CreateSequence("S2","ghijk-l");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  AlignedRegion ar = AlignedRegion(a,1,3,1);
+  AlignedColumn ac = ar[0];
+  BOOST_CHECK_EQUAL(ac.GetResidueIndex(0),1);
+  BOOST_CHECK_EQUAL(ac.GetResidueIndex(1),1);
+
+  ac = ar[1];
+  BOOST_CHECK_THROW(ac.GetResidueIndex(0),Error);
+  BOOST_CHECK_EQUAL(ac.GetResidueIndex(1),2);
+  BOOST_CHECK_THROW(ac.GetResidueIndex(2),std::out_of_range);
+  BOOST_CHECK_THROW(ac.GetResidueIndex(-1),std::out_of_range);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/modules/seq/base/tests/test_aligned_region.cc b/modules/seq/base/tests/test_aligned_region.cc
new file mode 100644
index 000000000..f22eb84bc
--- /dev/null
+++ b/modules/seq/base/tests/test_aligned_region.cc
@@ -0,0 +1,186 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#define BOOST_TEST_DYN_LINK
+#include <boost/test/unit_test.hpp>
+
+#include <ost/mol/mol.hh>
+
+#include <ost/invalid_handle.hh>
+#include <ost/integrity_error.hh>
+
+#include <ost/mol/mol.hh>
+#include <ost/seq/alignment_handle.hh>
+#include <ost/seq/aligned_region.hh>
+#include <ost/seq/sequence_handle.hh>
+#include <ost/seq/sequence_list.hh>
+#include <ost/seq/impl/sequence_list_impl.hh>
+#include <ost/seq/impl/sequence_impl.hh>
+#include <ost/seq/sequence_list.hh>
+
+using namespace ost;
+using namespace ost::seq;
+using namespace ost::mol;
+
+
+BOOST_AUTO_TEST_SUITE( aligned_region )
+
+BOOST_AUTO_TEST_CASE(aligned_region_triv)
+{
+  AlignmentHandle a = CreateAlignment();
+  SequenceHandle seq1 = CreateSequence("S1","ab-cdef");
+  SequenceHandle seq2 = CreateSequence("S2","ghijk-l");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  AlignedRegion ar = AlignedRegion(a,0,2,1);
+  BOOST_CHECK(ar.GetAlignmentHandle()==a);
+  BOOST_CHECK_EQUAL(ar.GetStart(),0);
+  BOOST_CHECK_EQUAL(ar.GetEnd(),2);
+  BOOST_CHECK_EQUAL(ar.GetLength(),2);
+  BOOST_CHECK_EQUAL(ar.GetMaster(),1);
+  ar.SetMaster(0);
+  BOOST_CHECK_EQUAL(ar.GetMaster(),0);
+  ar.SetMaster(-1);
+  BOOST_CHECK_EQUAL(ar.GetMaster(),-1);
+  BOOST_CHECK_THROW(ar.SetMaster(2),IntegrityError);
+  BOOST_CHECK_THROW(ar.SetMaster(-2),IntegrityError);
+
+  AlignedRegion ar_same = a.MakeRegion(0,2);
+  BOOST_CHECK(ar==ar_same);
+}
+
+BOOST_AUTO_TEST_CASE(aligned_region_delete)
+{
+  AlignmentHandle a = CreateAlignment();
+  SequenceHandle seq1 = CreateSequence("S1","ab-cdef");
+  SequenceHandle seq2 = CreateSequence("S2","ghijk-l");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  AlignedRegion ar = a.MakeRegion(1,2);
+  ar.Delete();
+  BOOST_CHECK_EQUAL(a.GetSequence(0).GetString(),"acdef");
+  BOOST_CHECK_EQUAL(a.GetSequence(1).GetString(),"gjk-l");
+
+  a = CreateAlignment();
+  seq1 = CreateSequence("S1","ab-cdef");
+  seq2 = CreateSequence("S2","ghijk-l");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  ar = a.MakeRegion(0,7);
+  ar.Delete();
+  BOOST_CHECK_EQUAL(a.GetSequence(0).GetString(),"");
+  BOOST_CHECK_EQUAL(a.GetSequence(1).GetString(),"");
+
+  a = CreateAlignment();
+  seq1 = CreateSequence("S1","ab-cdef");
+  seq2 = CreateSequence("S2","ghijk-l");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  ar = a.MakeRegion(0,0);
+  ar.Delete();
+  BOOST_CHECK_EQUAL(a.GetSequence(0).GetString(),"ab-cdef");
+  BOOST_CHECK_EQUAL(a.GetSequence(1).GetString(),"ghijk-l");
+}
+
+BOOST_AUTO_TEST_CASE(aligned_region_replace)
+{
+  AlignmentHandle a1 = CreateAlignment();
+  SequenceHandle seq11 = CreateSequence("S1","ab-cdef");
+  SequenceHandle seq12 = CreateSequence("S2","ghijk-l");
+  a1.AddSequence(seq11);
+  a1.AddSequence(seq12);
+  AlignedRegion ar1 = a1.MakeRegion(2,2);
+  AlignmentHandle a2 = CreateAlignment();
+  SequenceHandle seq21 = CreateSequence("S1","zzzzzzz");
+  SequenceHandle seq22 = CreateSequence("S2","ee-----");
+  a2.AddSequence(seq21);
+  a2.AddSequence(seq22);
+  AlignedRegion ar2 = a2.MakeRegion(2,2);
+  ar1.Replace(ar2);
+  BOOST_CHECK_EQUAL(a1.GetSequence(0).GetString(),"abzzdef");
+  BOOST_CHECK_EQUAL(a1.GetSequence(1).GetString(),"gh--k-l");
+
+  a1 = CreateAlignment();
+  seq11 = CreateSequence("S1","ab-cdef");
+  seq12 = CreateSequence("S2","ghijk-l");
+  a1.AddSequence(seq11);
+  a1.AddSequence(seq12);
+  ar1 = a1.MakeRegion(1,2);
+  a2 = CreateAlignment();
+  seq21 = CreateSequence("S1","zzzzzzz");
+  seq22 = CreateSequence("S2","ee-----");
+  a2.AddSequence(seq21);
+  a2.AddSequence(seq22);
+  ar2 = a2.MakeRegion(1,0);
+  ar1.Replace(ar2);
+  BOOST_CHECK_EQUAL(a1.GetSequence(0).GetString(),"acdef");
+  BOOST_CHECK_EQUAL(a1.GetSequence(1).GetString(),"gjk-l");
+
+  a1 = CreateAlignment();
+  seq11 = CreateSequence("S1","ab-cdef");
+  seq12 = CreateSequence("S2","ghijk-l");
+  a1.AddSequence(seq11);
+  a1.AddSequence(seq12);
+  ar1 = a1.MakeRegion(1,2);
+  a2 = CreateAlignment();
+  seq21 = CreateSequence("S1","zzzzzzz");
+  seq22 = CreateSequence("S2","ee-----");
+  a2.AddSequence(seq21);
+  a2.AddSequence(seq22);
+  ar2 = a2.MakeRegion(1,3);
+  ar1.Replace(ar2);
+  BOOST_CHECK_EQUAL(a1.GetSequence(0).GetString(),"azzzcdef");
+  BOOST_CHECK_EQUAL(a1.GetSequence(1).GetString(),"ge--jk-l");
+}
+
+BOOST_AUTO_TEST_CASE(aligned_region_shift)
+{
+  AlignmentHandle a = CreateAlignment();
+  SequenceHandle seq1 = CreateSequence("S1","ab-c");
+  SequenceHandle seq2 = CreateSequence("S2","ghij");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  AlignedRegion ar = a.MakeRegion(1,2);
+
+  BOOST_CHECK_NO_THROW(ar.ShiftLeft(1));
+  BOOST_CHECK_EQUAL(ar.GetStart(),0);
+  BOOST_CHECK_EQUAL(ar.GetEnd(),2);
+  BOOST_CHECK_EQUAL(ar.GetLength(),2);
+  BOOST_CHECK_EQUAL(a.GetSequence(0).GetString(),"b-ac");
+  BOOST_CHECK_EQUAL(a.GetSequence(1).GetString(),"higj");
+  BOOST_CHECK_NO_THROW(ar.ShiftLeft(0));
+  BOOST_CHECK_EQUAL(a.GetSequence(0).GetString(),"b-ac");
+  BOOST_CHECK_EQUAL(a.GetSequence(1).GetString(),"higj");
+
+  BOOST_CHECK_THROW(ar.ShiftLeft(1),IntegrityError);
+
+  BOOST_CHECK_NO_THROW(ar.ShiftRight(2));
+  BOOST_CHECK_EQUAL(ar.GetStart(),2);
+  BOOST_CHECK_EQUAL(ar.GetEnd(),4);
+  BOOST_CHECK_EQUAL(ar.GetLength(),2);
+  BOOST_CHECK_EQUAL(a.GetSequence(0).GetString(),"acb-");
+  BOOST_CHECK_EQUAL(a.GetSequence(1).GetString(),"gjhi");
+
+  BOOST_CHECK_NO_THROW(ar.ShiftRight(0));
+  BOOST_CHECK_EQUAL(a.GetSequence(0).GetString(),"acb-");
+  BOOST_CHECK_EQUAL(a.GetSequence(1).GetString(),"gjhi");
+
+  BOOST_CHECK_THROW(ar.ShiftRight(1),IntegrityError);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/modules/seq/base/tests/test_alignment.cc b/modules/seq/base/tests/test_alignment.cc
new file mode 100644
index 000000000..260ea5c23
--- /dev/null
+++ b/modules/seq/base/tests/test_alignment.cc
@@ -0,0 +1,223 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#define BOOST_TEST_DYN_LINK
+#include <boost/test/unit_test.hpp>
+
+#include <ost/invalid_handle.hh>
+#include <ost/mol/mol.hh>
+#include <ost/seq/alignment_handle.hh>
+#include <ost/seq/aligned_region.hh>
+#include <ost/seq/sequence_handle.hh>
+#include <ost/seq/sequence_list.hh>
+#include <ost/seq/impl/sequence_list_impl.hh>
+#include <ost/seq/impl/sequence_impl.hh>
+#include <ost/seq/sequence_list.hh>
+
+using namespace ost;
+using namespace ost::seq;
+using namespace ost::mol;
+
+
+struct Fixture {
+  Fixture() {
+    eh = CreateEntity();
+    eh.SetName("TestEntity");
+    XCSEditor e=eh.RequestXCSEditor();
+    chain = e.InsertChain("A");
+    res1 = e.AppendResidue(chain, "ARG");
+    e.InsertAtom(res1, "CA",geom::Vec3(1,0,0));
+    res2 = e.AppendResidue(chain, "ARG");
+    e.InsertAtom(res2, "CA",geom::Vec3(0,1,0));
+    res3 = e.AppendResidue(chain, "ARG");
+    e.InsertAtom(res3, "CA",geom::Vec3(0,0,1));
+  }
+  EntityHandle eh;
+  ChainHandle  chain;
+  ResidueHandle res1;
+  ResidueHandle res2;
+  ResidueHandle res3;
+};
+
+BOOST_AUTO_TEST_SUITE( alignment )
+
+BOOST_AUTO_TEST_CASE(alignment_triv)
+{
+  AlignmentHandle a;
+  BOOST_CHECK_THROW(a.AddSequence(CreateSequence("S1","-asdf-")),InvalidHandle);
+  a = CreateAlignment();
+  BOOST_CHECK_NO_THROW(a.AddSequence(CreateSequence("S1","-asdf-")));
+  BOOST_CHECK_THROW(a.AddSequence(SequenceHandle()),InvalidSequence);
+  BOOST_CHECK_THROW(a.AddSequence(CreateSequence("S2","-asdf-f")),InvalidSequence);
+  SequenceList list = CreateSequenceList();
+  list.AddSequence(CreateSequence("S1", "-asdf-"));
+  list.AddSequence(CreateSequence("S2", "fasdfas"));
+  BOOST_CHECK_THROW(AlignmentFromSequenceList(list),InvalidAlignment);
+  list = CreateSequenceList();
+  list.AddSequence(CreateSequence("S1", "-asdf-"));
+  list.AddSequence(CreateSequence("S2", "fasdfa"));
+  BOOST_CHECK_NO_THROW(AlignmentFromSequenceList(list));
+}
+
+BOOST_AUTO_TEST_CASE(alignment_count_and_length)
+{
+  AlignmentHandle a = CreateAlignment();
+  BOOST_CHECK_EQUAL(a.GetCount(),0);
+  BOOST_CHECK_EQUAL(a.GetLength(),0);
+  a.AddSequence(CreateSequence("S1","asdf"));
+  BOOST_CHECK_EQUAL(a.GetCount(),1);
+  BOOST_CHECK_EQUAL(a.GetLength(),4);
+  a.AddSequence(CreateSequence("S2","qwer"));
+  BOOST_CHECK_EQUAL(a.GetCount(),2);
+  BOOST_CHECK_EQUAL(a.GetLength(),4);
+}
+
+BOOST_AUTO_TEST_CASE(alignment_onelettercode)
+{
+  AlignmentHandle a = CreateAlignment();
+  SequenceHandle seq1 = CreateSequence("S1","-a-sdf");
+  SequenceHandle seq2 = CreateSequence("S2","q--wer");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  BOOST_CHECK_EQUAL(a.GetOneLetterCode(0,0),'-');
+  BOOST_CHECK_EQUAL(a.GetOneLetterCode(0,0),seq1.GetOneLetterCode(0));
+  BOOST_CHECK_EQUAL(a.GetOneLetterCode(1,0),'q');
+  BOOST_CHECK_EQUAL(a.GetOneLetterCode(1,0),seq2.GetOneLetterCode(0));
+  BOOST_CHECK_EQUAL(a.GetOneLetterCode(0,3),'s');
+  BOOST_CHECK_EQUAL(a.GetOneLetterCode(0,3),seq1.GetOneLetterCode(3));
+  BOOST_CHECK_EQUAL(a.GetOneLetterCode(1,3),'w');
+  BOOST_CHECK_EQUAL(a.GetOneLetterCode(1,3),seq2.GetOneLetterCode(3));
+  BOOST_CHECK_THROW(a.GetOneLetterCode(0,-1),Error);
+  BOOST_CHECK_THROW(a.GetOneLetterCode(1,6),Error);
+  BOOST_CHECK_THROW(a.GetOneLetterCode(2,0),Error);
+  BOOST_CHECK_THROW(a.GetOneLetterCode(-1,0),Error);
+}
+
+BOOST_AUTO_TEST_CASE(alignment_pos_and_index)
+{
+  AlignmentHandle a = CreateAlignment();
+  a.AddSequence(CreateSequence("S1","-a-sdf"));
+  a.AddSequence(CreateSequence("S2","q--wer"));
+  BOOST_CHECK_EQUAL(a.GetPos(0,1), 3);
+  BOOST_CHECK_EQUAL(a.GetResidueIndex(0,3), 1);
+  BOOST_CHECK_EQUAL(a.GetPos(1,2), 4);
+  BOOST_CHECK_EQUAL(a.GetResidueIndex(1,4), 2);
+  BOOST_CHECK_THROW(a.GetPos(0,-1),Error);
+  BOOST_CHECK_THROW(a.GetPos(1,4),Error);
+  BOOST_CHECK_THROW(a.GetPos(2,0),Error);
+  BOOST_CHECK_THROW(a.GetPos(-1,0),Error);
+}
+
+BOOST_AUTO_TEST_CASE(alignment_getseq)
+{
+  AlignmentHandle a = CreateAlignment();
+  SequenceHandle seq1 = CreateSequence("S1","-a-sdf");
+  SequenceHandle seq2 = CreateSequence("S2","q--wer");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  BOOST_CHECK_EQUAL(a.GetSequence(0), seq1);
+  BOOST_CHECK_EQUAL(a.GetSequence(1), seq2);
+  BOOST_CHECK_THROW(a.GetSequence(-1), Error);
+  BOOST_CHECK_THROW(a.GetSequence(2), Error);
+}
+
+BOOST_AUTO_TEST_CASE(alignment_attach_view)
+{
+  Fixture f;
+  EntityView v = f.eh.CreateFullView();
+  EntityView v2 = f.eh.CreateFullView();
+
+  AlignmentHandle a = CreateAlignment();
+  SequenceHandle seq1 = CreateSequence("S1","r-r");
+  SequenceHandle seq2 = CreateSequence("S2","aa-");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  a.AttachView(0,v);
+  a.AttachView(1,v2);
+  BOOST_CHECK_EQUAL(a.GetResidue(0,0), f.res1);
+  BOOST_CHECK_EQUAL(a.GetResidue(0,2), f.res3);
+  BOOST_CHECK_EQUAL(a.GetResidue(1,0), f.res1);
+  BOOST_CHECK_EQUAL(a.GetResidue(1,1), f.res2);
+  BOOST_CHECK_NO_THROW(a.AttachView(0,EntityView()));
+  BOOST_CHECK_EQUAL(a.GetResidue(0,1), EntityView());
+  BOOST_CHECK_EQUAL(a.GetResidue(0,3), EntityView());
+  BOOST_CHECK_THROW(a.GetResidue(-1,0),Error)
+}
+
+BOOST_AUTO_TEST_CASE(alignment_cut)
+{
+  AlignmentHandle a = CreateAlignment();
+  SequenceHandle seq1 = CreateSequence("S1","r-r");
+  SequenceHandle seq2 = CreateSequence("S2","aa-");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  a.Cut(1,2);
+  BOOST_CHECK_EQUAL(a.GetLength(),2);
+  BOOST_CHECK_EQUAL(a.GetOneLetterCode(0,0),'r');
+  BOOST_CHECK_EQUAL(a.GetOneLetterCode(0,1),'r');
+  BOOST_CHECK_THROW(a.GetOneLetterCode(0,2),Error);
+  BOOST_CHECK_EQUAL(a.GetOneLetterCode(1,0),'a');
+  BOOST_CHECK_EQUAL(a.GetOneLetterCode(1,1),'-');
+  BOOST_CHECK_THROW(a.GetOneLetterCode(1,2),Error);
+}
+
+BOOST_AUTO_TEST_CASE(alignment_shift_region)
+{
+  AlignmentHandle a = CreateAlignment();
+  SequenceHandle seq1 = CreateSequence("S1","abcdef");
+  SequenceHandle seq2 = CreateSequence("S2","ghijkl");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  a.ShiftRegion(2, 4, 2);
+  BOOST_CHECK_EQUAL(a.GetSequence(0).GetString(),"abefcd");
+  BOOST_CHECK_EQUAL(a.GetSequence(1).GetString(),"ghklij");
+
+  a.ShiftRegion(2, 2, 2);//Shift nothing
+  BOOST_CHECK_EQUAL(a.GetSequence(0).GetString(),"abefcd");
+
+  a.ShiftRegion(2,3,1,1);
+  BOOST_CHECK_EQUAL(a.GetSequence(0).GetString(),"abefcd");
+  BOOST_CHECK_EQUAL(a.GetSequence(1).GetString(),"ghlkij");
+
+  BOOST_CHECK_THROW(a.ShiftRegion(0,2,1,2),Error);
+  BOOST_CHECK_THROW(a.ShiftRegion(0,2,1,-2),Error);
+
+  BOOST_CHECK_THROW(a.ShiftRegion(0,2,-1),std::out_of_range);
+  BOOST_CHECK_THROW(a.ShiftRegion(0,5,2),std::out_of_range);
+}
+
+BOOST_AUTO_TEST_CASE(alignment_aligned_region)
+{
+  AlignmentHandle a = CreateAlignment();
+  SequenceHandle seq1 = CreateSequence("S1","abcdef");
+  SequenceHandle seq2 = CreateSequence("S2","ghijkl");
+  a.AddSequence(seq1);
+  a.AddSequence(seq2);
+  AlignedRegion ar = a.MakeRegion(1,2);
+  BOOST_CHECK_EQUAL(ar.GetLength(),2);
+  BOOST_CHECK_EQUAL(ar.GetStart(),1);
+  BOOST_CHECK_EQUAL(ar.GetEnd(),3);
+
+  BOOST_CHECK_THROW(ar = a.MakeRegion(-1,2,0),std::out_of_range);
+  BOOST_CHECK_THROW(ar = a.MakeRegion(0,7,0),std::out_of_range);
+  BOOST_CHECK_NO_THROW(ar = a.MakeRegion(2,4,0));
+  BOOST_CHECK_NO_THROW(ar = a.MakeRegion(3,2,0));
+  BOOST_CHECK_NO_THROW(ar = a.MakeRegion(3,3,0));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/modules/seq/base/tests/test_seq.py b/modules/seq/base/tests/test_seq.py
new file mode 100644
index 000000000..4eed73b11
--- /dev/null
+++ b/modules/seq/base/tests/test_seq.py
@@ -0,0 +1,127 @@
+import unittest
+from ost import *
+from ost import settings
+from ost import seq
+
+
+def fixture():
+  e=mol.CreateEntity()
+  ede=e.RequestXCSEditor()
+  chain=ede.InsertChain('A')
+  for res in 'ABCDEFGH':
+    r=ede.AppendResidue(chain, res)
+    r.SetOneLetterCode(res)
+    ede.InsertAtom(r, "XXX", geom.Vec3())
+    
+  return e
+  
+class TestSeq(unittest.TestCase):
+  
+  def setUp(self):
+    self.ent=fixture()
+
+  def testViewsFromSequences_01(self):
+    seq_a=seq.CreateSequence("A", "ABCD-FGH")
+    seq_a.AttachView(self.ent.Select('rname=A,B,C,D,F,G,H'))
+    seq_b=seq.CreateSequence("B", "ABCDEFGH")
+    seq_b.AttachView(self.ent.Select(''))
+    a, b=seq.ViewsFromSequences(seq_a, seq_b)
+    string_a=''.join([r.one_letter_code for r in a.residues])
+    string_b=''.join([r.one_letter_code for r in b.residues])
+    self.assertEqual(string_a, 'ABCDFGH')
+    self.assertEqual(string_b, 'ABCDFGH')
+ 
+  def testViewsFromSequences_02(self):
+    seq_a=seq.CreateSequence("A", "ABCD-FGH")
+    seq_a.AttachView(self.ent.Select('rname=A,B,C,D,F,G,H'))
+    seq_b=seq.CreateSequence("B", "ABCD-FGH")
+    seq_b.AttachView(self.ent.Select('rname=A,B,C,D,F,G,H'))
+    a, b=seq.ViewsFromSequences(seq_a, seq_b)
+    string_a=''.join([r.one_letter_code for r in a.residues])
+    string_b=''.join([r.one_letter_code for r in b.residues])
+    self.assertEqual(string_a, 'ABCDFGH')
+    self.assertEqual(string_b, 'ABCDFGH')
+    
+  def testViewsFromSequences_03(self):
+    seq_a=seq.CreateSequence("A", "ABCD--GH")
+    seq_a.AttachView(self.ent.Select('rname=A,B,C,D,G,H'))
+    seq_b=seq.CreateSequence("B", "ABCD-FGH")
+    seq_b.AttachView(self.ent.Select('rname=A,B,C,D,F,G,H'))
+    a, b=seq.ViewsFromSequences(seq_a, seq_b)
+    string_a=''.join([r.one_letter_code for r in a.residues])
+    string_b=''.join([r.one_letter_code for r in b.residues])
+    self.assertEqual(string_a, 'ABCDGH')
+    self.assertEqual(string_b, 'ABCDGH')
+ 
+  def testViewsFromSequences_04(self):
+    seq_a=seq.CreateSequence("A", "ABCD-FGH")
+    seq_a.AttachView(self.ent.Select('rname=A,B,C,D,F,G,H'))
+    seq_b=seq.CreateSequence("B", "ABCD--GH")
+    seq_b.AttachView(self.ent.Select('rname=A,B,C,D,G,H'))
+    a, b=seq.ViewsFromSequences(seq_a, seq_b)
+    string_a=''.join([r.one_letter_code for r in a.residues])
+    string_b=''.join([r.one_letter_code for r in b.residues])
+    self.assertEqual(string_a, 'ABCDGH')
+    self.assertEqual(string_b, 'ABCDGH')
+    
+  def testViewsFromSequences_05(self):
+    seq_a=seq.CreateSequence("A", "ABCD-F--")
+    seq_a.AttachView(self.ent.Select('rname=A,B,C,D,F'))
+    seq_b=seq.CreateSequence("B", "ABCDEFGH")
+    seq_b.AttachView(self.ent.Select('rname=A,B,C,D,E,F,G,H'))
+    a, b=seq.ViewsFromSequences(seq_a, seq_b)
+    string_a=''.join([r.one_letter_code for r in a.residues])
+    string_b=''.join([r.one_letter_code for r in b.residues])
+    self.assertEqual(string_a, 'ABCDF')
+    self.assertEqual(string_b, 'ABCDF')
+    
+  def testViewsFromSequences_06(self):
+    seq_a=seq.CreateSequence("A", "--CD-FGH")
+    seq_a.AttachView(self.ent.Select('rname=C,D,F,G,H'))
+    seq_b=seq.CreateSequence("B", "ABCDEFGH")
+    seq_b.AttachView(self.ent.Select('rname=A,B,C,D,E,F,G,H'))
+    a, b=seq.ViewsFromSequences(seq_a, seq_b)
+    string_a=''.join([r.one_letter_code for r in a.residues])
+    string_b=''.join([r.one_letter_code for r in b.residues])
+    self.assertEqual(string_a, 'CDFGH')
+    self.assertEqual(string_b, 'CDFGH')
+
+
+  def testViewsFromSequences_07(self):
+    seq_a=seq.CreateSequence("A", "AB-D-FGH")
+    seq_a.AttachView(self.ent.Select('rname=A,B,D,F,G,H'))
+    seq_b=seq.CreateSequence("B", "AB-DEF-H")
+    seq_b.AttachView(self.ent.Select('rname=A,B,D,E,F,H'))
+    a, b=seq.ViewsFromSequences(seq_a, seq_b)
+    string_a=''.join([r.one_letter_code for r in a.residues])
+    string_b=''.join([r.one_letter_code for r in b.residues])
+    self.assertEqual(string_a, 'ABDFH')
+    self.assertEqual(string_b, 'ABDFH')
+
+
+  def testViewsFromSequences_08(self):
+    seq_a=seq.CreateSequence("A", "A-C-E-G")
+    seq_a.AttachView(self.ent.Select('rname=A,C,E,G'))
+    seq_b=seq.CreateSequence("B", "-B-D-H-")
+    seq_b.AttachView(self.ent.Select('rname=B,D,H'))
+    a, b=seq.ViewsFromSequences(seq_a, seq_b)
+    string_a=''.join([r.one_letter_code for r in a.residues])
+    string_b=''.join([r.one_letter_code for r in b.residues])
+    self.assertEqual(string_a, '')
+    self.assertEqual(string_b, '')
+
+  def testViewsFromSequences_09(self):
+    seq_a=seq.CreateSequence("A", "B-D-FGH")
+    seq_a.AttachView(self.ent.Select('rname=A,B,D,F,G,H'))
+    seq_a.SetSequenceOffset(1)
+    seq_b=seq.CreateSequence("B", "B-DEF-H")
+    seq_b.SetSequenceOffset(1)
+    seq_b.AttachView(self.ent.Select('rname=A,B,D,E,F,H'))
+    a, b=seq.ViewsFromSequences(seq_a, seq_b)
+    string_a=''.join([r.one_letter_code for r in a.residues])
+    string_b=''.join([r.one_letter_code for r in b.residues])
+    self.assertEqual(string_a, 'BDFH')
+    self.assertEqual(string_b, 'BDFH')
+suite = unittest.TestLoader().loadTestsFromTestCase(TestSeq)
+unittest.TextTestRunner().run(suite)
+
diff --git a/modules/seq/base/tests/test_sequence.cc b/modules/seq/base/tests/test_sequence.cc
index 666ebe6c4..97997f915 100644
--- a/modules/seq/base/tests/test_sequence.cc
+++ b/modules/seq/base/tests/test_sequence.cc
@@ -19,12 +19,36 @@
 #define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 
+#include <ost/mol/mol.hh>
+
 #include <ost/seq/sequence_handle.hh>
 #include <ost/seq/invalid_sequence.hh>
 #include <ost/seq/sequence_op.hh>
 
 using namespace ost;
 using namespace ost::seq;
+using namespace ost::mol;
+
+
+struct Fixture {
+  Fixture() {
+    eh = CreateEntity();
+    eh.SetName("TestEntity");
+    XCSEditor e=eh.RequestXCSEditor();
+    chain = e.InsertChain("A");
+    res1 = e.AppendResidue(chain, "ARG");
+    e.InsertAtom(res1, "CA",geom::Vec3(1,0,0));
+    res2 = e.AppendResidue(chain, "ARG");
+    e.InsertAtom(res2, "CA",geom::Vec3(0,1,0));
+    res3 = e.AppendResidue(chain, "ARG");
+    e.InsertAtom(res3, "CA",geom::Vec3(0,0,1));
+  }
+  EntityHandle eh;
+  ChainHandle  chain;
+  ResidueHandle res1;
+  ResidueHandle res2;
+  ResidueHandle res3;
+};
 
 BOOST_AUTO_TEST_SUITE( seq )
 
@@ -34,18 +58,64 @@ BOOST_AUTO_TEST_CASE(seq_triv)
   BOOST_CHECK_THROW(CreateSequence("S1", "1"), InvalidSequence);
   BOOST_CHECK_THROW(CreateSequence("S1", "."), InvalidSequence);
   BOOST_CHECK_THROW(CreateSequence("S1", " "), InvalidSequence);
+  SequenceHandle s=CreateSequence("S1","-afbcdefghijkLMNOPQRSTUV-");
+  BOOST_CHECK_EQUAL(s.GetString(),"-afbcdefghijkLMNOPQRSTUV-");
+  BOOST_CHECK_NO_THROW(s.SetString("-afc--de-f"));
+  BOOST_CHECK_EQUAL(s.GetString(),"-afc--de-f");
+  BOOST_CHECK_THROW(s.SetString("1"), InvalidSequence);
+}
+
+BOOST_AUTO_TEST_CASE(seq_length)
+{
+  SequenceHandle s=CreateSequence("S1", "abfcdadeaf");
+  BOOST_CHECK_EQUAL(s.GetLength(),10);
+  s=CreateSequence("S1", "-afc--de-f");
+  BOOST_CHECK_EQUAL(s.GetLength(),10);
+  s=CreateSequence("S1", "");
+  BOOST_CHECK_EQUAL(s.GetLength(),0);
+}
+
+BOOST_AUTO_TEST_CASE(seq_string)
+{
+  SequenceHandle s=CreateSequence("S1", "abfcdadeaf");
+  BOOST_CHECK_EQUAL(s.GetString(),"abfcdadeaf");
+  BOOST_CHECK_EQUAL(s.GetGaplessString(),"abfcdadeaf");
+  s=CreateSequence("S1", "-afc--de-f");
+  BOOST_CHECK_EQUAL(s.GetString(),"-afc--de-f");
+  BOOST_CHECK_EQUAL(s.GetGaplessString(),"afcdef");
+  s=CreateSequence("S1", "");
+  BOOST_CHECK_EQUAL(s.GetString(),"");
+  BOOST_CHECK_EQUAL(s.GetGaplessString(),"");
+}
+
+BOOST_AUTO_TEST_CASE(seq_onelettercode)
+{
+  SequenceHandle s=CreateSequence("S1", "abfcdadeaf");
+  BOOST_CHECK_EQUAL(s.GetOneLetterCode(0),'a');
+  BOOST_CHECK_EQUAL(s.GetOneLetterCode(3),'c');
+  BOOST_CHECK_EQUAL(s.GetOneLetterCode(9),'f');
+  BOOST_CHECK_THROW(s.GetOneLetterCode(-1),Error);
+  BOOST_CHECK_THROW(s.GetOneLetterCode(10),Error);
+  s=CreateSequence("S1", "-afc--de-f");
+  BOOST_CHECK_EQUAL(s.GetOneLetterCode(0),'-');
+  BOOST_CHECK_EQUAL(s.GetOneLetterCode(1),'a');
+  BOOST_CHECK_EQUAL(s.GetOneLetterCode(9),'f');
+  BOOST_CHECK_THROW(s.GetOneLetterCode(-1),Error);
+  BOOST_CHECK_THROW(s.GetOneLetterCode(10),Error);
+  s=CreateSequence("S1", "");
+  BOOST_CHECK_THROW(s.GetOneLetterCode(0),Error);
 }
 
 BOOST_AUTO_TEST_CASE(seq_getnum) 
 {
   SequenceHandle s=CreateSequence("S1", "-afc--de-f");
   BOOST_CHECK_THROW(s.GetResidueIndex(0), Error);
-  BOOST_CHECK(s.GetResidueIndex(1)==1-1);
-  BOOST_CHECK(s.GetResidueIndex(2)==2-1);
-  BOOST_CHECK(s.GetResidueIndex(3)==3-1);
-  BOOST_CHECK(s.GetResidueIndex(6)==4-1);
-  BOOST_CHECK(s.GetResidueIndex(7)==5-1);
-  BOOST_CHECK(s.GetResidueIndex(9)==6-1);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(1),1-1);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(2),2-1);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(3),3-1);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(6),4-1);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(7),5-1);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(9),6-1);
   BOOST_CHECK_THROW(s.GetResidueIndex(-1), Error);
   BOOST_CHECK_THROW(s.GetResidueIndex(10), Error);
 }
@@ -62,4 +132,85 @@ BOOST_AUTO_TEST_CASE(seq_getpos)
   BOOST_CHECK(s.GetPos(5)==9);
 }
 
+BOOST_AUTO_TEST_CASE(seq_offset)
+{
+  SequenceHandle s=CreateSequence("S1", "-afc--de-f");
+  SequenceHandle s2=CreateSequence("S1", "-afc--de-f");
+  s.SetSequenceOffset(2);
+  BOOST_CHECK_THROW(s.GetPos(-1), Error);
+  BOOST_CHECK_THROW(s.GetPos(0), Error);
+  BOOST_CHECK_THROW(s.GetPos(1), Error);
+  BOOST_CHECK_EQUAL(s.GetPos(2),1);
+  BOOST_CHECK_EQUAL(s.GetPos(2),s2.GetPos(2-2));
+  BOOST_CHECK_EQUAL(s.GetPos(5),6);
+  BOOST_CHECK_EQUAL(s.GetPos(5),s2.GetPos(5-2));
+  BOOST_CHECK_EQUAL(s.GetPos(7),9);
+  BOOST_CHECK_EQUAL(s.GetPos(7),s2.GetPos(7-2));
+  BOOST_CHECK_THROW(s.GetPos(8), Error);
+  BOOST_CHECK_THROW(s.GetResidueIndex(0), Error);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(1),2);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(1),s2.GetResidueIndex(1)+2);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(6), 5);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(6),s2.GetResidueIndex(6)+2);
+  BOOST_CHECK_THROW(s.GetResidueIndex(10), Error);
+
+  s.SetSequenceOffset(-1);
+  BOOST_CHECK_THROW(s.GetPos(-2), Error);
+  BOOST_CHECK_EQUAL(s.GetPos(-1), 1);
+  BOOST_CHECK_EQUAL(s.GetPos(0), 2);
+  BOOST_CHECK_EQUAL(s.GetPos(0),s2.GetPos(0+1));
+  BOOST_CHECK_EQUAL(s.GetPos(2), 6);
+  BOOST_CHECK_EQUAL(s.GetPos(2),s2.GetPos(2+1));
+  BOOST_CHECK_EQUAL(s.GetPos(4),9);
+  BOOST_CHECK_EQUAL(s.GetPos(4),s2.GetPos(4+1));
+  BOOST_CHECK_THROW(s.GetPos(5), Error);
+  BOOST_CHECK_THROW(s.GetResidueIndex(0), Error);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(1),-1);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(1),s2.GetResidueIndex(1)-1);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(6), 2);
+  BOOST_CHECK_EQUAL(s.GetResidueIndex(6),s2.GetResidueIndex(6)-1);
+  BOOST_CHECK_THROW(s.GetResidueIndex(10), Error);
+}
+
+BOOST_AUTO_TEST_CASE(seq_gaps)
+{
+  SequenceHandle s=CreateSequence("S1", "");
+  BOOST_CHECK_EQUAL(s.GetFirstNonGap(),-1);
+  BOOST_CHECK_EQUAL(s.GetLastNonGap(),-1);
+
+  s=CreateSequence("S1", "afcdef");
+  BOOST_CHECK_EQUAL(s.GetFirstNonGap(),0);
+  BOOST_CHECK_EQUAL(s.GetLastNonGap(),5);
+
+  s=CreateSequence("S1", "-afc--de-f-");
+  BOOST_CHECK_EQUAL(s.GetFirstNonGap(),1);
+  BOOST_CHECK_EQUAL(s.GetLastNonGap(),9);
+}
+
+BOOST_AUTO_TEST_CASE(seq_attach_view)
+{
+  Fixture f;
+  SequenceHandle s=CreateSequence("S1", "r-r");
+  BOOST_CHECK_EQUAL(s.HasAttachedView(),false);
+  BOOST_CHECK_EQUAL(s.GetAttachedView(),EntityView());
+  BOOST_CHECK_EQUAL(s.GetResidue(0),ResidueHandle());
+
+  EntityView v = f.eh.CreateFullView();
+  s.AttachView(v);
+  BOOST_CHECK_EQUAL(s.HasAttachedView(),true);
+  BOOST_CHECK_EQUAL(s.GetAttachedView(),v);
+
+  BOOST_CHECK_EQUAL(s.GetResidue(0),f.res1);
+  BOOST_CHECK_EQUAL(s.GetResidue(s.GetPos(0)),f.res1);
+  BOOST_CHECK_EQUAL(s.GetResidue(1),ResidueHandle());
+  BOOST_CHECK_EQUAL(s.GetResidue(2),f.res3);
+  BOOST_CHECK_EQUAL(s.GetResidue(s.GetPos(1)),f.res3);
+
+  v = EntityView();
+  s.AttachView(v);
+  BOOST_CHECK_EQUAL(s.HasAttachedView(),false);
+  BOOST_CHECK_EQUAL(s.GetAttachedView(),EntityView());
+  BOOST_CHECK_EQUAL(s.GetResidue(0),ResidueHandle());
+}
+
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/modules/seq/base/tests/testfiles/testprotein.pdb b/modules/seq/base/tests/testfiles/testprotein.pdb
new file mode 100644
index 000000000..e7733fdb8
--- /dev/null
+++ b/modules/seq/base/tests/testfiles/testprotein.pdb
@@ -0,0 +1,15 @@
+ATOM      1  CA  MET A   1      20.601  35.494  57.793  1.00 41.58           C  
+ATOM      2  CA  ARG A   2      19.396  31.903  58.033  1.00 34.35           C  
+ATOM      3  CA  LEU A   3      18.330  32.402  61.664  1.00 34.70           C  
+ATOM      4  CA  ASP A   4      17.099  35.980  61.411  1.00 37.42           C  
+ATOM      5  CA  GLY A   5      15.027  37.141  64.378  1.00 40.00           C  
+ATOM      6  CA  LYS A   6      15.354  33.938  66.391  1.00 38.75           C  
+ATOM      7  CA  THR A   7      16.484  33.152  69.925  1.00 31.14           C  
+ATOM      8  CA  ALA A   8      18.759  30.274  70.854  1.00 29.72           C  
+ATOM      9  CA  LEU A   9      19.784  28.923  74.261  1.00 26.72           C  
+ATOM     10  CA  ILE A  10      23.077  27.016  74.090  1.00 24.46           C  
+ATOM     11  CA  THR A  11      24.256  25.247  77.240  1.00 28.56           C  
+ATOM     12  CA  GLY A  12      27.934  25.121  78.150  1.00 29.86           C  
+ATOM     13  CA  SER A  13      28.721  27.662  75.443  1.00 33.66           C  
+ATOM     14  CA  ALA A  14      31.320  29.688  77.335  1.00 36.95           C  
+ATOM     15  CA  ARG A  15      34.025  27.749  75.511  1.00 38.19           C  
diff --git a/scripts/init.py b/scripts/init.py
index 020a66079..6df88ea01 100644
--- a/scripts/init.py
+++ b/scripts/init.py
@@ -36,7 +36,6 @@ def _InitPanels(app):
   panels.AddWidgetToPool('ost.gui.RemoteLoader', -1)
   panels.AddWidgetToPool('ost.gui.SceneWin', 1)
   panels.AddWidgetToPool('ost.gui.SequenceViewer', 1)
-  panels.AddWidgetToPool('ost.gui.SequenceViewerV2', 1)
   if not panels.Restore("ui/perspective/panels"):
     panels.AddWidget(gui.PanelPosition.LEFT_PANEL, app.scene_win)
     panels.AddWidgetByName(gui.PanelPosition.LEFT_PANEL, 
-- 
GitLab