diff --git a/modules/io/pymod/__init__.py b/modules/io/pymod/__init__.py
index 82ab97c27b96400ea16d1bf5db285af1fea57c5b..996ff1ffcb76a3dddbd6b8b08bbee7e73b72fbe3 100644
--- a/modules/io/pymod/__init__.py
+++ b/modules/io/pymod/__init__.py
@@ -52,21 +52,27 @@ def LoadPDB(filename, restrict_chains="", no_hetatms=False,
     flags|=PDB.NO_HETATMS
   if join_spread_atom_records:
     flags|=PDB.JOIN_SPREAD_ATOM_RECORDS
-  reader.SetFlags(flags)
-  if load_multi:
-    ent_list=[]
-    while reader.HasNext():
-      ent=mol.CreateEntity()
-      reader.Import(ent, restrict_chains)
-      conop_inst.ConnectAll(builder, ent, 0)
-      ent_list.append(ent)
-    return ent_list
-  else:
-    ent=mol.CreateEntity()    
-    if reader.HasNext():
-      reader.Import(ent, restrict_chains)
-      conop_inst.ConnectAll(builder, ent, 0)
-    return ent
+  try:
+    PDB.PushFlags(PDB.Flags() | flags)
+    if load_multi:
+      ent_list=[]
+      while reader.HasNext():
+        ent=mol.CreateEntity()
+        reader.Import(ent, restrict_chains)
+        conop_inst.ConnectAll(builder, ent, 0)
+        ent_list.append(ent)
+      PDB.PopFlags()
+      return ent_list
+    else:
+      ent=mol.CreateEntity()    
+      if reader.HasNext():
+        reader.Import(ent, restrict_chains)
+        conop_inst.ConnectAll(builder, ent, 0)
+      PDB.PopFlags()
+      return ent
+  except:
+    PDB.PopFlags()
+    raise
 
 def SavePDB(models, filename):
   """
diff --git a/modules/io/pymod/export_pdb_io.cc b/modules/io/pymod/export_pdb_io.cc
index 6cc80b813ca1c95fca26604b91f93012684390e4..fe2a3a75f0635e36dbab85cc4157bacb696151d6 100644
--- a/modules/io/pymod/export_pdb_io.cc
+++ b/modules/io/pymod/export_pdb_io.cc
@@ -31,26 +31,38 @@ BOOST_PYTHON_FUNCTION_OVERLOADS(load_PDB_ov, LoadPDB, 1, 2)
 
 void (PDBWriter::*write_a)(const mol::EntityHandle&)=&PDBWriter::Write;
 void (PDBWriter::*write_b)(const mol::EntityView&)=&PDBWriter::Write;
+
+namespace {
+  void push_flags(unsigned int x) {PDB::PushFlags(x);}
+  unsigned int flags() {return PDB::Flags();}
+  void pop_flags() {PDB::PopFlags();}
+}
+
 void export_pdb_io()
 {
-  enum_<PDB::Type>("PDB")
-    .value("NO_HETATMS", PDB::NO_HETATMS)
-    .value("SKIP_FAULTY_RECORDS", PDB::SKIP_FAULTY_RECORDS)
-    .value("WRITE_MULTIPLE_MODELS", PDB::WRITE_MULTIPLE_MODELS)
-    .value("JOIN_SPREAD_ATOM_RECORDS", PDB::JOIN_SPREAD_ATOM_RECORDS)
-    .value("SEQUENTIAL_ATOM_IMPORT", PDB::SEQUENTIAL_ATOM_IMPORT)
-  ;
+  {
+    scope pdb_scope=class_<PDB>("PDB",no_init)
+      .def("PushFlags",&PDB::PushFlags)
+      .staticmethod("PushFlags")
+      .def("Flags",&PDB::Flags)
+      .staticmethod("Flags")
+      .def("PopFlags",&PDB::PopFlags)
+      .staticmethod("PopFlags")
+      ;
+    pdb_scope.attr("NO_HETATMS")=PDB::NO_HETATMS;
+    pdb_scope.attr("SKIP_FAULTY_RECORDS")=PDB::SKIP_FAULTY_RECORDS;
+    pdb_scope.attr("WRITE_MULTIPLE_MODELS")=PDB::WRITE_MULTIPLE_MODELS;
+    pdb_scope.attr("JOIN_SPREAD_ATOM_RECORDS")=PDB::JOIN_SPREAD_ATOM_RECORDS;
+  }
+
   class_<PDBReader, boost::noncopyable>("PDBReader", init<String>())
     .def("HasNext", &PDBReader::HasNext)
     .def("Import", &PDBReader::Import, 
          X_import(args("entity", "restrict_chains")))
-    .def("SetFlags", &PDBReader::SetFlags)
-    .def("GetSequentialAtoms", &PDBReader::GetSequentialAtoms)
   ;
   
   class_<PDBWriter, boost::noncopyable>("PDBWriter", init<String>())
     .def("Write", write_a)
     .def("Write", write_b)    
-    .def("SetFlags", &PDBWriter::SetFlags)
   ;
 }
diff --git a/modules/io/pymod/wrap_io.cc b/modules/io/pymod/wrap_io.cc
index 79920189ef60ba1cb71c122bb566907291646bef..b04d3ac78ab729a8125fd258f9b7de89c2f15653 100644
--- a/modules/io/pymod/wrap_io.cc
+++ b/modules/io/pymod/wrap_io.cc
@@ -28,6 +28,7 @@ using namespace boost::python;
 #include <ost/io/seq/save.hh>
 #include <ost/io/mol/entity_io_pdb_handler.hh>
 #include <ost/io/mol/entity_io_crd_handler.hh>
+#include <ost/io/mol/entity_io_mae_handler.hh>
 #include <ost/io/mol/entity_io_sdf_handler.hh>
 #include <ost/io/mol/pdb_reader.hh>
 #include <ost/io/mol/dcd_io.hh>
@@ -120,6 +121,9 @@ BOOST_PYTHON_MODULE(_io)
   def("LoadCHARMMTraj",load_dcd3);
   def("LoadCHARMMTraj",load_dcd4);
   def("SaveCHARMMTraj",SaveCHARMMTraj,save_charmm_trj_ov());
+
+  def("LoadMAE", &LoadMAE);
+
   export_pdb_io();
 #if OST_IMG_ENABLED  
   export_map_io();
diff --git a/modules/io/src/io_manager.cc b/modules/io/src/io_manager.cc
index 23ab54bd29a2bc3efe72085ac9f9242b80c7a69f..b03169d8c84e49f80a7af74c23cf2780d20928b3 100644
--- a/modules/io/src/io_manager.cc
+++ b/modules/io/src/io_manager.cc
@@ -20,6 +20,7 @@
 #include <ost/io/mol/entity_io_pdb_handler.hh>
 #include <ost/io/mol/entity_io_crd_handler.hh>
 #include <ost/io/mol/entity_io_sdf_handler.hh>
+#include <ost/io/mol/entity_io_mae_handler.hh>
 #include <ost/io/seq/fasta_io_handler.hh>
 #include <ost/io/seq/promod_io_handler.hh>
 #include <ost/io/mol/surface_io_msms_handler.hh>
@@ -43,6 +44,7 @@ IOManager::IOManager()
   RegisterFactory(EntityIOHandlerFactoryBaseP(new EntityIOPDBHandlerFactory));
   RegisterFactory(EntityIOHandlerFactoryBaseP(new EntityIOCRDHandlerFactory));
   RegisterFactory(EntityIOHandlerFactoryBaseP(new EntityIOSDFHandlerFactory));
+  RegisterFactory(EntityIOHandlerFactoryBaseP(new EntityIOMAEHandlerFactory));
   RegisterFactory(SequenceIOHandlerFactoryBasePtr(new FastaIOHandlerFactory));  
   RegisterFactory(SequenceIOHandlerFactoryBasePtr(new ClustalIOHandlerFactory));  
   RegisterFactory(SequenceIOHandlerFactoryBasePtr(new PromodIOHandlerFactory));    
diff --git a/modules/io/src/mol/CMakeLists.txt b/modules/io/src/mol/CMakeLists.txt
index b3fd346b6e87552242a509f853a0eb5ff093fd38..772a0c89c5963a7efb97004895c9736dfd29d206 100644
--- a/modules/io/src/mol/CMakeLists.txt
+++ b/modules/io/src/mol/CMakeLists.txt
@@ -1,32 +1,35 @@
 set(OST_IO_MOL_SOURCES
+dcd_io.cc
 entity_io_crd_handler.cc	
-pdb_reader.cc
+entity_io_mae_handler.cc	
 entity_io_pdb_handler.cc	
-pdb_writer.cc
 entity_io_sdf_handler.cc	
-save_entity.cc
 load_entity.cc
-surface_io_msms_handler.cc
 load_surface.cc
-dcd_io.cc
+pdb_io.cc
+pdb_reader.cc
+pdb_writer.cc
+save_entity.cc
 star_parser.cc
+surface_io_msms_handler.cc
 PARENT_SCOPE
 )
 
 set(OST_IO_MOL_HEADERS
-star_parser.hh
 dcd_io.hh
+entity_io_handler.hh		
 entity_io_crd_handler.hh	
+entity_io_mae_handler.hh	
+entity_io_pdb_handler.hh	
+entity_io_sdf_handler.hh	
+load_entity.hh			
+load_surface.hh			
 pdb_io.hh
-entity_io_handler.hh		
 pdb_reader.hh
-entity_io_pdb_handler.hh	
 pdb_writer.hh
-entity_io_sdf_handler.hh	
 save_entity.hh
-load_entity.hh			
 surface_io_handler.hh
-load_surface.hh			
+star_parser.hh
 surface_io_msms_handler.hh
 PARENT_SCOPE
 )
diff --git a/modules/io/src/mol/dcd_io.cc b/modules/io/src/mol/dcd_io.cc
index efe9f1dfb368cc888c5785279af00ee8510a3fb7..6fd936c42fc15ac93d6c3c753a3f76fcc0aeaf70 100644
--- a/modules/io/src/mol/dcd_io.cc
+++ b/modules/io/src/mol/dcd_io.cc
@@ -22,6 +22,8 @@
 */
 
 #include <fstream>
+#include <algorithm>
+
 #include <boost/iostreams/filter/gzip.hpp>
 #include <boost/filesystem/convenience.hpp>
 
@@ -58,12 +60,20 @@ struct DCDHeader {
   int t_atom_count,f_atom_count, atom_count;
 };
 
-mol::CoordGroupHandle load_dcd(const mol::AtomHandleList& alist,
+bool less_index(const mol::AtomHandle& a1, const mol::AtomHandle& a2)
+{
+  return a1.GetIndex()<a2.GetIndex();
+}
+
+mol::CoordGroupHandle load_dcd(const mol::AtomHandleList& alist2,
 			       const String& trj_fn,
 			       unsigned int stride)
 {
   Profile profile_load("LoadCHARMMTraj");
 
+  mol::AtomHandleList alist(alist2);
+  std::sort(alist.begin(),alist.end(),less_index);
+
   bool gap_flag = true;
 
   boost::filesystem::path trj_f(trj_fn);
@@ -121,7 +131,7 @@ mol::CoordGroupHandle load_dcd(const mol::AtomHandleList& alist,
   header.f_atom_count=header.icntrl[8];
   header.atom_count=header.t_atom_count-header.f_atom_count;
 
-  LOGN_MESSAGE("LoadCHARMMTraj: " << header.num << " trajectories with " 
+  LOGN_DEBUG("LoadCHARMMTraj: " << header.num << " trajectories with " 
                << header.atom_count << " atoms (" << header.f_atom_count 
                << " fixed) each");
 
@@ -136,7 +146,8 @@ mol::CoordGroupHandle load_dcd(const mol::AtomHandleList& alist,
   std::vector<geom::Vec3> clist(header.t_atom_count);
   std::vector<float> xlist(header.t_atom_count);
 
-  for(int i=0;i<header.num;++i) {
+  int i=0;
+  for(;i<header.num;++i) {
     if(skip_flag) ff.seekg(14*4,std::ios_base::cur);
     // read each frame
     if(!ff) {
@@ -169,9 +180,9 @@ mol::CoordGroupHandle load_dcd(const mol::AtomHandleList& alist,
     for(uint j=0;j<clist.size();++j) {
       clist[j].SetZ(xlist[j]);
     }
-    if(i%stride) {
-      cg.AddFrame(clist);
-    }
+
+    cg.AddFrame(clist);
+
   }
 
   ff.get();
@@ -179,6 +190,9 @@ mol::CoordGroupHandle load_dcd(const mol::AtomHandleList& alist,
     LOGN_VERBOSE("LoadCHARMMTraj: unexpected trailing file data, bytes read: " 
                  << ff.tellg());
   }
+
+  LOGN_VERBOSE("Loaded " << cg.GetFrameCount() << " frames with " << cg.GetAtomCount() << " atoms each");
+
   return cg;
 }
 
@@ -188,6 +202,7 @@ mol::CoordGroupHandle LoadCHARMMTraj(const String& crd_fn,
                                      const String& trj_fn,
                                      unsigned int stride)
 {
+  if(stride==0) stride=1;
   boost::filesystem::path crd_f(crd_fn);
 
   // first the coordinate reference file
@@ -197,21 +212,18 @@ mol::CoordGroupHandle LoadCHARMMTraj(const String& crd_fn,
   std::vector<mol::AtomHandle> alist;
   if(boost::filesystem::extension(crd_f)==".pdb") {
     PDBReader reader(crd_f);
-    reader.SetFlags(PDB::SEQUENTIAL_ATOM_IMPORT);
     LOGN_MESSAGE("importing coordinate data");
     reader.Import(ent);
-    alist = reader.GetSequentialAtoms();
   } else if (boost::filesystem::extension(crd_f)==".crd") {
     CRDReader reader(crd_f);
     LOGN_MESSAGE("importing coordinate data");
     reader.Import(ent);
-    alist = reader.GetSequentialAtoms();
   } else {
     throw(IOException("unsupported coordinate file format"));
   }
   conop::Conopology::Instance().ConnectAll(builder,ent);
 
-  return load_dcd(alist,trj_fn,stride);
+  return load_dcd(ent.GetAtomList(),trj_fn,stride);
 }
 
 
diff --git a/modules/io/src/mol/entity_io_crd_handler.cc b/modules/io/src/mol/entity_io_crd_handler.cc
index ce4a1679b765cc8aa13fbddb873b82c33f427871..cfbb7efccbc7986a61b903409c90755b4fe17a1f 100644
--- a/modules/io/src/mol/entity_io_crd_handler.cc
+++ b/modules/io/src/mol/entity_io_crd_handler.cc
@@ -43,9 +43,6 @@ namespace ost { namespace io {
 
 using boost::format;
 
-String FORMAT_NAME_STRING;
-String FORMAT_DESCRIPTION_STRING;
-
 CRDReader::CRDReader(const boost::filesystem::path& loc):
   sequential_atom_list_(),
   curr_chain_(),
diff --git a/modules/io/src/mol/entity_io_mae_handler.cc b/modules/io/src/mol/entity_io_mae_handler.cc
new file mode 100755
index 0000000000000000000000000000000000000000..e41fa029c98e38c157b2c729de228f71aa5e7bbf
--- /dev/null
+++ b/modules/io/src/mol/entity_io_mae_handler.cc
@@ -0,0 +1,345 @@
+//------------------------------------------------------------------------------
+// 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
+ */
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <vector>
+#include <string>
+
+#include <ctype.h>
+
+#include <boost/iostreams/filter/gzip.hpp>
+#include <boost/filesystem/convenience.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/format.hpp>
+#include <boost/regex.hpp>
+
+#include <ost/log.hh>
+#include <ost/conop/conop.hh>
+#include <ost/mol/xcs_editor.hh>
+#include <ost/profile.hh>
+
+#include <ost/io/io_exception.hh>
+#include <ost/io/swap_util.hh>
+
+#include "entity_io_mae_handler.hh"
+
+namespace ost { namespace io {
+
+using boost::format;
+
+  namespace {
+
+    std::vector<std::string> tokenize(const std::string& line)
+    {
+      std::vector<std::string> nrvo;
+      bool in_string=false;
+      int p0=0;
+      for(int p1=1;p1<line.size();++p1) {
+        if(in_string) {
+          if(line[p1]=='"') {
+            in_string=false;
+            nrvo.push_back(line.substr(p0,p1-p0));
+            ++p1;
+            p0=p1;
+            while(isspace(line[p1]) and p1<line.size()) {++p0;++p1;}
+            --p0; --p1;
+          }
+        } else {
+          if(isspace(line[p1])) {
+            nrvo.push_back(line.substr(p0+1,p1-p0-1));
+            ++p1;
+            p0=p1;
+            while(isspace(line[p1]) and p1<line.size()) {++p0;++p1;}
+            --p0; --p1;
+          } else if(line[p1]=='"') {
+            in_string=true;
+            p0=p1+1;
+          }
+        }
+      }
+      return nrvo;
+    }
+
+  }
+
+MAEReader::MAEReader(const boost::filesystem::path& loc):
+  curr_chain_(),
+  curr_residue_(),
+  chain_count_(0),
+  residue_count_(0),
+  atom_count_(0),
+  infile_(loc),
+  in_()
+{
+  if (boost::iequals(".gz", boost::filesystem::extension(loc))) {
+    in_.push(boost::iostreams::gzip_decompressor());    
+  }
+  in_.push(infile_);  
+  if(!infile_) throw IOException("could not open "+loc.string());
+}
+
+void MAEReader::Import(mol::EntityHandle& ent)
+{
+  Profile profile_import("MAEReader::Import");
+
+  static const boost::regex r_ct_block("f_m_ct +\\{");
+  static const boost::regex r_atom_block("m_atom\\[.*\\] +\\{");
+  static const boost::regex r_delim(":::");
+
+  String line;
+  bool in_ct_block=false;
+  bool in_atom_block=false;
+  bool parsing_atoms=false;
+  bool debug=true;
+  std::vector<std::string> prop_list;
+  int i_atom_name=-1;
+  int i_atom_xpos=-1;
+  int i_atom_ypos=-1;
+  int i_atom_zpos=-1;
+  int i_res_name=-1;
+  int i_res_num=-1;
+  int i_chain_name=-1;
+
+  mol::XCSEditor editor=ent.RequestXCSEditor(mol::BUFFERED_EDIT);
+
+  while(std::getline(in_,line)) {
+    line = boost::trim_copy(line);
+    if(in_ct_block) {
+      if(in_atom_block) {
+        if(parsing_atoms) {
+          if(boost::regex_match(line,r_delim)) {
+            std::cerr << "stopping atom parsing" << std::endl;
+            parsing_atoms=false;
+          } else {
+            // parsing atom line
+            std::vector<std::string> tokens=tokenize(line);
+            add_atom(ent,editor,
+                     tokens[i_atom_name],
+                     tokens[i_atom_xpos],
+                     tokens[i_atom_ypos],
+                     tokens[i_atom_zpos],
+                     tokens[i_res_name],
+                     tokens[i_res_num],
+                     tokens[i_chain_name]);
+          }
+        } else { // not parsing atoms
+          if(boost::regex_match(line,r_delim)) {
+            if(i_atom_name==-1 ||
+               i_atom_xpos==-1 ||
+               i_atom_ypos==-1 ||
+               i_atom_zpos==-1 ||
+               i_res_name==-1 ||
+               i_res_num==-1 ||
+               i_chain_name==-1) {
+              throw IOException("missing atom prop");
+            }
+            std::cerr << "starting atom parsing" << std::endl;
+            parsing_atoms=true;
+          } else if(line[0]=='}') {
+            std::cerr << "exiting atom block" << std::endl;
+            in_atom_block=false;
+          } else {
+            // parsing property line
+            int pid=prop_list.size();
+            prop_list.push_back(line);
+            std::cerr << "found property '" << prop_list.back() << "'" << std::endl;
+            if(line=="s_m_pdb_atom_name") i_atom_name=pid;
+            else if(line=="r_m_x_coord") i_atom_xpos=pid;
+            else if(line=="r_m_y_coord") i_atom_ypos=pid;
+            else if(line=="r_m_z_coord") i_atom_zpos=pid;
+            else if(line=="s_m_pdb_residue_name") i_res_name=pid;
+            else if(line=="i_m_residue_number") i_res_num=pid;
+            else if(line=="s_m_pdb_segment_name") i_chain_name=pid;
+          }
+        }
+      } else { // not in atom block
+        if(boost::regex_match(line,r_atom_block)) {
+          std::cerr << "entering atom block" << std::endl;
+          in_atom_block=true;
+        } else if(line[0]=='}') {
+          std::cerr << "exiting ct block" << std::endl;
+          in_ct_block=false;
+        }
+      }
+    } else { // not in ct block
+      if(boost::regex_match(line,r_ct_block)) {
+        std::cerr << "entering ct block" << std::endl;
+        in_ct_block=true;
+      }
+    }
+  }
+
+  LOGN_MESSAGE("imported " << chain_count_ << " chains, " << residue_count_
+                << " residues, " << atom_count_ << " atoms");  
+}
+
+
+void MAEReader::add_atom(mol::EntityHandle ent,
+                         mol::XCSEditor& editor,
+                         const std::string& aname, 
+                         const std::string& s_axpos, 
+                         const std::string& s_aypos, 
+                         const std::string& s_azpos, 
+                         const std::string& rname,
+                         const std::string& s_rnum,
+                         const std::string& cname)
+{
+  std::string ele = aname.substr(0,1);
+  int irnum = boost::lexical_cast<int>(s_rnum);
+  geom::Vec3 apos(boost::lexical_cast<Real>(s_axpos),
+                  boost::lexical_cast<Real>(s_aypos),
+                  boost::lexical_cast<Real>(s_azpos));
+
+  mol::ResidueKey rkey(rname);
+  
+  // some postprocessing
+  LOGN_TRACE( "cname: [" << cname << "]" );
+
+  mol::ResNum rnum(irnum);
+  
+  // determine chain and residue update
+  bool update_chain=false;
+  bool update_residue=false;
+  if(!curr_chain_) {
+    update_chain=true;
+    update_residue=true;
+  } else if(curr_chain_.GetName()!=cname) {
+    update_chain=true;
+    update_residue=true;
+  }
+
+  if(!curr_residue_) {
+    update_residue=true;
+  } else if(curr_residue_.GetNumber()!=rnum) {
+    update_residue=true;
+  }
+
+  if(update_chain) {  
+    if (!(curr_chain_=ent.FindChain(cname))) {
+      LOGN_DUMP("new chain " << cname);      
+      curr_chain_=editor.InsertChain(cname);
+      ++chain_count_;      
+    }
+  }
+
+  if(update_residue) {
+    if (!(curr_residue_=curr_chain_.FindResidue(rnum))) {
+      LOGN_DUMP("new residue " << rkey << " " << rnum);
+      curr_residue_=editor.AppendResidue(curr_chain_, rkey, rnum);
+      assert(curr_residue_.IsValid());
+      ++residue_count_;
+    }
+  }
+
+  // finally add atom
+  LOGN_DUMP("adding atom " << aname << " (" << ele << ") @" << apos);
+  mol::AtomProp aprop;
+  aprop.element=ele;
+  aprop.radius=conop::Conopology::Instance().GetDefaultAtomRadius(ele);
+  aprop.is_hetatm=false;
+  aprop.b_factor=0.0;
+  aprop.occupancy=1.0;
+  mol::AtomHandle ah = editor.InsertAtom(curr_residue_, aname, apos, aprop);
+}
+  
+
+
+
+bool EntityIOMAEHandler::RequiresBuilder() const
+{
+  return true;
+}
+
+void EntityIOMAEHandler::Import(mol::EntityHandle& ent,
+                                const boost::filesystem::path& loc)
+{
+  MAEReader reader(loc);
+  reader.Import(ent);
+}
+
+void EntityIOMAEHandler::Export(const mol::EntityView& ent,
+                                const boost::filesystem::path& loc) const
+{
+}
+
+namespace {
+
+bool mae_handler_is_responsible_for(const boost::filesystem::path& loc,
+                                    const String& type) {
+  if(type=="auto") {
+    String match_suf_string=loc.string();
+	std::transform(match_suf_string.begin(),match_suf_string.end(),match_suf_string.begin(),tolower);
+    if( detail::FilenameEndsWith(match_suf_string,".mae") || detail::FilenameEndsWith(match_suf_string,".mae.gz") ) {
+      return true;
+    }
+  } else if(type=="mae") {
+    return true;
+  }
+
+  return false;
+}
+
+}
+
+bool EntityIOMAEHandler::ProvidesImport(const boost::filesystem::path& loc,
+                                        const String& type)
+{
+  return mae_handler_is_responsible_for(loc, type);
+}
+
+bool EntityIOMAEHandler::ProvidesExport(const boost::filesystem::path& loc,
+                                        const String& type)
+{
+  return false;
+}
+
+mol::EntityHandle LoadMAE(const String& file_name) 
+{
+  Profile profile_load("LoadMAE");
+  conop::BuilderP builder = conop::Conopology::Instance().GetBuilder();  
+  MAEReader reader(file_name);
+  mol::EntityHandle ent=mol::CreateEntity();
+  mol::XCSEditor editor=ent.RequestXCSEditor(mol::BUFFERED_EDIT);
+  reader.Import(ent);
+  conop::Conopology::Instance().ConnectAll(builder,ent);    
+  return ent;
+}
+
+
+void EntityIOMAEHandler::Import(mol::EntityHandle& ent, 
+                                std::istream& stream)
+{
+  throw IOException("MAE format does not support import from stream");
+}
+
+
+void EntityIOMAEHandler::Export(const mol::EntityView& ent, 
+                                std::ostream& stream) const
+{
+  throw IOException("MAE format does not support export to stream");
+}
+
+}} // ns
+
+
diff --git a/modules/io/src/mol/entity_io_mae_handler.hh b/modules/io/src/mol/entity_io_mae_handler.hh
new file mode 100755
index 0000000000000000000000000000000000000000..3924bd143a8930774276bbc2cb256df3821a51c5
--- /dev/null
+++ b/modules/io/src/mol/entity_io_mae_handler.hh
@@ -0,0 +1,83 @@
+//------------------------------------------------------------------------------
+// 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_IO_ENTITY_IO_PLUGIN_MAE_H
+#define OST_IO_ENTITY_IO_PLUGIN_MAE_H
+
+#include <ost/io/mol/entity_io_handler.hh>
+
+#include <boost/iostreams/filtering_stream.hpp>
+#include <boost/filesystem/fstream.hpp>
+
+namespace ost { namespace io {
+
+class DLLEXPORT_OST_IO MAEReader {
+public:
+  MAEReader(const boost::filesystem::path& loc);
+  
+  void Import(mol::EntityHandle& ent);
+
+private:
+
+  void add_atom(mol::EntityHandle ent,
+                mol::XCSEditor& editor,const std::string& s_aname, 
+                const std::string& s_axpos, 
+                const std::string& s_aypos, 
+                const std::string& s_azpos, 
+                const std::string& s_rname,
+                const std::string& s_rnum,
+                const std::string& s_cname);
+
+  mol::ChainHandle curr_chain_;
+  mol::ResidueHandle curr_residue_;
+  int chain_count_;
+  int residue_count_;
+  int atom_count_;
+  boost::filesystem::ifstream infile_;
+  boost::iostreams::filtering_stream<boost::iostreams::input>  in_;
+};
+
+class DLLEXPORT_OST_IO EntityIOMAEHandler: public EntityIOHandler {
+public:
+  virtual void Import(mol::EntityHandle& ent, const boost::filesystem::path& loc);
+  
+  virtual void Export(const mol::EntityView& ent, 
+                      const boost::filesystem::path& loc) const;
+                      
+  virtual void Import(mol::EntityHandle& ent, std::istream& stream);
+
+  virtual void Export(const mol::EntityView& ent, std::ostream& stream) const;
+  
+  static bool ProvidesImport(const boost::filesystem::path& loc, 
+                             const String& format="auto");
+  static bool ProvidesExport(const boost::filesystem::path& loc, 
+                             const String& format="auto");
+  virtual bool RequiresBuilder() const;
+
+  static String GetFormatName() { return String("Mae"); }
+  static String GetFormatDescription() { return String("MAEstro coordinate file format"); }
+};
+
+
+typedef EntityIOHandlerFactory<EntityIOMAEHandler> EntityIOMAEHandlerFactory;
+
+mol::EntityHandle DLLEXPORT_OST_IO LoadMAE(const String& file_name);
+
+}} // ns
+
+#endif
diff --git a/modules/io/src/mol/entity_io_pdb_handler.cc b/modules/io/src/mol/entity_io_pdb_handler.cc
index ca64835e7372b51d8b7089d0197ce47cb04c6f96..99b8ea49560a7dbe9ef2ca79ab9dbbc855c94dbe 100644
--- a/modules/io/src/mol/entity_io_pdb_handler.cc
+++ b/modules/io/src/mol/entity_io_pdb_handler.cc
@@ -50,9 +50,12 @@ void EntityIOPDBHandler::Export(const mol::EntityView& ent,
 {
   PDBWriter writer(loc);
   if (boost::iequals(boost::filesystem::extension(loc), ".pqr")) {
-    writer.SetFlags(PDB::PQR_FORMAT);
+    PDB::PushFlags(PDB::Flags() | PDB::PQR_FORMAT);
+    writer.Write(ent);
+    PDB::PopFlags();
+  } else {
+    writer.Write(ent);
   }
-  writer.Write(ent);
 }
 
 void EntityIOPDBHandler::Import(mol::EntityHandle& ent, 
diff --git a/modules/io/src/mol/pdb_io.hh b/modules/io/src/mol/pdb_io.hh
index 140db87e3648055a3bff689f18657da8cceb820e..d9f3bc78ee50813cff776e1efa76452ae7a071be 100644
--- a/modules/io/src/mol/pdb_io.hh
+++ b/modules/io/src/mol/pdb_io.hh
@@ -19,22 +19,32 @@
 #ifndef OST_IO_PDB_IO_HH
 #define OST_IO_PDB_IO_HH
 
+#include <stack>
+
 namespace ost { namespace io {
   
 /// \brief flags that incluence the behaviour of the PDBReader and PDBWriter
 struct PDB {
-  typedef enum {
+
+  struct S {
+    static S& I();
+    std::stack<unsigned int> fstack;
+  };
+
     /// \brief skip faulty records
-    /// 
     /// This flag tells the PDB loader to ignore faulty records. By default,
     /// faulty records abort import.
-    SKIP_FAULTY_RECORDS=1,
+  static const unsigned int SKIP_FAULTY_RECORDS;
+
     /// \brief do not import HETATM records
-    NO_HETATMS=2,
+  static const unsigned int NO_HETATMS;
+
     /// \brief enable writing of multiple models
-    WRITE_MULTIPLE_MODELS=4,
+  static const unsigned int WRITE_MULTIPLE_MODELS;
+
     /// \brief enable for PQR
-    PQR_FORMAT=8,
+  static const unsigned int PQR_FORMAT;
+
     /// \brief Join atom records into one residue, even if the atom records
     ///     are not sequential.
     /// 
@@ -57,20 +67,15 @@ struct PDB {
     /// 
     /// By default, the atom 550 will start a new residue instead of being
     /// joined with atoms 43-48 into one residue.
-    JOIN_SPREAD_ATOM_RECORDS=16,
-    //// \brief keep track of the order of atom records
-    /// 
-    /// This option is mostly useful in combination with 
-    /// PDB::JOIN_SPREAD_ATOM_RECORDS and CoordGroups.
-    /// 
-    /// The atoms are accessible via PDBReader::GetSequentialAtoms()
-    SEQUENTIAL_ATOM_IMPORT=32,
+  static const unsigned int JOIN_SPREAD_ATOM_RECORDS;
+
     /// \brief only import C-alpha atoms
-    CALPHA_ONLY=64
-  } Type; 
-};
+  static const unsigned int CALPHA_ONLY;
 
-typedef unsigned int PDBFlags;
+  static void PushFlags(unsigned int flags);
+  static unsigned int Flags();
+  static void PopFlags();
+};
 
 }}
 
diff --git a/modules/io/src/mol/pdb_reader.cc b/modules/io/src/mol/pdb_reader.cc
index ec0dbaccb37e140bd8227659455beee97f516ad3..1ea6f6da8e0c2456f6e4503cfe851e15bf17740d 100644
--- a/modules/io/src/mol/pdb_reader.cc
+++ b/modules/io/src/mol/pdb_reader.cc
@@ -62,19 +62,19 @@ mol::ResNum to_res_num(int num, char ins_code)
 }
 
 PDBReader::PDBReader(std::istream& instream):
-  infile_(), instream_(instream), flags_(0)
+  infile_(), instream_(instream)
 {
   this->Init(boost::filesystem::path(""));
 }
 
 PDBReader::PDBReader(const String& filename)
-  : infile_(filename), instream_(infile_), flags_(0)
+  : infile_(filename), instream_(infile_)
 {
   this->Init(boost::filesystem::path(filename));
 }
 
 PDBReader::PDBReader(const boost::filesystem::path& loc):
-  infile_(loc), instream_(infile_), flags_(0)
+  infile_(loc), instream_(infile_)
 {
   this->Init(loc);
 }
@@ -106,7 +106,7 @@ bool PDBReader::HasNext()
   while (std::getline(in_, curr_line_) && ++line_num_) {
      StringRef curr_line(curr_line_.c_str(), curr_line_.length());
      if (IEquals(curr_line.substr(0, 6), StringRef("ATOM  ", 6)) ||
-         (!(flags_ & PDB::NO_HETATMS) &&
+         (!(PDB::Flags() & PDB::NO_HETATMS) &&
           IEquals(curr_line.substr(0, 6),StringRef("HETATM ", 6))) ||
           IEquals(curr_line.substr(0, 6),StringRef("ANISOU ", 6)) ||
          IEquals(curr_line.substr(0, 6), StringRef("SHEET ", 6)) ||
@@ -123,6 +123,8 @@ bool PDBReader::HasNext()
 void PDBReader::Import(mol::EntityHandle& ent,
                        const String& restrict_chains)
 {
+  LOGN_DEBUG("PDBReader: current flags: " << PDB::Flags());
+
   Profile profile_import("PDBReader::Import");
   this->ClearState();
   // first read curr_line and then read next...
@@ -171,7 +173,7 @@ void PDBReader::Import(mol::EntityHandle& ent,
           continue;
         }
         if (IEquals(curr_line.substr(0, 6), StringRef("HETATM", 6))) {
-          if (flags_ & PDB::NO_HETATMS)
+          if (PDB::Flags() & PDB::NO_HETATMS)
             continue;
           LOGN_TRACE("processing HETATM entry");
           this->ParseAndAddAtom(curr_line, line_num_, ent, 
@@ -250,17 +252,6 @@ void PDBReader::ClearState()
   hard_end_=false;
   helix_list_.clear();
   strand_list_.clear();
-  sequential_atom_list_.clear();
-}
-
-std::vector<mol::AtomHandle> PDBReader::GetSequentialAtoms() const
-{
-  return sequential_atom_list_;
-}
-
-void PDBReader::SetFlags(PDBFlags flags)
-{
-  flags_=flags;
 }
 
 bool PDBReader::ParseAtomIdent(const StringRef& line, int line_num, 
@@ -276,7 +267,7 @@ bool PDBReader::ParseAtomIdent(const StringRef& line, int line_num,
 
   std::pair<bool, int> a_num=line.substr(6, 5).ltrim().to_int();
   if (!a_num.first) {
-    if (flags_ & PDB::SKIP_FAULTY_RECORDS) {
+    if (PDB::Flags() & PDB::SKIP_FAULTY_RECORDS) {
       return false;
     }
     throw IOException(str(format("invalid atom number on line %d") %line_num));
@@ -286,7 +277,7 @@ bool PDBReader::ParseAtomIdent(const StringRef& line, int line_num,
   res_name=line.substr(17, 3).trim();
   std::pair<bool, int> res_num=line.substr(22, 4).ltrim().to_int();;
   if (!res_num.first) {
-    if (flags_ & PDB::SKIP_FAULTY_RECORDS) {
+    if (PDB::Flags() & PDB::SKIP_FAULTY_RECORDS) {
       return false;
     }
     throw IOException(str(format("invalid res number on line %d") % line_num));
@@ -311,7 +302,7 @@ void PDBReader::ParseAnisou(const StringRef& line, int line_num,
   for (int i=0;i<6; ++i) {
     std::pair<bool, int> result=line.substr(29+i*7, 6).to_int();
     if (!result.first) {
-      if (flags_ & PDB::SKIP_FAULTY_RECORDS) {
+      if (PDB::Flags() & PDB::SKIP_FAULTY_RECORDS) {
         return;
       }
       throw IOException(str(format("invalid ANISOU record on line %d")%line_num));
@@ -320,7 +311,7 @@ void PDBReader::ParseAnisou(const StringRef& line, int line_num,
   }
   String aname(atom_name.str());
   if (!curr_residue_.IsValid()) {
-    if (flags_ & PDB::SKIP_FAULTY_RECORDS) {
+    if (PDB::Flags() & PDB::SKIP_FAULTY_RECORDS) {
       return;
     } 
     const char* fmt_str="invalid ANISOU record for inexistent atom on line %d";
@@ -328,7 +319,7 @@ void PDBReader::ParseAnisou(const StringRef& line, int line_num,
   }
   mol::AtomHandle atom=curr_residue_.FindAtom(aname);
   if (!atom.IsValid()) {
-    if (flags_ & PDB::SKIP_FAULTY_RECORDS) {
+    if (PDB::Flags() & PDB::SKIP_FAULTY_RECORDS) {
       return;
     } 
     const char* fmt_str="invalid ANISOU record for inexistent atom on line %d";
@@ -367,7 +358,7 @@ void PDBReader::ParseAndAddAtom(const StringRef& line, int line_num,
   for (int i=0;i<3; ++i) {
     std::pair<bool, float> result=line.substr(30+i*8, 8).ltrim().to_float();
     if (!result.first) {
-      if (flags_ & PDB::SKIP_FAULTY_RECORDS) {
+      if (PDB::Flags() & PDB::SKIP_FAULTY_RECORDS) {
         return;
       }
       throw IOException(str(format("invalid coordinate on line %d")%line_num));
@@ -432,24 +423,31 @@ void PDBReader::ParseAndAddAtom(const StringRef& line, int line_num,
   }
 
   if(update_chain) {
-    if (!(curr_chain_=ent.FindChain(s_chain))) {
+    curr_chain_=mol::ChainHandle();
+#if 0
+    // TODO: should this depend on JOIN_SPREAD as well?
+    if (PDB::Flags() & PDB::JOIN_SPREAD_ATOM_RECORDS) {
+      curr_chain_=ent.FindChain(s_chain);
+    }
+#else
+      curr_chain_=ent.FindChain(s_chain);
+#endif
+    if(!curr_chain_.IsValid()) {
       LOGN_DUMP("new chain " << s_chain);
       curr_chain_=editor.InsertChain(s_chain);
       ++chain_count_;
     }
+    assert(curr_chain_.IsValid());
   }
   if(update_residue) {
-    if (flags_ & PDB::JOIN_SPREAD_ATOM_RECORDS) {
+    curr_residue_=mol::ResidueHandle();
+    if (PDB::Flags() & PDB::JOIN_SPREAD_ATOM_RECORDS) {
       curr_residue_=curr_chain_.FindResidue(res_num);
-      if (!curr_residue_.IsValid()) {
-        LOGN_DUMP("new residue " << res_name << " " << res_num);
-        curr_residue_=editor.AppendResidue(curr_chain_, res_name.str(), res_num);
-        ++residue_count_; 
-      }
-    } else {
+    }
+    if (!curr_residue_.IsValid()) {
       LOGN_DUMP("new residue " << res_name << " " << res_num);
       curr_residue_=editor.AppendResidue(curr_chain_, res_name.str(), res_num);
-      ++residue_count_;      
+      ++residue_count_; 
     }
     assert(curr_residue_.IsValid());
   }
@@ -493,16 +491,22 @@ void PDBReader::ParseAndAddAtom(const StringRef& line, int line_num,
     } else {
       mol::AtomHandle ah=editor.InsertAltAtom(curr_residue_, aname,
                                               String(1, alt_loc), apos, aprop);
-      if (flags_ & PDB::SEQUENTIAL_ATOM_IMPORT) {
+      /*
+	for now, this is not needed - the cg will use an global atom id sorted
+	list insteadx
+      if (PDB::Flags() & PDB::SEQUENTIAL_ATOM_IMPORT) {
         sequential_atom_list_.push_back(ah);
       }
+      */
       ++atom_count_;
     }
   } else {
     mol::AtomHandle ah = editor.InsertAtom(curr_residue_, aname, apos, aprop);
-    if (flags_ & PDB::SEQUENTIAL_ATOM_IMPORT) {
+    /*
+    if (PDB::Flags() & PDB::SEQUENTIAL_ATOM_IMPORT) {
       sequential_atom_list_.push_back(ah);
     }
+    */
     ++atom_count_;
   }
 }
diff --git a/modules/io/src/mol/pdb_reader.hh b/modules/io/src/mol/pdb_reader.hh
index 5c85e23a14a88e80d6229f728171914b9deaa6b9..6d9f715c6cd9071a471d33427464533bb6b29294 100644
--- a/modules/io/src/mol/pdb_reader.hh
+++ b/modules/io/src/mol/pdb_reader.hh
@@ -47,17 +47,7 @@ public:
   bool HasNext();
 
   void Import(mol::EntityHandle& ent,
-              const String& restrict_chains="");
-  void SetFlags(PDBFlags flags);
-  
-  /// \brief get list of atoms
-  /// 
-  /// The atom handles reflect the order of atom records in the PDb files. This 
-  /// is used to synchronize PDB and coordgroup io.
-  /// 
-  /// By default, the atom list is empty, The PDB::SEQUENTIAL_ATOM_IMPORT flag
-  /// must be set.
-  std::vector<mol::AtomHandle> GetSequentialAtoms() const;
+	      const String& restrict_chains="");
 
 private:
   void ClearState();
@@ -90,8 +80,7 @@ private:
   std::istream& instream_;
   boost::iostreams::filtering_stream<boost::iostreams::input>  in_;
   String curr_line_;
-  std::vector<mol::AtomHandle> sequential_atom_list_;
-  PDBFlags flags_;
+  
   // this needs to be set to true for reading pqr
   // file (i.e. pdb formatted file with charges in occupacy
   // column, and radii in b-factor column)
diff --git a/modules/io/src/mol/pdb_writer.cc b/modules/io/src/mol/pdb_writer.cc
index 9251f42b227ae6d8667724689f0b3a68d8dc81bd..a6b32d39636d278386fada049323629d4346bbf1 100644
--- a/modules/io/src/mol/pdb_writer.cc
+++ b/modules/io/src/mol/pdb_writer.cc
@@ -123,27 +123,20 @@ private:
 
 PDBWriter::PDBWriter(std::ostream& stream):
   outfile_(), outstream_(stream)
-{
-
-}
+{}
 
 PDBWriter::PDBWriter(const boost::filesystem::path& filename):
-  outfile_(filename.file_string().c_str()), outstream_(outfile_), mol_count_(0),
-  flags_(0)
-{
-
-}
+  outfile_(filename.file_string().c_str()), outstream_(outfile_), mol_count_(0)
+{}
 
 PDBWriter::PDBWriter(const String& filename):
-  outfile_(filename.c_str()), outstream_(outfile_),  mol_count_(0), flags_(0)
-{
-
-}
+  outfile_(filename.c_str()), outstream_(outfile_),  mol_count_(0)
+{}
 
 void PDBWriter::WriteModelLeader()
 {
   ++mol_count_;
-  if (flags_ & PDB::WRITE_MULTIPLE_MODELS) {
+  if (PDB::Flags() & PDB::WRITE_MULTIPLE_MODELS) {
     outstream_ << "MODEL     " << mol_count_ << std::endl;
   } else if (mol_count_>1) {
     throw IOException("Please enable the PDB::WRITE_MULTIPLE_MODELS flag to "
@@ -153,7 +146,7 @@ void PDBWriter::WriteModelLeader()
 
 void PDBWriter::WriteModelTrailer()
 {
-  if (flags_ & PDB::WRITE_MULTIPLE_MODELS) {
+  if (PDB::Flags() & PDB::WRITE_MULTIPLE_MODELS) {
     outstream_ << "ENDMDL" << std::endl;
   }
 }
@@ -163,18 +156,13 @@ void PDBWriter::WriteModel(H ent)
 {
   this->WriteModelLeader();
   PDBWriterImpl writer(outstream_);
-  if (flags_ & PDB::PQR_FORMAT) {
+  if (PDB::Flags() & PDB::PQR_FORMAT) {
     writer.SetIsPQR(true);
   }
   ent.Apply(writer);
   this->WriteModelTrailer();
 }
 
-void PDBWriter::SetFlags(PDBFlags flags)
-{
-  flags_=flags;
-}
-
 void PDBWriter::Write(const mol::EntityView& ent)
 {
   this->WriteModel(ent);
@@ -199,7 +187,7 @@ void PDBWriter::Write(const mol::AtomHandleList& atoms)
       }
       last_chain=(*i).GetResidue().GetChain();
     }
-    write_atom(outstream_, *i, counter, flags_ & PDB::PQR_FORMAT);      
+    write_atom(outstream_, *i, counter, PDB::Flags() & PDB::PQR_FORMAT);      
   }
   this->WriteModelTrailer();
 }
diff --git a/modules/io/src/mol/pdb_writer.hh b/modules/io/src/mol/pdb_writer.hh
index 83f2f923e38ede6435bda01ab860a1421d907ec4..971890eeb66d75cba69453e1782a185b84a51d24 100644
--- a/modules/io/src/mol/pdb_writer.hh
+++ b/modules/io/src/mol/pdb_writer.hh
@@ -42,8 +42,6 @@ public:
   PDBWriter(const boost::filesystem::path& filename);
   PDBWriter(std::ostream& outstream);
   
-  void SetFlags(PDBFlags flags);
-  
   void Write(const mol::EntityView& ent);
   void Write(const mol::EntityHandle& ent);
   
@@ -59,7 +57,6 @@ private:
   std::ofstream  outfile_;
   std::ostream&   outstream_;
   int mol_count_;
-  PDBFlags flags_;  
 };
  
 }}
diff --git a/modules/mol/base/pymod/export_atom.cc b/modules/mol/base/pymod/export_atom.cc
index 52983f3ae26775d4014f16028925230a4cc31420..ccebbfb0adf0f9b7eb3aba0f10ba914ef68e987c 100644
--- a/modules/mol/base/pymod/export_atom.cc
+++ b/modules/mol/base/pymod/export_atom.cc
@@ -46,6 +46,7 @@ void export_Atom()
     .def("GetProp", &AtomBase::GetProp,
          return_value_policy<copy_const_reference>())
     .def("SetProp", &AtomBase::SetProp, args("prop"))
+    .def("GetIndex", &AtomBase::GetIndex)
     .add_property("prop",
                   make_function(&AtomBase::GetProp,
                                 return_value_policy<copy_const_reference>()))
@@ -56,6 +57,7 @@ void export_Atom()
                   make_function(&AtomBase::GetName,
                                 return_value_policy<copy_const_reference>()),
                   &AtomBase::SetName)
+    .add_property("index",&AtomBase::GetIndex)
 
   ;
   generic_prop_def<AtomBase>(atom_base);
diff --git a/modules/mol/base/src/atom_base.cc b/modules/mol/base/src/atom_base.cc
index 95141733ff27a4ab798e67d9aa814b1d7201aa58..9a8cfb1fc0ce1438612555e2909c7be900fc7558 100644
--- a/modules/mol/base/src/atom_base.cc
+++ b/modules/mol/base/src/atom_base.cc
@@ -156,5 +156,11 @@ int AtomBase::GetIntProperty(Prop::ID prop_id) const
   return Impl()->GetIntProperty(prop_id);
 }
 
+unsigned long AtomBase::GetIndex() const
+{
+  this->CheckValidity();
+  return Impl()->GetIndex();
+}
+
 }} // ns
 
diff --git a/modules/mol/base/src/atom_base.hh b/modules/mol/base/src/atom_base.hh
index 0a17ce2508b7a904e92e738de0fe72fbf4a7249b..3b10fb8ca241ff4aa5c452d0b86a63c2bb848127 100644
--- a/modules/mol/base/src/atom_base.hh
+++ b/modules/mol/base/src/atom_base.hh
@@ -116,7 +116,10 @@ public:
   
   /// \brief Get int property by id
   int GetIntProperty(Prop::ID prop_id) const;
-public:
+
+  /// \brief Get the internal index
+  unsigned long GetIndex() const;
+
   /// \brief get atom implementation.
   ///
   /// Intended for internal use.
diff --git a/modules/mol/base/src/coord_frame.hh b/modules/mol/base/src/coord_frame.hh
index 4a04ca4e45ef0be5a7785e72c6198f046a960e42..017a58865a239a10bc7869ab4a2380047a528c85 100644
--- a/modules/mol/base/src/coord_frame.hh
+++ b/modules/mol/base/src/coord_frame.hh
@@ -29,17 +29,10 @@
 namespace ost { namespace mol {
 
 
-class CoordFrame;
-
+typedef std::vector<geom::Vec3> CoordFrame;
 typedef boost::shared_ptr<CoordFrame> CoordFramePtr;
 typedef std::vector<CoordFramePtr> CoordFrameList;
 
-class DLLEXPORT_OST_MOL CoordFrame : public std::vector<geom::Vec3> {
-public:
-  CoordFrame() {}
-  CoordFrame(Real ts) {}
-};
-
 }}
 
 #endif
diff --git a/modules/mol/base/src/coord_source.cc b/modules/mol/base/src/coord_source.cc
index a8d95ff1a9828a56663539407aa7df11ccf7b546..b25a91755d461be23870de214a5e592c038ece6a 100644
--- a/modules/mol/base/src/coord_source.cc
+++ b/modules/mol/base/src/coord_source.cc
@@ -20,6 +20,7 @@
 /*
   Author: Marco Biasini
  */
+#include <ost/log.hh>
 #include <ost/mol/atom_handle.hh>
 #include <ost/mol/xcs_editor.hh>
 #include <ost/mol/in_mem_coord_source.hh>
@@ -53,10 +54,12 @@ CoordSource::~CoordSource()
 void CoordSource::CopyFrame(uint frame_id)
 {
   if (atoms_.empty()) {
+    LOGN_DEBUG("atom list empty, ignored");
     return;
   }  
   CoordFramePtr frame=this->GetFrame(frame_id);
   if (!frame) {
+    LOGN_DEBUG("invalid frame given, ignored");
     return;
   }
   assert(frame->size()==atoms_.size());
@@ -64,7 +67,7 @@ void CoordSource::CopyFrame(uint frame_id)
   CoordFrame::const_iterator c=frame->begin();
   for (AtomHandleList::iterator i=atoms_.begin(), 
        e=atoms_.end(); i!=e; ++i, ++c) {
-    edi.SetAtomPos(*i, *c);
+     edi.SetAtomPos(*i, *c);
   }
 }
 
diff --git a/modules/mol/base/src/impl/atom_impl.cc b/modules/mol/base/src/impl/atom_impl.cc
index d8e37b25c38fd459f6e9d1c41d940f9247dd5852..cb3ecf87a290166e78a14329655b9ff7a733698c 100644
--- a/modules/mol/base/src/impl/atom_impl.cc
+++ b/modules/mol/base/src/impl/atom_impl.cc
@@ -40,7 +40,8 @@ AtomImpl::AtomImpl(const EntityImplPtr& e,
                    const ResidueImplPtr& r,
                    const String& n,
                    const geom::Vec3& p,
-                   const AtomProp& prop):
+                   const AtomProp& prop,
+                   unsigned long index):
   res_(r),
   name_(n),
   pos_(p),
@@ -48,7 +49,8 @@ AtomImpl::AtomImpl(const EntityImplPtr& e,
   prim_connector_(),
   connector_list_(),
   fragment_(),
-  state_(0)
+  state_(0),
+  index_(index)
 {
   EntityHandle ent = this->GetEntity();
   geom::Mat4 transf_matrix = ent.GetTransformationMatrix();
diff --git a/modules/mol/base/src/impl/atom_impl.hh b/modules/mol/base/src/impl/atom_impl.hh
index 3db9ff520d4cf7ce0bb03f540e8fa8687fc14339..f3c2cc1c03db42b317b49606c326979e5b473d46 100644
--- a/modules/mol/base/src/impl/atom_impl.hh
+++ b/modules/mol/base/src/impl/atom_impl.hh
@@ -50,7 +50,8 @@ class AtomImpl: public GenericPropertyContainerImpl,
                 public boost::enable_shared_from_this<AtomImpl> {
 public:
    AtomImpl(const EntityImplPtr& ent, const ResidueImplPtr& res,
-           const String& name, const geom::Vec3& pos, const AtomProp& prop);
+            const String& name, const geom::Vec3& pos, const AtomProp& prop,
+            unsigned long index);
 
   ~AtomImpl();
   void Apply(EntityVisitor& h);
@@ -137,6 +138,9 @@ public:
   Real GetFloatProperty(Prop::ID prop_id) const;
   
   int GetIntProperty(Prop::ID prop_id) const;                     
+
+  unsigned long GetIndex() const {return index_;}
+  void SetIndex(unsigned long index) {index_=index;}
                      
 private:
   ResidueImplW res_;
@@ -171,6 +175,8 @@ private:
     unsigned int mask = 0x1<<bit;
     return (state_ & mask)!=0;
   }
+
+  unsigned long index_;
 };
 
 /// \internal
diff --git a/modules/mol/base/src/impl/entity_impl.cc b/modules/mol/base/src/impl/entity_impl.cc
index e17a5a76dbcd2b23047cd34df54ed6ac3a5dff61..4806c7cbd382511d9ffaea3fa0adb0c43a332208 100644
--- a/modules/mol/base/src/impl/entity_impl.cc
+++ b/modules/mol/base/src/impl/entity_impl.cc
@@ -76,7 +76,8 @@ EntityImpl::EntityImpl():
   xcs_editor_count_(0),
   ics_editor_count_(0),  
   dirty_flags_(DisableICS),
-  name_("")
+  name_(""),
+  next_index_(0L)
 {    
 }
 
@@ -350,9 +351,9 @@ AtomImplPtr EntityImpl::CreateAtom(const ResidueImplPtr& rp,
 {
 #if MAKE_SHARED_AVAILABLE
   AtomImplPtr ap=boost::make_shared<AtomImpl>(shared_from_this(), rp, name, 
-                                              pos, prop);
+                                              pos, prop,next_index_++);
 #else
-  AtomImplPtr ap(new AtomImpl(shared_from_this(), rp, name, pos, prop));
+  AtomImplPtr ap(new AtomImpl(shared_from_this(), rp, name, pos, prop,next_index_++));
 #endif
   if (identity_transf_ == false) {
     geom::Vec3 transformed_pos = geom::Vec3(transformation_matrix_*geom::Vec4(pos));
diff --git a/modules/mol/base/src/impl/entity_impl.hh b/modules/mol/base/src/impl/entity_impl.hh
index 4042e92975df4ad29d2b8c327d6f113aa0d8b0aa..ebe32704b8309441f87898b52d37bbbaf7fbbe43 100644
--- a/modules/mol/base/src/impl/entity_impl.hh
+++ b/modules/mol/base/src/impl/entity_impl.hh
@@ -268,6 +268,9 @@ private:
   int ics_editor_count_;
   int dirty_flags_;
   String name_;
+
+  unsigned long next_index_;
+
   template <bool always_true>
   EntityView do_selection(const EntityHandle&, const Query&, QueryFlags) const;
 };
diff --git a/modules/mol/base/src/in_mem_coord_source.cc b/modules/mol/base/src/in_mem_coord_source.cc
index 98417d1594aa55ba4f26a0a9cfaa208c1fe2ad3f..089c667bd1971f1a7ea6ee7c77d807deaeeb3d8e 100644
--- a/modules/mol/base/src/in_mem_coord_source.cc
+++ b/modules/mol/base/src/in_mem_coord_source.cc
@@ -27,8 +27,8 @@ void InMemCoordSource::AddFrame(const CoordFramePtr& frame)
 
 void InMemCoordSource::AddFrame(const std::vector<geom::Vec3>& coords)
 {
-  frames_.push_back(CoordFramePtr(new CoordFrame(0.0)));
-  frames_.back()->insert(frames_.back()->end(), coords.begin(), coords.end());
+  CoordFramePtr fp(new CoordFrame(coords));
+  frames_.push_back(fp);
 }
 
 }}
diff --git a/modules/mol/base/tests/test_entity.cc b/modules/mol/base/tests/test_entity.cc
index 8deba9b01bad9b3a814daee98736ef1e8d0b465f..0504422946e34546f0c3dee532bb05de4fbd232a 100644
--- a/modules/mol/base/tests/test_entity.cc
+++ b/modules/mol/base/tests/test_entity.cc
@@ -95,10 +95,12 @@ BOOST_AUTO_TEST_CASE(entity_creator)
   AtomHandle atom1 = e.InsertAtom(res, "X1",geom::Vec3());
   BOOST_CHECK(res==atom1.GetResidue());
   BOOST_CHECK(atom1.GetName()=="X1");
+  BOOST_CHECK(atom1.GetIndex()==0);
 
   AtomHandle atom2 = e.InsertAtom(res, "X2",geom::Vec3());
   BOOST_CHECK(res==atom2.GetResidue());
   BOOST_CHECK(atom2.GetName()=="X2");
+  BOOST_CHECK(atom2.GetIndex()==1);
 
   BondHandle bond = e.Connect(atom1, atom2);