diff --git a/modules/io/pymod/export_mmcif_io.cc b/modules/io/pymod/export_mmcif_io.cc
index cb12690443525ac61625e1f93d50aaf3e76c1646..0d3759a4364726841a8555b86d8eb8577d47ad41 100644
--- a/modules/io/pymod/export_mmcif_io.cc
+++ b/modules/io/pymod/export_mmcif_io.cc
@@ -77,7 +77,7 @@ void export_mmcif_io()
     ;
 
   class_<MMCifWriter, boost::noncopyable>("MMCifWriter", init<const String&, const IOProfile&>())
-    .def("Process_atom_site", &MMCifWriter::Process_atom_site)
+    .def("SetEntity", &MMCifWriter::SetEntity)
     .def("Write", &MMCifWriter::Write)
     ;
 
diff --git a/modules/io/src/mol/mmcif_writer.cc b/modules/io/src/mol/mmcif_writer.cc
index 65a65774aa23f1aa90787e5dc2a9b8e75fdfca78..8632bba6ff251aaa5579eef4b3b05a995cd09b18 100644
--- a/modules/io/src/mol/mmcif_writer.cc
+++ b/modules/io/src/mol/mmcif_writer.cc
@@ -70,12 +70,133 @@ namespace {
     std::vector<int> indices;
   };
 
+  // internal object with all info to fill chem_comp_ category
+  struct CompInfo {
+    String type;
+  };
+
+  inline String chem_class_to_chem_comp_type(char chem_class) {
+    String type = "";
+    switch(chem_class) {
+      case 'P': {
+        type = "peptide linking";
+        break;
+      }
+      case 'D': {
+        type = "D-peptide linking";
+        break;
+      }
+      case 'L': {
+        type = "L-peptide linking";
+        break;
+      }
+      case 'R': {
+        type = "RNA linking";
+        break;
+      }
+      case 'S': {
+        type = "DNA linking";
+        break;
+      }
+      case 'N': {
+        type = "non-polymer";
+        break;
+      }
+      case 'X': {
+        type = "L-saccharide";
+        break;
+      }
+      case 'Y': {
+        type = "D-saccharide";
+        break;
+      }
+      case 'Z': {
+        type = "saccharide";
+        break;
+      }
+      case 'W': {
+        type = "non-polymer";
+        break;
+      }
+      case 'U': {
+        type = "non-polymer";
+        break;
+      }
+      default: {
+        std::stringstream err;
+        err << "Invalid chem class: "<<chem_class;
+        throw ost::io::IOException(err.str());
+
+      }
+    }
+    return type;
+  }
+
+  inline String chem_class_to_entity_poly_type(char chem_class) {
+    String type = "";
+    switch(chem_class) {
+      case 'P': {
+        type = "polypeptide(L)";
+        break;
+      }
+      case 'D': {
+        type = "polypeptide(D)";
+        break;
+      }
+      case 'L': {
+        type = "polypeptide(L)";
+        break;
+      }
+      case 'R': {
+        type = "polyribonucleotide";
+        break;
+      }
+      case 'S': {
+        type = "polydeoxyribonucleotide";
+        break;
+      }
+      case 'X': {
+        type = "polysaccharide(L)";
+        break;
+      }
+      case 'Y': {
+        type = "polysaccharide(D)";
+        break;
+      }
+      default: {
+        type = "other";
+      }
+    }
+    return type;
+  }
+
+  void Setup_chem_comp_(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());
+      auto it = comp_infos.find(res_name);
+      if(it != comp_infos.end()) {
+        // check whether type is consistent
+        if(it->second.type != type) {
+          throw ost::io::IOException("There can be only one");
+        }
+      } else {
+        CompInfo info;
+        info.type = type;
+        comp_infos[res_name] = info;
+      }
+    }
+  }
+
   // internal object with all info to fill entity_, struct_asym_,
   // entity_poly_seq_ categories
   struct EntityInfo {
     char chem_class; // all residues of this entity have this ChemClass
+    String poly_type; // relevant for _entity_poly
     std::vector<String> asym_ids; // relevant for _struct_asym.id
     std::vector<String> mon_ids; // relevant for _entity_poly_seq.mon_id
+    bool is_poly; // in principle mon_ids.size() > 1
   };
 
   int Setup_entity_(const String& asym_chain_name,
@@ -97,6 +218,8 @@ namespace {
       entity_infos.back().chem_class = ost::mol::ChemClass::WATER;
       entity_infos.back().asym_ids.push_back(asym_chain_name);
       entity_infos.back().mon_ids.push_back("HOH");
+      entity_infos.back().poly_type = "";
+      entity_infos.back().is_poly = false;
       return entity_idx; 
     }
 
@@ -114,6 +237,8 @@ namespace {
       entity_infos.back().chem_class = ost::mol::ChemClass::NON_POLYMER;
       entity_infos.back().asym_ids.push_back(asym_chain_name);
       entity_infos.back().mon_ids.push_back(res_list[0].GetName());
+      entity_infos.back().poly_type = "";
+      entity_infos.back().is_poly = false;
       return entity_idx;
     }
 
@@ -131,6 +256,8 @@ namespace {
       entity_infos.back().chem_class = ost::mol::ChemClass::UNKNOWN;
       entity_infos.back().asym_ids.push_back(asym_chain_name);
       entity_infos.back().mon_ids.push_back(res_list[0].GetName());
+      entity_infos.back().poly_type = "";
+      entity_infos.back().is_poly = false;
       return entity_idx;
     }
 
@@ -165,10 +292,20 @@ namespace {
       entity_infos.back().chem_class = chem_class;
       entity_infos.back().asym_ids.push_back(asym_chain_name);
       entity_infos.back().mon_ids = mon_ids;
+      entity_infos.back().poly_type = chem_class_to_entity_poly_type(chem_class);
+      entity_infos.back().is_poly = entity_infos.back().mon_ids.size() > 1;
     }
     return entity_idx;
   }
 
+  ost::io::StarLoop* Setup_atom_type_ptr() {
+    ost::io::StarLoopDesc desc;
+    desc.SetCategory("_atom_type");
+    desc.Add("symbol");
+    ost::io::StarLoop* sl = new ost::io::StarLoop(desc);
+    return sl;
+  }
+
   ost::io::StarLoop* Setup_atom_site_ptr() {
     ost::io::StarLoopDesc desc;
     desc.SetCategory("_atom_site");
@@ -193,6 +330,20 @@ namespace {
     return sl;
   }
 
+  ost::io::StarLoop* Setup_pdbx_poly_seq_scheme_ptr() {
+    ost::io::StarLoopDesc desc;
+    desc.SetCategory("_pdbx_poly_seq_scheme");
+    desc.Add("asym_id");
+    desc.Add("entity_id");
+    desc.Add("mon_id");
+    desc.Add("seq_id");
+    desc.Add("pdb_strand_id");
+    desc.Add("pdb_seq_num");
+    desc.Add("pdb_ins_code");
+    ost::io::StarLoop* sl = new ost::io::StarLoop(desc);
+    return sl;
+  }
+
   ost::io::StarLoop* Setup_entity_ptr() {
     ost::io::StarLoopDesc desc;
     desc.SetCategory("_entity");
@@ -211,6 +362,15 @@ namespace {
     return sl;    
   }
 
+  ost::io::StarLoop* Setup_entity_poly_ptr() {
+    ost::io::StarLoopDesc desc;
+    desc.SetCategory("_entity_poly");
+    desc.Add("entity_id");
+    desc.Add("type");
+    ost::io::StarLoop* sl = new ost::io::StarLoop(desc);
+    return sl;    
+  }
+
   ost::io::StarLoop* Setup_entity_poly_seq_ptr() {
     ost::io::StarLoopDesc desc;
     desc.SetCategory("_entity_poly_seq");
@@ -221,10 +381,72 @@ namespace {
     return sl;    
   }
 
+  ost::io::StarLoop* Setup_chem_comp_ptr() {
+    ost::io::StarLoopDesc desc;
+    desc.SetCategory("_chem_comp");
+    desc.Add("id");
+    desc.Add("type");
+    ost::io::StarLoop* sl = new ost::io::StarLoop(desc);
+    return sl;    
+  }
+
+  void Feed_atom_type_(ost::io::StarLoop* atom_type_ptr,
+                       ost::io::StarLoop* 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();
+    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(""));
+    for(auto symbol: symbols) {
+      atom_type_data[0] = ost::io::StarLoopDataItemDO(symbol);
+      atom_type_ptr->AddData(atom_type_data);
+    }
+  }
+
+  void Feed_pdbx_poly_seq_scheme(ost::io::StarLoop* pdbx_poly_seq_scheme_ptr,
+                                 const String& label_asym_id,
+                                 int label_entity_id,
+                                 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(""));
+    int label_seq_id = 1;
+    for(auto res: res_list) {
+      data[2] = ost::io::StarLoopDataItemDO(res.GetName());
+      data[3] = ost::io::StarLoopDataItemDO(label_seq_id);
+      data[4] = ost::io::StarLoopDataItemDO(res.GetChain().GetName());
+      data[5] = ost::io::StarLoopDataItemDO(res.GetNumber().GetNum());
+      char ins_code = res.GetNumber().GetInsCode();      
+      if(ins_code == '\0') {
+        data[6] = ost::io::StarLoopDataItemDO("");
+      } else {
+        String tmp = " ";
+        tmp[0] = ins_code;
+        data[6] = ost::io::StarLoopDataItemDO(tmp);
+      }      
+      pdbx_poly_seq_scheme_ptr->AddData(data);
+      label_seq_id += 1;
+    }
+  }
+
   void Feed_atom_site_(ost::io::StarLoop* atom_site_ptr,
                        const String& label_asym_id,
                        int label_entity_id,
-                       const ost::mol::ResidueHandleList& res_list) {
+                       const ost::mol::ResidueHandleList& res_list,
+                       bool is_poly) {
     int label_seq_id = 1;
     for(auto res: res_list) {
       String comp_id = res.GetName();
@@ -250,7 +472,11 @@ namespace {
         // label_entity_id
         at_data.push_back(ost::io::StarLoopDataItemDO(label_entity_id));
         // label_seq_id
-        at_data.push_back(ost::io::StarLoopDataItemDO(label_seq_id));
+        if(is_poly) {
+          at_data.push_back(ost::io::StarLoopDataItemDO(label_seq_id));
+        } else {
+          at_data.push_back(ost::io::StarLoopDataItemDO("."));
+        }
         // label_alt_id
         at_data.push_back(ost::io::StarLoopDataItemDO("."));
         // Cartn_x
@@ -319,22 +545,50 @@ namespace {
   void Feed_entity_poly_seq_(ost::io::StarLoop* entity_poly_seq_ptr,
                              const std::vector<EntityInfo>& entity_info) {
     // reuse data vector for efficiency
-    std::vector<ost::io::StarLoopDataItemDO> mon_data;
-    mon_data.push_back(ost::io::StarLoopDataItemDO(0));
-    mon_data.push_back(ost::io::StarLoopDataItemDO("ALA"));
-    mon_data.push_back(ost::io::StarLoopDataItemDO(1));
+    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));
+
+    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_ptr->AddData(entity_poly_seq_data);
+        }
+      }
+    }
+  }
 
+  void Feed_entity_poly_(ost::io::StarLoop* entity_poly_ptr,
+                         const std::vector<EntityInfo>& 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"));
     for(size_t entity_idx = 0; entity_idx < entity_info.size(); ++entity_idx) {
-      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) {
-        mon_data[0] = ost::io::StarLoopDataItemDO(entity_idx);
-        mon_data[1] = ost::io::StarLoopDataItemDO(mon_ids[mon_idx]);
-        mon_data[2] = ost::io::StarLoopDataItemDO(mon_idx+1);
-        entity_poly_seq_ptr->AddData(mon_data);
+      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_ptr->AddData(entity_poly_data);
       }
     }
   }
 
+  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"));
+    for(auto it = comp_infos.begin(); it != comp_infos.end(); ++it) {
+      comp_data[0] = it->first;
+      comp_data[1] = it->second.type;
+      chem_comp_ptr->AddData(comp_data);
+    }
+  }
 }
 
 namespace ost { namespace io {
@@ -342,47 +596,78 @@ namespace ost { namespace io {
 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_seq_(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_;
+  }
 }
 
-void MMCifWriter::Process_atom_site(const ost::mol::EntityHandle& ent) {
-
+void MMCifWriter::SetEntity(const ost::mol::EntityHandle& ent) {
 
   // tabula rasa
+  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_;
+  }
 
+  atom_type_ = Setup_atom_type_ptr();
   atom_site_ = Setup_atom_site_ptr();
+  pdbx_poly_seq_scheme_ = Setup_pdbx_poly_seq_scheme_ptr();
   entity_ = Setup_entity_ptr();
   struct_asym_ = Setup_struct_asym_ptr();
+  entity_poly_ = Setup_entity_poly_ptr();
   entity_poly_seq_ = Setup_entity_poly_seq_ptr();
+  chem_comp_ = Setup_chem_comp_ptr();
 
   std::vector<std::vector<ost::mol::ResidueHandle> > L_chains; // L_PEPTIDE_LINKING
   std::vector<std::vector<ost::mol::ResidueHandle> > D_chains; // D_PEPTIDE_LINKING
@@ -394,16 +679,18 @@ void MMCifWriter::Process_atom_site(const ost::mol::EntityHandle& ent) {
   std::vector<std::vector<ost::mol::ResidueHandle> > W_chains; // WATER
   std::vector<ost::mol::ResidueHandle> N_chains; // NON_POLYMER (1 res per chain)
   std::vector<ost::mol::ResidueHandle> U_chains; // UNKNOWN (1 res per chain)
+  std::map<String, CompInfo> comp_infos;
 
   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);
+
     // we don't just go for chain type here...
     // just think of PDB entries that have a polypeptide, water and a ligand
     // in the same chain...
-
     bool has_l_peptide_linking = false;
     bool has_d_peptide_linking = false;
     bool has_peptide_linking = false;
@@ -533,7 +820,12 @@ void MMCifWriter::Process_atom_site(const ost::mol::EntityHandle& ent) {
                                   ost::mol::ChemClass::L_PEPTIDE_LINKING,
                                   res_list,
                                   entity_info);
-    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list);
+    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list,
+                    entity_info[entity_id].is_poly);
+    if(entity_info[entity_id].is_poly) {
+      Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme_, chain_name,
+                                entity_id, res_list);
+    }
   }
 
   // process D_PEPTIDE_LINKING
@@ -543,7 +835,12 @@ void MMCifWriter::Process_atom_site(const ost::mol::EntityHandle& ent) {
                                   ost::mol::ChemClass::D_PEPTIDE_LINKING,
                                   res_list,
                                   entity_info);
-    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list);
+    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list,
+                    entity_info[entity_id].is_poly);
+    if(entity_info[entity_id].is_poly) {
+      Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme_, chain_name,
+                                entity_id, res_list);
+    }
   }
 
   // process PEPTIDE_LINKING
@@ -553,7 +850,12 @@ void MMCifWriter::Process_atom_site(const ost::mol::EntityHandle& ent) {
                                   ost::mol::ChemClass::PEPTIDE_LINKING,
                                   res_list,
                                   entity_info);
-    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list);
+    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list,
+                    entity_info[entity_id].is_poly);
+    if(entity_info[entity_id].is_poly) {
+      Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme_, chain_name,
+                                entity_id, res_list);
+    }
   }
 
   // process RNA_LINKING
@@ -563,7 +865,12 @@ void MMCifWriter::Process_atom_site(const ost::mol::EntityHandle& ent) {
                                   ost::mol::ChemClass::RNA_LINKING,
                                   res_list,
                                   entity_info);
-    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list);
+    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list,
+                    entity_info[entity_id].is_poly);
+    if(entity_info[entity_id].is_poly) {
+      Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme_, chain_name,
+                                entity_id, res_list);
+    }
   }
 
   // process DNA_LINKING
@@ -573,7 +880,12 @@ void MMCifWriter::Process_atom_site(const ost::mol::EntityHandle& ent) {
                                   ost::mol::ChemClass::DNA_LINKING,
                                   res_list,
                                   entity_info);
-    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list);
+    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list,
+                    entity_info[entity_id].is_poly);
+    if(entity_info[entity_id].is_poly) {
+      Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme_, chain_name,
+                                entity_id, res_list);
+    }
   }
 
   // process L_SACHARIDE
@@ -583,7 +895,12 @@ void MMCifWriter::Process_atom_site(const ost::mol::EntityHandle& ent) {
                                   ost::mol::ChemClass::L_SACCHARIDE,
                                   res_list,
                                   entity_info);
-    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list);
+    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list,
+                    entity_info[entity_id].is_poly);
+    if(entity_info[entity_id].is_poly) {
+      Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme_, chain_name,
+                                entity_id, res_list);
+    }
   }
 
   // process D_SACHARIDE
@@ -593,7 +910,12 @@ void MMCifWriter::Process_atom_site(const ost::mol::EntityHandle& ent) {
                                   ost::mol::ChemClass::D_SACCHARIDE,
                                   res_list,
                                   entity_info);
-    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list);
+    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list,
+                    entity_info[entity_id].is_poly);
+    if(entity_info[entity_id].is_poly) {
+      Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme_, chain_name,
+                                entity_id, res_list);
+    }
   }
 
   // process WATER
@@ -603,7 +925,12 @@ void MMCifWriter::Process_atom_site(const ost::mol::EntityHandle& ent) {
                                   ost::mol::ChemClass::WATER,
                                   res_list,
                                   entity_info);
-    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list);
+    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list,
+                    entity_info[entity_id].is_poly);
+    if(entity_info[entity_id].is_poly) {
+      Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme_, chain_name,
+                                entity_id, res_list);
+    }
   }
 
   // process NON_POLYMER
@@ -615,7 +942,12 @@ void MMCifWriter::Process_atom_site(const ost::mol::EntityHandle& ent) {
                                   ost::mol::ChemClass::NON_POLYMER,
                                   res_list,
                                   entity_info);
-    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list);
+    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list,
+                    entity_info[entity_id].is_poly);
+    if(entity_info[entity_id].is_poly) {
+      Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme_, chain_name,
+                                entity_id, res_list);
+    }
   }
 
   // process UNKNOWN
@@ -627,17 +959,29 @@ void MMCifWriter::Process_atom_site(const ost::mol::EntityHandle& ent) {
                                   ost::mol::ChemClass::UNKNOWN,
                                   res_list,
                                   entity_info);
-    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list);
+    Feed_atom_site_(atom_site_, chain_name, entity_id, res_list,
+                    entity_info[entity_id].is_poly);
+    if(entity_info[entity_id].is_poly) {
+      Feed_pdbx_poly_seq_scheme(pdbx_poly_seq_scheme_, chain_name,
+                                entity_id, res_list);
+    }
   }
 
   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_);
   this->Push(entity_);
   this->Push(struct_asym_);
+  this->Push(entity_poly_);
   this->Push(entity_poly_seq_);
+  this->Push(pdbx_poly_seq_scheme_);
+  this->Push(atom_type_);
   this->Push(atom_site_);
 }
 
diff --git a/modules/io/src/mol/mmcif_writer.hh b/modules/io/src/mol/mmcif_writer.hh
index d5f1e01bd18e66052232fff379e2495f3e5f53eb..619ff270d4093b15f346968315019d020db88b24 100644
--- a/modules/io/src/mol/mmcif_writer.hh
+++ b/modules/io/src/mol/mmcif_writer.hh
@@ -36,23 +36,20 @@ public:
 
   virtual ~MMCifWriter();
 
-  // initializes
-  // atom_site_
-  // entity_
-  // struct_asym_
-  // entity_poly_seq_
-  void Process_atom_site(const ost::mol::EntityHandle& ent);
+  void SetEntity(const ost::mol::EntityHandle& ent);
 
 private:
-
   IOProfile profile_;
+  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_;
 };
 
- 
 }} // ns
 
-#endif
\ No newline at end of file
+#endif
diff --git a/modules/io/src/mol/star_base.hh b/modules/io/src/mol/star_base.hh
index 2433a0af6bb9deed53657bc636f7a60982c73b11..1441d2db6672b71e72205ef2d9b0d787ad1f20e0 100644
--- a/modules/io/src/mol/star_base.hh
+++ b/modules/io/src/mol/star_base.hh
@@ -232,9 +232,21 @@ public:
     // - 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 {
+    } else if(has_space) {
+      value_ = "'" + value + "'";
+    }
+    else {
       value_ = value;
     }
   }
@@ -272,6 +284,8 @@ public:
     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");
@@ -279,6 +293,8 @@ public:
     data_.insert(data_.end(), data.begin(), data.end());
   }
 
+  const std::vector<StarLoopDataItemDO>& GetData() { return data_; }
+
   int GetN() {
     return data_.size() / desc_.GetSize();
   }