FREEMARKER-208: Added ?c_lower_case, and ?c_upper_case, which are the non-localized (computer language) variants of ?lower_case, and ?upper_case. The primary problem people run into with the localized versions is that with Turkish locale the letter i, and I has different conversions as in most languages, which causes problem if the conversion was for computer consumption (for technical purposes), and not for humans.
diff --git a/src/main/java/freemarker/core/BuiltIn.java b/src/main/java/freemarker/core/BuiltIn.java
index fcea193..1631b76 100644
--- a/src/main/java/freemarker/core/BuiltIn.java
+++ b/src/main/java/freemarker/core/BuiltIn.java
@@ -85,8 +85,8 @@
 
     static final Set<String> CAMEL_CASE_NAMES = new TreeSet<>();
     static final Set<String> SNAKE_CASE_NAMES = new TreeSet<>();
-    static final int NUMBER_OF_BIS = 291;
-    static final HashMap<String, BuiltIn> BUILT_INS_BY_NAME = new HashMap(NUMBER_OF_BIS * 3 / 2 + 1, 1f);
+    static final int NUMBER_OF_BIS = 295;
+    static final HashMap<String, BuiltIn> BUILT_INS_BY_NAME = new HashMap<>(NUMBER_OF_BIS * 3 / 2 + 1, 1f);
 
     static final String BI_NAME_SNAKE_CASE_WITH_ARGS = "with_args";
     static final String BI_NAME_CAMEL_CASE_WITH_ARGS = "withArgs";
@@ -247,6 +247,7 @@
         putBI("long", new longBI());
         putBI("lower_abc", "lowerAbc", new BuiltInsForNumbers.lower_abcBI());
         putBI("lower_case", "lowerCase", new BuiltInsForStringsBasic.lower_caseBI());
+        putBI("c_lower_case", "cLowerCase", new BuiltInsForStringsBasic.c_lower_caseBI());
         putBI("map", new BuiltInsForSequences.mapBI());
         putBI("namespace", new BuiltInsForMultipleTypes.namespaceBI());
         putBI("new", new NewBI());
@@ -300,6 +301,7 @@
         putBI("uncap_first", "uncapFirst", new BuiltInsForStringsBasic.uncap_firstBI());
         putBI("upper_abc", "upperAbc", new BuiltInsForNumbers.upper_abcBI());
         putBI("upper_case", "upperCase", new BuiltInsForStringsBasic.upper_caseBI());
+        putBI("c_upper_case", "cUpperCase", new BuiltInsForStringsBasic.c_upper_caseBI());
         putBI("url", new BuiltInsForStringsEncoding.urlBI());
         putBI("url_path", "urlPath", new BuiltInsForStringsEncoding.urlPathBI());
         putBI("values", new BuiltInsForHashes.valuesBI());
diff --git a/src/main/java/freemarker/core/BuiltInsForStringsBasic.java b/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
index c97c93e..ce69d42 100644
--- a/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
+++ b/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
@@ -20,6 +20,7 @@
 package freemarker.core;
 
 import java.util.List;
+import java.util.Locale;
 import java.util.StringTokenizer;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -435,7 +436,14 @@
         TemplateModel calculateResult(String s, Environment env) {
             return new SimpleScalar(s.toLowerCase(env.getLocale()));
         }
-    }    
+    }
+
+    static class c_lower_caseBI extends BuiltInForString {
+        @Override
+        TemplateModel calculateResult(String s, Environment env) {
+            return new SimpleScalar(s.toLowerCase(Locale.ROOT));
+        }
+    }
 
     static class padBI extends BuiltInForString {
         
@@ -830,6 +838,13 @@
         }
     }
 
+    static class c_upper_caseBI extends BuiltInForString {
+        @Override
+        TemplateModel calculateResult(String s, Environment env) {
+            return new SimpleScalar(s.toUpperCase(Locale.ROOT));
+        }
+    }
+
     static class word_listBI extends BuiltInForString {
         @Override
         TemplateModel calculateResult(String s, Environment env) {
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index a34780e..2198ffc 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -12710,6 +12710,16 @@
 
           <listitem>
             <para><link
+            linkend="ref_builtin_c_lower_case">c_lower_case</link></para>
+          </listitem>
+
+          <listitem>
+            <para><link
+            linkend="ref_builtin_c_upper_case">c_upper_case</link></para>
+          </listitem>
+
+          <listitem>
+            <para><link
             linkend="ref_builtin_cap_first">cap_first</link></para>
           </listitem>
 
@@ -13306,6 +13316,50 @@
 
           <para>In the case of <literal>"- green mouse"</literal>, the first
           word is the <literal>-</literal>.</para>
+
+          <para>Note that this uses locale-aware conversion, that is, the
+          result can be different depending on the current
+          <literal>locale</literal> (language, country).</para>
+        </section>
+
+        <section xml:id="ref_builtin_c_lower_case">
+          <title>c_lower_case</title>
+
+          <indexterm>
+            <primary>c_lower_case built-in</primary>
+          </indexterm>
+
+          <para>The string converted to lower case, for computer consumption
+          (<quote>c</quote> as in the <link
+          linkend="ref_builtin_c"><literal>c</literal> built-in</link>). Put
+          simply, it will be converted to lower case as in English, regardless
+          of the current <literal>locale</literal> (language, country). For
+          example <literal>"ITEM list"?c_lower_case</literal> will be
+          <literal>"item list"</literal>, always.</para>
+
+          <para>For lower case conversion for human consumption use the <link
+          linkend="ref_builtin_lower_case"><literal>lower_case</literal>
+          built-in</link> instead!</para>
+        </section>
+
+        <section xml:id="ref_builtin_c_upper_case">
+          <title>c_upper_case</title>
+
+          <indexterm>
+            <primary>c_upper_case built-in</primary>
+          </indexterm>
+
+          <para>The string converted to upper case, for computer consumption
+          (<quote>c</quote> as in the <link
+          linkend="ref_builtin_c"><literal>c</literal> built-in</link>). Put
+          simply, it will be converted to upper case as in English, regardless
+          of the current <literal>locale</literal> (language, country). For
+          example <literal>"ITEM list"?c_upper_case</literal> will be
+          <literal>"ITEM LIST"</literal>, always.</para>
+
+          <para>For upper case conversion for human consumption use the <link
+          linkend="ref_builtin_upper_case"><literal>upper_case</literal>
+          built-in</link> instead!</para>
         </section>
 
         <section xml:id="ref_builtin_capitalize">
@@ -14150,9 +14204,18 @@
             <primary>lower_case built-in</primary>
           </indexterm>
 
-          <para>The lower case version of the string. For example
-          <literal>"GrEeN MoUsE"?lower_case</literal> will be <literal>"green
-          mouse"</literal>.</para>
+          <para>The lower case version of the string, using rules that depend
+          on the current <literal>locale</literal> (language, country). For
+          example <literal>"KARIŞIK işaretler"?lower_case</literal> will be
+          <literal>"karişik işaretler"</literal> in most locales, but will be
+          <literal>"karışık işaretler"</literal> in Turkish
+          (<literal>tr_TR</literal>) locale (note the missing dot above some
+          of the <quote>i</quote>-s).</para>
+
+          <para>To convert to lower case for computer consumption (as opposed
+          to human consumption), use the <link
+          linkend="ref_builtin_c_lower_case"><literal>c_lower_case</literal>
+          built-in</link> instead!</para>
         </section>
 
         <section xml:id="ref_builtin_matches">
@@ -15005,8 +15068,10 @@
 
           <para>The opposite of <link
           linkend="ref_builtin_cap_first"><literal>cap_first</literal></link>.
-          The string with the very first word of the string
-          un-capitalized.</para>
+          The string with the very first word of the string un-capitalized.
+          Note that this uses locale-aware conversion, that is, the result can
+          be different depending on the current <literal>locale</literal>
+          (language, country).</para>
         </section>
 
         <section xml:id="ref_builtin_upper_case">
@@ -15016,9 +15081,17 @@
             <primary>upper_case built-in</primary>
           </indexterm>
 
-          <para>The upper case version of the string. For example
-          <literal>"GrEeN MoUsE"</literal> will be <literal>"GREEN
-          MOUSE"</literal>.</para>
+          <para>The upper case version of the string, using rules that depend
+          on the current <literal>locale</literal> (language, country). For
+          example <literal>"KARIŞIK işaretler"?upper_case</literal> will be
+          <literal>"KARIŞIK IŞARETLER"</literal> in most locales, but with
+          Turkish locale it will be <literal>"KARIŞIK İŞARETLER"</literal>
+          (note the dot above the 2nd <quote>I</quote>).</para>
+
+          <para>To convert to upper case for computer consumption (as opposed
+          to human consumption), use the <link
+          linkend="ref_builtin_c_upper_case"><literal>c_upper_case</literal>
+          built-in</link> instead!</para>
         </section>
 
         <section xml:id="ref_builtin_url">
@@ -29512,6 +29585,23 @@
 
           <itemizedlist>
             <listitem>
+              <para><link
+              xlink:href="https://issues.apache.org/jira/browse/FREEMARKER-208">FREEMARKER-208</link>:
+              Added <link
+              linkend="ref_builtin_c_lower_case"><literal>?c_lower_case</literal></link>,
+              and <link
+              linkend="ref_builtin_c_upper_case"><literal>?c_upper_case</literal></link>,
+              which are the non-localized (computer language) variants of
+              <literal>?lower_case</literal>, and
+              <literal>?upper_case</literal>. The primary problem people run
+              into with the localized versions is that with Turkish locale the
+              letter <literal>i</literal>, and <literal>I</literal> has
+              different conversions as in most languages, which causes problem
+              if the conversion was for computer consumption (for technical
+              purposes), and not for humans.</para>
+            </listitem>
+
+            <listitem>
               <para>When setting the <literal>number_format</literal> setting
               (also when formatting with
               <literal>?string(<replaceable>format</replaceable>)</literal>),
@@ -29565,6 +29655,19 @@
             </listitem>
 
             <listitem>
+              <para>Added
+              <literal>Environment.getCTemplateNumberFormat()</literal> that
+              returns a
+              <literal>freemarker.core.TemplateNumberFormat</literal>, and
+              deprecated <literal>getCNumberFormat()</literal> that returns a
+              <literal>java.text.NumberFormat</literal>. The new
+              <literal>?c</literal> behavior (see earlier) is only reflected
+              by the new method, and what the deprecated methods returns is
+              stuck at 2.3.31 <literal>incompatible_improvements</literal>
+              mode.</para>
+            </listitem>
+
+            <listitem>
               <para><link
               xlink:href="https://issues.apache.org/jira/browse/FREEMARKER-190">FREEMARKER-190</link>:
               Updated dom4j version used during FreeMarker project compilation
diff --git a/src/test/resources/freemarker/test/templatesuite/expected/string-builtins1.txt b/src/test/resources/freemarker/test/templatesuite/expected/string-builtins1.txt
index 6e689ac..adeb39a 100644
--- a/src/test/resources/freemarker/test/templatesuite/expected/string-builtins1.txt
+++ b/src/test/resources/freemarker/test/templatesuite/expected/string-builtins1.txt
@@ -110,3 +110,4 @@
 [<\/script>] = [<\/script>]
 [\u003C![CDATA[] = [\u003C![CDATA[]
 []]\u003E] = []]\u003E]
+
diff --git a/src/test/resources/freemarker/test/templatesuite/templates/string-builtins1.ftl b/src/test/resources/freemarker/test/templatesuite/templates/string-builtins1.ftl
index 84c794f..f2f249e 100644
--- a/src/test/resources/freemarker/test/templatesuite/templates/string-builtins1.ftl
+++ b/src/test/resources/freemarker/test/templatesuite/templates/string-builtins1.ftl
@@ -127,3 +127,10 @@
 [${"</script>"?json_string}] = [<\/script>]
 [${"<![CDATA["?json_string}] = [\u003C![CDATA[]
 [${"]]>"?json_string}] = []]\u003E]
+
+<#-- ?c_...: -->
+<#setting locale="tr_TR">
+<@assertEquals actual="i"?upper_case expected="\x0130" />
+<@assertEquals actual="i"?c_upper_case expected="I" />
+<@assertEquals actual="I"?lower_case expected="\x0131" />
+<@assertEquals actual="I"?c_lower_case expected="i" />