diff --git a/modules/io/src/mol/CMakeLists.txt b/modules/io/src/mol/CMakeLists.txt
index 8d242c3e75422c451d2b9a9b8d13a7b0063a9434..f281e45a35fef883c3720eb30cf6adf7d2f07523 100644
--- a/modules/io/src/mol/CMakeLists.txt
+++ b/modules/io/src/mol/CMakeLists.txt
@@ -31,7 +31,6 @@ PARENT_SCOPE
 
 set(OST_IO_MOL_HEADERS
 chemdict_parser.hh
-star_base.hh
 star_parser.hh
 star_writer.hh
 mmcif_reader.hh
diff --git a/modules/io/src/mol/mmcif_writer.cc b/modules/io/src/mol/mmcif_writer.cc
index b5e6bb56f75fb31314f264c73179ae019bb1becf..8398f4c0ec26b5378b0f23ab89ded228cf138e52 100644
--- a/modules/io/src/mol/mmcif_writer.cc
+++ b/modules/io/src/mol/mmcif_writer.cc
@@ -18,10 +18,8 @@
 //------------------------------------------------------------------------------
 
 #include <ost/mol/chem_class.hh>
-
 #include <ost/io/mol/mmcif_writer.hh>
 
-
 namespace {
 
   // generates as many chain names as you want (potentially multiple characters)
@@ -286,7 +284,7 @@ namespace {
     String type;
   };
 
-  inline String chem_class_to_chem_comp_type(char chem_class) {
+  inline String ChemClassToChemCompType(char chem_class) {
     String type = "";
     switch(chem_class) {
       case 'P': {
@@ -342,7 +340,7 @@ namespace {
     return type;
   }
 
-  inline String mon_id_to_olc(char chem_class,
+  inline String MonIDToOLC(char chem_class,
                               const String& mon_id) {
 
     // hardcoded table according
@@ -527,11 +525,11 @@ namespace {
     return "(" + mon_id + ")";
   }
 
-  void Setup_chem_comp_(const ost::mol::ResidueHandleList& res_list,
+  void SetupChemComp(const ost::mol::ResidueHandleList& res_list,
                         std::map<String, CompInfo>& comp_infos) {
     for(auto res: res_list) {
       String res_name = res.GetName();
-      String type = chem_class_to_chem_comp_type(res.GetChemClass());
+      String type = ChemClassToChemCompType(res.GetChemClass());
       auto it = comp_infos.find(res_name);
       if(it != comp_infos.end()) {
         // check whether type is consistent
@@ -546,9 +544,9 @@ namespace {
     }
   }
 
-  bool Match_entity_resnum(const ost::mol::ResidueHandleList& res_list,
-                           const ost::io::MMCifWriterEntity& info,
-                           Real beyond_frac = 0.05) {
+  bool MatchEntityResnum(const ost::mol::ResidueHandleList& res_list,
+                         const ost::io::MMCifWriterEntity& info,
+                         Real beyond_frac = 0.05) {
     // Checks if res_list matches SEQRES given in info.mon_ids
     // It may be that res_list defines residues beyond this SEQRES or
     // has residues that are not yet defined, i.e. the respective mon_id is "-".
@@ -583,7 +581,7 @@ namespace {
     }
   }
 
-  bool Match_entity(const ost::mol::ResidueHandleList& res_list,
+  bool MatchEntity(const ost::mol::ResidueHandleList& res_list,
                     const ost::io::MMCifWriterEntity& info) {
     // checks if the residue names in res_list are an exact match
     // with mon_ids in info
@@ -594,7 +592,7 @@ namespace {
     return mon_ids == info.mon_ids;
   }
 
-  void Add_asym(const String& asym_chain_name,
+  void AddAsym(const String& asym_chain_name,
                 ost::io::MMCifWriterEntity& info) {
     // adds asym_chain_name to info under the assumption that mon_ids
     // exactly match => just add a copy of mon_ids to asym_alns
@@ -602,13 +600,13 @@ namespace {
     info.asym_alns.push_back(info.mon_ids);
   }
 
-  void Add_asym_resnum(const String& asym_chain_name,
+  void AddAsymResnum(const String& asym_chain_name,
                        const ost::mol::ResidueHandleList& res_list,
                        ost::io::MMCifWriterEntity& info) {
 
     if(!info.is_poly) {
       // no need for SEQRES alignment vodoo
-      Add_asym(asym_chain_name, info);
+      AddAsym(asym_chain_name, info);
       return;
     }
 
@@ -618,7 +616,7 @@ namespace {
 
     for(auto res: res_list) {
       int num = res.GetNumber().GetNum();
-      // assumes that Match_entity_resnum has already been run to check for
+      // assumes that MatchEntityResnum has already been run to check for
       // resnum < 1
       mon_ids.push_back(res.GetName());
       resnums.push_back(num);
@@ -647,8 +645,8 @@ namespace {
       if(info.mon_ids[resnums[i]-1] == "-") {
         info.mon_ids[resnums[i]-1] = mon_ids[i];
         const ost::mol::ResidueHandle& res = res_list[i];
-        info.seq_olcs[resnums[i]-1] = mon_id_to_olc(res.GetChemClass(),
-                                                    mon_ids[i]);
+        info.seq_olcs[resnums[i]-1] = MonIDToOLC(res.GetChemClass(),
+                                                 mon_ids[i]);
         char olc = res.GetOneLetterCode();
         if(olc < 'A' || olc > 'Z') {
           info.seq_can_olcs[resnums[i]-1] = "X";
@@ -663,12 +661,12 @@ namespace {
     info.asym_alns.push_back(aln_mon_ids);
   }
 
-  int Setup_entity(const String& asym_chain_name,
-                   const String& type,
-                   const String& poly_type,
-                   const ost::mol::ResidueHandleList& res_list,
-                   bool resnum_alignment,
-                   std::vector<ost::io::MMCifWriterEntity>& entity_infos) {
+  int SetupEntity(const String& asym_chain_name,
+                  const String& type,
+                  const String& poly_type,
+                  const ost::mol::ResidueHandleList& res_list,
+                  bool resnum_alignment,
+                  std::vector<ost::io::MMCifWriterEntity>& entity_infos) {
 
     bool is_poly = type == "polymer";
 
@@ -684,13 +682,13 @@ namespace {
       if(entity_infos[i].type == type &&
          entity_infos[i].poly_type == poly_type) {
         if(is_poly && resnum_alignment) {
-          if(Match_entity_resnum(res_list, entity_infos[i])) {
-            Add_asym_resnum(asym_chain_name, res_list, entity_infos[i]);
+          if(MatchEntityResnum(res_list, entity_infos[i])) {
+            AddAsymResnum(asym_chain_name, res_list, entity_infos[i]);
             return i;
           }   
         } else {
-           if(Match_entity(res_list, entity_infos[i])) {
-             Add_asym(asym_chain_name, entity_infos[i]);
+           if(MatchEntity(res_list, entity_infos[i])) {
+             AddAsym(asym_chain_name, entity_infos[i]);
              return i;
            }
         }
@@ -721,8 +719,8 @@ namespace {
       for(size_t i = 0; i < res_mon_ids.size(); ++i) {
         mon_ids[resnums[i]-1] = res_mon_ids[i];
         const ost::mol::ResidueHandle& res = res_list[i];
-        seq[resnums[i]-1] = mon_id_to_olc(res.GetChemClass(),
-                                          mon_ids[resnums[i]-1]);
+        seq[resnums[i]-1] = MonIDToOLC(res.GetChemClass(),
+                                       mon_ids[resnums[i]-1]);
         char olc = res.GetOneLetterCode();
         if(olc < 'A' || olc > 'Z') {
           seq_can[resnums[i]-1] = "X";
@@ -733,7 +731,7 @@ namespace {
     } else {
       for(auto res: res_list) {
         mon_ids.push_back(res.GetName());
-        seq.push_back(mon_id_to_olc(res.GetChemClass(), res.GetName()));
+        seq.push_back(MonIDToOLC(res.GetChemClass(), res.GetName()));
         char olc = res.GetOneLetterCode();
         if(olc < 'A' || olc > 'Z') {
           seq_can.push_back("X");
@@ -743,7 +741,6 @@ namespace {
       }
     }
 
-
     int entity_idx = entity_infos.size();
     entity_infos.push_back(ost::io::MMCifWriterEntity());
     entity_infos.back().type = type;
@@ -754,18 +751,18 @@ namespace {
     entity_infos.back().is_poly = is_poly;
 
     if(is_poly && resnum_alignment) {
-      Add_asym_resnum(asym_chain_name, res_list, entity_infos.back());
+      AddAsymResnum(asym_chain_name, res_list, entity_infos.back());
     } else {
-      Add_asym(asym_chain_name, entity_infos.back());
+      AddAsym(asym_chain_name, entity_infos.back());
     }
 
     return entity_idx;
   }
 
-  int Setup_entity_(const String& asym_chain_name,
-                    const ost::mol::ResidueHandleList& res_list,
-                    bool resnum_alignment,
-                    std::vector<ost::io::MMCifWriterEntity>& entity_infos) {
+  int SetupEntity(const String& asym_chain_name,
+                  const ost::mol::ResidueHandleList& res_list,
+                  bool resnum_alignment,
+                  std::vector<ost::io::MMCifWriterEntity>& entity_infos) {
 
     String type = GuessEntityType(res_list);
     bool is_poly = type == "polymer";
@@ -773,15 +770,15 @@ namespace {
     if(is_poly) {
       poly_type = GuessEntityPolyType(res_list);
     }
-    return Setup_entity(asym_chain_name, type, poly_type, res_list,
-                        resnum_alignment, entity_infos);
+    return SetupEntity(asym_chain_name, type, poly_type, res_list,
+                       resnum_alignment, entity_infos);
   }
 
-  int Setup_entity_(const String& asym_chain_name,
-                    ost::mol::ChainType chain_type,
-                    const ost::mol::ResidueHandleList& res_list,
-                    bool resnum_alignment, 
-                    std::vector<ost::io::MMCifWriterEntity>& entity_infos) {
+  int SetupEntity(const String& asym_chain_name,
+                  ost::mol::ChainType chain_type,
+                  const ost::mol::ResidueHandleList& res_list,
+                  bool resnum_alignment, 
+                  std::vector<ost::io::MMCifWriterEntity>& entity_infos) {
     // use chain_type info attached to chain to determine
     // _entity.type and _entity_poly.type
     String type = GuessEntityType(chain_type);
@@ -801,20 +798,20 @@ namespace {
         throw ost::io::IOException(ss.str());
       }
     }
-    return Setup_entity(asym_chain_name, type, poly_type, res_list,
-                        resnum_alignment, entity_infos);
+    return SetupEntity(asym_chain_name, type, poly_type, res_list,
+                       resnum_alignment, entity_infos);
   }
 
-  ost::io::StarLoop* Setup_atom_type_ptr() {
-    ost::io::StarLoopDesc desc;
+  ost::io::StarWriterLoopPtr Setup_atom_type_ptr() {
+    ost::io::StarWriterLoopDesc desc;
     desc.SetCategory("_atom_type");
     desc.Add("symbol");
-    ost::io::StarLoop* sl = new ost::io::StarLoop(desc);
+    ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc));
     return sl;
   }
 
-  ost::io::StarLoop* Setup_atom_site_ptr() {
-    ost::io::StarLoopDesc desc;
+  ost::io::StarWriterLoopPtr Setup_atom_site_ptr() {
+    ost::io::StarWriterLoopDesc desc;
     desc.SetCategory("_atom_site");
     desc.Add("group_PDB");
     desc.Add("type_symbol");
@@ -833,12 +830,12 @@ namespace {
     desc.Add("auth_asym_id");
     desc.Add("id");
     desc.Add("pdbx_PDB_ins_code");
-    ost::io::StarLoop* sl = new ost::io::StarLoop(desc);
+    ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc));
     return sl;
   }
 
-  ost::io::StarLoop* Setup_pdbx_poly_seq_scheme_ptr() {
-    ost::io::StarLoopDesc desc;
+  ost::io::StarWriterLoopPtr Setup_pdbx_poly_seq_scheme_ptr() {
+    ost::io::StarWriterLoopDesc desc;
     desc.SetCategory("_pdbx_poly_seq_scheme");
     desc.Add("asym_id");
     desc.Add("entity_id");
@@ -847,92 +844,92 @@ namespace {
     desc.Add("pdb_strand_id");
     desc.Add("pdb_seq_num");
     desc.Add("pdb_ins_code");
-    ost::io::StarLoop* sl = new ost::io::StarLoop(desc);
+    ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc));
     return sl;
   }
 
-  ost::io::StarLoop* Setup_entity_ptr() {
-    ost::io::StarLoopDesc desc;
+  ost::io::StarWriterLoopPtr Setup_entity_ptr() {
+    ost::io::StarWriterLoopDesc desc;
     desc.SetCategory("_entity");
     desc.Add("id");
     desc.Add("type");
-    ost::io::StarLoop* sl = new ost::io::StarLoop(desc);
+    ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc));
     return sl;
   }
 
-  ost::io::StarLoop* Setup_struct_asym_ptr() {
-    ost::io::StarLoopDesc desc;
+  ost::io::StarWriterLoopPtr Setup_struct_asym_ptr() {
+    ost::io::StarWriterLoopDesc desc;
     desc.SetCategory("_struct_asym");
     desc.Add("id");
     desc.Add("entity_id");
-    ost::io::StarLoop* sl = new ost::io::StarLoop(desc);
+    ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc));
     return sl;    
   }
 
-  ost::io::StarLoop* Setup_entity_poly_ptr() {
-    ost::io::StarLoopDesc desc;
+  ost::io::StarWriterLoopPtr Setup_entity_poly_ptr() {
+    ost::io::StarWriterLoopDesc desc;
     desc.SetCategory("_entity_poly");
     desc.Add("entity_id");
     desc.Add("type");
     desc.Add("pdbx_seq_one_letter_code");
     desc.Add("pdbx_seq_one_letter_code_can");
-    ost::io::StarLoop* sl = new ost::io::StarLoop(desc);
+    ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc));
     return sl;    
   }
 
-  ost::io::StarLoop* Setup_entity_poly_seq_ptr() {
-    ost::io::StarLoopDesc desc;
+  ost::io::StarWriterLoopPtr Setup_entity_poly_seq_ptr() {
+    ost::io::StarWriterLoopDesc desc;
     desc.SetCategory("_entity_poly_seq");
     desc.Add("entity_id");
     desc.Add("mon_id");
     desc.Add("num");
-    ost::io::StarLoop* sl = new ost::io::StarLoop(desc);
+    ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc));
     return sl;    
   }
 
-  ost::io::StarLoop* Setup_chem_comp_ptr() {
-    ost::io::StarLoopDesc desc;
+  ost::io::StarWriterLoopPtr Setup_chem_comp_ptr() {
+    ost::io::StarWriterLoopDesc desc;
     desc.SetCategory("_chem_comp");
     desc.Add("id");
     desc.Add("type");
-    ost::io::StarLoop* sl = new ost::io::StarLoop(desc);
+    ost::io::StarWriterLoopPtr sl(new ost::io::StarWriterLoop(desc));
     return sl;    
   }
 
-  void Feed_atom_type_(ost::io::StarLoop* atom_type_ptr,
-                       ost::io::StarLoop* atom_site_ptr) {
+  void Feed_atom_type(ost::io::StarWriterLoopPtr atom_type_ptr,
+                      ost::io::StarWriterLoopPtr atom_site_ptr) {
     // we're just extracting every type_symbol that we observed
     // in atom_site (this is a bit of circular stupidity...)
     std::set<String> symbols;
     int desc_size = atom_site_ptr->GetDesc().GetSize();
     int type_symbol_idx = atom_site_ptr->GetDesc().GetIndex("type_symbol");
     int N = atom_site_ptr->GetN();
-    const std::vector<ost::io::StarLoopDataItemDO>& data = atom_site_ptr->GetData();
+    const std::vector<ost::io::StarWriterLoopDataItem>& data = atom_site_ptr->GetData();
     for(int i = 0; i < N; ++i) {
       symbols.insert(data[i*desc_size + type_symbol_idx].GetValue());
     }
-    std::vector<ost::io::StarLoopDataItemDO> atom_type_data;
-    atom_type_data.push_back(ost::io::StarLoopDataItemDO(""));
+    std::vector<ost::io::StarWriterLoopDataItem> atom_type_data;
+    atom_type_data.push_back(ost::io::StarWriterLoopDataItem(""));
     for(auto symbol: symbols) {
-      atom_type_data[0] = ost::io::StarLoopDataItemDO(symbol);
+      atom_type_data[0] = ost::io::StarWriterLoopDataItem(symbol);
       atom_type_ptr->AddData(atom_type_data);
     }
   }
 
-  void Feed_pdbx_poly_seq_scheme(ost::io::StarLoop* pdbx_poly_seq_scheme_ptr,
+  void Feed_pdbx_poly_seq_scheme(ost::io::StarWriterLoopPtr pdbx_poly_seq_scheme_ptr,
                                  const String& label_asym_id,
                                  int label_entity_id,
                                  ost::io::MMCifWriterEntity& entity_info,
                                  const ost::mol::ResidueHandleList& res_list) {
 
-    std::vector<ost::io::StarLoopDataItemDO> data;
-    data.push_back(ost::io::StarLoopDataItemDO(label_asym_id));
-    data.push_back(ost::io::StarLoopDataItemDO(label_entity_id));
-    data.push_back(ost::io::StarLoopDataItemDO(""));
-    data.push_back(ost::io::StarLoopDataItemDO(0));
-    data.push_back(ost::io::StarLoopDataItemDO(""));
-    data.push_back(ost::io::StarLoopDataItemDO(0));
-    data.push_back(ost::io::StarLoopDataItemDO(""));
+    std::vector<ost::io::StarWriterLoopDataItem> data;
+    data.push_back(ost::io::StarWriterLoopDataItem(label_asym_id));
+    data.push_back(ost::io::StarWriterLoopDataItem(label_entity_id));
+    data.push_back(ost::io::StarWriterLoopDataItem(""));
+    data.push_back(ost::io::StarWriterLoopDataItem(0));
+    data.push_back(ost::io::StarWriterLoopDataItem(""));
+    data.push_back(ost::io::StarWriterLoopDataItem(0));
+    data.push_back(ost::io::StarWriterLoopDataItem(""));
 
     int asym_idx = entity_info.GetAsymIdx(label_asym_id);
     const std::vector<String>& aln = entity_info.asym_alns[asym_idx];
@@ -948,35 +945,35 @@ namespace {
         throw "ksajdhfgjkaljshdfsfgd";
       }
 
-      data[2] = ost::io::StarLoopDataItemDO(res_name);
-      data[3] = ost::io::StarLoopDataItemDO(label_seq_id + 1);
+      data[2] = ost::io::StarWriterLoopDataItem(res_name);
+      data[3] = ost::io::StarWriterLoopDataItem(label_seq_id + 1);
 
       // the remaining data items honor String properties if set:
       // pdb_auth_chain_name, pdb_auth_resnum and pdb_auth_ins_code
 
       if(res.GetChain().HasProp("pdb_auth_chain_name")) {
         data[4] = 
-        ost::io::StarLoopDataItemDO(res.GetChain().GetStringProp("pdb_auth_chain_name"));
+        ost::io::StarWriterLoopDataItem(res.GetChain().GetStringProp("pdb_auth_chain_name"));
       } else {
-        data[4] = ost::io::StarLoopDataItemDO(res.GetChain().GetName());  
+        data[4] = ost::io::StarWriterLoopDataItem(res.GetChain().GetName());  
       }
 
       if(res.HasProp("pdb_auth_resnum")) {
-        data[5] = ost::io::StarLoopDataItemDO(res.GetStringProp("pdb_auth_resnum"));
+        data[5] = ost::io::StarWriterLoopDataItem(res.GetStringProp("pdb_auth_resnum"));
       } else {
-        data[5] = ost::io::StarLoopDataItemDO(res.GetNumber().GetNum());
+        data[5] = ost::io::StarWriterLoopDataItem(res.GetNumber().GetNum());
       }
 
       if(res.HasProp("pdb_auth_ins_code")) {
-        data[6] = ost::io::StarLoopDataItemDO(res.GetStringProp("pdb_auth_ins_code"));
+        data[6] = ost::io::StarWriterLoopDataItem(res.GetStringProp("pdb_auth_ins_code"));
       } else {
         char ins_code = res.GetNumber().GetInsCode();      
         if(ins_code == '\0') {
-          data[6] = ost::io::StarLoopDataItemDO("");
+          data[6] = ost::io::StarWriterLoopDataItem("");
         } else {
           String tmp = " ";
           tmp[0] = ins_code;
-          data[6] = ost::io::StarLoopDataItemDO(tmp);
+          data[6] = ost::io::StarWriterLoopDataItem(tmp);
         }      
       }
       pdbx_poly_seq_scheme_ptr->AddData(data);
@@ -984,11 +981,11 @@ namespace {
     }
   }
 
-  void Feed_atom_site_(ost::io::StarLoop* atom_site_ptr,
-                       const String& label_asym_id,
-                       int label_entity_id,
-                       const ost::io::MMCifWriterEntity& entity_info,
-                       const ost::mol::ResidueHandleList& res_list) {
+  void Feed_atom_site(ost::io::StarWriterLoopPtr atom_site_ptr,
+                      const String& label_asym_id,
+                      int label_entity_id,
+                      const ost::io::MMCifWriterEntity& entity_info,
+                      const ost::mol::ResidueHandleList& res_list) {
 
     int asym_idx = entity_info.GetAsymIdx(label_asym_id);
     const std::vector<String>& aln = entity_info.asym_alns[asym_idx];
@@ -1023,110 +1020,110 @@ namespace {
         auth_seq_id = ss.str();
       }
       for(auto at: at_list) {
-        std::vector<ost::io::StarLoopDataItemDO> at_data;
+        std::vector<ost::io::StarWriterLoopDataItem> at_data;
         // group_PDB
         if(at.IsHetAtom()) {
-          at_data.push_back(ost::io::StarLoopDataItemDO("HETATM"));
+          at_data.push_back(ost::io::StarWriterLoopDataItem("HETATM"));
         } else {
-          at_data.push_back(ost::io::StarLoopDataItemDO("ATOM"));
+          at_data.push_back(ost::io::StarWriterLoopDataItem("ATOM"));
         }
         // type_symbol
-        at_data.push_back(ost::io::StarLoopDataItemDO(at.GetElement()));
+        at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetElement()));
         // label_atom_id
-        at_data.push_back(ost::io::StarLoopDataItemDO(at.GetName()));
+        at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetName()));
         // label_comp_id
-        at_data.push_back(ost::io::StarLoopDataItemDO(comp_id));
+        at_data.push_back(ost::io::StarWriterLoopDataItem(comp_id));
         // label_asym_id
-        at_data.push_back(ost::io::StarLoopDataItemDO(label_asym_id));
+        at_data.push_back(ost::io::StarWriterLoopDataItem(label_asym_id));
         // label_entity_id
-        at_data.push_back(ost::io::StarLoopDataItemDO(label_entity_id));
+        at_data.push_back(ost::io::StarWriterLoopDataItem(label_entity_id));
         // label_seq_id
         if(entity_info.is_poly) {
-          at_data.push_back(ost::io::StarLoopDataItemDO(label_seq_id+1));
+          at_data.push_back(ost::io::StarWriterLoopDataItem(label_seq_id+1));
         } else {
-          at_data.push_back(ost::io::StarLoopDataItemDO("."));
+          at_data.push_back(ost::io::StarWriterLoopDataItem("."));
         }
         // label_alt_id
-        at_data.push_back(ost::io::StarLoopDataItemDO("."));
+        at_data.push_back(ost::io::StarWriterLoopDataItem("."));
         // Cartn_x
-        at_data.push_back(ost::io::StarLoopDataItemDO(at.GetPos().GetX(), 3));
+        at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetPos().GetX(), 3));
         // Cartn_y
-        at_data.push_back(ost::io::StarLoopDataItemDO(at.GetPos().GetY(), 3));
+        at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetPos().GetY(), 3));
         // Cartn_z
-        at_data.push_back(ost::io::StarLoopDataItemDO(at.GetPos().GetZ(), 3));
+        at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetPos().GetZ(), 3));
         // occupancy
-        at_data.push_back(ost::io::StarLoopDataItemDO(at.GetOccupancy(), 2));
+        at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetOccupancy(), 2));
         // B_iso_or_equiv
-        at_data.push_back(ost::io::StarLoopDataItemDO(at.GetBFactor(), 2));
+        at_data.push_back(ost::io::StarWriterLoopDataItem(at.GetBFactor(), 2));
         // auth_seq_id
-        at_data.push_back(ost::io::StarLoopDataItemDO(auth_seq_id));
+        at_data.push_back(ost::io::StarWriterLoopDataItem(auth_seq_id));
         // auth_asym_id
-        at_data.push_back(ost::io::StarLoopDataItemDO(auth_asym_id));
+        at_data.push_back(ost::io::StarWriterLoopDataItem(auth_asym_id));
         // id
-        at_data.push_back(ost::io::StarLoopDataItemDO(atom_site_ptr->GetN()));
+        at_data.push_back(ost::io::StarWriterLoopDataItem(atom_site_ptr->GetN()));
         // pdbx_PDB_ins_code
-        at_data.push_back(ost::io::StarLoopDataItemDO("")); // CHECK THIS, ADD STUFF FROM AUTH_SEQ_ID?
+        at_data.push_back(ost::io::StarWriterLoopDataItem("")); // CHECK THIS, ADD STUFF FROM AUTH_SEQ_ID?
         atom_site_ptr->AddData(at_data);
       }
       ++label_seq_id;
     }
   }
 
-  void Feed_entity_(ost::io::StarLoop* entity_ptr,
-                    const std::vector<ost::io::MMCifWriterEntity>& entity_info) {
+  void Feed_entity(ost::io::StarWriterLoopPtr entity_ptr,
+                   const std::vector<ost::io::MMCifWriterEntity>& entity_info) {
     for(size_t entity_idx = 0; entity_idx < entity_info.size(); ++entity_idx) {
-      std::vector<ost::io::StarLoopDataItemDO> ent_data;
-      ent_data.push_back(ost::io::StarLoopDataItemDO(entity_idx));
-      ent_data.push_back(ost::io::StarLoopDataItemDO(entity_info[entity_idx].type));
+      std::vector<ost::io::StarWriterLoopDataItem> ent_data;
+      ent_data.push_back(ost::io::StarWriterLoopDataItem(entity_idx));
+      ent_data.push_back(ost::io::StarWriterLoopDataItem(entity_info[entity_idx].type));
       entity_ptr->AddData(ent_data);
     }
   }
 
-  void Feed_struct_asym_(ost::io::StarLoop* struct_asym_ptr,
-                         const std::vector<ost::io::MMCifWriterEntity>& entity_info) {
+  void Feed_struct_asym(ost::io::StarWriterLoopPtr struct_asym_ptr,
+                        const std::vector<ost::io::MMCifWriterEntity>& entity_info) {
     for(size_t entity_idx = 0; entity_idx < entity_info.size(); ++entity_idx) {
       for(auto asym_id : entity_info[entity_idx].asym_ids) {
-        std::vector<ost::io::StarLoopDataItemDO> asym_data;
-        asym_data.push_back(ost::io::StarLoopDataItemDO(asym_id));
-        asym_data.push_back(ost::io::StarLoopDataItemDO(entity_idx));
+        std::vector<ost::io::StarWriterLoopDataItem> asym_data;
+        asym_data.push_back(ost::io::StarWriterLoopDataItem(asym_id));
+        asym_data.push_back(ost::io::StarWriterLoopDataItem(entity_idx));
         struct_asym_ptr->AddData(asym_data);
       }
     }
   }
 
-  void Feed_entity_poly_seq_(ost::io::StarLoop* entity_poly_seq_ptr,
-                             const std::vector<ost::io::MMCifWriterEntity>& entity_info) {
+  void Feed_entity_poly_seq(ost::io::StarWriterLoopPtr entity_poly_seq_ptr,
+                            const std::vector<ost::io::MMCifWriterEntity>& entity_info) {
     // reuse data vector for efficiency
-    std::vector<ost::io::StarLoopDataItemDO> entity_poly_seq_data;
-    entity_poly_seq_data.push_back(ost::io::StarLoopDataItemDO(0));
-    entity_poly_seq_data.push_back(ost::io::StarLoopDataItemDO("ALA"));
-    entity_poly_seq_data.push_back(ost::io::StarLoopDataItemDO(1));
+    std::vector<ost::io::StarWriterLoopDataItem> entity_poly_seq_data;
+    entity_poly_seq_data.push_back(ost::io::StarWriterLoopDataItem(0));
+    entity_poly_seq_data.push_back(ost::io::StarWriterLoopDataItem("ALA"));
+    entity_poly_seq_data.push_back(ost::io::StarWriterLoopDataItem(1));
 
     for(size_t entity_idx = 0; entity_idx < entity_info.size(); ++entity_idx) {
       if(entity_info[entity_idx].is_poly) {
         const std::vector<String>& mon_ids = entity_info[entity_idx].mon_ids;
         for(size_t mon_idx = 0; mon_idx < mon_ids.size(); ++mon_idx) {
-          entity_poly_seq_data[0] = ost::io::StarLoopDataItemDO(entity_idx);
-          entity_poly_seq_data[1] = ost::io::StarLoopDataItemDO(mon_ids[mon_idx]);
-          entity_poly_seq_data[2] = ost::io::StarLoopDataItemDO(mon_idx+1);
+          entity_poly_seq_data[0] = ost::io::StarWriterLoopDataItem(entity_idx);
+          entity_poly_seq_data[1] = ost::io::StarWriterLoopDataItem(mon_ids[mon_idx]);
+          entity_poly_seq_data[2] = ost::io::StarWriterLoopDataItem(mon_idx+1);
           entity_poly_seq_ptr->AddData(entity_poly_seq_data);
         }
       }
     }
   }
 
-  void Feed_entity_poly_(ost::io::StarLoop* entity_poly_ptr,
-                         const std::vector<ost::io::MMCifWriterEntity>& entity_info) {
+  void Feed_entity_poly(ost::io::StarWriterLoopPtr entity_poly_ptr,
+                        const std::vector<ost::io::MMCifWriterEntity>& entity_info) {
     // reuse data vector for efficiency
-    std::vector<ost::io::StarLoopDataItemDO> entity_poly_data;
-    entity_poly_data.push_back(ost::io::StarLoopDataItemDO(0));
-    entity_poly_data.push_back(ost::io::StarLoopDataItemDO("other"));
-    entity_poly_data.push_back(ost::io::StarLoopDataItemDO("A"));
-    entity_poly_data.push_back(ost::io::StarLoopDataItemDO("A"));
+    std::vector<ost::io::StarWriterLoopDataItem> entity_poly_data;
+    entity_poly_data.push_back(ost::io::StarWriterLoopDataItem(0));
+    entity_poly_data.push_back(ost::io::StarWriterLoopDataItem("other"));
+    entity_poly_data.push_back(ost::io::StarWriterLoopDataItem("A"));
+    entity_poly_data.push_back(ost::io::StarWriterLoopDataItem("A"));
     for(size_t entity_idx = 0; entity_idx < entity_info.size(); ++entity_idx) {
       if(entity_info[entity_idx].is_poly) {
-        entity_poly_data[0] = ost::io::StarLoopDataItemDO(entity_idx);
-        entity_poly_data[1] = ost::io::StarLoopDataItemDO(entity_info[entity_idx].poly_type);
+        entity_poly_data[0] = ost::io::StarWriterLoopDataItem(entity_idx);
+        entity_poly_data[1] = ost::io::StarWriterLoopDataItem(entity_info[entity_idx].poly_type);
         std::stringstream seq;
         std::stringstream seq_can;
         for(size_t idx = 0; idx < entity_info[entity_idx].mon_ids.size(); ++idx) {
@@ -1150,11 +1147,11 @@ namespace {
     }
   }
 
-  void Feed_chem_comp_(ost::io::StarLoop* chem_comp_ptr,
-                       const std::map<String, CompInfo>& comp_infos) {
-    std::vector<ost::io::StarLoopDataItemDO> comp_data;
-    comp_data.push_back(ost::io::StarLoopDataItemDO("ALA"));
-    comp_data.push_back(ost::io::StarLoopDataItemDO("L-peptide linking"));
+  void Feed_chem_comp(ost::io::StarWriterLoopPtr chem_comp_ptr,
+                      const std::map<String, CompInfo>& comp_infos) {
+    std::vector<ost::io::StarWriterLoopDataItem> comp_data;
+    comp_data.push_back(ost::io::StarWriterLoopDataItem("ALA"));
+    comp_data.push_back(ost::io::StarWriterLoopDataItem("L-peptide linking"));
     for(auto it = comp_infos.begin(); it != comp_infos.end(); ++it) {
       comp_data[0] = it->first;
       comp_data[1] = it->second.type;
@@ -1162,25 +1159,25 @@ namespace {
     }
   }
 
-  void SetStructure_(const ost::mol::EntityHandle& ent,
-                     std::map<String, CompInfo>& comp_infos,
-                     std::vector<ost::io::MMCifWriterEntity>& entity_info,
-                     ost::io::StarLoop* atom_site,
-                     ost::io::StarLoop* pdbx_poly_seq_scheme) {
+  void ProcessEnt(const ost::mol::EntityHandle& ent,
+                  std::map<String, CompInfo>& comp_infos,
+                  std::vector<ost::io::MMCifWriterEntity>& entity_info,
+                  ost::io::StarWriterLoopPtr atom_site,
+                  ost::io::StarWriterLoopPtr pdbx_poly_seq_scheme) {
     ost::mol::ChainHandleList chain_list = ent.GetChainList();
     for(auto ch: chain_list) {
 
       ost::mol::ResidueHandleList res_list = ch.GetResidueList();
 
-      Setup_chem_comp_(res_list, comp_infos);
+      SetupChemComp(res_list, comp_infos);
       String chain_name = ch.GetName();
-      int entity_id = Setup_entity_(chain_name,
-                                    ch.GetType(),
-                                    res_list,
-                                    true,
-                                    entity_info);
-      Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id],
-                      res_list);
+      int entity_id = SetupEntity(chain_name,
+                                  ch.GetType(),
+                                  res_list,
+                                  true,
+                                  entity_info);
+      Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id],
+                     res_list);
       if(entity_info[entity_id].is_poly) {
         Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name,
                                   entity_id, entity_info[entity_id], res_list);
@@ -1188,11 +1185,11 @@ namespace {
     }
   }
 
-  void SetStructuremmCIFify_(const ost::mol::EntityHandle& ent,
-                             std::map<String, CompInfo>& comp_infos,
-                             std::vector<ost::io::MMCifWriterEntity>& entity_info,
-                             ost::io::StarLoop* atom_site,
-                             ost::io::StarLoop* pdbx_poly_seq_scheme) {
+  void ProcessEntmmCIFify(const ost::mol::EntityHandle& ent,
+                          std::map<String, CompInfo>& comp_infos,
+                          std::vector<ost::io::MMCifWriterEntity>& entity_info,
+                          ost::io::StarWriterLoopPtr atom_site,
+                          ost::io::StarWriterLoopPtr pdbx_poly_seq_scheme) {
 
     std::vector<std::vector<ost::mol::ResidueHandle> > L_chains; // L_PEPTIDE_LINKING
     std::vector<std::vector<ost::mol::ResidueHandle> > D_chains; // D_PEPTIDE_LINKING
@@ -1209,7 +1206,7 @@ namespace {
 
       ost::mol::ResidueHandleList res_list = ch.GetResidueList();
 
-      Setup_chem_comp_(res_list, comp_infos);
+      SetupChemComp(res_list, comp_infos);
 
       // we don't just go for chain type here...
       // just think of PDB entries that have a polypeptide, water and a ligand
@@ -1340,12 +1337,12 @@ namespace {
     // process L_PEPTIDE_LINKING
     for(auto res_list: L_chains) {
       String chain_name = chain_name_gen.Get();
-      int entity_id = Setup_entity_(chain_name,
-                                    res_list,
-                                    false,
-                                    entity_info);
-      Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id],
-                      res_list);
+      int entity_id = SetupEntity(chain_name,
+                                  res_list,
+                                  false,
+                                  entity_info);
+      Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id],
+                     res_list);
       if(entity_info[entity_id].is_poly) {
         Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name,
                                   entity_id, entity_info[entity_id], res_list);
@@ -1355,12 +1352,12 @@ namespace {
     // process D_PEPTIDE_LINKING
     for(auto res_list: D_chains) {
       String chain_name = chain_name_gen.Get();
-      int entity_id = Setup_entity_(chain_name,
-                                    res_list,
-                                    false,
-                                    entity_info);
-      Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id],
-                      res_list);
+      int entity_id = SetupEntity(chain_name,
+                                  res_list,
+                                  false,
+                                  entity_info);
+      Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id],
+                     res_list);
       if(entity_info[entity_id].is_poly) {
         Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name,
                                   entity_id, entity_info[entity_id], res_list);
@@ -1370,12 +1367,12 @@ namespace {
     // process PEPTIDE_LINKING
     for(auto res_list: P_chains) {
       String chain_name = chain_name_gen.Get();
-      int entity_id = Setup_entity_(chain_name,
-                                    res_list,
-                                    false,
-                                    entity_info);
-      Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id],
-                      res_list);
+      int entity_id = SetupEntity(chain_name,
+                                  res_list,
+                                  false,
+                                  entity_info);
+      Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id],
+                     res_list);
       if(entity_info[entity_id].is_poly) {
         Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name,
                                   entity_id, entity_info[entity_id], res_list);
@@ -1385,12 +1382,12 @@ namespace {
     // process RNA_LINKING
     for(auto res_list: R_chains) {
       String chain_name = chain_name_gen.Get();
-      int entity_id = Setup_entity_(chain_name,
-                                    res_list,
-                                    false,
-                                    entity_info);
-      Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id],
-                      res_list);
+      int entity_id = SetupEntity(chain_name,
+                                  res_list,
+                                  false,
+                                  entity_info);
+      Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id],
+                     res_list);
       if(entity_info[entity_id].is_poly) {
         Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name,
                                   entity_id, entity_info[entity_id], res_list);
@@ -1400,12 +1397,12 @@ namespace {
     // process DNA_LINKING
     for(auto res_list: S_chains) {
       String chain_name = chain_name_gen.Get();
-      int entity_id = Setup_entity_(chain_name,
-                                    res_list,
-                                    false,
-                                    entity_info);
-      Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id],
-                      res_list);
+      int entity_id = SetupEntity(chain_name,
+                                  res_list,
+                                  false,
+                                  entity_info);
+      Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id],
+                     res_list);
       if(entity_info[entity_id].is_poly) {
         Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name,
                                   entity_id, entity_info[entity_id], res_list);
@@ -1415,12 +1412,12 @@ namespace {
     // process SACHARIDE
     for(auto res_list: Z_chains) {
       String chain_name = chain_name_gen.Get();
-      int entity_id = Setup_entity_(chain_name,
-                                    res_list,
-                                    false,
-                                    entity_info);
-      Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id],
-                      res_list);
+      int entity_id = SetupEntity(chain_name,
+                                  res_list,
+                                  false,
+                                  entity_info);
+      Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id],
+                     res_list);
       if(entity_info[entity_id].is_poly) {
         Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name,
                                   entity_id, entity_info[entity_id], res_list);
@@ -1430,12 +1427,12 @@ namespace {
     // process WATER
     for(auto res_list: W_chains) {
       String chain_name = chain_name_gen.Get();
-      int entity_id = Setup_entity_(chain_name,
-                                    res_list,
-                                    false,
-                                    entity_info);
-      Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id],
-                      res_list);
+      int entity_id = SetupEntity(chain_name,
+                                  res_list,
+                                  false,
+                                  entity_info);
+      Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id],
+                     res_list);
       if(entity_info[entity_id].is_poly) {
         Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name,
                                   entity_id, entity_info[entity_id], res_list);
@@ -1447,12 +1444,12 @@ namespace {
       ost::mol::ResidueHandleList res_list;
       res_list.push_back(res);
       String chain_name = chain_name_gen.Get();
-      int entity_id = Setup_entity_(chain_name,
-                                    res_list,
-                                    false,
-                                    entity_info);
-      Feed_atom_site_(atom_site, chain_name, entity_id, entity_info[entity_id],
-                      res_list);
+      int entity_id = SetupEntity(chain_name,
+                                  res_list,
+                                  false,
+                                  entity_info);
+      Feed_atom_site(atom_site, chain_name, entity_id, entity_info[entity_id],
+                     res_list);
       if(entity_info[entity_id].is_poly) {
         Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme, chain_name,
                                   entity_id, entity_info[entity_id], res_list);
@@ -1482,70 +1479,35 @@ int MMCifWriterEntity::GetAsymIdx(const String& asym_id) const {
 
 MMCifWriter::MMCifWriter(const String& filename, const IOProfile& profile):
   StarWriter(filename),
-  profile_(profile),
-  atom_type_(NULL),
-  atom_site_(NULL),
-  pdbx_poly_seq_scheme_(NULL),
-  entity_(NULL),
-  struct_asym_(NULL),
-  entity_poly_(NULL),
-  entity_poly_seq_(NULL),
-  chem_comp_(NULL) { }
-
-MMCifWriter::~MMCifWriter() {
-  if(atom_type_ != NULL) {
-    delete atom_type_;
-  }
-  if(atom_site_ != NULL) {
-    delete atom_site_;
-  }
-  if(pdbx_poly_seq_scheme_ != NULL) {
-    delete pdbx_poly_seq_scheme_;
-  }
-  if(entity_ != NULL) {
-    delete entity_;
-  }
-  if(struct_asym_ != NULL) {
-    delete struct_asym_;
-  }
-  if(entity_poly_ != NULL) {
-    delete entity_poly_;
-  }
-  if(entity_poly_seq_ != NULL) {
-    delete entity_poly_seq_;
-  }
-  if(chem_comp_ != NULL) {
-    delete chem_comp_;
-  }
-}
+  profile_(profile) { }
 
 void MMCifWriter::SetStructure(const ost::mol::EntityHandle& ent,
                                bool mmcif_conform) {
 
   // tabula rasa
-  if(atom_type_ != NULL) {
-    delete atom_type_;
+  if(atom_type_) {
+    atom_type_.reset();
   }
-  if(atom_site_ != NULL) {
-    delete atom_site_;
+  if(atom_site_) {
+    atom_site_.reset();
   }
-  if(pdbx_poly_seq_scheme_ != NULL) {
-    delete pdbx_poly_seq_scheme_;
+  if(pdbx_poly_seq_scheme_) {
+    pdbx_poly_seq_scheme_.reset();
   }
-  if(entity_ != NULL) {
-    delete entity_;
+  if(entity_) {
+    entity_.reset();
   }
-  if(struct_asym_ != NULL) {
-    delete struct_asym_;
+  if(struct_asym_) {
+    struct_asym_.reset();
   }
-  if(entity_poly_ != NULL) {
-    delete entity_poly_;
+  if(entity_poly_) {
+    entity_poly_.reset();
   }
-  if(entity_poly_seq_ != NULL) {
-    delete entity_poly_seq_;
+  if(entity_poly_seq_) {
+    entity_poly_seq_.reset();
   }
-  if(chem_comp_ != NULL) {
-    delete chem_comp_;
+  if(chem_comp_) {
+    chem_comp_.reset();
   }
 
   atom_type_ = Setup_atom_type_ptr();
@@ -1559,29 +1521,27 @@ void MMCifWriter::SetStructure(const ost::mol::EntityHandle& ent,
 
   std::map<String, CompInfo> comp_infos;
 
-  // The SetStructure functions fill comp_info and entity_info_, i.e. gather
+  // The ProcessEnt functions fill comp_info and entity_info_, i.e. gather
   // info on all unique compounds and entities observed in ent and relate the
   // entities with asym chain names that are directly written to
   // atom_site_/pdbx_poly_seq_scheme_.
   if(mmcif_conform) {
     // chains are assumed to be mmCIF conform - that means water in separate
     // chains, ligands in separate chains etc. Chain types are inferred from
-    // chain type property set to the chains in ent. If any of the residues in
-    // the respective chains is incompatible with the set chain type, an error
-    // is thrown.
-    SetStructure_(ent, comp_infos, entity_info_,
-                  atom_site_, pdbx_poly_seq_scheme_);
+    // chain type property set to the chains in ent.
+    ProcessEnt(ent, comp_infos, entity_info_,
+            atom_site_, pdbx_poly_seq_scheme_);
   } else {
     // rule based splitting of chains into mmCIF conform chains
-    SetStructuremmCIFify_(ent, comp_infos, entity_info_,
-                          atom_site_, pdbx_poly_seq_scheme_);
+    ProcessEntmmCIFify(ent, comp_infos, entity_info_,
+                       atom_site_, pdbx_poly_seq_scheme_);
   } 
-  Feed_entity_(entity_, entity_info_);
-  Feed_struct_asym_(struct_asym_, entity_info_);
-  Feed_entity_poly_(entity_poly_, entity_info_);
-  Feed_entity_poly_seq_(entity_poly_seq_, entity_info_);
-  Feed_chem_comp_(chem_comp_, comp_infos);
-  Feed_atom_type_(atom_type_, atom_site_); 
+  Feed_entity(entity_, entity_info_);
+  Feed_struct_asym(struct_asym_, entity_info_);
+  Feed_entity_poly(entity_poly_, entity_info_);
+  Feed_entity_poly_seq(entity_poly_seq_, entity_info_);
+  Feed_chem_comp(chem_comp_, comp_infos);
+  Feed_atom_type(atom_type_, atom_site_); 
 
   // finalize
   this->Push(chem_comp_);
diff --git a/modules/io/src/mol/mmcif_writer.hh b/modules/io/src/mol/mmcif_writer.hh
index fd91f67499927c8a580354f95f14ac16bb7a5175..be110936480178a3db6a8b378871d787d68fdae2 100644
--- a/modules/io/src/mol/mmcif_writer.hh
+++ b/modules/io/src/mol/mmcif_writer.hh
@@ -70,21 +70,21 @@ public:
 
   MMCifWriter(const String& filename, const IOProfile& profile);
 
-  virtual ~MMCifWriter();
+  virtual ~MMCifWriter() { }
 
   void SetStructure(const ost::mol::EntityHandle& ent, bool mmcif_conform=true);
 
 private:
   IOProfile profile_;
   std::vector<MMCifWriterEntity> entity_info_;
-  StarLoop* atom_type_;
-  StarLoop* atom_site_;
-  StarLoop* pdbx_poly_seq_scheme_;
-  StarLoop* entity_;
-  StarLoop* struct_asym_;
-  StarLoop* entity_poly_;
-  StarLoop* entity_poly_seq_;
-  StarLoop* chem_comp_;
+  StarWriterLoopPtr atom_type_;
+  StarWriterLoopPtr atom_site_;
+  StarWriterLoopPtr pdbx_poly_seq_scheme_;
+  StarWriterLoopPtr entity_;
+  StarWriterLoopPtr struct_asym_;
+  StarWriterLoopPtr entity_poly_;
+  StarWriterLoopPtr entity_poly_seq_;
+  StarWriterLoopPtr chem_comp_;
 };
 
 }} // ns
diff --git a/modules/io/src/mol/star_base.hh b/modules/io/src/mol/star_base.hh
deleted file mode 100644
index 1441d2db6672b71e72205ef2d9b0d787ad1f20e0..0000000000000000000000000000000000000000
--- a/modules/io/src/mol/star_base.hh
+++ /dev/null
@@ -1,323 +0,0 @@
-//------------------------------------------------------------------------------
-// This file is part of the OpenStructure project <www.openstructure.org>
-//
-// Copyright (C) 2008-2023 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_STAR_BASE_HH
-#define OST_IO_STAR_BASE_HH
-
-#include <map>
-#include <algorithm>
-#include <ost/string_ref.hh>
-#include <ost/io/io_exception.hh>
-
-namespace{
-  // float to string with specified number of decimals
-  void fts(Real f, int decimals, String& s) {
-    char data[20];
-    size_t len;
-    switch(decimals){
-      case 0:
-        len = std::snprintf(data, sizeof(data), "%.0f", f);
-        break;
-      case 1:
-        len = std::snprintf(data, sizeof(data), "%.1f", f);
-        break;
-      case 2:
-        len = std::snprintf(data, sizeof(data), "%.2f", f);
-        break;
-      case 3:
-        len = std::snprintf(data, sizeof(data), "%.3f", f);
-        break;
-      case 4:
-        len = std::snprintf(data, sizeof(data), "%.4f", f);
-        break;
-      case 5:
-        len = std::snprintf(data, sizeof(data), "%.5f", f);
-        break;
-      case 6:
-        len = std::snprintf(data, sizeof(data), "%.6f", f);
-        break;
-      default:
-        throw ost::io::IOException("Max decimals in float conversion: 6");
-    }
-  
-    if(len < 0 || len > 20) {
-      throw ost::io::IOException("float conversion failed");
-    }
-    s.assign(data, len);
-  }
-}
-
-namespace ost { namespace io {
-
-
-typedef enum {
-  STAR_DIAG_WARNING,
-  STAR_DIAG_ERROR
-} StarDiagType;
-
-
-class DLLEXPORT_OST_IO StarObject {
-public:
-  virtual ~StarObject() { }
-  virtual void ToStream(std::ostream& s) = 0;
-};
-
-class DLLEXPORT_OST_IO StarDataItem : public StarObject{
-public:
-  StarDataItem(const StringRef& category, const StringRef& name, 
-                const StringRef& value): 
-    category_(category), name_(name), value_(value)
-  { }
-
-  virtual void ToStream(std::ostream& s) {
-    s << category_ << '.' << name_ << ' ' << value_ << std::endl;
-  }
-
-  const StringRef& GetCategory() const { return category_; }
-  const StringRef& GetName() const { return name_; }
-  const StringRef& GetValue() const { return value_; }
-private:
-  StringRef category_;
-  StringRef name_;
-  StringRef value_;
-};
-
-
-class DLLEXPORT_OST_IO StarDataItemDO : public StarObject{
-  // basically a copy of StarDataItem but with data ownership
-  // Problem with StringRef: It's purely pointer based
-  // => data needs to reside elsewhere
-public:
-  StarDataItemDO(const String& category, const String& name, 
-                 const String& value): 
-    category_(category), name_(name)
-  {
-    // cases we still need to deal with:
-    // - special characters in strings (put in quotation marks)
-    // - long strings (semicolon based syntax)
-    // see https://mmcif.wwpdb.org/docs/tutorials/mechanics/pdbx-mmcif-syntax.html
-    if(value == "") {
-      value_ = ".";
-    } else {
-      value_ = value;
-    }
-  }
-
-  StarDataItemDO(const String& category, const String& name, 
-                 Real value, int decimals): 
-    category_(category), name_(name)
-  {
-    fts(value, decimals, value_);
-  }
-
-  StarDataItemDO(const String& category, const String& name, 
-                 int value): 
-    category_(category), name_(name)
-  {
-    value_ = std::to_string(value);
-  }
-
-  virtual void ToStream(std::ostream& s) {
-    s << category_ << '.' << name_ << ' ' << value_ << std::endl;
-  }
-
-  const String& GetCategory() const { return category_; }
-  const String& GetName() const { return name_; }
-  const String& GetValue() const { return value_; }
-private:
-  String category_;
-  String name_;
-  String value_;
-};
-
-class DLLEXPORT_OST_IO StarDataCategoryDO : public StarObject {
-public:
-  StarDataCategoryDO(const String& category): category_(category) {}
-
-  void Add(const StarDataItemDO& data_item) {
-    if(data_item.GetCategory() != category_) {
-      throw ost::io::IOException("category mismatch");
-    }
-    data_items_.push_back(data_item);
-  }
-
-  virtual void ToStream(std::ostream& s) {
-    for(auto it = data_items_.begin(); it != data_items_.end(); ++it) {
-      it->ToStream(s);
-    }
-  }
-
-private:
-  String category_;
-  std::vector<StarDataItemDO> data_items_;
-};
-
-class DLLEXPORT_OST_IO StarLoopDesc : public StarObject {
-public:
-  StarLoopDesc():
-    category_("")
-  { }
-  
-  int GetIndex(const String& name) const
-  {
-    std::map<String, int>::const_iterator i=index_map_.find(name);
-    return i==index_map_.end() ? -1 : i->second;
-  }
-  
-  void SetCategory(const StringRef& category)
-  {
-    category_=category.str();
-  }
-
-  void SetCategory(const String& category)
-  {
-    category_=category;
-  }  
-
-  void Add(const StringRef& name)
-  {
-    index_map_.insert(std::make_pair(name.str(), index_map_.size()));
-  }
-  void Add(const String& name)
-  {
-    index_map_.insert(std::make_pair(name, index_map_.size()));
-  }
-  size_t GetSize() const 
-  {
-    return index_map_.size();
-  }
-  void Clear()
-  {
-    category_.clear();
-    index_map_.clear();
-  }
-
-  virtual void ToStream(std::ostream& s) {
-    std::vector<std::pair<int, String> > tmp;
-    for(auto it = index_map_.begin(); it != index_map_.end(); ++it) {
-      tmp.push_back(std::make_pair(it->second, it->first));
-    }
-    std::sort(tmp.begin(), tmp.end());
-    for(auto it = tmp.begin(); it != tmp.end(); ++it) {
-      s << category_ << "." << it->second << std::endl;
-    }
-  }
-
-  const String& GetCategory() const { return category_; }
-private:
-  String                category_;
-  std::map<String, int> index_map_;
-};
-
-class DLLEXPORT_OST_IO StarLoopDataItemDO{
-public:
-
-  StarLoopDataItemDO(const String& value) {
-    // cases we still need to deal with:
-    // - special characters in strings (put in quotation marks)
-    // - long strings (semicolon based syntax)
-    // see https://mmcif.wwpdb.org/docs/tutorials/mechanics/pdbx-mmcif-syntax.html
-
-
-    bool has_space = false;
-    for(char c: value) {
-      if(isspace(c)) {
-        has_space = true;
-        break;
-      }
-    }
-    if(value == "") {
-      value_ = ".";
-    } else if(has_space) {
-      value_ = "'" + value + "'";
-    }
-    else {
-      value_ = value;
-    }
-  }
-
-  StarLoopDataItemDO(Real value, int decimals) {
-    fts(value, decimals, value_);
-  }
-
-  StarLoopDataItemDO(int value) {
-    value_ = std::to_string(value);
-  }
-
-  const String& GetValue() const { return value_; }
-
-  virtual void ToStream(std::ostream& s) {
-    s << value_;
-  }
-
-private:
-  String value_;
-};
-
-class DLLEXPORT_OST_IO StarLoop: public StarObject {
-public:
-
-  StarLoop() { }
-
-  StarLoop(const StarLoopDesc& desc): desc_(desc) { }
-
-  void SetDesc(const StarLoopDesc& desc) {
-    if(!data_.empty()) {
-      throw ost::io::IOException("Can only set new StarLoop desc in "
-                                 "in empty loop");
-    }
-    desc_ = desc;
-  }
-
-  const StarLoopDesc& GetDesc() { return desc_; }
-
-  void AddData(const std::vector<StarLoopDataItemDO>& data) {
-    if(data.size() != desc_.GetSize()) {
-      throw ost::io::IOException("Invalid data size when adding to StarLoop");
-    }
-    data_.insert(data_.end(), data.begin(), data.end());
-  }
-
-  const std::vector<StarLoopDataItemDO>& GetData() { return data_; }
-
-  int GetN() {
-    return data_.size() / desc_.GetSize();
-  }
-
-  virtual void ToStream(std::ostream& s) {
-    s << "loop_" << std::endl;
-    desc_.ToStream(s);
-    int desc_size = desc_.GetSize();
-    for(size_t i = 0; i < data_.size(); ++i) {
-      data_[i].ToStream(s);
-      if((i+1) % desc_size == 0) {
-        s << std::endl;
-      } else {
-        s << ' ';
-      }
-    }
-  }
-
-private:
-  StarLoopDesc desc_;
-  std::vector<StarLoopDataItemDO> data_;
-};
- 
-}} // ns
-
-#endif
diff --git a/modules/io/src/mol/star_parser.hh b/modules/io/src/mol/star_parser.hh
index 0d13b1a50ab4be12b2da85c72adf725f4bee4d59..bc6a3947a6694ec83e8e3fd699d30223cc87359f 100644
--- a/modules/io/src/mol/star_parser.hh
+++ b/modules/io/src/mol/star_parser.hh
@@ -31,10 +31,70 @@
 #include <map>
 #include <ost/string_ref.hh>
 #include <ost/io/module_config.hh>
-#include <ost/io/mol/star_base.hh>
 
 namespace ost { namespace io {
 
+
+typedef enum {
+  STAR_DIAG_WARNING,
+  STAR_DIAG_ERROR
+} StarDiagType;
+
+
+class DLLEXPORT_OST_IO StarDataItem {
+public:
+  StarDataItem(const StringRef& category, const StringRef& name, 
+                const StringRef& value): 
+    category_(category), name_(name), value_(value)
+  { }
+  const StringRef& GetCategory() const { return category_; }
+  const StringRef& GetName() const { return name_; }
+  const StringRef& GetValue() const { return value_; }
+private:
+  StringRef category_;
+  StringRef name_;
+  StringRef value_;
+};
+
+class DLLEXPORT_OST_IO StarLoopDesc {
+public:
+  StarLoopDesc():
+    category_("")
+  { }
+  
+  int GetIndex(const String& name) const
+  {
+    std::map<String, int>::const_iterator i=index_map_.find(name);
+    return i==index_map_.end() ? -1 : i->second;
+  }
+  
+  void SetCategory(const StringRef& category)
+  {
+    category_=category.str();
+  }
+  
+
+
+  void Add(const StringRef& name)
+  {
+    index_map_.insert(std::make_pair(name.str(), index_map_.size()));
+  }
+  size_t GetSize() const 
+  {
+    return index_map_.size();
+  }
+  void Clear()
+  {
+    category_.clear();
+    index_map_.clear();
+  }
+
+  const String& GetCategory() const { return category_; }
+private:
+  String                category_;
+  std::map<String, int> index_map_;
+};
+
 /// \brief parser for the STAR file format
 /// 
 /// \section star_format STAR format description
diff --git a/modules/io/src/mol/star_writer.hh b/modules/io/src/mol/star_writer.hh
index f858e021a81ff6e0e012dd29c7c6f4291258c1ac..3ef9c64c06cbc64baad51867828acc8378caf445 100644
--- a/modules/io/src/mol/star_writer.hh
+++ b/modules/io/src/mol/star_writer.hh
@@ -23,26 +23,283 @@
 #include <fstream>
 #include <boost/iostreams/filtering_stream.hpp>
 #include <boost/iostreams/filter/gzip.hpp>
+#include <boost/shared_ptr.hpp>
 #include <ost/string_ref.hh>
-#include <ost/io/mol/star_base.hh>
+#include <ost/io/io_exception.hh>
 
+namespace{
+  // float to string with specified number of decimals
+  void fts(Real f, int decimals, String& s) {
+    char data[20];
+    size_t len;
+    switch(decimals){
+      case 0:
+        len = std::snprintf(data, sizeof(data), "%.0f", f);
+        break;
+      case 1:
+        len = std::snprintf(data, sizeof(data), "%.1f", f);
+        break;
+      case 2:
+        len = std::snprintf(data, sizeof(data), "%.2f", f);
+        break;
+      case 3:
+        len = std::snprintf(data, sizeof(data), "%.3f", f);
+        break;
+      case 4:
+        len = std::snprintf(data, sizeof(data), "%.4f", f);
+        break;
+      case 5:
+        len = std::snprintf(data, sizeof(data), "%.5f", f);
+        break;
+      case 6:
+        len = std::snprintf(data, sizeof(data), "%.6f", f);
+        break;
+      default:
+        throw ost::io::IOException("Max decimals in float conversion: 6");
+    }
+  
+    if(len < 0 || len > 20) {
+      throw ost::io::IOException("float conversion failed");
+    }
+    s.assign(data, len);
+  }
+}
 
 namespace ost { namespace io {
 
+class StarWriterObject;
+class StarWriterDataItem;
+class StarWriterDataCategory;
+class StarWriterLoopDesc;
+class StarWriterLoopDataItem;
+class StarWriterLoop;
+typedef boost::shared_ptr<StarWriterObject> StarWriterObjectPtr;
+typedef boost::shared_ptr<StarWriterDataItem> StarWriterDataItemPtr;
+typedef boost::shared_ptr<StarWriterDataCategory> StarWriterDataCategoryPtr;
+typedef boost::shared_ptr<StarWriterLoopDesc> StarWriterLoopDescPtr;
+typedef boost::shared_ptr<StarWriterLoopDataItem> StarWriterLoopDataItemPtr;
+typedef boost::shared_ptr<StarWriterLoop> StarWriterLoopPtr;
+
+class DLLEXPORT_OST_IO StarWriterObject {
+public:
+  virtual ~StarWriterObject() { }
+  virtual void ToStream(std::ostream& s) = 0;
+};
+
+class DLLEXPORT_OST_IO StarWriterDataItem : public StarWriterObject {
+
+public:
+  StarWriterDataItem(const String& category, const String& name, 
+                     const String& value): category_(category), name_(name) {
+    // cases we still need to deal with:
+    // - special characters in strings (put in quotation marks)
+    // - long strings (semicolon based syntax)
+    // see https://mmcif.wwpdb.org/docs/tutorials/mechanics/pdbx-mmcif-syntax.html
+    if(value == "") {
+      value_ = ".";
+    } else {
+      value_ = value;
+    }
+  }
+
+  StarWriterDataItem(const String& category, const String& name, 
+                     Real value, int decimals):  category_(category),
+                                                 name_(name) {
+    fts(value, decimals, value_);
+  }
+
+  StarWriterDataItem(const String& category, const String& name, 
+                     int value): category_(category), name_(name) {
+    value_ = std::to_string(value);
+  }
+
+  virtual void ToStream(std::ostream& s) {
+    s << category_ << '.' << name_ << ' ' << value_ << std::endl;
+  }
+
+  const String& GetCategory() const { return category_; }
+  const String& GetName() const { return name_; }
+  const String& GetValue() const { return value_; }
+private:
+  String category_;
+  String name_;
+  String value_;
+};
+
+class DLLEXPORT_OST_IO StarWriterDataCategory : public StarWriterObject {
+public:
+  StarWriterDataCategory(const String& category): category_(category) { }
+
+  void Add(const StarWriterDataItem& data_item) {
+    if(data_item.GetCategory() != category_) {
+      throw ost::io::IOException("category mismatch");
+    }
+    data_items_.push_back(data_item);
+  }
+
+  virtual void ToStream(std::ostream& s) {
+    for(auto it = data_items_.begin(); it != data_items_.end(); ++it) {
+      it->ToStream(s);
+    }
+  }
+
+private:
+  String category_;
+  std::vector<StarWriterDataItem> data_items_;
+};
+
+class DLLEXPORT_OST_IO StarWriterLoopDesc : public StarWriterObject {
+public:
+  StarWriterLoopDesc(): category_("") { }
+  
+  int GetIndex(const String& name) const {
+    std::map<String, int>::const_iterator i=index_map_.find(name);
+    return i==index_map_.end() ? -1 : i->second;
+  }
+
+  void SetCategory(const String& category) {
+    category_=category;
+  }  
+
+  void Add(const String& name) {
+    index_map_.insert(std::make_pair(name, index_map_.size()));
+  }
+
+  size_t GetSize() const  {
+    return index_map_.size();
+  }
+
+  void Clear() {
+    category_.clear();
+    index_map_.clear();
+  }
+
+  virtual void ToStream(std::ostream& s) {
+    std::vector<std::pair<int, String> > tmp;
+    for(auto it = index_map_.begin(); it != index_map_.end(); ++it) {
+      tmp.push_back(std::make_pair(it->second, it->first));
+    }
+    std::sort(tmp.begin(), tmp.end());
+    for(auto it = tmp.begin(); it != tmp.end(); ++it) {
+      s << category_ << "." << it->second << std::endl;
+    }
+  }
+
+  const String& GetCategory() const { return category_; }
+private:
+  String                category_;
+  std::map<String, int> index_map_;
+};
+
+class DLLEXPORT_OST_IO StarWriterLoopDataItem{
+public:
+
+  StarWriterLoopDataItem(const String& value) {
+    // cases we still need to deal with:
+    // - special characters in strings (put in quotation marks)
+    // - long strings (semicolon based syntax)
+    // see https://mmcif.wwpdb.org/docs/tutorials/mechanics/pdbx-mmcif-syntax.html
+
+
+    bool has_space = false;
+    for(char c: value) {
+      if(isspace(c)) {
+        has_space = true;
+        break;
+      }
+    }
+    if(value == "") {
+      value_ = ".";
+    } else if(has_space) {
+      value_ = "'" + value + "'";
+    }
+    else {
+      value_ = value;
+    }
+  }
+
+  StarWriterLoopDataItem(Real value, int decimals) {
+    fts(value, decimals, value_);
+  }
+
+  StarWriterLoopDataItem(int value) {
+    value_ = std::to_string(value);
+  }
+
+  const String& GetValue() const { return value_; }
+
+  virtual void ToStream(std::ostream& s) {
+    s << value_;
+  }
+
+private:
+  String value_;
+};
+
+class DLLEXPORT_OST_IO StarWriterLoop: public StarWriterObject {
+public:
+
+  StarWriterLoop() { }
+
+  StarWriterLoop(const StarWriterLoopDesc& desc): desc_(desc) { }
+
+  void SetDesc(const StarWriterLoopDesc& desc) {
+    if(!data_.empty()) {
+      throw ost::io::IOException("Can only set new StarLoop desc in "
+                                 "in empty loop");
+    }
+    desc_ = desc;
+  }
+
+  const StarWriterLoopDesc& GetDesc() { return desc_; }
+
+  void AddData(const std::vector<StarWriterLoopDataItem>& data) {
+    if(data.size() != desc_.GetSize()) {
+      throw ost::io::IOException("Invalid data size when adding to StarLoop");
+    }
+    data_.insert(data_.end(), data.begin(), data.end());
+  }
+
+  const std::vector<StarWriterLoopDataItem>& GetData() { return data_; }
+
+  int GetN() {
+    return data_.size() / desc_.GetSize();
+  }
+
+  virtual void ToStream(std::ostream& s) {
+    s << "loop_" << std::endl;
+    desc_.ToStream(s);
+    int desc_size = desc_.GetSize();
+    for(size_t i = 0; i < data_.size(); ++i) {
+      data_[i].ToStream(s);
+      if((i+1) % desc_size == 0) {
+        s << std::endl;
+      } else {
+        s << ' ';
+      }
+    }
+  }
+
+private:
+  StarWriterLoopDesc desc_;
+  std::vector<StarWriterLoopDataItem> data_;
+};
+
+
 class DLLEXPORT_OST_IO StarWriter {
 public:
   StarWriter(std::ostream& stream);
   StarWriter(const String& filename);
   virtual ~StarWriter() { }
 
-  void Push(StarObject* obj) { categories_to_write_.push_back(obj); }
+  void Push(StarWriterObjectPtr obj) { categories_to_write_.push_back(obj); }
   void Write(const String& data_name);
 private:
   String filename_;
   bool file_open_;
   std::ofstream fstream_;
   boost::iostreams::filtering_stream<boost::iostreams::output> stream_;
-  std::vector<StarObject*> categories_to_write_;
+  std::vector<StarWriterObjectPtr> categories_to_write_;
 };
 
 }} // ns