diff --git a/modules/mol/base/pymod/export_query.cc b/modules/mol/base/pymod/export_query.cc
index 7930cd4260d5f5a335aa5b5c5fc68da405f0de43..8f1fc94605e6beed10d61b0f65f94733fcd05f78 100644
--- a/modules/mol/base/pymod/export_query.cc
+++ b/modules/mol/base/pymod/export_query.cc
@@ -68,5 +68,5 @@ void export_Query()
          return_value_policy<copy_const_reference>())
   ;
   
-
+  def("QueryQuoteName", &QueryQuoteName);
 }
diff --git a/modules/mol/base/src/query.hh b/modules/mol/base/src/query.hh
index c76454670162e200696f62f6d9a7f17b422d4f20..d855703c3e55f3e366bbda51b8c6dc79e309e114 100644
--- a/modules/mol/base/src/query.hh
+++ b/modules/mol/base/src/query.hh
@@ -117,6 +117,25 @@ private:
   impl::QueryImplP   impl_;
 };
 
+// inlined helper function to quote strings for use in queries (e.g. cname=..).
+// throws Error if string cannot be quoted
+inline String DLLEXPORT_OST_MOL QueryQuoteName(const String& name) {
+  // check what quotation marks to use
+  char quote = '\'';
+  if (name.find('\'') != String::npos) {
+    if (name.find('"') != String::npos) {
+      throw Error("Cannot quote chain name " + name + " because it contains '"
+                  " and \" in its name.");
+    }
+    quote = '"';
+  }
+  // check problematic \ at end (escapes quotation mark and breaks logic)
+  if (name[name.length() - 1] == '\\') {
+    throw Error("Cannot quote chain name " + name + "because it ends in \\.");
+  }
+  return quote + name + quote;
+}
+
 }} // ns
 
 #endif
diff --git a/modules/mol/base/tests/test_query.cc b/modules/mol/base/tests/test_query.cc
index 57fc557bfd58947ea592d013b609ebc91650fa60..5f8865ae5b71d48e0247615b106ce34525f192bf 100644
--- a/modules/mol/base/tests/test_query.cc
+++ b/modules/mol/base/tests/test_query.cc
@@ -286,7 +286,7 @@ BOOST_AUTO_TEST_CASE(test_query_throw)
   BOOST_CHECK_NO_THROW(e.Select("gcnotsetprop:0=1"));
 }
 
-BOOST_AUTO_TEST_CASE(test_glob) 
+BOOST_AUTO_TEST_CASE(test_glob)
 {
   EntityHandle e=make_query_test_entity();
   ensure_counts(e, "rname=MET and aname=C*", 1, 1, 5);
@@ -299,4 +299,48 @@ BOOST_AUTO_TEST_CASE(test_glob)
   ensure_counts(e, "rname=LEU and aname=?D?", 1, 1, 2);
 }
 
+BOOST_AUTO_TEST_CASE(test_quoting)
+{
+  // possible letters taken from mmCIF dictionary
+  // -> http://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Items/_atom_site.label_asym_id.html
+  // not ok for us: '\' alone
+  String single_letters = " ][_,.;:\"&<>()/{}'`~!@#$\%|+-"
+                          "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh"
+                          "ijklmnopqrstuvwxyz";
+  // put into vector
+  std::vector<String> chain_names;
+  for (size_t i = 0; i < single_letters.length(); ++i) {
+    chain_names.push_back(String(1, single_letters[i]));
+  }
+  // add some multi letter names and empty chain name too
+  // not ok: mixing ' and ", '\' at end
+  chain_names.push_back("\\ ][_,.;:&<>()/{}'`~!@#$\%|+-");
+  chain_names.push_back("ABCDEFGHIJKLMNOPQRSTU'VWXYZ0123456789abcdefgh");
+  chain_names.push_back("ijklmno\"pqrstuvwxyz");
+  chain_names.push_back("");
+  // setup entity
+  EntityHandle ent = CreateEntity();
+  XCSEditor edi = ent.EditXCS();
+  for (size_t i = 0; i < chain_names.size(); ++i) {
+    edi.InsertChain(chain_names[i]);
+  }
+  // test quoting
+  String query_all = "cname=";
+  for (size_t i = 0; i < chain_names.size(); ++i) {
+    const String quoted_name = QueryQuoteName(chain_names[i]);
+    BOOST_CHECK_EQUAL(ent.Select("cname=" + quoted_name).GetChainCount(), 1);
+    query_all += quoted_name;
+    if (i != chain_names.size() - 1) query_all += ",";
+  }
+  BOOST_CHECK_EQUAL(ent.Select(query_all).GetChainCount(),
+                    int(chain_names.size()));
+  // note: quoting * keeps it as wild card!
+  BOOST_CHECK_EQUAL(ent.Select("cname=" + QueryQuoteName("*")).GetChainCount(),
+                    int(chain_names.size()));
+  // expected failures (mixing ' and ", '\' at end)
+  BOOST_CHECK_THROW(QueryQuoteName("'\""), Error);
+  BOOST_CHECK_THROW(QueryQuoteName("\\"), Error);
+  BOOST_CHECK_THROW(QueryQuoteName("a\\"), Error);
+}
+
 BOOST_AUTO_TEST_SUITE_END();