/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.uima.analysis_engine.impl;

import java.util.HashMap;
import java.util.Map;

import org.apache.uima.cas.text.Language;

/**
 * Class used to canonicalize language string
 */
public class RsLang {

 /**
   * global set for canonical language strings
   */
  private static final Map<String, String> canonicalLanguageStrings = new HashMap<String, String>();
 
  /**
   * 
   * @param language
   * @return x-unspecified if lang is null or a canonical version of the lang string
   */
//  @edu.umd.cs.findbugs.annotations.SuppressWarnings("DM_STRING_CTOR")
  static String getCanonicalLanguageString(String language) {
    if (language == null || language.equals(Language.UNSPECIFIED_LANGUAGE)) {  // represents x-unspecified
      return Language.UNSPECIFIED_LANGUAGE;
    }
    synchronized(canonicalLanguageStrings) {
      String cl = canonicalLanguageStrings.get(language);
      if (cl == null) {
        // make new string based on trimmed chars if needed, in case holding on to big string
        language = new String(language);
        canonicalLanguageStrings.put(language, language);
        return language;
      }
      return cl;
    }
  }
}

@@ -887,16 +887,37 @@
 va.util.
+concurrent.Concurrent
 HashMap;
@@ -935,16 +935,37 @@
 va.util.
+concurrent.Concurrent
 Map;%0D%0A%0D%0A
@@ -1175,16 +1175,26 @@
 c final 
+Concurrent
 Map%3CStri
@@ -1236,16 +1236,26 @@
 s = new 
+Concurrent
 HashMap%3C
@@ -1706,56 +1706,8 @@
  %7D%0D%0A
-    synchronized(canonicalLanguageStrings) %7B%0D%0A  
     
@@ -1752,29 +1752,36 @@
 et(language)
+, clOther
 ;%0D%0A
-  
     if (cl =
@@ -1791,18 +1791,16 @@
 ull) %7B%0D%0A
-  
       //
@@ -1882,24 +1882,181 @@
 g string%0D%0A  
+    // This strange construct is intended to drop references to big char arrays  %0D%0A      //   where only a part the big char arrays constitute this string.%0D%0A
       langua
@@ -2070,16 +2070,23 @@
 w String
+Builder
 (languag
@@ -2078,32 +2078,69 @@
 Builder(language
+.length()).append(language).toString(
 );%0D%0A        cano
@@ -2133,17 +2133,25 @@
 %0D%0A      
- 
+clOther =
  canonic
@@ -2171,16 +2171,24 @@
 ings.put
+IfAbsent
 (languag
@@ -2208,24 +2208,50 @@
 %0D%0A      
-  return
+cl = (clOther != null) ? clOther :
  languag
@@ -2258,23 +2258,19 @@
 e;%0D%0A    
- 
- 
 %7D%0D%0A
-  
     retu
@@ -2277,23 +2277,16 @@
 rn cl;%0D%0A
-    %7D%0D%0A
   %7D%0D%0A%7D%0D%0A

Remove sync, switch to ConcurrentHashMap