diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3904dad1..dd5d2e81 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,9 +52,21 @@ if(MSVC AND ENABLE_STATIC_RUNTIME)
   endforeach(flag_var)
 endif()
 
-set(TAGLIB_LIB_MAJOR_VERSION "1")
-set(TAGLIB_LIB_MINOR_VERSION "10")
-set(TAGLIB_LIB_PATCH_VERSION "0")
+# Read version information from file taglib/toolkit/taglib.h into variables
+# TAGLIB_LIB_MAJOR_VERSION, TAGLIB_LIB_MINOR_VERSION, TAGLIB_LIB_PATCH_VERSION.
+foreach(version_part MAJOR MINOR PATCH)
+  set(version_var_name "TAGLIB_${version_part}_VERSION")
+  file(STRINGS taglib/toolkit/taglib.h version_line
+       REGEX "^#define +${version_var_name}")
+  if(NOT version_line)
+    message(FATAL_ERROR "${version_var_name} not found in taglib.h")
+  endif()
+  string(REGEX MATCH "${version_var_name} +([^ ]+)" result ${version_line})
+  set(TAGLIB_LIB_${version_part}_VERSION ${CMAKE_MATCH_1})
+endforeach(version_part)
+
+# Only used to force cmake rerun when taglib.h changes.
+configure_file(taglib/toolkit/taglib.h ${CMAKE_CURRENT_BINARY_DIR}/taglib.h.stamp)
 
 if("${TAGLIB_LIB_PATCH_VERSION}" EQUAL "0")
   set(TAGLIB_LIB_VERSION_STRING "${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}")
diff --git a/NEWS b/NEWS
index 24d4525c..1c0d8383 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@
  * New API for creating FileRef from IOStream.
  * Added support for ID3v2 PCST and WFED frames.
  * Added String::clear().
+ * Added alternative functions to XiphComment::removeField().
  * Better handling of duplicate ID3v2 tags in all kinds of files.
  * Better handling of duplicate tags in WAV files.
  * Fixed crash when calling File::properties() after strip().
@@ -10,6 +11,7 @@
  * Fixed updating the comment field of Vorbis comments.
  * Marked ByteVector::null and ByteVector::isNull() deprecated.
  * Marked String::null and ByteVector::isNull() deprecated.
+ * Marked XiphComment::removeField() deprecated.
  * Many smaller bug fixes and performance improvements.
 
 TagLib 1.10 (Nov 11, 2015)
diff --git a/taglib/ogg/xiphcomment.cpp b/taglib/ogg/xiphcomment.cpp
index 263b96dd..af1f3efc 100644
--- a/taglib/ogg/xiphcomment.cpp
+++ b/taglib/ogg/xiphcomment.cpp
@@ -274,22 +274,36 @@ void Ogg::XiphComment::addField(const String &key, const String &value, bool rep
 
 void Ogg::XiphComment::removeField(const String &key, const String &value)
 {
-  if(!value.isNull()) {
-    StringList::Iterator it = d->fieldListMap[key].begin();
-    while(it != d->fieldListMap[key].end()) {
-      if(value == *it)
-        it = d->fieldListMap[key].erase(it);
-      else
-        it++;
-    }
-  }
+  if(!value.isNull())
+    removeFields(key, value);
   else
-    d->fieldListMap.erase(key);
+    removeFields(key);
+}
+
+void Ogg::XiphComment::removeFields(const String &key)
+{
+  d->fieldListMap.erase(key.upper());
+}
+
+void Ogg::XiphComment::removeFields(const String &key, const String &value)
+{
+  StringList &fields = d->fieldListMap[key.upper()];
+  for(StringList::Iterator it = fields.begin(); it != fields.end(); ) {
+    if(*it == value)
+      it = fields.erase(it);
+    else
+      ++it;
+  }
+}
+
+void Ogg::XiphComment::removeAllFields()
+{
+  d->fieldListMap.clear();
 }
 
 bool Ogg::XiphComment::contains(const String &key) const
 {
-  return d->fieldListMap.contains(key) && !d->fieldListMap[key].isEmpty();
+  return !d->fieldListMap[key.upper()].isEmpty();
 }
 
 ByteVector Ogg::XiphComment::render(bool addFramingBit) const
diff --git a/taglib/ogg/xiphcomment.h b/taglib/ogg/xiphcomment.h
index ec9cbd05..d2e414fc 100644
--- a/taglib/ogg/xiphcomment.h
+++ b/taglib/ogg/xiphcomment.h
@@ -184,9 +184,33 @@ namespace TagLib {
       /*!
        * Remove the field specified by \a key with the data \a value.  If
        * \a value is null, all of the fields with the given key will be removed.
+       *
+       * \deprecated Using this method may lead to a linkage error.
        */
+      // BIC: remove and merge with below
       void removeField(const String &key, const String &value = String::null);
 
+      /*!
+       * Remove all the fields specified by \a key.
+       *
+       * \see removeAllFields()
+       */
+      void removeFields(const String &key);
+
+      /*!
+       * Remove all the fields specified by \a key with the data \a value.
+       *
+       * \see removeAllFields()
+       */
+      void removeFields(const String &key, const String &value);
+
+      /*!
+       * Remove all the fields in the comment.
+       *
+       * \see removeFields()
+       */
+      void removeAllFields();
+
       /*!
        * Returns true if the field is contained within the comment.
        *
diff --git a/tests/test_xiphcomment.cpp b/tests/test_xiphcomment.cpp
index 00ae4f56..33a55412 100644
--- a/tests/test_xiphcomment.cpp
+++ b/tests/test_xiphcomment.cpp
@@ -1,7 +1,7 @@
 #include <string>
 #include <stdio.h>
-#include <flacfile.h>
 #include <xiphcomment.h>
+#include <vorbisfile.h>
 #include <tpropertymap.h>
 #include <tdebug.h>
 #include <cppunit/extensions/HelperMacros.h>
@@ -19,6 +19,7 @@ class TestXiphComment : public CppUnit::TestFixture
   CPPUNIT_TEST(testSetTrack);
   CPPUNIT_TEST(testInvalidKeys);
   CPPUNIT_TEST(testClearComment);
+  CPPUNIT_TEST(testRemoveFields);
   CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -78,20 +79,46 @@ public:
 
   void testClearComment()
   {
-    ScopedFileCopy copy("no-tags", ".flac");
+    ScopedFileCopy copy("empty", ".ogg");
 
     {
-      FLAC::File f(copy.fileName().c_str());
-      f.xiphComment()->addField("COMMENT", "Comment1");
+      Ogg::Vorbis::File f(copy.fileName().c_str());
+      f.tag()->addField("COMMENT", "Comment1");
       f.save();
     }
     {
-      FLAC::File f(copy.fileName().c_str());
-      f.xiphComment()->setComment("");
-      CPPUNIT_ASSERT_EQUAL(String(""), f.xiphComment()->comment());
+      Ogg::Vorbis::File f(copy.fileName().c_str());
+      f.tag()->setComment("");
+      CPPUNIT_ASSERT_EQUAL(String(""), f.tag()->comment());
     }
   }
 
+  void testRemoveFields()
+  {
+    Ogg::Vorbis::File f(TEST_FILE_PATH_C("empty.ogg"));
+    f.tag()->addField("title", "Title1");
+    f.tag()->addField("Title", "Title1", false);
+    f.tag()->addField("titlE", "Title2", false);
+    f.tag()->addField("TITLE", "Title3", false);
+    f.tag()->addField("artist", "Artist1");
+    f.tag()->addField("ARTIST", "Artist2", false);
+    CPPUNIT_ASSERT_EQUAL(String("Title1 Title1 Title2 Title3"), f.tag()->title());
+    CPPUNIT_ASSERT_EQUAL(String("Artist1 Artist2"), f.tag()->artist());
+
+    f.tag()->removeFields("title", "Title1");
+    CPPUNIT_ASSERT_EQUAL(String("Title2 Title3"), f.tag()->title());
+    CPPUNIT_ASSERT_EQUAL(String("Artist1 Artist2"), f.tag()->artist());
+
+    f.tag()->removeFields("Artist");
+    CPPUNIT_ASSERT_EQUAL(String("Title2 Title3"), f.tag()->title());
+    CPPUNIT_ASSERT(f.tag()->artist().isEmpty());
+
+    f.tag()->removeAllFields();
+    CPPUNIT_ASSERT(f.tag()->title().isEmpty());
+    CPPUNIT_ASSERT(f.tag()->artist().isEmpty());
+    CPPUNIT_ASSERT_EQUAL(String("Xiph.Org libVorbis I 20050304"), f.tag()->vendorID());
+  }
+
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(TestXiphComment);