← Back to team overview

maria-developers team mailing list archive

Re: Review of base64.diff and german2.diff

 

Hi Monty,

thanks for review.


Btw, I did not tell you what the german2 patch actually includes:


1. WL#4013 Unicode german2 collation
   itself.

2. WL#5624 Collation customization improvements
   (prerequisite for german2)
   http://dev.mysql.com/worklog/task/?id=5624

3. Joro's patch for "Bug#62429 XML: ExtractValue, UpdateXML max arg length 127 chars."
   (prerequisite for WL#5624)

4. Partially, mtr tests for WL#5624.
   The other part of the WL#5624 tests depends on the WEIGHT_STRING()
   function which we have not merged yet.


Comparing to the first version of the patch,
the second version additionally includes:

- Monty's review suggestions addressed.
- Added *partially* tests for WL#5624 (those not needing WEIGHT_STRING)
- Added "WL#5624 Part 13. More verbosity when reading character set
  definition file" which I somehow missed in the first version.


Please also see comments inline:


On 09/12/2013 04:32 PM, Michael Widenius wrote:

Review of german2.diff

=== modified file 'include/my_global.h'
--- include/my_global.h	2013-07-21 14:39:19 +0000
+++ include/my_global.h	2013-08-29 08:27:09 +0000
@@ -1218,4 +1218,11 @@ static inline double rint(double x)
  #define HAVE_EXTERNAL_CLIENT
  #endif /* EMBEDDED_LIBRARY */

+
+enum loglevel {
+   ERROR_LEVEL=       0,
+   WARNING_LEVEL=     1,
+   INFORMATION_LEVEL= 2
+};
+
  #endif /* my_global_h */

Not sure why the above, which is a my_sys construct, should be in
my_global.h.  Please add at least a comment about this.

my_sys.h includes m_ctype.h.
The definition of loglevel was in my_sys.h,
but now it's needed in m_ctype.h as well.
So I just moved the definition of loglevel to my_global.h,
which is seen in both m_ctype.h and my_sys.h.
That solved the problem, but as you say, introduced
extra visibility of "loglevel", which is not good.


In the second version of the patch (attached) I
just moved the definition of loglevel from my_sys.h
to m_ctype.h instead.
It solves all definition dependencies and does not
introduce extra visibility.



=== modified file 'mysys/charset.c'
--- mysys/charset.c	2012-08-14 14:23:34 +0000
+++ mysys/charset.c	2013-08-29 12:38:44 +0000
@@ -66,6 +66,9 @@ static my_bool init_state_maps(struct ch
    if (!(cs->ident_map= ident_map= (uchar*) my_once_alloc(256, MYF(MY_WME))))
      return 1;

+  state_map= (uchar *) cs->state_map;
+  ident_map= (uchar *) cs->ident_map;

Why is the above needed?
They are already set one line above.
(In addition cs->state_map and cs->ident_map are already uchar *)

Thanks for noticing this. Removed.


--- strings/ctype-simple.c	2013-07-21 14:39:19 +0000
+++ strings/ctype-simple.c	2013-08-29 09:05:07 +0000
@@ -1163,12 +1163,12 @@ static int pcmp(const void * f, const vo
    return res;
  }

-static my_bool create_fromuni(struct charset_info_st *cs,
-                              void *(*alloc)(size_t))
+static my_bool
+create_fromuni(struct charset_info_st *cs,
+               MY_CHARSET_LOADER *loader)
  {
    uni_idx	idx[PLANE_NUM];
    int		i,n;
-  struct my_uni_idx_st *tab_from_uni;

    /*
      Check that Unicode map is loaded.
@@ -1209,18 +1209,18 @@ static my_bool create_fromuni(struct cha
    for (i=0; i < PLANE_NUM; i++)
    {
      int ch,numchars;
-    uchar *tab;

      /* Skip empty plane */
      if (!idx[i].nchars)
        break;

      numchars=idx[i].uidx.to-idx[i].uidx.from+1;
-    if (!(idx[i].uidx.tab= tab= (uchar*)
-          alloc(numchars * sizeof(*idx[i].uidx.tab))))
+    if (!(idx[i].uidx.tab= (uchar *)
+                           (loader->once_alloc) (numchars *
+                                                 sizeof(*idx[i].uidx.tab))))
        return TRUE;

-    bzero(tab,numchars*sizeof(*tab));
+    bzero((char*) idx[i].uidx.tab, numchars * sizeof(*idx[i].uidx.tab));

      for (ch=1; ch < PLANE_SIZE; ch++)
      {
@@ -1228,32 +1228,32 @@ static my_bool create_fromuni(struct cha
        if (wc >= idx[i].uidx.from && wc <= idx[i].uidx.to && wc)
        {
          int ofs= wc - idx[i].uidx.from;
-        tab[ofs]= ch;
+        ((char *) idx[i].uidx.tab)[ofs]= ch;
        }
      }
    }

Why remove tab to be a shortcut for idx[i].uidx.from ?
Shouldn't it be faster and shorter to use tab than using idx[i].uidx.from?
(At least in this place)

I guess you mean idx[i].uidx.tab.

Okey, I restored the variable.

But generally I don't like pointer aliases (as it's bug prone).
Moreover, having an alias in this code does not improve performance,
because this code is called only once per collation during mysqld life
time.

The best choice would probably be to move the loop inside a function
and pass idx[i].uidx.tab into the function.




-static const uint16 page0FCdata[]= { /* FC00 (3 weights per char) */
+static uint16 page0FCdata[]= { /* FC00 (3 weights per char) */
  0x134F,0x135E,0x0000, 0x134F,0x1364,0x0000, 0x134F,0x13B0,0x0000,
  0x134F,0x13C7,0x0000, 0x134F,0x13C8,0x0000, 0x1352,0x135E,0x0000,
  0x1352,0x1364,0x0000, 0x1352,0x1365,0x0000, 0x1352,0x13B0,0x0000,
@@ -6006,7 +6005,7 @@ static const uint16 page0FCdata[]= { /*
  0x1381,0x13C8,0x0000, 0x1382,0x13C7,0x0000, 0x1382,0x13C8,0x0000,
  0x1364,0x13C7,0x0000 };

If we are not going to change the above, better to keep these as
const!

They will then be in the const segment and you will have protection
from anyone trying to change these!


Changed back to const.
I had to do two casts though, in this variable definition,
to resolve const/non-const conflict:

MY_UCA_INFO my_uca_v400=
{
  {
    {
      0xFFFF,    /* maxchar           */
      (uchar *) uca_length,
      (uint16 **) uca_weight,
      {          /* Contractions:     */
        0,       /*   nitems          */
        NULL,    /*   item            */
        NULL     /*   flags           */
      }
    },
  },

which should be fine.




<cut>

+my_uca_add_contraction(MY_CONTRACTIONS *list, my_wc_t *wc, size_t len,
+                       my_bool with_context)
  {
-  MY_CONTRACTIONS *list= (MY_CONTRACTIONS*) cs->contractions;
    MY_CONTRACTION *next= &list->item[list->nitems];
-  DBUG_ASSERT(len == 2); /* We currently support only contraction2 */
-  next->ch[0]= wc[0];
-  next->ch[1]= wc[1];
+  size_t i;
+  /*
+    Contraction is always at least 2 characters.
+    Contraction is never longer than MY_UCA_MAX_CONTRACTION,
+    which is guaranteed by using my_coll_rule_expand() with proper limit.
+  */
+  DBUG_ASSERT(len > 1 && len <= MY_UCA_MAX_CONTRACTION);
+  for (i= 0; i < len; i++)
+  {
+    /*
+      We don't support contractions with U+0000.
+      my_coll_rule_expand() guarantees there're no U+0000 in a contraction.
+    */
+    DBUG_ASSERT(wc[i] != 0);
+    next->ch[i]= wc[i];
+  }
+  if (i < MY_UCA_MAX_CONTRACTION)
+    next->ch[i]= 0; /* Add end-of-line marker */

Wouldn't it make life easier to always have the marker there?
(Ie, always have place for the marker).
At least you can remove one if from the code.  If there is more than
one if to remove, then it's a simple optimzation do to...

The Unicode Collation Algorithm tables are quite huge.
See ctype-uca.c. Adding a space for 0-terminator for every
character weight would make the tables even huger.
Not sure if we should do this.
Originally, in mysql-4.1 times, I intentionally made this to reduce
table sizes.



<cut>

+static int
+my_coll_parser_too_long_error(MY_COLL_RULE_PARSER *p, const char *name)
+{
+  my_snprintf(p->errstr, sizeof(p->errstr), "%s is too long", name);
+  return 0;
+}

You should limit '%s' to 64 characters so that one gets the name in
the output even if it's over sizeof()...
>
> %-.64s ....

The list of possible values that are passed to this functions is:

"Contraction"
"Expansion"
"Context"
"logical position"

No needs for %-.64s.



<cut>

Regards,
Monty

=== modified file 'include/m_ctype.h'
--- include/m_ctype.h	2013-08-07 15:40:25 +0000
+++ include/m_ctype.h	2013-09-17 11:21:50 +0000
@@ -23,6 +23,12 @@
 #include <my_attribute.h>
 #include "my_global.h"                          /* uint16, uchar */
 
+enum loglevel {
+   ERROR_LEVEL=       0,
+   WARNING_LEVEL=     1,
+   INFORMATION_LEVEL= 2
+};
+
 #ifdef	__cplusplus
 extern "C" {
 #endif
@@ -57,28 +63,39 @@ extern "C" {
 typedef const struct my_charset_handler_st MY_CHARSET_HANDLER;
 typedef const struct my_collation_handler_st MY_COLLATION_HANDLER;
 
-typedef const struct unicase_info_st MY_UNICASE_INFO;
+typedef struct unicase_info_st MY_UNICASE_INFO;
 typedef const struct uni_ctype_st MY_UNI_CTYPE;
 typedef const struct my_uni_idx_st MY_UNI_IDX;
 
-struct unicase_info_st
+typedef struct unicase_info_char_st
 {
   uint32 toupper;
   uint32 tolower;
   uint32 sort;
+} MY_UNICASE_CHARACTER;
+
+
+struct unicase_info_st
+{
+  my_wc_t maxchar;
+  MY_UNICASE_CHARACTER **page;
 };
 
-extern MY_UNICASE_INFO *const my_unicase_default[256];
-extern MY_UNICASE_INFO *const my_unicase_turkish[256];
-extern MY_UNICASE_INFO *const my_unicase_mysql500[256];
 
-#define MY_UCA_MAX_CONTRACTION 4
+extern MY_UNICASE_INFO my_unicase_default;
+extern MY_UNICASE_INFO my_unicase_turkish;
+extern MY_UNICASE_INFO my_unicase_mysql500;
+extern MY_UNICASE_INFO my_unicase_unicode520;
+
+#define MY_UCA_MAX_CONTRACTION 6
 #define MY_UCA_MAX_WEIGHT_SIZE 8
+#define MY_UCA_WEIGHT_LEVELS   1
 
 typedef struct my_contraction_t
 {
   my_wc_t ch[MY_UCA_MAX_CONTRACTION];   /* Character sequence              */
   uint16 weight[MY_UCA_MAX_WEIGHT_SIZE];/* Its weight string, 0-terminated */
+  my_bool with_context;
 } MY_CONTRACTION;
 
 
@@ -89,6 +106,46 @@ typedef struct my_contraction_list_t
   char *flags;           /* Character flags, e.g. "is contraction head") */
 } MY_CONTRACTIONS;
 
+my_bool my_uca_can_be_contraction_head(const MY_CONTRACTIONS *c, my_wc_t wc);
+my_bool my_uca_can_be_contraction_tail(const MY_CONTRACTIONS *c, my_wc_t wc);
+uint16 *my_uca_contraction2_weight(const MY_CONTRACTIONS *c,
+                                   my_wc_t wc1, my_wc_t wc2);
+
+
+/* Collation weights on a single level (e.g. primary, secondary, tertiarty) */
+typedef struct my_uca_level_info_st
+{
+  my_wc_t maxchar;
+  uchar   *lengths;
+  uint16  **weights;
+  MY_CONTRACTIONS contractions;
+} MY_UCA_WEIGHT_LEVEL;
+
+
+typedef struct uca_info_st
+{
+  MY_UCA_WEIGHT_LEVEL level[MY_UCA_WEIGHT_LEVELS];
+
+  /* Logical positions */
+  my_wc_t first_non_ignorable;
+  my_wc_t last_non_ignorable;
+  my_wc_t first_primary_ignorable;
+  my_wc_t last_primary_ignorable;
+  my_wc_t first_secondary_ignorable;
+  my_wc_t last_secondary_ignorable;
+  my_wc_t first_tertiary_ignorable;
+  my_wc_t last_tertiary_ignorable;
+  my_wc_t first_trailing;
+  my_wc_t last_trailing;
+  my_wc_t first_variable;
+  my_wc_t last_variable;
+
+} MY_UCA_INFO;
+
+
+
+extern MY_UCA_INFO my_uca_v400;
+
 
 struct uni_ctype_st
 {
@@ -122,7 +179,7 @@ extern MY_UNI_CTYPE my_uni_ctype[256];
 #define MY_CS_BINSORT	16     /* if binary sort order           */
 #define MY_CS_PRIMARY	32     /* if primary collation           */
 #define MY_CS_STRNXFRM	64     /* if strnxfrm is used for sort   */
-#define MY_CS_UNICODE	128    /* is a charset is full unicode   */
+#define MY_CS_UNICODE	128    /* is a charset is BMP Unicode    */
 #define MY_CS_READY	256    /* if a charset is initialized    */
 #define MY_CS_AVAILABLE	512    /* If either compiled-in or loaded*/
 #define MY_CS_CSSORT	1024   /* if case sensitive sort order   */	
@@ -130,6 +187,7 @@ extern MY_UNI_CTYPE my_uni_ctype[256];
 #define MY_CS_PUREASCII 4096   /* if a charset is pure ascii     */
 #define MY_CS_NONASCII  8192   /* if not ASCII-compatible        */
 #define MY_CS_UNICODE_SUPPLEMENT 16384 /* Non-BMP Unicode characters */
+#define MY_CS_LOWER_SORT 32768 /* If use lower case as weight   */
 #define MY_CHARSET_UNDEFINED 0
 
 /* Character repertoire flags */
@@ -202,13 +260,24 @@ enum my_lex_states
 
 struct charset_info_st;
 
+typedef struct my_charset_loader_st
+{
+  char error[128];
+  void *(*once_alloc)(size_t);
+  void *(*malloc)(size_t);
+  void *(*realloc)(void *, size_t);
+  void (*free)(void *);
+  void (*reporter)(enum loglevel, const char *format, ...);
+  int  (*add_collation)(struct charset_info_st *cs);
+} MY_CHARSET_LOADER;
+
 
 extern int (*my_string_stack_guard)(int);
 
 /* See strings/CHARSET_INFO.txt for information about this structure  */
 struct my_collation_handler_st
 {
-  my_bool (*init)(struct charset_info_st *, void *(*alloc)(size_t));
+  my_bool (*init)(struct charset_info_st *, MY_CHARSET_LOADER *);
   /* Collation routines */
   int     (*strnncoll)(CHARSET_INFO *,
 		       const uchar *, size_t, const uchar *, size_t, my_bool);
@@ -259,7 +328,7 @@ typedef size_t (*my_charset_conv_case)(C
 /* See strings/CHARSET_INFO.txt about information on this structure  */
 struct my_charset_handler_st
 {
-  my_bool (*init)(struct charset_info_st *, void *(*alloc)(size_t));
+  my_bool (*init)(struct charset_info_st *, MY_CHARSET_LOADER *loader);
   /* Multibyte routines */
   uint    (*ismbchar)(CHARSET_INFO *, const char *, const char *);
   uint    (*mbcharlen)(CHARSET_INFO *, uint c);
@@ -322,6 +391,13 @@ struct my_charset_handler_st
 extern MY_CHARSET_HANDLER my_charset_8bit_handler;
 extern MY_CHARSET_HANDLER my_charset_ucs2_handler;
 
+
+/*
+  We define this CHARSET_INFO_DEFINED here to prevent a repeat of the
+  typedef in hash.c, which will cause a compiler error.
+*/
+#define CHARSET_INFO_DEFINED
+
 /* See strings/CHARSET_INFO.txt about information on this structure  */
 struct charset_info_st
 {
@@ -337,11 +413,10 @@ struct charset_info_st
   const uchar *to_lower;
   const uchar *to_upper;
   const uchar *sort_order;
-  const MY_CONTRACTIONS *contractions;
-  const uint16 *const *sort_order_big;
+  MY_UCA_INFO *uca;
   const uint16 *tab_to_uni;
-  MY_UNI_IDX   *tab_from_uni;
-  MY_UNICASE_INFO *const *caseinfo;
+  MY_UNI_IDX  *tab_from_uni;
+  MY_UNICASE_INFO *caseinfo;
   const uchar  *state_map;
   const uchar  *ident_map;
   uint      strxfrm_multiply;
@@ -349,8 +424,8 @@ struct charset_info_st
   uchar     casedn_multiply;
   uint      mbminlen;
   uint      mbmaxlen;
-  uint16    min_sort_char;
-  uint16    max_sort_char; /* For LIKE optimization */
+  my_wc_t   min_sort_char;
+  my_wc_t   max_sort_char; /* For LIKE optimization */
   uchar     pad_char;
   my_bool   escape_with_backslash_is_dangerous;
   
@@ -600,10 +675,10 @@ int my_wildcmp_unicode(CHARSET_INFO *cs,
                        const char *str, const char *str_end,
                        const char *wildstr, const char *wildend,
                        int escape, int w_one, int w_many,
-                       MY_UNICASE_INFO *const *weights);
+                       MY_UNICASE_INFO *weights);
 
-extern my_bool my_parse_charset_xml(const char *bug, size_t len,
-				    int (*add)(struct charset_info_st *cs));
+extern my_bool my_parse_charset_xml(MY_CHARSET_LOADER *loader,
+                                    const char *buf, size_t buflen);
 extern char *my_strchr(CHARSET_INFO *cs, const char *str, const char *end,
                        pchar c);
 extern size_t my_strcspn(CHARSET_INFO *cs, const char *str, const char *end,
@@ -620,6 +695,9 @@ uint my_charset_repertoire(CHARSET_INFO
 
 my_bool my_charset_is_ascii_compatible(CHARSET_INFO *cs);
 
+const MY_CONTRACTIONS *my_charset_get_contractions(const CHARSET_INFO *cs,
+                                                   int level);
+
 extern size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
                               const char* fmt, va_list ap);
 

=== modified file 'include/m_string.h'
--- include/m_string.h	2013-07-21 14:39:19 +0000
+++ include/m_string.h	2013-08-29 10:01:47 +0000
@@ -73,10 +73,12 @@ extern "C" {
 #endif
 
 /*
-  my_str_malloc() and my_str_free() are assigned to implementations in
-  strings/alloc.c, but can be overridden in the calling program.
+  my_str_malloc(), my_str_realloc() and my_str_free() are assigned to
+  implementations in strings/alloc.c, but can be overridden in
+  the calling program.
  */
 extern void *(*my_str_malloc)(size_t);
+extern void *(*my_str_realloc)(void *, size_t);
 extern void (*my_str_free)(void *);
 
 #if defined(HAVE_STPCPY) && MY_GNUC_PREREQ(3, 4) && !defined(__INTEL_COMPILER)

=== modified file 'include/my_sys.h'
--- include/my_sys.h	2013-07-21 14:39:19 +0000
+++ include/my_sys.h	2013-09-17 12:37:26 +0000
@@ -270,12 +270,6 @@ extern char	wild_many,wild_one,wild_pref
 extern const char *charsets_dir;
 extern my_bool timed_mutexes;
 
-enum loglevel {
-   ERROR_LEVEL,
-   WARNING_LEVEL,
-   INFORMATION_LEVEL
-};
-
 enum cache_type
 {
   TYPE_NOT_SET= 0, READ_CACHE, WRITE_CACHE,
@@ -946,15 +940,20 @@ void my_uuid2str(const uchar *guid, char
 void my_uuid_end();
 
 /* character sets */
+extern void my_charset_loader_init_mysys(MY_CHARSET_LOADER *loader);
 extern uint get_charset_number(const char *cs_name, uint cs_flags);
 extern uint get_collation_number(const char *name);
 extern const char *get_charset_name(uint cs_number);
 
 extern CHARSET_INFO *get_charset(uint cs_number, myf flags);
 extern CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags);
+extern CHARSET_INFO *my_collation_get_by_name(MY_CHARSET_LOADER *loader,
+                                              const char *name, myf flags);
 extern CHARSET_INFO *get_charset_by_csname(const char *cs_name,
 					   uint cs_flags, myf my_flags);
-
+extern CHARSET_INFO *my_charset_get_by_name(MY_CHARSET_LOADER *loader,
+                                            const char *name,
+                                            uint cs_flags, myf my_flags);
 extern my_bool resolve_charset(const char *cs_name,
                                CHARSET_INFO *default_cs,
                                CHARSET_INFO **cs);

=== modified file 'include/my_xml.h'
--- include/my_xml.h	2013-03-19 14:53:48 +0000
+++ include/my_xml.h	2013-08-29 09:58:41 +0000
@@ -52,8 +52,15 @@ typedef struct xml_stack_st
   int flags;
   enum my_xml_node_type current_node_type;
   char errstr[128];
-  char attr[128];
-  char *attrend;
+
+  struct {
+    char static_buffer[128];
+    char *buffer;
+    size_t buffer_size;
+    char *start;
+    char *end;
+  } attr;
+
   const char *beg;
   const char *cur;
   const char *end;

=== modified file 'mysql-test/r/ctype_ldml.result'
--- mysql-test/r/ctype_ldml.result	2010-03-24 15:03:44 +0000
+++ mysql-test/r/ctype_ldml.result	2013-09-17 16:22:29 +0000
@@ -411,10 +411,19 @@ select * from information_schema.collati
 COLLATION_NAME	CHARACTER_SET_NAME	ID	IS_DEFAULT	IS_COMPILED	SORTLEN
 utf8mb4_test_ci	utf8mb4	326			8
 utf16_test_ci	utf16	327			8
+utf8mb4_test_400_ci	utf8mb4	328			8
+utf8_bengali_standard_ci	utf8	336			8
+utf8_bengali_traditional_ci	utf8	337			8
 utf8_phone_ci	utf8	352			8
 utf8_test_ci	utf8	353			8
+utf8_5624_1	utf8	354			8
+utf8_5624_2	utf8	355			8
+utf8_5624_3	utf8	356			8
+utf8_5624_4	utf8	357			8
 ucs2_test_ci	ucs2	358			8
 ucs2_vn_ci	ucs2	359			8
+ucs2_5624_1	ucs2	360			8
+utf8_5624_5	utf8	368			8
 utf32_test_ci	utf32	391			8
 utf8_maxuserid_ci	utf8	2047			8
 show collation like '%test%';
@@ -423,6 +432,7 @@ latin1_test	latin1	99		Yes	1
 utf8_test_ci	utf8	353			8
 ucs2_test_ci	ucs2	358			8
 utf8mb4_test_ci	utf8mb4	326			8
+utf8mb4_test_400_ci	utf8mb4	328			8
 utf16_test_ci	utf16	327			8
 utf32_test_ci	utf32	391			8
 show collation like 'ucs2_vn_ci';
@@ -449,3 +459,631 @@ SHOW COLLATION LIKE 'utf8_phone_ci';
 Collation	Charset	Id	Default	Compiled	Sortlen
 utf8_phone_ci	utf8	352			8
 SET NAMES utf8;
+SELECT hex(@a:=convert(_utf32 0x10400 using utf8mb4) collate utf8mb4_test_400_ci), hex(lower(@a));
+hex(@a:=convert(_utf32 0x10400 using utf8mb4) collate utf8mb4_test_400_ci)	hex(lower(@a))
+F0909080	F0909080
+SELECT hex(@a:=convert(_utf32 0x10428 using utf8mb4) collate utf8mb4_test_400_ci), hex(upper(@a));
+hex(@a:=convert(_utf32 0x10428 using utf8mb4) collate utf8mb4_test_400_ci)	hex(upper(@a))
+F09090A8	F09090A8
+SELECT hex(@a:=convert(_utf32 0x2C00 using utf8mb4) collate utf8mb4_test_400_ci), hex(lower(@a));
+hex(@a:=convert(_utf32 0x2C00 using utf8mb4) collate utf8mb4_test_400_ci)	hex(lower(@a))
+E2B080	E2B080
+SELECT hex(@a:=convert(_utf32 0x2C30 using utf8mb4) collate utf8mb4_test_400_ci), hex(upper(@a));
+hex(@a:=convert(_utf32 0x2C30 using utf8mb4) collate utf8mb4_test_400_ci)	hex(upper(@a))
+E2B0B0	E2B0B0
+#
+# WL#5624 Collation customization improvements
+#
+SET NAMES utf8 COLLATE utf8_5624_1;
+CREATE TABLE t1 AS SELECT REPEAT(' ', 16) AS a LIMIT 0;
+INSERT INTO t1 VALUES ('012345'),('001234'),('000123'),('000012'),('000001');
+INSERT INTO t1 VALUES ('12345'),('01234'),('00123'),('00012'),('00001');
+INSERT INTO t1 VALUES ('1234'),('0123'),('0012'),('0001');
+INSERT INTO t1 VALUES ('123'),('012'),('001');
+INSERT INTO t1 VALUES ('12'),('01');
+INSERT INTO t1 VALUES ('1'),('9');
+INSERT INTO t1 VALUES ('ГАИ'),('ГИБДД');
+INSERT INTO t1 VALUES ('a'),('b'),('c'),('d'),('e');
+INSERT INTO t1 VALUES ('cz'),('ÄŠ'),('Ä‹');
+INSERT INTO t1 VALUES ('f'),('fz'),('g'),('Ä '),('Ä¡');
+INSERT INTO t1 VALUES ('h'),('hz'),('GĦ'),('Għ'),('gĦ'),('għ');
+INSERT INTO t1 VALUES ('i'),('iz'),('Ħ'),('ħ');
+INSERT INTO t1 VALUES ('y'),('yz'),('z'),('Ż'),('ż');
+INSERT INTO t1 VALUES ('ā'),('Ā'),('á'),('Á'),('à'),('À');
+INSERT INTO t1 VALUES ('ē'),('é'),('ě'),('ê'),('Ē'),('É'),('Ě'),('Ê');
+INSERT INTO t1 VALUES ('a'),('~'),('!'),('@'),('#'),('$'),('%'),('^');
+INSERT INTO t1 VALUES ('('),(')'),('-'),('+'),('|'),('='),(':'),(';');
+INSERT INTO t1 VALUES ('"'),('\''),('?');
+INSERT INTO t1 VALUES ('ch'),('k'),('cs'),('ccs'),('cscs');
+INSERT INTO t1 VALUES ('aa-'),('ab-'),('ac-'),('ad-'),('ae-'),('af-'),('az-');
+INSERT INTO t1 VALUES ('lp-fni'),('lp-lni');
+INSERT INTO t1 VALUES ('lp-fpi'),('lp-lpi');
+INSERT INTO t1 VALUES ('lp-fsi'),('lp-lsi');
+INSERT INTO t1 VALUES ('lp-fti'),('lp-lti');
+INSERT INTO t1 VALUES ('lp-ft'),('lp-lt');
+INSERT INTO t1 VALUES ('lp-fv'),('lp-lv');
+INSERT INTO t1 VALUES ('lb-fni'),('lb-lni');
+INSERT INTO t1 VALUES ('lb-fv'),('lb-lv');
+INSERT INTO t1 VALUES (_ucs2 0x3106),(_ucs2 0x3110), (_ucs2 0x3111), (_ucs2 0x3112);
+INSERT INTO t1 VALUES (_ucs2 0x32A3), (_ucs2 0x3231);
+INSERT INTO t1 VALUES (_ucs2 0x84D9), (_ucs2 0x98F5), (_ucs2 0x7CF3), (_ucs2 0x5497);
+SELECT a FROM t1 ORDER BY a, LENGTH(a), BINARY a;
+a
+lp-ft
+lp-lt
+lp-fpi
+lp-fsi
+lp-fti
+lp-lpi
+lp-lsi
+lp-lti
+lb-fv
+lb-fni
+lp-fv
+lp-fni
+-
+=
+|
+lb-lv
+lp-lv
+1
+01
+001
+0001
+00001
+000001
+12
+012
+0012
+00012
+000012
+123
+0123
+00123
+000123
+1234
+01234
+001234
+12345
+012345
+9
+~
+!
+@
+#
+$
+%
+^
+(
+)
++
+:
+;
+"
+'
+?
+a
+a
+aa-
+ab-
+ac-
+ad-
+ae-
+af-
+az-
+b
+À
+Á
+à
+á
+Ä€
+ā
+c
+k
+ch
+cs
+ccs
+cscs
+cz
+ÄŠ
+Ä‹
+d
+É
+Ê
+é
+ê
+Ä’
+Ä“
+Äš
+Ä›
+e
+f
+fz
+Ä 
+Ä¡
+g
+GĦ
+Għ
+gĦ
+għ
+h
+hz
+Ħ
+ħ
+i
+iz
+y
+yz
+Å»
+ż
+z
+ГАИ
+ГИБДД
+lb-lni
+lp-lni
+ㄆ
+ㄐ
+ã„‘
+ã„’
+㊣
+㈱
+è“™
+飵
+ç³³
+å’—
+#
+# WL#5624, the same test with UCS2
+#
+ALTER TABLE t1 CONVERT TO CHARACTER SET ucs2 COLLATE ucs2_5624_1;
+SELECT a FROM t1 ORDER BY a, LENGTH(a), BINARY(a);
+a
+lp-ft
+lp-lt
+lp-fpi
+lp-fsi
+lp-fti
+lp-lpi
+lp-lsi
+lp-lti
+lb-fv
+lb-fni
+lp-fv
+lp-fni
+-
+=
+|
+lb-lv
+lp-lv
+1
+01
+001
+0001
+00001
+000001
+12
+012
+0012
+00012
+000012
+123
+0123
+00123
+000123
+1234
+01234
+001234
+12345
+012345
+9
+~
+!
+@
+#
+$
+%
+^
+(
+)
++
+:
+;
+"
+'
+?
+a
+a
+aa-
+ab-
+ac-
+ad-
+ae-
+af-
+az-
+b
+À
+Á
+à
+á
+Ä€
+ā
+c
+k
+ch
+cs
+ccs
+cscs
+cz
+ÄŠ
+Ä‹
+d
+É
+Ê
+é
+ê
+Ä’
+Ä“
+Äš
+Ä›
+e
+f
+fz
+Ä 
+Ä¡
+g
+GĦ
+Għ
+gĦ
+għ
+h
+hz
+Ħ
+ħ
+i
+iz
+y
+yz
+Å»
+ż
+z
+ГАИ
+ГИБДД
+lb-lni
+lp-lni
+ㄆ
+ㄐ
+ã„‘
+ã„’
+㊣
+㈱
+è“™
+飵
+ç³³
+å’—
+DROP TABLE t1;
+#
+# WL#5624, unsupported features
+#
+SET NAMES utf8 COLLATE utf8_5624_2;
+ERROR HY000: Unknown collation: 'utf8_5624_2'
+SHOW WARNINGS;
+Level	Code	Message
+Error	1273	Unknown collation: 'utf8_5624_2'
+Warning	1273	Syntax error at '[strength tertiary]'
+#
+# WL#5624, reset before primary ignorable
+#
+SET NAMES utf8 COLLATE utf8_5624_3;
+ERROR HY000: Unknown collation: 'utf8_5624_3'
+SHOW WARNINGS;
+Level	Code	Message
+Error	1273	Unknown collation: 'utf8_5624_3'
+Warning	1273	Can't reset before a primary ignorable character U+A48C
+#
+# WL#5624, \u without hex digits is equal to {'\', 'u'}
+#
+SET NAMES utf8 COLLATE utf8_5624_4;
+CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES ('\\'),('u'),('x'),('X');
+SELECT a FROM t1 ORDER BY a, LENGTH(a), BINARY(a);
+a
+\
+x
+u
+X
+DROP TABLE t1;
+#
+# WL#5624, testing Bengali collations
+#
+SET NAMES utf8, collation_connection=utf8_bengali_standard_ci;
+CREATE TABLE t1 AS SELECT REPEAT (' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES (_ucs2 0x09FA), (_ucs2 0x09F8), (_ucs2 0x09F9), (_ucs2 0x09F2);
+INSERT INTO t1 VALUES (_ucs2 0x09DC), (_ucs2 0x09A109BC);
+INSERT INTO t1 VALUES (_ucs2 0x09A2), (_ucs2 0x09DD), (_ucs2 0x09A209BC);
+INSERT INTO t1 VALUES (_ucs2 0x09A3);
+SELECT HEX(CONVERT(a USING ucs2)), HEX(a)
+FROM t1 ORDER BY a, BINARY a;
+HEX(CONVERT(a USING ucs2))	HEX(a)
+09FA	E0A7BA
+09F8	E0A7B8
+09F9	E0A7B9
+09F2	E0A7B2
+09A109BC	E0A6A1E0A6BC
+09DC	E0A79C
+09A2	E0A6A2
+09A209BC	E0A6A2E0A6BC
+09DD	E0A79D
+09A3	E0A6A3
+DROP TABLE t1;
+SET NAMES utf8, collation_connection=utf8_bengali_traditional_ci;
+CREATE TABLE t1 AS SELECT REPEAT (' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES
+(_ucs2 0x0985),(_ucs2 0x0986),(_ucs2 0x0987),(_ucs2 0x0988),
+(_ucs2 0x0989),(_ucs2 0x098A),(_ucs2 0x098B),(_ucs2 0x09E0),
+(_ucs2 0x098C),(_ucs2 0x09E1),(_ucs2 0x098F),(_ucs2 0x0990),
+(_ucs2 0x0993);
+INSERT INTO t1 VALUES
+(_ucs2 0x0994),(_ucs2 0x0982),(_ucs2 0x0983),(_ucs2 0x0981),
+(_ucs2 0x099509CD), (_ucs2 0x099609CD), (_ucs2 0x099709CD), (_ucs2 0x099809CD),
+(_ucs2 0x099909CD), (_ucs2 0x099A09CD), (_ucs2 0x099B09CD), (_ucs2 0x099C09CD),
+(_ucs2 0x099D09CD), (_ucs2 0x099E09CD), (_ucs2 0x099F09CD), (_ucs2 0x09A009CD),
+(_ucs2 0x09A109CD), (_ucs2 0x09A209CD), (_ucs2 0x09A309CD),
+(_ucs2 0x09CE), (_ucs2 0x09A409CD200D), (_ucs2 0x09A409CD),
+(_ucs2 0x09A509CD),(_ucs2 0x09A609CD),
+(_ucs2 0x09A709CD), (_ucs2 0x09A809CD), (_ucs2 0x09AA09CD), (_ucs2 0x09AB09CD),
+(_ucs2 0x09AC09CD), (_ucs2 0x09AD09CD), (_ucs2 0x09AE09CD), (_ucs2 0x09AF09CD),
+(_ucs2 0x09B009CD), (_ucs2 0x09F009CD), (_ucs2 0x09B209CD), (_ucs2 0x09F109CD),
+(_ucs2 0x09B609CD), (_ucs2 0x09B709CD), (_ucs2 0x09B809CD), (_ucs2 0x09B909CD);
+INSERT INTO t1 VALUES 
+(_ucs2 0x099509CD0985),(_ucs2 0x0995),
+(_ucs2 0x099509CD0986),(_ucs2 0x099509BE),
+(_ucs2 0x099509CD0987),(_ucs2 0x099509BF),
+(_ucs2 0x099509CD0988),(_ucs2 0x099509C0),
+(_ucs2 0x099509CD0989),(_ucs2 0x099509C1),
+(_ucs2 0x099509CD098A),(_ucs2 0x099509C2),
+(_ucs2 0x099509CD098B),(_ucs2 0x099509C3),
+(_ucs2 0x099509CD09E0),(_ucs2 0x099509C4),
+(_ucs2 0x099509CD098C),(_ucs2 0x099509E2),
+(_ucs2 0x099509CD09E1),(_ucs2 0x099509E3),
+(_ucs2 0x099509CD098F),(_ucs2 0x099509C7),
+(_ucs2 0x099509CD0990),(_ucs2 0x099509C8),
+(_ucs2 0x099509CD0993),(_ucs2 0x099509CB),
+(_ucs2 0x099509CD0994),(_ucs2 0x099509CC);
+SELECT HEX(CONVERT(a USING ucs2)), HEX(a)
+FROM t1 ORDER BY a, BINARY(a);
+HEX(CONVERT(a USING ucs2))	HEX(a)
+0985	E0A685
+0986	E0A686
+0987	E0A687
+0988	E0A688
+0989	E0A689
+098A	E0A68A
+098B	E0A68B
+09E0	E0A7A0
+098C	E0A68C
+09E1	E0A7A1
+098F	E0A68F
+0990	E0A690
+0993	E0A693
+0994	E0A694
+0982	E0A682
+0983	E0A683
+0981	E0A681
+099509CD	E0A695E0A78D
+0995	E0A695
+099509CD0985	E0A695E0A78DE0A685
+099509BE	E0A695E0A6BE
+099509CD0986	E0A695E0A78DE0A686
+099509BF	E0A695E0A6BF
+099509CD0987	E0A695E0A78DE0A687
+099509C0	E0A695E0A780
+099509CD0988	E0A695E0A78DE0A688
+099509C1	E0A695E0A781
+099509CD0989	E0A695E0A78DE0A689
+099509C2	E0A695E0A782
+099509CD098A	E0A695E0A78DE0A68A
+099509C3	E0A695E0A783
+099509CD098B	E0A695E0A78DE0A68B
+099509C4	E0A695E0A784
+099509CD09E0	E0A695E0A78DE0A7A0
+099509CD098C	E0A695E0A78DE0A68C
+099509E2	E0A695E0A7A2
+099509CD09E1	E0A695E0A78DE0A7A1
+099509E3	E0A695E0A7A3
+099509C7	E0A695E0A787
+099509CD098F	E0A695E0A78DE0A68F
+099509C8	E0A695E0A788
+099509CD0990	E0A695E0A78DE0A690
+099509CB	E0A695E0A78B
+099509CD0993	E0A695E0A78DE0A693
+099509CC	E0A695E0A78C
+099509CD0994	E0A695E0A78DE0A694
+099609CD	E0A696E0A78D
+099709CD	E0A697E0A78D
+099809CD	E0A698E0A78D
+099909CD	E0A699E0A78D
+099A09CD	E0A69AE0A78D
+099B09CD	E0A69BE0A78D
+099C09CD	E0A69CE0A78D
+099D09CD	E0A69DE0A78D
+099E09CD	E0A69EE0A78D
+099F09CD	E0A69FE0A78D
+09A009CD	E0A6A0E0A78D
+09A109CD	E0A6A1E0A78D
+09A209CD	E0A6A2E0A78D
+09A309CD	E0A6A3E0A78D
+09A409CD	E0A6A4E0A78D
+09A409CD200D	E0A6A4E0A78DE2808D
+09CE	E0A78E
+09A509CD	E0A6A5E0A78D
+09A609CD	E0A6A6E0A78D
+09A709CD	E0A6A7E0A78D
+09A809CD	E0A6A8E0A78D
+09AA09CD	E0A6AAE0A78D
+09AB09CD	E0A6ABE0A78D
+09AC09CD	E0A6ACE0A78D
+09AD09CD	E0A6ADE0A78D
+09AE09CD	E0A6AEE0A78D
+09AF09CD	E0A6AFE0A78D
+09B009CD	E0A6B0E0A78D
+09F009CD	E0A7B0E0A78D
+09B209CD	E0A6B2E0A78D
+09F109CD	E0A7B1E0A78D
+09B609CD	E0A6B6E0A78D
+09B709CD	E0A6B7E0A78D
+09B809CD	E0A6B8E0A78D
+09B909CD	E0A6B9E0A78D
+SELECT
+GROUP_CONCAT(HEX(CONVERT(a USING ucs2)) ORDER BY LENGTH(a), BINARY a)
+FROM t1 GROUP BY a ORDER BY a;
+GROUP_CONCAT(HEX(CONVERT(a USING ucs2)) ORDER BY LENGTH(a), BINARY a)
+0985
+0986
+0987
+0988
+0989
+098A
+098B
+09E0
+098C
+09E1
+098F
+0990
+0993
+0994
+0982
+0983
+0981
+099509CD
+0995,099509CD0985
+099509BE,099509CD0986
+099509BF,099509CD0987
+099509C0,099509CD0988
+099509C1,099509CD0989
+099509C2,099509CD098A
+099509C3,099509CD098B
+099509C4,099509CD09E0
+099509E2,099509CD098C
+099509E3,099509CD09E1
+099509C7,099509CD098F
+099509C8,099509CD0990
+099509CB,099509CD0993
+099509CC,099509CD0994
+099609CD
+099709CD
+099809CD
+099909CD
+099A09CD
+099B09CD
+099C09CD
+099D09CD
+099E09CD
+099F09CD
+09A009CD
+09A109CD
+09A209CD
+09A309CD
+09CE,09A409CD,09A409CD200D
+09A509CD
+09A609CD
+09A709CD
+09A809CD
+09AA09CD
+09AB09CD
+09AC09CD
+09AD09CD
+09AE09CD
+09AF09CD
+09B009CD
+09F009CD
+09B209CD
+09F109CD
+09B609CD
+09B709CD
+09B809CD
+09B909CD
+DROP TABLE t1;
+#
+# WL#5624, shift after, using expansion
+#
+SET NAMES utf8 COLLATE utf8_5624_5;
+CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES ('0'),('1'),('0z'),(_ucs2 0x0030FF9D);
+INSERT INTO t1 VALUES ('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),('i');
+INSERT INTO t1 VALUES ('j'),('k'),('l'),('m'),('n'),('o'),('p'),('q'),('r');
+INSERT INTO t1 VALUES ('s'),('t'),('u'),('v'),('w'),('x'),('y'),('z');
+INSERT INTO t1 VALUES ('aa'),('aaa');
+INSERT INTO t1 VALUES ('A'),('B'),('C'),('D'),('E'),('F'),('G'),('H'),('I');
+INSERT INTO t1 VALUES ('J'),('K'),('L'),('M'),('N'),('O'),('P'),('Q'),('R');
+INSERT INTO t1 VALUES ('S'),('T'),('U'),('V'),('W'),('X'),('Y'),('Z');
+INSERT INTO t1 VALUES ('AA'),('AAA');
+SELECT a FROM t1 ORDER BY a, LENGTH(a), BINARY(a);
+a
+0
+0z
+0ン
+a
+b
+c
+d
+e
+f
+g
+h
+i
+j
+k
+l
+m
+n
+o
+p
+q
+r
+s
+t
+u
+v
+w
+x
+y
+z
+aa
+aaa
+A
+B
+C
+D
+E
+F
+G
+H
+I
+J
+K
+L
+M
+N
+O
+P
+Q
+R
+S
+T
+U
+V
+W
+X
+Y
+Z
+AA
+AAA
+1
+DROP TABLE t1;
+#
+# End of WL#5624
+#
+#
+# Bug#14197426 PARSE ERRORS IN LOADABLE UCA / LDML COLLATIONS ARE SILENTLY IGNORED
+#
+# Search for occurrences of [ERROR] Syntax error at '[strength tertiary]'
+Occurances : 1

=== modified file 'mysql-test/r/ctype_uca.result'
--- mysql-test/r/ctype_uca.result	2012-02-29 20:55:04 +0000
+++ mysql-test/r/ctype_uca.result	2013-08-29 12:56:12 +0000
@@ -2240,6 +2240,112 @@ Z,z,Ź,ź,Ż,ż
 ǁ
 Ç‚
 ǃ
+select group_concat(c1 order by c1) from t1 group by c1 collate utf8_german2_ci;
+group_concat(c1 order by c1)
+÷
+×
+A,a,À,Á,Â,Ã,Å,à,á,â,ã,å,Ā,ā,Ă,ă,Ą,ą,Ǎ,ǎ,Ǟ,ǟ,Ǡ,ǡ,Ǻ,ǻ
+AA,Aa,aA,aa
+Ä,Æ,ä,æ
+Ǣ,ǣ,Ǽ,ǽ
+B,b
+Æ€
+Ɓ
+Ƃ,ƃ
+C,c,Ç,ç,Ć,ć,Ĉ,ĉ,Ċ,ċ,Č,č
+CH,Ch,cH,ch
+Ƈ,ƈ
+D,d,Ď,ď
+DZ,Dz,DŽ,Dž,dZ,dz,dŽ,dž,DŽ,Dž,dž,DZ,Dz,dz
+Đ,đ
+Ɖ
+ÆŠ
+Ƌ,ƌ
+Ð,ð
+E,e,È,É,Ê,Ë,è,é,ê,ë,Ē,ē,Ĕ,ĕ,Ė,ė,Ę,ę,Ě,ě
+Ǝ,ǝ
+Ə
+Ɛ
+F,f
+Æ‘,Æ’
+G,g,Ĝ,ĝ,Ğ,ğ,Ġ,ġ,Ģ,ģ,Ǧ,ǧ,Ǵ,ǵ
+Ǥ,ǥ
+Æ“
+Æ”
+Æ¢,Æ£
+H,h,Ĥ,ĥ
+ƕ,Ƕ
+Ħ,ħ
+I,i,Ì,Í,Î,Ï,ì,í,î,ï,Ĩ,ĩ,Ī,ī,Ĭ,ĭ,Į,į,İ,Ǐ,ǐ
+IJ,Ij,iJ,ij,IJ,ij
+ı
+Æ—
+Æ–
+J,j,Ĵ,ĵ,ǰ
+K,k,Ķ,ķ,Ǩ,ǩ
+Ƙ,ƙ
+L,l,Ĺ,ĺ,Ļ,ļ,Ľ,ľ
+Ä¿,Å€
+LJ,Lj,lJ,lj,LJ,Lj,lj
+LL,Ll,lL,ll
+Ł,ł
+Æš
+Æ›
+M,m
+N,n,Ñ,ñ,Ń,ń,Ņ,ņ,Ň,ň,Ǹ,ǹ
+NJ,Nj,nJ,nj,NJ,Nj,nj
+Ɲ
+Æž
+ÅŠ,Å‹
+O,o,Ò,Ó,Ô,Õ,ò,ó,ô,õ,Ō,ō,Ŏ,ŏ,Ő,ő,Ơ,ơ,Ǒ,ǒ,Ǫ,ǫ,Ǭ,ǭ
+OE,Oe,oE,oe,Ö,ö,Œ,œ
+Ø,ø,Ǿ,ǿ
+Ɔ
+ÆŸ
+P,p
+Ƥ,ƥ
+Q,q
+ĸ
+R,r,Ŕ,ŕ,Ŗ,ŗ,Ř,ř
+RR,Rr,rR,rr
+Ʀ
+S,s,Ś,ś,Ŝ,ŝ,Ş,ş,Š,š,ſ
+SS,Ss,sS,ss,ß
+Æ©
+ƪ
+T,t,Ţ,ţ,Ť,ť
+ƾ
+Ŧ,ŧ
+Æ«
+Ƭ,ƭ
+Æ®
+U,u,Ù,Ú,Û,ù,ú,û,Ũ,ũ,Ū,ū,Ŭ,ŭ,Ů,ů,Ű,ű,Ų,ų,Ư,ư,Ǔ,ǔ,Ǖ,ǖ,Ǘ,ǘ,Ǚ,ǚ,Ǜ,ǜ
+Ü,ü
+Ɯ
+Ʊ
+V,v
+Ʋ
+W,w,Ŵ,ŵ
+X,x
+Y,y,Ý,ý,ÿ,Ŷ,ŷ,Ÿ
+Ƴ,ƴ
+Z,z,Ź,ź,Ż,ż,Ž,ž
+ƍ
+Ƶ,ƶ
+Ʒ,Ǯ,ǯ
+Ƹ,ƹ
+ƺ
+Þ,þ
+Æ¿,Ç·
+Æ»
+Ƨ,ƨ
+Ƽ,ƽ
+Æ„,Æ…
+ʼn
+Ç€
+ǁ
+Ç‚
+ǃ
 drop table t1;
 SET NAMES utf8;
 CREATE TABLE t1 (c varchar(255) NOT NULL COLLATE utf8_general_ci, INDEX (c));
@@ -3192,3 +3298,45 @@ drop table t1;
 #
 # End of 5.5 tests
 #
+#
+# WL#4013 Unicode german2 collation
+#
+SET collation_connection=utf8_german2_ci;
+drop table if exists t1;
+create table t1 as select repeat(' ', 64) as s1;
+select collation(s1) from t1;
+collation(s1)
+utf8_german2_ci
+delete from t1;
+insert into t1 values ('a'),('ae'),(_latin1 0xE4);
+insert into t1 values ('o'),('oe'),(_latin1 0xF6);
+insert into t1 values ('s'),('ss'),(_latin1 0xDF);
+insert into t1 values ('u'),('ue'),(_latin1 0xFC);
+select s1, hex(s1) from t1 order by s1, binary s1;
+s1	hex(s1)
+a	61
+ae	6165
+ä	C3A4
+o	6F
+oe	6F65
+ö	C3B6
+s	73
+ss	7373
+ß	C39F
+u	75
+ue	7565
+ü	C3BC
+select group_concat(s1 order by binary s1) from t1 group by s1;
+group_concat(s1 order by binary s1)
+a
+ae,ä
+o
+oe,ö
+s
+ss,ß
+u
+ue,ü
+drop table t1;
+#
+# End of 5.6 tests
+#

=== modified file 'mysql-test/std_data/Index.xml'
--- mysql-test/std_data/Index.xml	2010-02-24 09:15:34 +0000
+++ mysql-test/std_data/Index.xml	2013-09-17 12:16:40 +0000
@@ -18,6 +18,109 @@
       </rules>
     </collation>
 
+    <collation name="utf8_5624_1" id="354">
+      <rules>
+        <!-- long contractions and expansions -->
+        <reset>12345</reset><q>012345</q><q>12345</q>
+        <reset>1234</reset><q>001234</q><q>01234</q>
+        <reset>123</reset><q>000123</q><q>00123</q><q>0123</q>
+        <reset>12</reset><q>000012</q><q>00012</q><q>0012</q><q>012</q>
+        <reset>1</reset><q>000001</q><q>00001</q><q>0001</q><q>001</q><q>01</q>
+        <!-- some non-latin contractions and expansions -->
+        <reset>ГАИ</reset><i>ГИБДД</i>
+
+        <!-- reset before: Maltese -->
+        <reset before="primary">d</reset><p>ÄŠ</p><t>Ä‹</t>
+        <reset before="primary">g</reset><p>Ä </p><t>Ä¡</t>
+        <reset before="primary">h</reset><p>GĦ</p><t>Għ</t><t>gĦ</t><t>għ</t>
+        <reset before="primary">i</reset><p>Ħ</p><t>ħ</t>
+        <reset before="primary">z</reset><p>Ż</p><t>ż</t>
+        <!-- higher levels  -->
+        <reset before="secondary">b</reset><s>ā</s><t>Ā</t>
+        <reset before="tertiary">b</reset><t>á</t><t>Á</t>
+        <reset before="quaternary">b</reset><q>à</q><q>À</q>
+
+        <!-- abbreviated syntax: put some punctuation immediately before a -->
+        <reset before="primary">a</reset><pc>~!@#$%^*()+:;"'?</pc>
+        <reset>d</reset><sc>ēé</sc>
+        <reset>d</reset><tc>ĒÉ</tc>
+        <reset>d</reset><qc>ěê</qc>
+        <reset>d</reset><ic>ĚÊ</ic>
+
+        <!-- normal expansion syntax -->
+        <reset>c</reset><x><s>k</s><extend>h</extend></x>
+        <reset>cs</reset><x><t>ccs</t><extend>cs</extend></x>
+
+        <!-- previous context -->
+        <reset>a</reset><x><context>b</context><p>-</p></x>
+        <reset>c</reset><x><context>c</context><s>-</s></x>
+        <reset>d</reset><x><context>d</context><t>-</t></x>
+        <reset>e</reset><x><context>e</context><q>-</q></x>
+        <reset>f</reset><x><context>f</context><i>-</i></x>
+
+        <!-- logical reset positions -->
+        <reset><first_non_ignorable/></reset><p>lp-fni</p>
+        <reset><last_non_ignorable/></reset><p>lp-lni</p>
+        <reset><first_primary_ignorable/></reset><p>lp-fpi</p>
+        <reset><last_primary_ignorable/></reset><p>lp-lpi</p>
+        <reset><first_secondary_ignorable/></reset><p>lp-fsi</p>
+        <reset><last_secondary_ignorable/></reset><p>lp-lsi</p>
+        <reset><first_tertiary_ignorable/></reset><p>lp-fti</p>
+        <reset><last_tertiary_ignorable/></reset><p>lp-lti</p>
+        <reset><first_trailing/></reset><p>lp-ft</p>
+        <reset><last_trailing/></reset><p>lp-lt</p>
+        <reset><first_variable/></reset><p>lp-fv</p>
+        <reset><last_variable/></reset><p>lp-lv</p>
+
+        <!-- logical positions and reset before -->
+        <reset before="primary"><first_non_ignorable/></reset><p>lb-fni</p>
+        <reset before="primary"><last_non_ignorable/></reset><p>lb-lni</p>
+        <reset before="primary"><first_variable/></reset><p>lb-fv</p>
+        <reset before="primary"><last_variable/></reset><p>lb-lv</p>
+
+        <!-- long tailoring: pinyin order from CLDR's zh.xml  -->
+        <reset><last_non_ignorable/></reset>
+        <pc>ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩ吖阿啊锕錒嗄厑哎哀唉埃挨欸溾锿鎄啀捱皑凒嵦溰嘊敱敳皚癌毐昹娾嗳矮蔼躷噯濭﨟藹譪霭靄艾伌爱砹硋隘嗌塧嫒愛碍叆暧瑷僾壒嬡懓薆懝曖璦賹餲鴱皧瞹馤礙譺鑀鱫靉安侒峖桉氨庵菴谙媕萻葊痷腤鹌蓭誝鞌鞍盦諳闇馣鮟盫鵪韽鶕玵啽雸垵俺唵埯铵隌揞晻罯銨犴岸按洝荌案胺豻堓婩暗貋儑錌黯肮骯岇昂昻枊盎醠凹坳垇柪軪爊敖厫隞嗷嗸嶅廒滶獒獓遨摮熬璈蔜磝翱聱螯翶謷翺鳌鏖鰲鷔鼇抝芺拗袄媪镺媼襖岙扷岰傲奡奥嫯慠骜奧澚墺嶴澳懊擙謸鏊驁八仈巴叭扒朳玐吧夿岜芭疤哵捌笆粑紦羓蚆釟豝鲃魞叐犮抜坺妭拔茇炦癹胈釛菝詙跋軷颰魃墢鼥把钯鈀靶坝弝爸垻罢跁鲅罷鮁覇矲霸壩灞欛挀掰白百佰柏栢捭竡粨絔摆擺襬呗庍拝败拜唄敗猈稗粺鞁薭贁韛兡瓸扳攽朌班般颁斑搬斒頒瘢螁螌褩癍辬阪坂岅昄板版瓪钣粄舨鈑蝂魬闆办半伴扮姅怑拌绊秚湴絆鉡靽辦瓣邦峀垹帮捠梆浜邫幇幚縍幫鞤绑綁榜牓膀玤蚌傍棒棓硥谤塝徬稖蒡蜯磅镑艕謗鎊勹包佨孢苞胞剝笣煲龅蕔褒闁襃齙窇嫑雹宝怉饱保鸨珤堡堢媬葆寚飹飽褓駂鳵緥鴇賲藵寳寶靌勽报抱豹趵铇菢袌報鉋鲍靤骲暴髱虣鮑儤曓爆忁鑤萡陂卑杯盃桮悲揹碑鹎藣鵯喺北鉳贝狈貝邶备昁牬苝背钡俻倍悖狽被偝偹梖珼鄁備僃惫焙琲軰辈愂碚禙蓓蛽犕褙誖骳輩鋇憊糒鞴鐾奔泍贲倴渀逩犇賁锛錛本苯奙畚楍坌捹桳笨撪獖輽伻祊奟崩绷絣閍嵭痭嘣綳繃甭埄埲菶琣琫鞛泵迸逬跰塴甏镚蹦鏰皀屄偪毴逼豍螕鲾鎞鵖鰏柲荸鼻嬶匕比夶朼佊吡妣沘疕彼柀秕俾笔粃粊舭啚筆鄙聛貏匂币必毕闭佖坒庇诐邲妼怭枈畀畁苾哔毖珌疪胇荜陛毙狴畢袐铋婢庳敝梐萆萞閇閉堛弻弼愊愎湢皕禆筚詖貱赑嗶彃楅滗滭煏痹痺腷蓖蓽蜌裨跸辟鉍閟飶幣弊熚獙碧稫箅箆綼蔽鄪馝幤潷獘罼襅駜髲壁嬖廦篦篳縪薜觱避鮅斃濞臂蹕鞞髀奰璧鄨饆繴襞襣鏎鞸韠躃躄魓贔鐴驆鷝鷩鼊边砭笾猵编萹煸牑甂箯編蝙獱邉鍽鳊邊鞭鯾鯿籩炞贬扁窆匾貶惼碥稨褊糄鴘藊卞弁忭抃汳汴苄釆峅拚便变変昪覍徧揙缏遍閞辡緶艑頨辧辨辩辪辫辮辯變灬杓彪标飑骉髟淲猋脿墂幖滮蔈颮骠標熛膘麃瘭镖飙飚儦颷瀌藨謤爂臕贆鏢穮镳飆飇飈飊驃鑣驫表婊裱諘褾錶檦俵摽鳔鰾憋鳖鱉鼈虌龞別别咇莂蛂徶襒蟞蹩瘪癟彆汃邠砏宾彬傧斌椕滨缤槟瑸豩賓賔镔儐濒濱濵虨豳璸瀕霦繽蠙鑌顮氞摈殡膑髩擯鬂殯臏髌鬓髕鬢冫仌氷冰兵栟掤梹鋲檳丙邴陃怲抦秉苪昞昺柄炳饼眪窉蛃棅禀鈵鉼鞆餅餠燷并並併幷垪庰倂栤病竝偋傡寎摒誁鮩靐癶拨波癷玻剥盋砵袚袯钵饽啵紴缽脖菠袰碆鉢僠嶓撥播餑磻蹳驋鱍仢伯孛犻驳帛泊狛瓝苩侼勃柭胉郣亳挬浡瓟秡钹铂桲淿舶博渤湐葧鹁愽搏猼鈸鉑馎鲌僰煿牔箔膊艊馛駁踣鋍镈壆薄馞駮鮊襏豰嚗懪礡簙鎛餺鵓犦髆髉欂襮礴鑮蚾跛箥簸孹擘檗糪譒蘗蔔峬庯逋钸晡鈽誧餔轐醭卜卟补哺捕補鳪獛鵏鸔不布佈吥步咘怖歨歩钚勏埗悑捗荹部埠瓿鈈廍蔀踄郶篰餢簿嚓擦攃礤礸遪囃偲猜才材财財戝裁纔采倸埰婇寀彩採睬跴綵踩菜棌蔡縩乲参參叄飡骖叅喰湌傪嬠餐驂残蚕惭殘慚蝅慙蠶蠺惨朁慘噆憯穇黪黲灿粲儏澯薒燦璨謲爘仓仺伧沧苍鸧倉舱傖凔嵢滄獊蒼濸艙螥罉鶬匨蔵藏欌鑶賶撡操糙曺曹嘈嶆漕蓸槽褿艚螬鏪艹艸草愺懆騲肏鄵襙鼜冊册侧厕恻拺测荝敇畟側厠笧粣萗廁惻測策萴筞筴蓛墄箣憡簎嵾膥岑梣涔笒噌层層嶒竲驓蹭硛硳岾猠乽叉扠扱芆杈肞臿挿訍偛嗏插揷馇銟锸艖疀鍤鎈餷秅垞查査茬茶嵖搽猹靫槎詧察碴褨檫衩蹅镲鑔奼汊岔侘诧剎姹差紁詫拆钗釵犲侪柴祡豺喍儕茝虿勑袃瘥蠆囆辿觇梴掺搀覘裧摻鋓幨襜攙婵谗孱棎湹禅馋嬋煘缠僝獑蝉蝊誗鋋儃廛潹潺緾磛禪毚鄽镡瀍蟬儳劖繵蟾酁嚵壥巉瀺欃纏纒躔镵艬讒鑱饞产刬旵丳浐剗谄產産铲阐蒇剷嵼摌滻幝蕆諂閳燀簅冁繟醦譂鏟闡囅灛讇忏硟摲懴颤懺羼韂顫伥昌倀娼淐猖菖阊晿椙琩裮锠錩閶鲳鯧鼚长仧兏肠苌長镸尝偿常徜瓺萇甞腸嘗塲嫦瑺膓鋿償嚐蟐鲿鏛鱨厂场昶惝場敞僘厰廠氅鋹怅玚畅倡鬯唱悵瑒暢畼誯韔抄弨怊欩钞訬焯超鈔繛牊晁巢巣朝鄛鼌漅嘲樔潮窲罺轈鼂謿吵炒眧煼麨巐仦仯耖觘车伡車俥砗唓莗硨蛼扯偖撦奲屮彻坼迠烢烲聅掣硩頙徹撤澈勶瞮爡抻郴棽琛嗔綝瞋諃賝謓尘臣忱沉辰陈迧茞宸烥莀莐陳敐晨訦谌軙愖揨鈂煁蔯塵樄瘎霃螴諶薼麎曟鷐趻硶碜墋夦磣踸贂闯衬疢称龀趁趂榇稱齓齔儭嚫谶櫬襯讖阷泟虰柽爯棦浾偁蛏铛牚琤赪憆摚靗撐撑緽橕瞠赬頳檉竀穪蟶鏳鏿饓鐺丞成朾呈承枨诚郕乗城娍宬峸洆荿乘埕挰珹脀掁珵窚脭铖堘惩棖椉程筬絾裎塍塖溗碀誠畻酲鋮憕澂澄橙檙鯎瀓懲騬侱徎悜逞骋庱睈騁秤吃妛杘侙哧彨胵蚩鸱瓻眵笞粚喫訵嗤媸摛痴絺噄瞝誺螭鴟鵄癡魑齝攡麶彲黐弛池驰坘迟岻泜茌持竾荎俿歭匙淔耛蚳赿筂貾遅趍遟馳墀漦踟遲篪謘尺叺呎肔侈卶齿垑拸胣恥耻蚇袳豉欼歯袲裭鉹褫齒彳叱斥灻赤饬抶迣勅恜炽翄翅敕烾痓啻湁飭傺痸腟跮鉓雴憏翤遫銐慗瘛翨熾懘糦趩饎鶒鷘充冲忡沖茺浺珫翀舂嘃摏徸憃憧衝罿艟蹖虫崇崈隀漴褈緟蝩蟲爞宠埫寵铳揰銃抽紬搊瘳篘犨犫仇俦帱栦惆绸菗椆畴絒愁皗稠筹裯詶酧酬綢踌儔雔嬦幬懤薵燽雠疇籌躊醻讎讐丑丒吜杽侴偢瞅醜矁魗臭臰遚殠出岀初摴樗貙齣刍除芻厨滁蒢豠锄榋耡蒭蜍趎鉏雏犓蕏廚篨鋤橱懨幮櫉蟵躇雛櫥蹰鶵躕杵础椘储楮禇楚褚濋儲檚璴礎齭齼亍処处竌怵拀绌豖欪竐俶敊埱珿絀處傗琡鄐搐滀触踀閦儊嘼諔憷橻斶歜臅黜觸矗搋膗揣啜嘬踹巛川氚穿剶瑏传舡舩船圌猭遄傳椽歂暷篅輲舛荈喘僢汌串玔钏釧賗鶨刅囱疮窓窗牎摐牕瘡窻床牀噇傸漺磢闖创怆刱剏剙創愴吹炊龡垂倕埀桘陲捶菙搥棰腄槌锤箠錘鎚顀旾杶春萅堾媋暙椿槆瑃箺蝽橁輴櫄鰆鶞纯陙唇浱純莼淳脣湻犉滣蒓鹑漘蓴醇醕錞鯙鶉偆萶惷睶賰踳蠢踔戳辶辵娕娖惙涰绰逴腏辍酫綽趠輟龊擉磭歠嚽齪鑡齱呲玼疵趀偨縒骴词珁垐柌祠茈茨堲瓷詞辝慈甆辞鈶磁雌鹚糍辤飺餈嬨濨薋鴜礠蠀辭鶿鷀此佌泚皉跐朿次佽刺刾庛茦栨莿絘蛓赐螆賜嗭从匆囪苁忩枞茐怱從悤棇焧葱楤漗聡蓯蔥骢暰樅樬熜瑽璁緫聦聪瞛篵聰蟌繱鏦騘驄丛従婃孮徖悰淙琮慒漎潀潈潨誴賨賩樷藂叢灇欉爜憁謥凑湊楱腠辏輳粗觕麁麄麤徂殂促猝媨酢瘄蔟誎趗噈憱踧醋瘯簇縬蹙鼀蹴蹵顣汆撺镩蹿攛躥鑹攅櫕巑欑穳窜熶篡殩篹簒竄爨崔催凗缞墔嶉慛摧榱槯獕磪縗鏙乼漼璀趡皠伜忰疩倅紣翆脃脆啐啛悴淬萃毳焠瘁粹綷翠膵膬竁襊顇臎邨村皴墫澊竴存拵踆刌忖寸吋籿搓瑳遳磋撮蹉醝髊虘嵯嵳痤睉矬蒫蔖鹾鹺齹脞剉剒厝夎挫莝莡措逪棤锉蓌错銼錯咑哒耷畣搭嗒褡噠墶撘鎝达迏迖呾妲怛沓垯炟羍荅荙剳匒笪逹溚答詚達跶瘩靼薘鞑燵繨蟽鎉躂鐽韃龖龘打大亣眔橽呆呔獃懛歹傣代汏轪侢垈岱帒甙绐迨带待怠柋殆玳贷帯軑埭帶紿蚮袋軚逮貸軩瑇廗叇曃緿鮘鴏戴艜黛簤蹛瀻霴襶黱靆丹妉单担単眈砃耼耽郸聃躭酖單媅殚瘅匰箪褝鄲頕儋勯擔殫癉襌簞聸伔刐狚玬瓭胆衴疸紞掸亶馾撣澸黕膽旦但帎沊泹诞柦疍訑啖啗弹惮淡萏蛋啿氮腅蜑觛窞誕僤噉髧嘾彈憚憺澹禫餤駳鴠甔癚嚪贉霮饏当珰裆筜當儅噹澢璫襠簹艡蟷挡党谠擋譡黨攩灙欓讜氹凼圵宕砀垱荡档菪婸瓽逿雼潒碭瞊蕩趤壋檔璗盪礑簜蘯闣刀刂叨屶忉朷氘舠釖鱽魛捯导岛陦倒宲島捣祷禂搗隝嶋嶌槝導隯壔嶹擣蹈禱到悼焘盗菿椡盜道稲翢噵稻衜檤衟燾翿軇瓙纛恴得淂悳惪锝嘚徳德鍀的揼扥扽灯登豋噔嬁燈璒竳簦艠覴蹬等戥邓僜凳鄧隥墱嶝瞪磴镫櫈鐙仾低奃彽袛啲埞羝隄堤趆嘀滴镝磾鍉鞮鏑廸狄肑籴苖迪唙敌涤荻梑笛觌靮滌髢嫡蔋蔐頔魡敵篴嚁藡豴糴覿鸐氐厎诋邸阺呧坻底弤抵拞柢牴砥掋菧觝詆軧聜骶鯳地弚坔弟旳杕玓怟枤苐俤帝埊娣递逓偙啇梊焍眱祶第菂谛釱媂棣睇缔蒂僀禘腣遞鉪馰墑墬摕碲蔕蝃遰慸甋締嶳諦踶螮嗲敁掂傎厧嵮滇槙瘨颠蹎巅顚顛癫巓巔攧癲齻典奌点婰敟椣碘蒧蕇踮點电佃甸阽坫店垫扂玷钿唸婝惦淀奠琔殿蜔鈿電墊壂橂澱靛磹癜簟驔刁叼汈刟虭凋奝弴彫蛁琱貂碉鳭殦瞗雕鮉鲷簓鼦鯛鵰扚屌弔伄吊钓窎訋调掉釣铞鈟竨蓧銱雿調瘹窵鋽藋鑃爹跌褺苵迭垤峌恎挕绖胅瓞眣耊啑戜谍喋堞幉惵揲畳絰耋臷詄趃叠殜牃牒镻嵽碟蜨褋艓蝶疂諜蹀鲽曡曢鰈疉疊氎哋昳眰嚸丁仃叮帄玎甼疔盯钉耵酊釘靪奵顶頂鼎嵿鼑薡鐤订忊饤矴定訂飣啶萣椗腚碇锭碠聢聣錠磸顁丟丢铥颩銩东冬咚岽東苳昸氡倲鸫埬娻崬涷笗菄氭蝀鮗鼕鯟鶇鶫董墥嬞懂箽蕫諌动冻侗垌姛峒峝恫挏栋洞胨迵凍戙胴動崠硐棟湩腖働詷駧霘吺剅唗都兜兠蔸橷篼艔斗乧阧抖枓钭陡蚪鈄豆郖浢荳逗饾鬥梪毭脰酘痘閗窦鬦鋀餖斣闘竇鬪鬬鬭剢阇嘟督醏闍毒涜读渎椟牍犊裻読蝳獨錖凟匵嬻瀆櫝殰牘犢瓄皾騳黩讀豄贕韣髑鑟韇韥黷讟厾独笃堵帾琽赌睹覩賭篤芏妒杜肚妬度荰秺渡靯镀螙殬鍍蠧蠹耑偳媏端褍鍴短段断塅缎葮椴煅瑖腶碫锻緞毈簖鍛斷躖籪叾垖堆塠嵟痽磓頧鴭鐜队对兊兌兑対祋怼陮隊碓綐對憝濧薱镦懟瀩譈鐓譵吨惇敦蜳墩墪壿撴獤噸撉橔犜礅蹲蹾驐盹趸躉伅囤庉沌炖盾砘逇钝顿遁鈍腞頓碷遯憞潡燉踲多夛咄哆茤剟崜敠毲裰嚉仛夺铎剫掇敓敚喥敪痥鈬奪凙踱鮵鐸朵朶哚垛挅挆埵缍椯趓躱躲綞亸軃鬌嚲刴剁沲陊陏饳垜尮柮桗堕舵惰跢跥跺飿墮嶞憜墯鵽妸妿娿屙讹吪囮迗俄娥峨峩涐莪珴訛皒睋鈋锇鹅蛾磀誐鋨頟额魤額鵝鵞譌枙砈婀惡噁騀鵈厄歺屵戹岋阨呃扼苊阸呝砐轭咢咹垩姶峉匎恶砨蚅饿偔卾堊悪硆谔軛鄂阏堮崿愕湂萼豟軶遌遏廅搤搹琧腭詻僫蝁锷鹗蕚遻頞颚餓噩擜覨諤閼餩鍔鳄歞顎櫮鰐鶚讍鑩齶鱷奀恩蒽煾峎摁鞥仒乻旕儿而児侕兒陑峏洏耏荋栭胹唲袻鸸粫聏輀鲕隭髵鮞鴯轜尒尓尔耳迩洱饵栮毦珥铒爾鉺餌駬薾邇趰二弍弐佴刵咡贰貮衈貳誀樲发沷発發彂髪橃醗乏伐姂垡疺罚茷阀栰傠筏瞂罰閥罸藅佱法砝鍅灋珐琺髮帆忛犿番勫噃墦嬏幡憣旙旛翻藩轓颿籓飜鱕凡凢凣匥杋柉矾籵钒舤烦舧笲釩棥煩緐樊蕃橎燔璠膰薠繁襎繙羳蹯瀿礬蘩鐇蠜鷭反仮払辺返氾犯奿汎泛饭范贩畈訉軓梵盕笵販軬飯飰滼嬎範嬔瀪匚方邡坊芳枋牥钫淓蚄堏趽鈁錺鴋防妨房肪埅鲂魴仿访彷纺昉昘瓬眆倣旊紡舫訪髣鶭放飞妃非飛啡婓婔渄绯菲扉猆靟裶緋蜚霏鲱餥馡騑騛鯡飝肥淝暃腓蜰蟦朏胐匪诽奜悱斐棐榧翡蕜誹篚吠废杮沸狒肺昲费俷剕厞疿屝萉廃費痱镄廢蕟曊癈鼣濷櫠鐨靅分吩帉纷芬昐氛玢竕衯紛翂棻訜躮酚鈖雰朆餴饙坆坟妢岎汾枌炃肦梤羒蚠蚡棼焚蒶馚隫墳幩蕡魵鳻橨燌燓豮鼢羵鼖豶轒鐼馩黂粉瞓黺份坋弅奋忿秎偾愤粪僨憤奮膹糞鲼瀵鱝丰风仹凨凬妦沣沨凮枫封疯盽砜風峯峰偑桻烽琒崶渢溄猦葑锋楓犎蜂瘋碸僼篈鄷鋒檒豐鎽鏠酆寷灃蘴靊飌麷冯夆捀浲逢堸馮摓綘缝艂縫讽覂唪諷凤奉甮俸湗焨煈赗鳯鳳鴌賵蘕瓰覅仏佛坲梻垺紑缶否妚缹缻雬鴀夫伕邞呋妋姇枎玞肤怤柎砆胕荂衭娐尃荴旉紨趺酜麸稃跗鈇筟綒鄜孵豧敷膚鳺麩糐麬麱懯乀巿弗伏凫甶冹刜孚扶芙芣芾咈岪帗彿怫拂服泭绂绋苻茀俘垘枹柫氟洑炥玸畉畐祓罘茯郛韨鳬哹栿浮畗砩莩蚨匐桴涪烰琈符笰紱紼翇艴菔虙袱幅棴絥罦葍福粰綍艀蜉辐鉘鉜颫鳧榑稪箙複韍幞澓蝠髴鴔諨踾輻鮄癁襆鮲黻襥鵩鶝呒抚甫府弣拊斧俌郙俯釜釡捬脯辅椨焤盙腑滏蜅腐輔撫鬴簠黼阝父讣付妇负附咐坿竎阜驸复峊祔訃負赴蚥袝陚偩冨副婏婦蚹傅媍富復秿萯蛗覄詂赋椱缚腹鲋禣褔赙緮蕧蝜蝮賦駙縛輹鮒賻鍑鍢鳆覆馥鰒猤旮伽嘠钆尜釓嘎噶錷尕玍尬魀侅该郂陔垓姟峐荄晐赅畡祴絯隑該豥賅賌忋改絠鎅丐乢匃匄杚钙盖摡溉葢鈣戤概蓋槩槪漑瓂干甘忓芉迀攼杆玕肝坩泔苷柑竿疳酐粓亁凲尲尴筸漧鳱尶尷魐仠皯秆衦赶敢桿笴稈感澉趕橄擀簳鳡鱤旰汵盰矸绀倝凎淦紺詌骭幹榦檊赣贛灨冈罓冮刚阬岗纲肛岡牨疘矼缸钢剛罡堈掆釭棡犅堽綱罁鋼鎠崗港杠焵筻槓戆戇皋羔羙高皐髙臯滜睪槔睾膏槹橰篙糕餻櫜韟鷎鼛鷱夰杲菒稁搞缟槀槁獔稾稿镐縞藁檺藳鎬吿告勂诰郜峼祮祰锆筶暠禞誥鋯戈圪犵纥戓肐牫疙牱紇哥胳袼鸽割搁彁歌滒戨閤鴐鴚擱謌鴿鎶呄佮匌挌茖阁革敋格鬲愅臵葛蛒蛤裓隔嗝塥滆觡搿槅膈閣镉鞈韐骼諽輵鮯櫊鎘韚轕鞷騔鰪哿舸个各虼個硌铬箇鉻獦给給根跟哏亘艮茛揯搄更刯庚畊浭耕掶菮椩焿絚赓鹒緪縆羮賡羹鶊郠哽埂峺挭绠耿莄梗綆鲠骾鯁亙堩啹喼嗰工弓公厷功攻杛供糼肱宫宮恭蚣躬龚匑塨幊愩觥躳匔碽篢髸觵龏龔廾巩汞拱唝拲栱珙輁鞏共贡羾貢慐熕贑兝兣勾佝沟钩袧缑鈎溝鉤緱褠篝簼鞲韝岣狗苟枸玽耇耉笱耈蚼豿坸构诟购垢姤茩冓够夠訽媾彀搆詬遘雊構煹觏撀覯購估咕姑孤沽泒柧轱唂唃罛鸪笟菇菰蛄蓇觚軱軲辜酤毂鈲箍箛嫴篐橭鮕鴣轂鹘鶻古夃扢汩诂谷股峠牯骨罟羖逧钴傦啒淈脵蛊蛌尳愲焸硲詁馉鹄榾鈷鼓鼔嘏榖皷穀縎糓薣濲臌餶瀔盬瞽鵠蠱固怘故凅顾堌崓崮梏牿棝祻雇痼稒锢頋僱錮鲴鯝顧瓜刮苽胍鸹歄焻煱颪趏劀緺銽颳鴰騧冎叧呱剐剮啩寡卦坬诖挂掛罣絓罫褂詿乖拐枴柺箉夬叏怪恠关观官冠覌倌萖棺蒄窤関瘝癏観闗鳏關鰥觀鱞馆琯痯筦管輨舘錧館躀鳤卝毌丱贯泴悺惯掼涫貫悹祼慣摜潅遦樌盥罆雚鏆灌爟瓘矔礶鹳罐鑵鸛鱹光灮侊炗炚炛咣垙姯洸茪桄烡珖胱硄僙輄銧黆欟广広犷廣獷臩俇逛臦撗归圭妫龟规邽皈茥闺帰珪胿亀硅窐袿規媯椝瑰郌嫢摫閨鲑嬀嶲槻槼璝瞡膭鮭龜巂歸鬶騩瓌鬹櫷宄氿轨庋佹匦诡陒垝姽恑癸軌鬼庪祪匭晷湀蛫觤詭厬簋蟡刽刿攰昋柜炅攱贵桂椢筀貴溎蓕跪瞆劊劌撌槶瞶禬簂櫃襘鳜鞼鱖鱥丨衮惃绲袞辊滚蓘裷滾緄蔉磙緷輥鲧鮌鯀棍棞睔睴璭謴呙咼埚郭啯堝崞楇聒鈛锅墎瘑嘓彉濄蝈鍋彍蟈囯囶囻国圀國帼掴腘幗慖摑漍聝蔮膕虢馘果惈淉猓菓馃椁褁槨粿綶蜾裹輠餜鐹过過腂妎铪鉿丷哈咍嗨孩骸海胲烸塰酼醢亥骇害氦嗐餀駭駴嚡饚乤兯佄顸哻蚶酣頇嫨谽憨馠魽鼾邗含邯函咁肣凾虷唅圅娢浛崡晗梒涵焓寒嵅韩甝筨爳蜬澏鋡韓厈罕浫喊蔊豃鬫汉屽扞汗闬旱垾悍捍晘涆猂莟晥淊焊琀菡釬閈皔睅傼蛿颔馯撖漢蜭暵熯銲鋎憾撼翰螒頷顄駻譀雗瀚蘫鶾夯魧妔苀迒斻杭垳绗笐航蚢颃貥筕絎頏沆茠蒿嚆薅薧竓蚝毫椃嗥獆噑豪嘷獋儫曍嚎壕濠籇蠔譹好郝号昊昦秏哠恏悎浩耗晧淏傐皓滈聕號暤暭澔皜皞皡薃皥颢灏顥鰝灝兞诃呵抲欱喝訶嗬蠚禾合何劾咊和姀河郃峆曷柇狢盇籺阂饸哬敆核盉盍荷啝涸渮盒秴菏萂蚵龁惒粭訸颌楁毼詥貈貉鉌阖鲄熆閡鹖麧澕頜篕翮螛魺礉闔鞨齕覈鶡皬鑉龢佫垎贺袔隺寉焃湼賀嗃煂碋熇褐赫鹤翯壑癋燺爀鶴齃靍靎鸖靏黒黑嘿潶嬒拫痕鞎佷很狠詪恨亨哼悙涥脝姮恆恒桁烆珩胻鸻横橫衡鴴鵆蘅鑅啈堼囍乊乥叿灴轰哄訇烘軣揈渹焢硡谾薨輷嚝鍧轟仜弘妅红吰宏汯玒纮闳宖泓玜苰垬娂洪竑紅荭虹浤紘翃耾硔紭谹鸿渱竤粠葒葓鈜閎綋翝谼潂鉷鞃魟篊鋐彋蕻霐黉霟鴻黌晎嗊讧訌閧撔澋澒銾闀闂鬨齁侯矦喉帿猴葔瘊睺銗篌糇翭骺鍭餱鯸吼吽犼后郈厚垕後洉逅候鄇堠豞鲎鲘鮜鱟乎匢虍呼垀忽昒曶泘苸恗烀轷匫唿惚淴虖軤雽嘑寣滹雐幠歑膴謼囫抇弧狐瓳胡壶壷斛焀喖壺媩搰湖猢絗葫楜煳瑚嘝蔛鹕槲箶糊蝴衚魱縠螜醐頶觳鍸餬瀫鬍鰗鶘鶦鶮乕汻虎浒唬萀琥虝滸箎錿鯱互弖戶户戸冱冴芐帍护沍沪岵怙戽昈枑祜笏粐婟扈瓠綔鄠嫭嫮摢滬蔰槴熩鳸簄鍙嚛鹱護鳠韄頀鱯鸌花芲埖婲椛硴糀誮錵蘤华哗姡骅華铧滑猾嘩撶璍磆蕐螖鋘譁鏵驊鷨化划杹画话崋桦婳畫嬅畵觟話劃摦槬樺嫿澅諙諣黊繣舙蘳怀徊淮槐褢踝懐褱懷瀤櫰耲蘹坏咶壊壞蘾欢欥歓鴅懁鵍酄嚾懽獾歡貛讙驩还环郇峘洹狟荁桓萈萑堚寏絙雈綄羦貆锾阛寰澴缳還環豲鍰镮鹮糫繯轘闤鐶鬟瓛睆缓輐緩攌幻奂肒奐宦唤换浣涣烉患梙焕逭喚喛嵈愌換渙痪煥瑍豢漶瘓槵鲩擐澣瞣藧鯇鯶鰀巟肓荒衁朚塃慌皇偟凰隍黃黄喤堭媓崲徨惶揘湟葟遑楻煌瑝墴潢獚锽熿璜篁艎蝗癀磺穔諻簧蟥鍠餭鳇趪韹鐄騜鰉鱑鷬怳恍炾宺晃晄奛谎幌愰詤熀縨謊櫎皩兤滉榥曂皝鎤灰灳诙咴恢拻挥洃虺袆晖烣珲豗婎媈揮翚辉隓暉楎煇琿禈詼幑睳褘噅噕撝翬輝麾徽隳瀈鰴囘回囬佪廻廽恛洄茴迴烠蚘逥痐蛔蛕蜖鮰悔螝毇檓燬譭卉屷汇会讳泋哕浍绘芔荟诲恚恵桧烩烪贿彗晦秽喙惠湏絵缋翙阓匯彙彚會毀毁滙詯賄僡嘒瘣蔧誨圚寭慧憓暳槥潓蕙噦徻橞澮獩璤薈薉諱頮檅檜燴璯篲藱餯嚖懳瞺穢繢蟪櫘繪翽譓儶譮鏸闠孈鐬靧韢譿顪昏昬荤婚惛涽阍惽棔殙葷睧睯閽忶浑馄渾魂餛繉轋鼲诨俒倱圂掍混焝溷慁觨諢吙耠锪劐鍃豁攉騞佸活秮秳火伙邩钬鈥漷夥沎或货咟俰捇眓获閄剨掝祸貨惑旤湱禍嗀蒦嚄奯擭濩獲霍檴謋雘矆穫镬嚯瀖耯艧藿蠖嚿曤臛癨矐鑊靃夻丌讥击刉叽饥乩刏圾机玑肌芨矶鸡枅咭迹剞唧姬屐积笄飢基绩喞嵆嵇攲敧犄筓缉赍勣嗘畸稘跻鳮僟毄箕銈嘰撃槣樭畿稽緝觭賫躸齑墼憿機激璣禨積錤隮擊磯簊績羁賷鄿櫅耭雞譏韲鶏譤鐖饑癪躋鞿鷄齎羇虀鑇覉鑙齏羈鸄覊亼及伋吉岌彶忣汲级即极亟佶郆卽叝姞急狤皍笈級揤疾觙偮卙庴楖焏脨谻戢棘極殛湒集塉嫉愱楫蒺蝍趌辑槉耤膌銡嶯潗瘠箿蕀蕺踖鞊鹡橶檝濈螏輯襋蹐鍓艥籍轚鏶霵鶺鷑躤雦雧几己丮妀犱泲虮挤脊掎鱾幾戟嵴麂魢撠擠穖蟣彐彑旡计记伎纪坖妓忌技芰芶际剂季哜垍峜既洎济紀茍計剤紒继觊記偈寂寄徛悸旣梞済祭萕惎臮葪蔇兾痵継蓟裚跡際墍暨漃漈禝稩穊誋跽霁鲚暩稷諅鲫冀劑曁穄縘薊襀髻嚌檕濟繋罽覬鮆檵璾蹟鯽鵋齌廭懻癠穧糭繫蘎骥鯚瀱繼蘮鱀蘻霽鰶鰿鱭驥加夹夾宊抸佳拁泇迦枷毠浃珈埉家浹痂梜笳耞袈袷傢猳葭裌跏犌腵鉫嘉镓糘豭貑鎵麚圿扴岬郏荚郟唊恝莢戛脥铗戞蛱颊蛺跲餄鋏頬頰鴶鵊甲叚玾胛斚贾钾婽徦斝椵賈鉀榎槚瘕檟价驾架假嫁幏榢價稼駕嗧戋奸尖幵坚歼间冿戔玪肩艰姦姧兼监堅惤猏笺菅菺豜湔牋犍缄葌葏間靬搛椷椾煎瑊睷碊缣蒹豣監箋樫熞緘蕑蕳鲣鳽鹣熸篯縑鋻艱鞬餰馢麉瀐鞯鳒殱礛覸鵳瀸鰔櫼殲譼鰜鶼籛韀鰹囏虃鑯韉囝拣枧俭柬茧倹挸捡笕减剪帴梘检湕趼揀揃検減睑硷裥詃锏弿暕瑐筧简絸谫彅戩戬碱儉翦撿檢藆襇襉謇蹇瞼礆簡繭謭鬋鰎鹸瀽蠒鐗鐧鹻譾襺鹼见件見侟建饯剑洊牮荐贱俴健剣栫涧珔舰剱徤渐袸谏釼寋旔楗毽溅腱臶葥跈践閒賎鉴键僭榗槛漸劍劎墹澗箭糋諓賤趝踐踺劒劔橺薦諫鍵餞瞯瞷磵礀螹鍳擶檻濺繝瀳覵鏩聻艦轞鑑鑒鑬鑳江姜将茳浆畕豇葁摪翞僵漿螀壃彊缰薑橿殭螿鳉疅礓疆繮韁鱂讲奖桨傋蒋勥奨奬蔣槳獎耩膙講顜匞匠夅弜杢降洚绛將弶袶絳畺酱摾滰嵹犟糡醤糨醬櫤謽艽芁交郊姣娇峧浇茭茮骄胶椒焦焳蛟跤僬嘄虠鲛嬌嶕嶣憍澆膠蕉燋膲礁穚鮫鵁鹪簥蟭轇鐎驕鷦鷮櫵臫角佼侥挢狡绞饺捁晈烄笅皎矫脚铰搅湫筊絞剿勦敫湬煍腳賋僥摷暞踋鉸餃儌劋撟撹徼敽敿缴曒璬矯皦蟜鵤繳譑孂纐攪灚鱎叫呌峤挍訆珓窌轿较敎教窖滘較嘂嘦斠漖酵噍嶠潐噭嬓獥藠趭轎醮譥皭釂阶疖皆接掲痎秸菨階喈嗟堦媘嫅揭椄湝脻街煯稭鞂蝔擑癤鶛卩卪孑尐节讦刦刧劫岊昅刼劼杰疌衱诘拮洁结迼倢桀桝莭訐偼婕崨捷袺傑媫結蛣颉嵥楬楶滐睫節蜐詰鉣魝截榤碣竭蓵鲒潔羯誱踕頡幯擳嶻擮礍鍻鮚巀櫭蠞蠘蠽她姐毑媎解觧飷檞丯介吤岕庎忦戒芥屆届斺玠界畍疥砎衸诫借悈蚧徣堺楐琾蛶骱犗誡褯魪藉繲巾今斤钅兓金釒津矜砛荕衿觔埐珒紟惍琎堻琻筋嶜璡鹶黅襟仅卺巹紧堇菫僅厪谨锦嫤廑漌盡緊蓳馑槿瑾錦謹饉伒劤尽劲妗近进侭枃勁浕荩晉晋浸烬赆祲進煡缙寖搢溍禁靳墐慬瑨僸凚歏殣觐儘噤濅縉賮嚍壗嬧濜藎燼璶覲贐齽坕坙巠京泾经茎亰秔荆荊涇莖婛惊旌旍猄経菁晶稉腈睛粳經兢精聙橸鲸鵛鯨鶁鶄麖鼱驚麠井丼阱刭坓宑汫汬肼剄穽颈景儆幜憬璄憼暻燝燞璟璥頸蟼警妌净弪径迳俓浄胫倞凈弳徑痉竞逕婙婧桱梷淨竟竫脛敬痙竧靓傹靖境獍誩踁静頚靚曔镜靜瀞鏡競竸冂冋坰扃埛絅駉駫蘏冏囧泂迥侰炯逈浻烱煚窘颎綗僒煛熲澃燑燛褧顈蘔丩勼纠朻牞究糺鸠糾赳阄萛啾揂揪揫鳩摎樛鬏鬮九久乆乣奺汣杦灸玖舏韭紤酒镹韮匛旧臼咎畂疚柩柾倃桕厩救就廄匓舅僦廏廐慦殧舊鹫鯦麔匶齨鷲欍凥圧抅匊居拘泃狙苴驹倶挶捄疽痀眗砠罝陱娵婅婮崌掬梮涺椐琚腒趄跔锔裾雎艍蜛諊踘鋦駒鮈鴡鞠鞫鶋局泦侷狊桔毩淗焗菊郹椈毱湨犑輂僪粷蓻跼趜躹閰橘檋駶鵙蹫鵴巈蘜鶪鼰鼳驧咀弆沮举矩莒挙椇筥榉榘蒟龃聥舉踽擧櫸齟欅襷句巨讵姖岠怇拒洰苣邭具怚拠昛歫炬秬钜俱倨冣剧粔耟蚷袓埧埾惧据詎距焣犋跙鉅飓虡豦锯寠愳窭聚駏劇勮屦踞鮔壉懅據澽窶遽鋸屨颶瞿貗簴躆醵懼鐻爠姢娟捐涓脧裐鹃勬鋑鋗镌鎸鵑鐫蠲卷呟帣埍捲菤锩臇錈奆劵弮倦勌桊狷绢隽淃瓹眷鄄睊絭罥雋睠絹飬慻蔨餋獧羂噘撅撧屩屫亅孒孓决刔氒诀妜抉決芵泬玦玨挗珏砄绝虳觉倔捔欮蚗崛掘斍桷殌焆覐觖訣赽趹逫傕厥絕絶覚趉鈌劂勪瑴谲駃嶡嶥憰潏熦爴獗瘚蕝蕨鴂鴃噱憠橛橜镼爵臄镢蟨蟩爑譎蹶蹷鶌嚼矍覺鐍鐝灍爝觼彏戄攫玃鷢欔矡龣貜躩钁军君均汮姰袀軍钧莙蚐桾皲菌鈞碅筠皸皹覠銁銞鲪麇鍕鮶麏麕呁俊郡陖埈峻捃晙浚馂骏焌珺畯竣箘箟蜠儁寯懏餕燇濬駿鵔鵕鵘攈咔咖喀卡佧垰胩裃鉲开奒揩衉锎開鐦凯剀垲恺闿铠凱剴慨蒈塏愷楷輆暟锴鍇鎧闓颽忾炌炏欬烗勓嘅愾鎎乫刊栞勘龛堪嵁戡龕冚坎侃砍莰偘埳惂堿欿塪歁輡轁顑竷轗看衎崁墈阚瞰磡闞矙忼砊粇康嫝嵻慷漮槺穅糠躿鏮鱇扛摃亢伉匟邟囥抗犺闶炕钪鈧閌尻髛丂攷考拷洘栲烤铐犒銬鲓靠鮳鯌匼坷苛柯牁珂科胢轲疴趷钶嵙棵痾萪軻颏搕犐稞窠鈳榼薖颗樖瞌磕蝌頦醘顆髁礚壳咳殻揢翗嶱可岢炣渇嵑敤渴克刻剋勀勊客峇恪娔尅课堁氪骒缂嗑愙溘锞碦緙課錁礊騍肎肯肻垦恳啃豤貇墾錹懇掯裉褃劥吭坈坑挳硁牼硜铿硻誙銵鍞鏗巪乬唟厼怾空倥埪崆悾涳硿箜躻躼錓鵼孔恐控鞚廤抠芤眍剾彄摳瞘口劶叩扣怐敂冦宼寇釦窛筘滱蔲蔻瞉簆鷇扝刳矻郀枯哭桍堀崫圐跍窟骷鮬狜苦楛库俈绔庫秙焅袴喾絝裤瘔酷褲嚳夸姱晇舿誇侉咵垮銙挎胯跨骻蒯擓巜凷圦块快侩郐哙狯脍塊筷鲙儈墤鄶噲廥獪膾旝糩鱠宽寛寬髋鑧髖梡欵款歀窽窾匡劻诓邼匩哐恇洭筐筺誆軭抂狂狅诳軖軠誑鵟夼儣懭邝圹纩况旷岲況矿昿贶框眖砿眶絋絖貺軦鉱鋛鄺壙黋懬曠爌矌礦穬纊鑛亏刲岿悝盔窥聧窺虧闚顝巋蘬奎晆逵鄈頄馗喹揆葵骙戣暌楏楑魁睽蝰頯櫆藈鍨鍷騤夔蘷虁巙躨卼傀煃跬頍磈蹞尯匮欳喟媿愦愧溃蒉蒊馈匱嘳嬇憒潰篑聩聭蕢樻殨謉餽簣聵籄鐀饋鑎坤昆晜堃堒婫崐崑猑菎裈焜琨髠裩锟髡鹍尡潉蜫褌髨熴瑻醌錕鲲臗騉鯤鵾鶤悃捆阃壸梱祵硱稇裍壼稛綑閫閸困涃睏扩拡括挄栝桰筈萿葀蛞阔廓噋頢髺擴濶闊鞟韕懖霩鞹鬠穒垃拉柆啦翋菈搚邋旯砬揦磖喇藞嚹剌溂腊揧楋瘌蜡蝋辢辣蝲臈攋爉臘鬎櫴瓎镴鯻蠟鑞鞡来來俫倈崃徕涞莱郲婡崍庲徠梾淶猍萊逨棶琜筙铼箂錸騋鯠鶆麳唻赉睐睞赖賚濑賴頼顂癞鵣瀨瀬籁藾癩襰籟兰岚拦栏婪嵐葻阑蓝蓞谰厱澜褴儖斓篮懢燣藍襕镧闌璼襤譋幱攔瀾灆籃繿蘭斕欄礷襴囒灡籣欗讕躝襽鑭钄韊览浨揽缆榄漤罱醂壈懒覧擥嬾懶孄覽孏攬欖爦纜烂滥燗嚂壏濫爁爛爤瓓灠糷啷勆郎郞欴狼莨嫏廊桹琅蓈榔瑯硠稂锒筤艆蜋郒螂躴鋃鎯駺悢朗阆朖烺塱蓢樃誏閬朤埌崀浪蒗唥捞粩撈劳労牢狫窂哰唠崂浶勞痨铹僗嘮嶗憥朥癆磱簩蟧醪鐒顟髝耂老佬咾姥恅荖栳珯硓铑蛯銠潦橑鮱轑涝烙嗠耢酪嫪憦澇橯耮軂仂阞乐叻忇扐氻艻玏泐竻砳勒楽韷樂簕鳓鰳饹餎雷嫘缧蔂樏畾檑縲镭櫑瓃羸礧纍罍蘲鐳轠壨鑘靁虆鱩欙纝鼺厽耒诔垒塁絫傫誄磊蕌磥蕾儡壘癗藟櫐矋礨灅蠝蘽讄儽鑸鸓肋泪洡类涙淚累酹銇頛頪擂錑攂礌颣類纇蘱禷嘞脷塄棱楞碐稜踜薐冷倰堎愣睖唎刕厘剓梨狸离荲莉骊悡梸犁菞喱棃犂鹂剺漓睝筣缡艃蓠蜊嫠孷樆璃盠竰貍氂犛糎蔾褵鋫鲡黎篱縭罹錅蟍謧醨嚟藜邌釐離鯏斄鏫鯬鵹黧囄灕蘺蠡蠫孋廲劙鑗穲籬驪鱺鸝礼李里俚峛哩娌峲浬逦理裡锂粴裏豊鋰鲤澧禮鯉蟸醴鳢邐鱧欚力历厉屴立吏朸丽利励呖坜沥苈例岦戾枥沴疠苙隶俐俪栃栎疬砅茘荔赲轹郦娳悧栗栛栵涖猁珕砺砾秝莅唳婯悷琍笠粒粝蚸蛎傈凓厤棙痢蛠詈跞雳塛慄搮溧蒚蒞鉝鳨厯厲暦歴瑮綟蜧勵曆歷篥隷鴗巁檪濿癘磿隸鬁儮曞櫔爄犡禲蠇嚦壢攊櫟瀝瓅礪藶麗櫪爏瓑皪盭礫糲蠣儷癧礰酈鷅麜囇攦躒轢欐讈轣攭瓥靂鱱靋瓈俩倆嫾奁连帘怜涟莲連梿联裢亷嗹廉慩溓漣蓮匲奩熑覝劆匳噒憐磏聨聫褳鲢濂濓縺翴聮薕螊櫣燫聯臁蹥謰鎌镰簾蠊譧鬑鐮鰱籢籨敛琏脸裣摙槤璉蔹嬚斂歛臉鄻襝羷蘝蘞练娈炼恋浰殓堜媡湅萰链僆楝煉瑓潋稴練澰錬殮鍊鏈瀲鰊戀纞簗良俍凉梁涼椋辌粮粱墚綡踉樑輬糧両两兩唡啢掚脼裲緉蜽魉魎亮哴谅辆喨晾湸量煷輌諒輛鍄蹽辽疗聊僚寥嵺廖憀漻膋嘹嫽寮嶚嶛憭撩敹獠缭遼暸燎璙窷膫療竂镣鹩屪廫簝繚蟟豂賿蹘爎鐐髎飉鷯钌釕鄝蓼爒镽了尥尦炓料尞撂瞭咧毟挘埓列劣冽劽姴峢挒洌茢迾埒浖烈烮捩猎猟脟蛚裂煭睙聗趔巤颲儠鮤鴷擸獵犣躐鬛鬣鱲厸邻林临啉崊惏淋晽琳粦痳碄箖粼鄰隣嶙潾獜遴斴暽燐璘辚霖瞵磷臨繗翷麐轔壣瀶鏻鳞驎麟鱗菻亃稟僯凛凜撛廩廪懍懔澟檁檩癛癝顲吝恡悋赁焛賃蔺橉甐膦閵疄藺蹸躏躙躪轥拎伶刢灵囹坽夌姈岭岺彾泠狑苓昤朎柃玲瓴凌皊砱秢竛铃陵鸰婈崚掕棂淩琌笭紷绫羚翎聆舲菱蛉衑祾詅跉軨蓤裬鈴閝零龄綾蔆輘霊駖澪蕶錂霗魿鲮鴒鹷燯霛霝齢瀮酃鯪孁蘦齡櫺醽靈欞爧麢龗阾袊领領嶺令另呤炩溜熘刘沠畄浏流留旈琉畱硫裗媹嵧旒蒥蓅遛馏骝榴瑠飗劉瑬瘤磂镏駠鹠橊璢疁镠癅蟉駵嚠懰瀏藰鎏鎦餾麍鏐飀鐂騮飅鰡鶹驑柳栁桞珋桺绺锍綹熮罶鋶橮羀嬼六翏塯廇澑磟鹨蹓霤雡飂鬸鷚瓼甅囖咯龙屸咙泷茏昽栊珑胧眬砻竜笼聋隆湰嶐槞漋蕯癃窿篭龍嚨巃巄瀧蘢鏧霳曨朧櫳爖瓏矓礱礲襱龒籠聾蠪蠬龓豅躘鑨靇驡鸗陇垄垅拢儱隴壟壠攏竉哢梇硦衖徿贚娄偻婁喽溇蒌僂楼嘍廔慺蔞遱樓熡耧蝼瞜耬艛螻謱軁髅鞻髏嵝搂塿嶁摟漊甊篓簍陋屚漏瘘镂瘺瘻鏤露噜撸嚕擼卢庐芦垆枦泸炉栌胪轳舮鸬玈舻颅鈩鲈魲盧嚧壚廬攎瀘獹璷蘆櫨爐瓐臚矑籚纑罏艫蠦轤鑪顱髗鱸鸕黸卤虏挔捛掳鹵硵鲁虜塷滷蓾樐澛魯擄橹磠镥瀂櫓氌艣鏀艪鐪鑥圥甪陆侓坴彔录峍勎赂辂陸娽淕淥渌硉菉逯鹿椂琭祿禄僇剹勠滤盝睩碌稑賂路輅塶廘摝漉箓粶蔍戮樚熝膔膟觮趢踛辘醁潞穋蕗錄録錴璐簏螰鴼濾簶蹗轆騄鹭簬簵鏕鯥鵦鵱麓鏴騼籙觻虂鷺氇驴闾榈閭馿氀膢櫚藘曥鷜驢吕呂侣郘侶旅梠焒祣稆铝屡絽缕屢膂膐褛鋁履褸儢穞縷穭寽垏律哷虑率绿嵂氯葎綠緑慮箻勴繂櫖爈鑢孪峦挛栾鸾脔滦銮鵉圝奱孌孿巒攣曫欒灓羉臠圞灤虊鑾癴癵鸞卵乱釠亂掠略畧锊稤稥圙鋝鋢擽抡掄仑伦囵沦纶侖轮倫陯圇婨崘崙惀淪菕棆腀碖綸蜦踚輪磮錀鯩稐耣论埨溣論捋頱囉罗啰猡脶萝逻椤腡锣箩骡镙螺羅覶鏍儸覼騾玀蘿邏欏鸁籮鑼饠驘剆倮砢蓏裸躶瘰蠃臝攞曪癳泺峈洛络荦骆洜珞笿絡落摞漯犖雒駱鮥鵅濼纙鱳嘸呣妈媽嬤嬷麻痲嫲蔴犘蟆蟇马犸玛码蚂馬溤獁遤瑪碼螞鎷鷌鰢亇杩祃閁骂唛傌睰嘜榪禡罵駡礣鬕吗嗎嘛埋薶霾买荬買嘪蕒鷶劢迈佅売麦卖脉脈麥衇勱賣邁霡霢颟顢姏悗蛮慲摱馒槾樠瞒瞞鞔饅鳗鬗鬘鰻蠻屘満睌满滿螨襔蟎鏋矕曼僈谩鄤墁嫚幔慢漫獌缦蔄蔓熳澫澷镘縵蟃謾鏝蘰牤邙吂忙汒芒尨杗杧盲厖恾笀茫哤娏浝狵牻硭釯铓痝蛖鋩駹蘉莽莾茻壾漭蟒蠎匁猫貓毛矛毜毝枆牦茅旄渵軞酕堥蛑锚緢髦蝥髳錨蟊鶜冇卯夘戼峁泖茆昴铆笷蓩鉚冃皃芼冐茂冒眊贸耄袤覒媢帽貿鄚愗暓楙毷瑁瞀貌鄮蝐懋唜庅嚒濹嚰么癦呅沒没枚玫苺栂眉脄莓梅珻脢郿堳媒嵋湄湈猸睂葿楣楳煤瑂禖腜塺槑酶镅鹛鋂霉徾鎇矀攗蘪鶥攟黴毎每凂美挴浼媄嵄渼媺镁嬍燘躾鎂黣妹抺沬昧祙袂眛媚寐痗跊鬽煝睸韎魅篃蝞嚜椚门扪玣钔門閅捫菛璊穈鍆虋闷焖悶暪燜懑懣们們掹擝氓甿虻冡庬罞莔萌萠夢溕盟雺甍儚橗瞢蕄蝱鄳鄸幪懞濛獴曚朦檬氋矇礞鯍艨鹲矒靀饛顭鸏勐猛瓾蒙锰艋蜢錳懵蠓鯭鼆孟梦夣懜霥霿踎咪瞇冞弥祢迷袮猕谜蒾詸謎醚彌擟糜縻麊麋禰靡獼麛爢戂攠瓕蘼镾醾醿鸍釄米羋芈侎沵弭洣敉眫粎脒眯渳葞蝆蔝銤濔瀰孊灖冖糸汨沕宓泌觅峚祕宻秘密淧覓覔幂谧塓幎覛嘧榓滵漞熐蔤蜜鼏冪樒幦濗藌謐櫁簚羃宀芇眠婂绵媔棉綿緜臱蝒嬵檰櫋矈矊矏丏汅免沔黾俛勉眄娩偭冕勔喕愐湎缅葂腼緬鮸靣面糆麪麫麺麵喵苗媌描瞄鹋嫹鶓鱙杪眇秒淼渺缈篎緲藐邈妙庙玅竗庿廟乜吀咩哶孭灭覕搣滅蔑薎鴓幭懱瀎篾櫗蠛衊鑖鱴瓱民垊姄岷忞怋旻旼玟苠珉盿冧罠崏捪琘琝缗暋瑉痻碈鈱緍緡賯錉鴖鍲皿冺刡闵抿泯勄敃闽悯敏笢笽湣閔愍敯黽閩僶慜憫潣簢鳘蠠鰵名明鸣洺眀茗冥朙眳铭鄍嫇溟猽蓂暝榠銘鳴瞑螟覭佲姳凕慏酩命掵詺谬缪繆謬摸嚤尛谟嫫馍摹模膜麼麽摩魹橅磨糢謨謩擵饃嚩蘑譕髍魔劘饝抹懡麿末劰圽妺帓怽歾歿殁沫茉陌帞昩枺皌眜眿砞秣莈莫眽粖絈袹蛨貃嗼塻寞漠蓦貊銆靺墨嫼暯瘼瞐瞙镆魩黙縸默貘藦蟔鏌爅驀礳纆耱乮哞牟侔劺恈洠桙眸谋鉾謀瞴鍪鴾麰蟱某母毪獏墲氁亩牡姆拇峔牳畆畒胟娒畝畞砪畮鉧踇木仫目凩沐狇坶炑牧苜毣莯蚞钼募萺雮墓幕幙慔楘睦鉬慕暮樢艒霂穆鞪旀丆椧拏拿挐誽镎鎿乸哪雫内那吶妠纳肭娜衲钠納袦捺笝豽軜貀鈉嗱蒳靹魶腉熋摨孻乃奶艿氖疓妳廼迺倷釢嬭奈柰耐萘渿鼐褦螚錼囡男抩枏枬侽南柟娚畘莮难喃遖暔楠煵諵難赧揇湳萳腩蝻戁婻囔乪嚢囊蠰鬞馕欜饢擃曩攮灢儾齉孬檂呶怓挠峱硇铙猱蛲詉碙撓嶩獶蟯夒譊鐃巎獿垴恼悩脑匘脳堖惱嫐瑙腦碯闹婥淖閙鬧臑疒讷呐抐眲訥呢娞馁腇餒鮾鯘內氝焾嫩能莻嗯鈪銰啱妮尼坭怩泥籾倪屔秜郳铌埿婗淣猊蚭棿跜鈮蜺觬貎輗霓鲵鯢麑齯臡伱伲你拟抳狔苨柅掜旎晲孴鉨馜儗儞隬擬薿檷鑈屰氼迡昵胒逆匿痆眤堄惄嫟愵溺睨腻暱縌膩嬺拈年秊哖秥鲇鮎鲶鵇黏鯰涊捻淰辇撚撵碾輦簐攆蹨躎卄廿念姩埝艌娘嬢孃酿醸釀鸟茑茒袅鳥嫋裊蔦嬝褭嬲尿脲捏揑肀帇圼苶枿陧涅聂臬啮惗菍隉喦敜嗫嵲鉩踂噛摰槷踗踙镊镍嶭篞臲錜颞蹑嚙聶鎳闑孼孽櫱籋蘖囁齧巕糱糵蠥囓讘躡鑷顳钀脌囜您拰宁咛拧狞柠聍寍寕寜寧儜凝嚀嬣擰獰薴檸聹鑏鬡鸋橣矃佞侫泞甯寗澝濘妞牛牜汼忸扭沑狃纽杻炄钮紐莥鈕靵农侬哝浓脓秾農儂辳噥憹濃蕽禯膿穠襛醲欁繷弄挊挵癑齈羺譨啂槈耨獳檽鎒鐞譳奴伖孥驽笯駑伮努弩砮胬怒傉搙女钕籹釹衂恧朒衄疟虐瘧奻渜暖煖煗餪硸黁燶郍挪梛傩搻儺橠诺喏掿逽搦锘榒稬諾蹃糑鍩懦懧糥穤糯桛噢哦筽毮夞乯鞰讴欧殴瓯鸥塸歐毆熰甌膒鴎櫙藲謳鏂鷗齵吘呕偶腢嘔耦蕅藕怄沤慪漚妑皅趴舥啪葩杷爬耙掱琶筢潖帊帕怕袙拍俳徘排猅棑牌箄輫簰犤哌派湃蒎鎃磗眅畨潘攀爿柈盘跘媻幋蒰搫槃盤磐縏蹒瀊蟠蹣鎜鞶坢冸判沜泮炍叛牉盼畔袢詊溿頖鋬鵥襻鑻乓汸沗肨胮雱滂膖霶厐庞逄旁舽嫎篣螃鳑龎龐鰟蠭嗙耪覫髈炐胖抛拋脬刨咆垉庖狍炮炰爮袍匏蚫軳鞄褜麅跑奅泡疱皰砲萢麭礟礮呸怌肧柸胚衃醅阫陪陫培毰赔锫裴裵賠錇俖伂沛佩帔姵斾旆浿珮配笩蓜辔馷嶏霈轡喷噴濆歕瓫盆湓葐呠翉翸喯匉怦抨泙恲胓砰梈烹硑軯閛漰嘭駍磞芃朋挷竼倗莑堋弸彭棚椖傰塜塳搒漨硼稝蓬鹏槰樥熢憉澎輣篷膨錋韸髼蟚蟛鬅纄韼鵬騯鬔鑝捧淎皏剻掽椪碰踫浌巼闏乶喸丕伓伾批纰邳坯怶披抷炋狉狓砒悂秛秠紕铍旇翍耚豾釽鈚鈹鉟銔劈磇駓髬噼錃錍魾憵礔礕闢霹皮阰芘岯枇毞肶毗毘疲笓蚍郫陴啤埤崥蚽豼椑焷琵脾腗榌鲏罴膍蜱隦魮壀鮍篺螷貔簲羆鵧朇鼙蠯匹庀仳圮苉脴痞銢諀鴄擗噽癖嚭屁淠渒揊媲嫓睤睥潎僻澼嚊甓疈譬鷿鸊片囨偏媥犏篇翩鶣骈胼腁楄楩賆諚骿蹁駢騈覑谝貵諞骗魸騗騙剽彯漂缥飘磦旚縹翲螵犥飃飄魒瓢薸闝殍瞟篻醥皫顠票僄勡嘌嫖徱慓氕撇撆暼瞥丿苤鐅嫳姘拼礗穦馪驞玭贫貧琕嫔频頻嬪薲嚬矉颦顰品榀朩牝汖娉聘乒甹俜涄砯艵竮頩平评凭呯坪岼苹郱屏帡枰洴玶荓娦瓶屛帲淜萍蚲塀幈焩甁缾聠蓱蛢評軿鲆凴慿箳輧憑鮃檘簈蘋钋坡岥泼娝釙颇溌酦潑醱鏺婆嘙蔢鄱皤謈櫇叵尀钷笸鉕駊廹岶迫敀昢洦珀哱烞破砶粕奤蒪頗魄剖颒抔抙捊掊裒箁咅哣婄堷犃兺哛仆攴攵扑抪炇巬巭柨陠痡铺駇噗撲鋪擈鯆圤匍莆菩菐葡蒱蒲僕酺墣璞濮瞨穙镤贌纀鏷朴圃埔浦烳普圑溥暜谱潽樸氆諩檏镨譜蹼鐠舖舗瀑曝七迉沏妻恓柒倛凄栖桤缼郪娸悽戚捿桼淒萋朞期棲欺紪褄僛嘁慽榿槭漆緀慼磎諆踦諿霋蹊魌鏚鶈亓祁齐圻岐岓忯芪亝其奇斉歧祇祈肵疧竒剘斊旂耆脐蚑蚔蚚颀埼崎帺掑淇渏猉畦萁跂軝釮骐骑嵜棊棋琦琪祺蛴愭碁碕褀锜頎鬾鬿旗粸綥綦綨緕蜝蜞齊璂禥蕲踑螧錡鲯懠濝藄檱櫀簱臍騎騏鳍蘄鯕鵸鶀麒籏纃艩蠐鬐騹魕鰭玂麡乞邔企屺岂芑启呇杞玘盀唘豈起啓啔啟婍绮晵棨裿綮綺諬簯闙气讫気汔迄弃汽矵芞呮泣炁盵咠契砌荠栔氣訖唭欫夡愒棄湆湇葺碛摖暣甈碶噐憇器憩磜磧磩薺礘罊蟿掐葜拤跒酠鞐圶冾帢恰洽殎硈愘髂千仟阡圱圲奷扦汘芊迁佥岍杄汧茾欦竏臤钎拪牵粁悭蚈谸铅婜孯牽釺掔谦鈆雃僉愆签鉛骞鹐慳搴摼撁箞諐遷褰謙顅檶攐攑櫏簽鏲鵮攓騫鐱鬜鬝籤韆仱岒忴扲拑乹前荨钤歬虔钱钳乾偂掮揵軡媊鈐鉆鉗墘榩箝銭潜羬蕁橬錢黔鎆黚騝濳騚灊籖鰬凵浅肷淺嵰慊遣槏膁蜸潛谴缱繾譴鑓欠刋伣芡俔茜倩悓堑傔嵌棈椠嗛皘蒨塹歉綪蔳儙槧篏輤篟壍嬱縴呛羌戕戗斨枪玱羗猐琷跄嗴椌獇腔嗆溬蜣锖嶈戧槍牄瑲羫锵篬錆蹌镪蹡鎗鏘鏹強强墙嫱蔷樯漒蔃墻嬙廧薔檣牆謒艢蘠抢羟搶羥墏摤繈襁繦炝唴熗羻兛瓩悄硗郻鄗嵪跷鄡鄥劁敲踍锹墝碻頝骹墽幧橇燆缲磽鍫鍬繑繰趬蹺蹻鐰乔侨荍荞桥硚菬喬睄僑槗谯嘺嫶憔蕎鞒樵橋犞癄瞧礄藮譙趫鐈鞽顦巧釥愀髜俏诮陗峭帩窍殼翘誚髚僺撬撽鞘韒竅翹鞩躈切苆癿茄聺且厒妾怯匧窃倿悏挈洯惬淁笡愜蛪朅箧緁锲魥篋踥穕藒鍥鯜鐑竊籡亲侵钦衾骎菳媇嵚綅誛嶔親顉駸鮼寴庈芩芹埁珡矝秦耹菦蚙捦琴琹禽鈙雂勤嗪嫀溱靲噙擒斳鳹懄檎澿瘽螓懃蠄坅昑笉梫赺赾寑锓寝寢鋟螼吢吣抋沁唚菣揿欽搇撳瀙藽靑青氢轻倾卿郬圊埥氫淸清軽傾廎蜻輕鲭鯖鑋夝甠剠勍情殑硘晴棾氰葝暒擏樈擎檠黥苘顷请庼頃漀請檾謦庆凊掅殸碃箐靘慶磬儬濪罄櫦宆跫銎卭邛穷穹茕桏笻筇赹惸焪焭琼舼蛩蛬煢熍睘瞏窮儝憌橩璚藑瓊竆藭瓗丘丠邱坵恘秋秌寈蚯媝萩楸蓲鹙篍緧蝵穐趥鳅蟗鞦鞧蘒鰌鰍鶖鱃龝叴囚扏犰玌朹汓肍求虬泅虯俅觓訄訅酋唒浗紌莍逎逑釚梂殏毬球赇釻崷巯渞湭皳盚遒煪絿蛷裘巰觩賕璆蝤銶醔鮂鼽鯄鵭蠤鰽搝糗区曲伹佉匤岖诎阹驱坥屈岨岴抾浀祛胠袪區蛆躯筁粬蛐詘趋嶇駆憈敺誳駈麹髷魼趨麯軀麴黢驅鰸鱋佢劬斪朐朑胊菃衐鸲淭渠絇翑葋軥蕖璖磲螶鴝璩翵蟝鼩蘧匷忂灈戵欋氍籧臞癯蠷衢躣蠼鑺鸜取竘娶紶詓竬蝺龋齲厺去刞呿迲郥耝阒觑趣閴麮闃覰覷鼁覻峑恮悛圈圏棬駩騡鐉全权佺诠姾泉洤荃拳牷辁啳埢婘惓痊硂铨湶犈筌絟腃葲搼楾瑔觠詮跧輇蜷銓権踡縓醛闎鳈鬈孉巏鰁權齤蠸颧顴犭犬汱甽畎烇绻綣虇劝券巻牶椦勧韏勸炔缺蒛瘸却卻埆崅悫雀硞确舃阕塙搉皵碏阙鹊愨榷墧慤毃確趞燩闋礐闕鵲礭夋囷峮逡輑宭帬裙羣群裠亽罖囕呥肰衻袇蚦袡蚺然髥嘫髯燃繎冄冉姌苒染珃媣蒅橪穣儴勷瀼獽蘘禳瓤穰躟鬤壌嚷壤攘爙纕让懹譲讓荛饶桡蕘橈襓饒犪扰娆隢嬈擾绕遶繞惹热熱人亻仁壬忈朲忎秂芢鈓魜銋鵀忍荏栠栣荵秹棯稔綛躵刃刄认仞仭讱任屻扨纫妊杒牣纴肕轫韧饪姙紉衽恁紝訒軔梕袵絍腍葚靭靱韌飪認餁扔仍辸礽芿陾日驲囸釰鈤馹戎肜栄狨绒茙茸荣容峵毧烿媶嵘絨羢嫆嵤搈搑摉榵溶蓉榕榮熔瑢穁蝾褣镕氄縙融螎駥髶嬫嶸爃鎔瀜曧蠑冗宂傇軵穃厹禸柔粈媃揉渘葇瑈腬糅蝚蹂輮鍒鞣瓇騥鰇鶔楺煣韖肉宍嶿邚如侞帤茹桇袽铷渪筎蒘銣蕠儒鴑嚅嬬孺濡薷鴽曘燸襦繻蠕颥醹顬鱬汝肗乳辱鄏入扖込杁洳嗕媷溽缛蓐鳰褥縟擩堧撋壖阮朊软耎偄軟媆愞瑌腝嫰碝緛蝡輭瓀礝桵甤緌蕤蕊蕋橤繠蘂蘃汭芮枘蚋锐瑞蜹睿銳鋭叡壡闰润閏閠潤橍挼捼叒若偌弱鄀婼渃焫楉嵶蒻箬篛爇鰙鰯鶸仨桬撒洒訯靸潵灑卅钑飒脎萨鈒摋隡馺颯薩櫒栍毢愢揌塞毸腮嘥噻鳃顋鰓嗮赛僿賽簺虄三弎叁毵毶厁毿犙鬖壭伞傘散糁糂馓橵糝糣糤繖鏒饊俕閐桒桑槡嗓搡磉褬颡鎟顙丧喪掻慅搔溞骚缫繅臊鳋颾騒騷鰠鱢扫掃嫂埽瘙氉矂髞色洓栜涩啬渋铯雭歮琗嗇瑟歰銫澁懎擌濇濏瘷穑澀璱瀒穡繬穯轖鏼譅飋裇聓森槮襂篸僧鬙閪縇杀沙纱乷刹砂唦挱殺猀粆紗莎铩痧硰蔱裟榝樧魦鲨閷鎩鯊鯋繺傻儍繌倽唼啥帹萐喢歃煞翜箑翣閯霎筛篩簁簛晒曬山彡邖圸删刪杉杣芟姍姗衫钐埏挻狦珊舢烻痁脠軕笘釤閊跚剼搧嘇幓煽蔪潸澘曑檆縿膻鯅羴羶闪陕炶陝閃晱煔睒熌覢讪汕疝苫剡扇訕赸傓善椫銏骟僐鄯墠墡缮嬗擅敾樿膳磰謆赡繕蟮蟺譱贍鐥饍騸鳝灗鱓鱔伤殇商愓觞傷墒慯滳漡蔏殤熵螪觴謪鬺裳垧扄晌赏賞鑜丄上仩尙尚恦绱緔弰捎梢烧莦焼焽稍旓筲艄蛸輎蕱燒颵髾鮹勺芍苕柖玿萔韶少劭卲邵绍哨娋袑紹綤潲奢猞赊畲輋賒賖檨舌佘虵蛇蛥舍捨厍设社舎厙射涉涻渉設赦弽慑摂摄滠慴摵蔎蠂韘騇懾攝灄麝欇申屾扟伸身侁呻妽籶绅罙诜姺柛氠珅穼籸娠峷甡眒砷堔深紳兟椮葠裑訷罧蓡詵甧蔘燊薓駪鲹鯓鵢鯵鰺神榊鉮鰰邥弞抌沈审矤哂矧宷谂谉婶渖訠審諗頣魫曋瞫嬸瀋覾讅肾侺昚甚胂涁眘渗祳脤腎愼慎椹瘆蜃滲鋠瘮升生阩呏声斘昇枡泩苼殅牲珄竔胜陞曻陹笙湦焺甥鉎聲鍟鼪鵿渑绳縄憴澠繩譝鱦省眚偗渻圣晟晠剰盛剩勝琞貹嵊聖墭榺蕂橳賸尸失师呞虱虲诗邿鸤屍施浉狮師絁釶湤湿葹溮溼獅蒒蓍詩鉇瑡酾鳲箷蝨鳾褷鲺濕鍦鯴鰤鶳襹籭釃十饣什石辻佦时竍识实実旹飠姼峕拾炻祏蚀食埘時莳寔湜遈塒嵵溡蒔鉐實榯蝕鉽篒鲥鮖鼫識鼭鰣史矢乨豕使始驶兘宩屎笶榁鉂駛士氏礻世丗仕市示卋式忕亊叓戺事侍势呩柹视试饰冟室恀恃拭是昰枾柿眂贳适栻烒眎眡舐轼逝铈笹視釈崼弑徥揓谥貰释勢嗜弒煶睗筮觢試軾鈰鉃飾舓褆誓適奭銴噬嬕澨諟諡遾餝檡螫謚簭籂襫釋鰘齛兙瓧収收手扌守垨首艏寿受狩兽售授涭绶痩膄壽瘦綬夀獣獸鏉书殳抒纾叔杸枢陎姝柕倏倐書殊紓掓梳淑焂菽軗鄃疎疏舒摅毹毺綀输瑹跾踈樞蔬輸橾鮛儵攄瀭鵨尗秫婌孰赎塾熟璹贖暏暑黍署鼠属鼡蜀潻薥薯曙癙藷襡糬襩籔蠴鱪鸀鱰朮术戍束沭述侸咰怷树竖荗恕庶庻絉蒁術尌裋数竪腧鉥墅漱潄數澍豎樹濖錰鏣鶐鶑虪刷唰耍誜衰摔甩帅帥蟀卛闩拴閂栓涮腨双滝霜雙孀骦孇騻欆礵鷞鹴艭驦鸘爽塽慡樉縔鏯灀谁脽誰氵水氺閖帨涗涚祱稅税裞睡吮楯顺舜順蕣橓瞚瞤瞬鬊说哾說説妁烁朔铄欶硕矟嗍搠蒴嗽槊碩獡箾鎙爍鑠厶纟丝司糹私咝泀俬思恖虒鸶媤斯絲缌蛳楒禗鉰飔凘厮榹禠罳蜤銯锶嘶噝廝撕澌磃緦蕬鋖燍螄鍶蟖蟴颸騦鐁鷥鼶死巳亖四罒寺汜伺似佀兕姒泤祀価孠泗饲驷俟娰枱柶牭梩洍涘肂飤笥耜釲竢覗嗣肆貄鈻飼禩駟蕼儩騃瀃螦乺忪松枀枩娀柗倯凇梥崧庺淞菘嵩硹蜙憽檧濍鬆怂悚捒耸竦傱愯嵷慫聳駷讼宋诵送颂訟頌誦餸鎹凁捜鄋嗖廀廋搜溲獀蒐蓃馊飕摗锼艘螋醙鎪餿颼騪叜叟傁嗾瞍擞薮擻藪櫢瘶苏甦酥稣窣穌鯂蘇蘓櫯囌俗玊夙诉泝肃洬涑珟素速宿梀殐粛骕傃粟訴谡嗉塐塑嫊愫溯溸肅遡鹔僳愬榡膆蔌觫趚遬憟樎樕潥碿鋉餗潚縤橚璛簌藗謖蹜驌鱐鷫狻痠酸匴祘笇筭蒜算夊芕虽倠哸浽荽荾眭葰滖睢熣濉鞖雖绥隋随遀綏隨瓍膸瀡髄髓亗岁砕祟粋谇埣嵗脺遂歲歳煫睟碎隧嬘澻穂誶賥檖燧璲禭穗穟繀襚邃旞繐繸鐆譢鐩孙狲荪孫飧搎猻蓀飱槂蕵薞畃损笋隼筍損榫箰簨鎨鶽巺潠唆娑莏傞挲桫梭睃嗦羧蓑摍缩趖簑簔縮髿鮻所唢索琐琑惢锁嗩暛溑瑣鎍鎖鎻鎼鏁逤溹蜶他它牠祂咜趿铊塌榙溻鉈褟蹹侤塔墖獭鮙鳎獺鰨挞狧闼崉涾搨遝遢阘榻毾禢撻澾誻踏嚃錔嚺濌蹋鞜闒鞳闥譶躢襨囼孡骀珆胎駘台旲邰坮抬苔炱炲菭跆鲐箈臺颱儓鮐嬯擡薹檯籉太冭夳忲汰态肽钛泰粏舦酞鈦溙態燤坍贪怹啴痑舑貪摊滩嘽潬瘫擹攤灘癱坛昙倓谈郯婒惔弾覃榃痰锬谭墰墵憛潭談醈壇曇橝錟檀顃罈藫壜譚貚醰譠罎鷤忐坦袒钽菼毯鉭嗿憳憻暺醓璮襢叹炭埮探傝湠赕僋嘆碳舕撢歎賧汤铴湯嘡劏羰蝪薚镗蹚鏜鐋鞺鼞饧坣唐堂傏啺棠鄌塘嵣搪溏蓎隚榶漟煻瑭禟膅樘磄糃膛橖篖糖螗踼糛螳赯醣餳鎕餹闛饄鶶帑倘偒淌傥耥躺镋鎲儻戃曭爣矘钂烫摥趟燙仐夲弢涛绦掏絛詜嫍幍慆搯滔槄瑫韬飸縚縧濤謟鞱韜饕匋迯咷洮逃桃陶啕梼淘绹萄祹裪綯蜪鞀醄鞉鋾錭駣檮饀騊鼗讨套討畓忑忒特貣脦犆铽慝鋱蟘膯鼟疼痋幐腾誊漛滕邆縢螣駦謄儯藤騰籐鰧籘虅驣霯唞朰剔梯锑踢銻鷈鷉厗绨偍珶啼媞崹惿提渧稊缇罤遆鹈嗁瑅綈碮徲漽緹蕛蝭题趧蹄醍謕蹏鍗鳀鴺題鮷鵜騠鯷鶗鶙体挮躰骵軆體戻屉剃洟倜悌涕逖屜悐惕掦逷惖揥替楴裼褅歒殢髰薙嚏鬀嚔瓋鬄籊鐟趯天兲婖添酟靔黇靝田屇沺恬畋畑盷胋畠甛甜菾湉塡填搷阗碵緂磌窴鴫璳闐鷆鷏忝殄倎唺悿捵淟晪琠腆觍痶睓舔餂覥賟錪靦掭瑱睼舚旫佻庣恌挑祧聎芀条岧岹迢祒條笤蓚蓨龆樤蜩鋚鞗髫鲦螩鯈鎥齠鰷宨晀朓脁窕誂窱嬥眺粜铫絩覜趒跳頫糶怗贴萜聑貼跕铁蛈鉄僣銕鴩鐡鐢鐵驖呫帖飻餮厅庁汀艼听町耓厛烃桯烴綎鞓聴聼廰聽廳邒廷亭庭莛停婷嵉渟筳葶蜓楟榳閮霆聤蝏諪鼮圢侹娗挺涏梃烶珽脡铤艇颋艈誔鋌頲濎乭囲炵通痌嗵蓪樋熥仝同佟彤峂庝哃狪茼晍桐浵烔砼蚒眮秱铜童粡絧衕赨酮鉖僮勭鉵銅餇鲖潼獞曈朣橦氃犝膧瞳穜鮦统捅桶筒統筩綂恸痛慟憅偷偸婾媮鍮亠头投骰緰頭妵紏敨殕斢黈蘣透凸禿秃怢突唋涋捸堗湥痜葖嶀鋵鵚鼵図图凃峹庩徒悇捈涂荼途屠梌揬稌塗嵞瘏筡腯蒤鈯圖圗廜潳跿酴馟鍎駼鵌鶟鷋鷵土圡吐汢钍釷兎迌兔莵堍菟鵵湍猯煓貒团団抟剬剸團塼慱摶槫漙篿檲鏄糰鷒鷻圕疃彖湪褖推蓷藬颓隤尵頹頺頽魋穨蘈蹪俀脮腿僓蹆骽退娧煺蛻蜕褪駾吞呑旽涒啍朜焞暾黗屯忳芚饨豘豚軘飩鲀魨霕臀臋氽畽坉乇讬托扡汑饦杔侂咃拕拖沰侻挩捝莌袥託涶脫脱飥馲魠驝驮佗陀陁坨岮沱狏迱驼柁砣砤袉鸵紽堶詑跎酡碢馱槖駄踻駝駞橐鮀鴕鼧騨鼍驒鼉彵妥毤庹媠椭楕嫷撱橢鵎鰖拓柝唾萚跅毻箨蘀籜屲劸哇娃徍挖洼娲畖窊啘媧嗗蛙搲溛漥窪鼃攨瓦佤邷咓瓲砙袜聉嗢腽膃襪韈韤歪喎竵崴外顡乛弯剜婠帵塆湾睕蜿潫豌彎壪灣丸刓汍纨芄完岏忨抏玩笂紈捖顽烷琓貦頑邜宛倇唍挽晚盌莞埦婉惋晩梚涴绾脘菀晼椀琬皖畹碗綩綰輓踠鋔鍐万卍卐妧杤捥腕萬翫鋄薍錽贃鎫贎尣尩尪尫汪亡亾兦王仼彺莣蚟网忹往徃枉罔惘菵暀棢焹蛧辋網蝄誷輞瀇魍妄忘迋旺盳望朢危威烓偎逶隇隈喴媁媙愄揋揻渨煀葨葳微椳楲溦煨詴縅蝛覣嶶薇燰鳂癐巍鰃鰄囗为韦圩围帏沩违闱峗峞洈為韋桅涠唯帷惟维喡圍嵬幃湋溈爲琟違潍維蓶鄬潙潿醀濰鍏闈鮠癓覹犩霺霻厃伟伪尾纬芛苇委炜玮洧娓捤浘荱诿偉偽崣梶痏硊萎隗骩嵔廆徫愇猥葦蒍骪骫暐椲煒瑋痿腲艉韪僞碨蜲蜼鲔寪緯蔿諉踓韑頠薳儰濻鍡鮪壝韙颹瀢韡亹斖卫未位味苿畏胃叞軎尉硙菋谓喂媦渭猬煟墛蔚慰熭犚磑緭蝟衛懀濊璏罻衞謂錗餧鮇螱褽餵魏藯轊鏏霨鳚蘶饖讆躗讏躛昷塭温榅殟溫瑥辒榲瘟豱輼轀鳁鎾饂鰛鰮文彣纹芠炆砇闻紋蚉蚊珳阌鈫雯瘒聞馼魰鳼鴍螡閺閿蟁闅鼤闦闧刎吻呚忟抆呡肳紊桽脗稳穏穩问妏汶莬問渂脕揾搵絻顐璺翁嗡鹟螉鎓鶲勜奣塕嵡滃蓊暡瞈聬瓮蕹甕罋齆挝倭涡莴唩涹渦猧萵喔窝窩蜗撾蝸踒我婐婑捰仴沃肟卧臥偓捾媉幄握渥焥硪楃腛斡瞃濣瓁臒龌齷乌圬弙汙汚污邬呜杇巫屋洿诬钨烏趶剭窏釫鄔嗚誈歍誣箼螐鴮鎢鰞无毋吳吴吾呉芜郚唔娪梧洖浯茣莁珸祦鹀無禑蜈蕪璑鵐鯃鼯鷡乄五午仵伍坞妩庑忤怃迕旿武玝侮俉倵捂啎娬牾珷塢摀熓碔鹉瑦舞嫵廡憮潕錻儛橆甒鵡躌兀勿务戊阢伆屼扤岉杌芴忢物矹敄误務悞悟悮粅逜晤焐焑婺嵍痦隖靰骛奦嵨溩雾寤熃誤鹜鋈窹霚鼿霧齀蘁騖鶩夕兮忚汐西覀吸希扸卥昔析矽穸肸肹俙徆怸诶郗饻唏奚娭屖屗息悕晞氥浠牺狶莃唽悉惜桸欷淅渓烯焁焈琋硒菥赥釸傒惁晰晳焟焬犀睎稀粞翕翖舾鄎厀嵠徯溪煕皙蒠锡僖榽熄熈熙緆蜥誒豨餏嘻噏嬆嬉瘜膝餙凞樨橀歙歚熹熺熻窸羲螅螇錫燨犠瞦礂蟋谿豀豯貕繥雟鯑鵗觹譆醯鏭隵巇曦爔犧酅觽鼷蠵鸂觿鑴习郋席習袭觋媳椺蒵蓆嶍漝覡趘槢蝷薂隰檄謵鎴霫鳛飁騱騽襲鰼驨杫枲洗玺徙铣喜徚葈葸鈢屣漇蓰銑憘憙暿橲歖禧諰壐縰謑蟢蹝璽鱚矖纚躧匸卌戏屃系饩呬忥怬细郄係咥恄盻郤欯绤細釳阋塈椞舄趇隙慀滊禊綌赩隟熂犔稧戯潝潟澙蕮覤戱黖戲磶虩餼鬩嚱闟霼衋呷疨虾谺傄閕敮煆颬瞎蝦鰕匣侠狎俠峡柙炠狭陜峽烚狹珨祫硖笚翈舺陿溊硤遐搳暇瑕筪碬舝辖磍縀蕸縖赮魻轄鍜霞鎋黠騢鶷閜丅下吓圷疜夏梺厦廈睱諕嚇懗罅夓鏬仙仚屳先奾纤佡忺氙杴祆秈苮枮籼珗莶掀铦跹酰锨僊僲嘕銛鲜暹韯嬐憸薟鍁鍂繊褼韱鮮馦蹮孅廯攕譣纎鶱襳躚纖鱻伭咞闲妶弦贤咸唌挦涎胘娴娹婱絃舷蚿衔啣湺痫蛝閑鹇嫌衘甉銜嫺嫻憪撏澖誸賢諴輱醎癇癎藖鹹礥贒鑦鷳鷴鷼冼狝显险崄毨烍猃蚬険赻筅尟尠搟禒蜆跣箲藔險嶮獫獮藓鍌燹顕幰攇櫶蘚玁韅顯灦县岘苋现线臽限姭宪県陥哯垷娊娨峴晛涀莧陷現硍馅睍絤缐羡献粯羨腺僩僴綫誢撊線鋧憲橌縣錎餡豏麲瀗臔獻糮鏾霰鼸乡芗相香郷厢啌鄉鄊廂湘缃葙鄕楿薌箱緗膷襄忀骧麘欀瓖镶鱜鑲驤瓨佭详庠栙祥絴翔詳跭享亯响蚃饷晑飨想銄餉鲞嚮蠁鮝鯗響饗饟鱶向姠巷项珦象缿萫項像勨嶑曏橡襐蟓鐌鱌灱灲呺枭侾削哓枵骁宯宵庨恷消绡虓逍鸮啋婋梟焇猇萧痚痟硝硣窙翛萷销揱綃嘐歊潇箫踃嘵憢撨獢銷霄彇膮蕭魈鴞穘簘藃蟂蟏謞鴵嚣瀟簫蟰髇嚻囂櫹髐鷍蠨驍毊虈洨郩崤淆訤誵小晓暁筱筿皛曉篠謏皢孝肖効咲恔俲哮效校涍笑啸傚敩滧詨嘋嘨誟嘯歗熽斅斆些楔歇蝎蠍劦协旪邪協胁垥奊峫恊拹挟挾脅脇脋衺偕斜谐猲絜翓嗋愶携瑎綊熁膎勰撷擕緳缬蝢鞋諧燲擷鞵襭鐷攜纈讗龤写冩寫藛伳灺泄泻祄绁缷卸洩炧炨卨娎屑屓偰徢械焎禼紲亵媟屟揳渫絏絬谢僁塮榍榭褉噧屧暬緤韰嶰廨懈澥獬糏薢薤邂燮褻謝夑瀉鞢瀣爕蟹蠏齘齥齂躠屭躞忄心邤妡忻芯辛昕杺欣盺俽莘惞訢鈊锌新歆廞鋅噷噺嬜薪馨鑫馫枔鬵鐔伈潃阠伩囟孞炘信軐脪衅訫焮馸舋顖釁兴狌星垶骍惺猩煋瑆腥蛵觪箵篂興謃鮏曐觲騂皨鯹刑行邢形陉侀郉哘型洐钘陘娙硎裄铏鈃鉶銒鋞睲醒擤杏姓幸性荇倖莕婞悻涬塂緈嬹臖凶兄兇匈芎讻忷汹哅恟洶胷胸訩詾雄熊诇詗夐敻休俢修咻庥烋烌羞脩脙鸺臹貅馐樇銝髤髹鎀鮴鵂饈鏅飍苬朽綇滫糔秀岫珛绣袖琇锈溴綉璓裦褎褏銹螑繍繡鏥鏽齅戌旴疞盱欨砉胥须訏顼虗虚谞媭幁揟欻虛須楈窢頊嘘稰需魆噓墟嬃歔縃蕦蝑歘諝譃魖驉鑐鬚俆徐蒣许呴姁诩冔栩珝偦許湑暊詡鄦糈醑盨旭伵序汿侐卹沀叙恤昫洫垿欰殈烅珬畜勖勗敍敘烼绪续酗喣壻婿朂溆絮訹嗅慉煦続蓄賉槒漵潊盢瞁緒聟銊獝稸緖藇瞲藚續鱮蓿吅轩昍咺宣晅軒梋谖喧塇媗愃愋揎萱萲暄煊瑄蓒睻儇禤箮翧蝖嬛蕿諠諼鍹駽矎翾藼蘐蠉譞鰚讂玄玹痃悬旋琁蜁嫙漩暶璇檈璿懸选烜暅選癣癬怰泫昡炫绚眩袨铉琄眴衒渲絢楥楦鉉碹蔙镟鞙颴縼繏鏇贙疶蒆靴薛辥鞾穴斈乴坹学岤峃茓泶袕鸴踅學嶨澩燢觷雤鷽雪樰膤艝轌鳕鱈血吷怴泧狘疦桖烕谑趐謔瀥坃勋埙焄勛塤熏窨蔒勲勳薫駨嚑壎獯薰曛燻臐矄蘍壦爋纁醺廵寻巡旬驯杊询峋恂洵浔紃荀栒桪毥珣偱尋循揗詢馴鄩鲟噚潯攳樳燂燅燖璕襑蟳鱏鱘灥卂训讯伨汛迅侚徇狥迿逊殉訊訓訙奞巽殾遜愻賐噀蕈顨鑂丫压呀庘押鸦桠鸭孲铔椏鴉錏鴨壓鵶鐚牙伢岈芽厓枒琊笌蚜堐崕崖涯猚瑘睚衙漄齖疋厊庌哑唖啞痖雅瘂蕥劜圠亚穵襾讶亜犽迓亞玡垭娅挜砑俹氩埡婭掗訝揠氬猰聐圔稏窫齾咽恹剦烟珚胭偣崦淹焉菸阉湮腌傿煙鄢嫣漹蔫嶖樮醃閹嬮篶懕臙黫讠円延闫严妍芫言訁岩昖沿炎郔姸娫狿研莚娮盐琂硏訮閆阎嵒嵓筵綖蜒塩揅楌詽碞蔅颜虤閻厳檐顏顔嚴壛巌簷櫩麙壧孍巖巗巚欕礹鹽麣夵抁沇乵兖奄俨兗匽弇衍偃厣掩眼萒郾酓嵃愝扊揜棪渰渷琰遃隒椼硽罨裺演褗戭蝘魇噞躽縯檿黡厴甗鰋鶠黤齞龑儼黬黭顩鼴巘曮魘鼹齴黶厌妟觃牪姲彥彦砚唁宴晏艳覎验偐掞焔谚隁喭堰敥焰焱猒硯葕雁椻滟鳫厭墕暥熖酽嬊谳餍鴈燄燕諺赝鬳曕鴳酀騐験嚥嬿艶贋軅爓醶騴鷃灔贗贘觾讌醼饜驗鷰艷灎釅驠灧讞豓豔灩央咉姎抰泱殃胦眏秧鸯鉠雵鞅鍈鴦扬羊阦阳旸杨炀佯劷氜疡钖飏垟徉昜洋羏烊珜眻陽崵崸揚蛘敭暘楊煬禓瘍諹輰鍚鴹颺鐊鰑霷鸉卬仰佒坱奍岟养炴氧痒紻傟楧軮慃氱羪養駚懩攁瀁癢礢怏柍恙样羕詇様漾樣幺夭吆妖枖祅訞喓葽楆腰鴁邀爻尧尭肴垚姚峣轺倄烑珧窑傜堯揺殽谣軺嗂媱徭愮搖摇猺遙遥摿暚榣瑤瑶銚飖餆嶢嶤徺磘窯窰餚繇謠謡鎐鳐颻蘨顤鰩仸宎岆抭杳殀狕苭咬柼眑窅窈舀偠婹崾溔蓔榚鴢闄騕齩鷕穾药要袎窔筄葯詏熎覞靿獟鹞薬鼼曜燿艞藥矅曣耀纅鷂讑鑰倻椰暍噎潱蠮爷耶捓揶铘爺釾鋣鎁擨也吔亪冶埜野嘢漜壄业叶曳页邺夜抴亱枼洂頁捙晔枽烨偞掖液谒堨殗腋葉鄓墷楪業馌僷曄曅歋燁擖擛皣瞱鄴靥嶪嶫澲謁餣嚈擫曗瞸鍱擪爗礏鎑饁鵺靨驜鸈膶岃一弌辷衤伊衣医吚壱依祎咿洢猗畩郼铱壹揖欹蛜禕嫛漪稦銥嬄噫夁瑿鹥繄檹毉醫黟譩鷖黳乁仪匜圯夷冝宐杝沂诒侇宜怡沶狋衪迤饴咦姨峓弬恞柂瓵荑贻迻宧巸扅栘桋眙胰袘酏痍移萓媐椬羠蛦詒貽遗暆椸誃跠頉颐飴疑儀熪遺嶬彛彜螔頤頥寲嶷簃顊鮧彝彞謻鏔籎觺讉鸃乙已以迆钇佁攺矣苡苢庡舣蚁釔倚扆笖逘偯崺旑椅鈘鉯鳦旖輢敼螘檥礒艤蟻顗轙齮乂义亿弋刈忆艺仡匇肊议阣亦伇屹异忔芅伿佚劮呓坄役抑曵杙耴苅译邑佾呭呹妷峄怈怿易枍泆炈秇绎诣驿俋奕帟帠弈枻浂玴疫羿衵轶唈垼悒挹栧栺欭浥浳益袣谊貤陭勚埶埸悘悥殹異羛翊翌萟訲訳豙豛逸釴隿幆敡晹棭殔湙焲蛡詍跇軼鈠骮亄兿意溢獈痬竩缢義肄裔裛詣勩嫕廙榏潩瘗膉蓺蜴靾駅億撎槸毅熠熤熼瘞誼镒鹝鹢黓劓圛墿嬑嬟嶧憶懌曀殪澺燚瘱瞖穓縊艗薏螠褹寱斁曎檍歝燡燱翳翼臆貖鮨癔藙藝贀鎰镱繶繹豷霬鯣鶂鶃鶍瀷蘙譯議醳醷饐囈鐿鷁鷊懿襼驛鷧虉鷾讛齸乚囙因阥阴侌垔姻洇茵荫音骃栶殷氤陰凐秵裀铟陻隂喑堙婣愔筃絪歅溵禋蒑蔭慇瘖銦磤緸鞇諲霒駰噾濦闉霠韾冘乑吟犾苂斦垠泿圁峾烎狺珢粌荶訔唫婬寅崟崯淫訡银鈝龂滛碒鄞夤蔩訚誾銀龈噖殥璌嚚檭蟫霪齗齦鷣廴尹引吲饮蚓隐淾釿鈏飲隠靷飮朄趛檃瘾隱嶾濥螾蘟櫽癮讔印茚洕胤垽湚猌廕酳慭癊憖憗鮣懚檼应応英偀桜珱莺啨婴媖愥渶绬朠煐瑛嫈碤锳嘤撄滎甇緓缨罂蝧賏樱璎噟罃褮霙鴬鹦嬰應膺韺甖鎣鹰鶧嚶孆孾攖瀴罌蘡櫻瓔礯譻鶯鑍纓蠳鷪軈鷹鸎鸚盁迎茔盈荥荧莹萤营萦蛍営溁溋萾僌塋楹滢蓥潆熒蝇瑩蝿嬴營縈螢濙濚濴藀覮謍赢巆攍攚瀛瀠瀯蠅櫿灐籝灜贏籯矨郢浧梬颍颕颖摬影潁瘿穎頴巊廮鐛癭映暎硬媵膡鞕瀅譍哟唷喲佣拥痈邕庸傭嗈鄘雍墉嫞慵滽槦牅銿噰壅擁澭郺镛臃癕雝鏞鳙廱灉饔鱅鷛癰喁颙顒鰫永甬咏怺泳俑勇勈栐埇悀柡涌恿傛惥愑湧硧詠塎嵱彮愹蛹慂踊禜鲬踴鯒用苚砽醟优忧攸呦怮泑幽悠麀滺憂優鄾嚘懮瀀櫌纋耰尢尤由沋犹邮怞油肬怣斿柚疣峳浟秞莜莤莸逌郵铀偤蚰訧逰游猶遊鱿楢猷鈾鲉輏駀蕕蝣魷輶鮋櫾邎友有丣卣苃酉羑庮羐莠梄聈脜铕湵蒏禉蜏銪槱牖牗黝又右幼佑侑孧狖糿哊囿姷宥峟牰祐诱迶唀梎蚴亴貁釉酭誘鼬扜纡迂迃穻陓紆虶唹淤盓渝瘀箊于亐予邘伃余妤扵杅欤玗玙於盂臾衧鱼俞兪禺竽舁茰荢娛娯娱狳谀酑馀渔萸釪隃隅雩魚堣堬崳嵎嵛愉揄楰湡畬畭硢腴逾骬愚楡榆歈牏瑜艅虞觎漁睮窬舆褕歶羭蕍蝓諛雓餘魣嬩懙澞覦踰歟璵螸輿鍝礖謣髃鮽旟籅騟鯲鰅鷠鸆与伛宇屿羽雨俁俣挧禹语圄峿祤偊匬圉庾敔鄅萭萮铻傴寙斞楀瑀瘐與語窳鋙龉噳嶼貐斔麌蘌齬玉驭吁圫聿芋芌妪忬饫育郁彧昱狱秗茟俼峪栯浴砡钰预喐域堉悆惐欲淢淯袬谕逳阈喅喩喻媀寓庽御棛棜棫焴琙矞裕遇飫馭鹆愈滪煜稢罭蒮蓣誉鈺預嫗嶎戫毓獄瘉緎蜟蜮輍銉隩噊慾稶蓹薁豫遹鋊鳿澦燏燠蕷諭錥閾鴥鴧鴪儥礇禦魊鹬癒礜穥篽繘醧鵒櫲饇蘛譽轝鐭霱欎驈鬻籞鱊鷸鸒欝軉鬰鬱灪籲爩囦鸢剈冤弲悁眢鸳寃渁渆渊渕惌淵葾棩蒬蜎鹓箢鳶蜵駌鋺鴛嬽鵷灁鼘鼝元贠邧员园沅杬垣爰貟原員圆笎蚖袁厡酛圎援湲猨缘鈨鼋園圓塬媴嫄源溒猿獂蒝榞榬辕緣縁蝝蝯魭圜橼羱薗螈謜轅黿鎱櫞邍騵鶢鶰厵远盶逺遠夗肙妴苑怨院垸衏傆媛掾瑗禐愿裫褑褤噮願曰曱约約箹矱彟彠月戉刖汋岄抈礿岳枂玥恱钥悅悦蚎蚏軏钺阅捳跀跃粤越鈅粵鉞閱閲嬳樾篗嶽龠籆瀹蘥黦爚禴躍籥鸑籰龥鸙蒀煴蒕熅奫蝹赟頵馧贇云勻匀伝呍囩妘抣沄纭芸昀畇眃秐郧涢紜耘耺鄖雲愪氲溳筼蒷氳熉澐蕓鋆橒篔縜繧允阭夽抎狁玧陨荺殒喗鈗隕殞褞馻磒霣齫齳孕运枟郓恽晕鄆酝傊惲愠缊運慍暈腪韫韵熨緼蕰蕴縕薀賱醖醞餫藴韗韞蘊韻帀匝沞咂拶沯桚紥紮鉔魳臜臢杂砸韴雑磼襍雜囐雥災灾甾哉栽烖菑渽溨睵賳宰载崽載再在扗洅傤酨儎縡兂糌簪簮鐕咱偺喒昝寁撍儧攒儹攢趱趲暂暫賛赞錾鄼濽蹔酂瓉贊鏨瓒酇囋灒讃瓚禶襸讚饡牂羘赃賍臧賘贓髒贜驵駔奘弉脏塟葬銺臓臟傮遭糟蹧醩凿鑿早枣栆蚤棗璅澡璪薻藻灶皁皂唕唣造梍喿慥煰艁噪簉燥竃譟趮躁竈啫伬则択沢择泎泽责迮則唶啧帻笮舴責溭矠嘖嫧幘箦蔶樍歵諎赜擇澤皟瞔簀耫礋襗謮賾蠌齚齰鸅仄夨庂汄昃昗捑崱稄贼賊鲗蠈鰂鱡怎谮譖譛囎曽曾増鄫增憎缯橧熷璔矰磳罾繒譄鱛锃鋥甑赠贈吒迊咋抯挓柤哳偧喳揸渣溠楂劄皶箚樝觰皻皼譇齄齇扎札甴轧軋闸蚻铡煠牐閘霅鍘譗厏苲眨砟搩鲊鲝踷鮓鮺乍灹诈咤奓柵栅炸宱痄蚱詐搾摣榨膪醡夈粂捚斋斎斏摘榸齋宅翟窄鉙债砦債寨瘵沾毡旃栴粘蛅飦惉詀趈詹閚谵噡嶦澶薝邅霑氈氊瞻鹯旜譫饘鳣驙魙鱣鸇讝拃斩飐展盏崭斬琖搌盞嶃嶄榐辗颭嫸醆橏蹍輾皽黵占佔战栈桟站偡绽菚棧湛戦綻嶘輚骣戰虥虦覱轏蘸驏张弡張章傽鄣嫜彰慞漳獐粻蔁遧暲樟璋餦蟑鏱騿鱆麞仉涨涱掌漲幥礃鞝鐣丈仗扙帐杖胀账粀帳脹痮障墇嶂幛賬瘬瘴瞕佋钊妱巶招昭炤盄釗啁鉊駋窼鍣爫找沼瑵召兆诏枛垗狣赵笊肁旐棹罀詔照罩箌肇肈趙曌燳鮡櫂瞾羄蜇嫬遮厇折歽矺砓籷虴哲埑粍袩啠悊晢晣辄喆棏蛰詟谪摺輒樀磔輙銸辙蟄嚞謫謺鮿轍讁襵讋者锗赭褶鍺这柘浙這淛嗻蔗樜鹧蟅鷓贞针侦浈珍珎貞帪栕桢眞真砧祯針偵敒桭酙寊湞葴遉搸斟楨獉甄禎蒖蓁鉁靕榛槇殝瑧碪禛潧箴樼澵臻薽錱轃鍖鍼籈鱵屒诊抮枕姫弫昣胗轸畛疹眕袗紾聄萙裖覙診軫嫃缜稹駗縝縥辴鬒黰圳阵纼侲挋陣鸩振朕栚紖眹赈塦揕絼蜄敶誫賑鋴镇震鴆鎭鎮黮凧争佂姃征怔爭峥挣炡狰烝眐钲埩崝崢掙猙睁聇铮媜揁筝徰睜蒸鉦徴箏徵踭篜錚鬇癥氶抍糽拯掟塣晸愸撜整正㊣证诤郑帧政症幀証鄭諍鴊證之支卮汁芝吱巵汥枝知织肢徔栀祗秓秖胑胝衹衼倁疷祬秪脂隻梔戠椥臸搘禔綕榰蜘馶鳷謢鴲織蘵鼅禵执侄坧直姪値值聀聁釞埴執职植殖禃絷跖瓡墌摭馽嬂慹漐踯樴膱縶職蟙蹠蹢軄躑夂止只凪劧旨阯址坁帋扺汦沚纸芷抧祉茋咫恉指枳洔砋轵淽疻紙訨趾軹黹酯藢襧阤至芖志忮扻豸制厔垁帙帜治炙质郅俧峙庢庤挃柣栉洷祑陟娡徏挚晊桎狾秩致袟贽轾乿偫徝掷梽猘畤痔秲秷窒紩翐袠觗貭铚鸷傂崻彘智滞痣蛭骘寘廌搱滍稙稚筫置跱輊锧雉墆槜滯潌疐瘈製覟誌銍幟憄摯潪熫稺膣觯質踬鋕旘瀄緻隲駤鴙儨劕懥擲擿櫛穉螲懫贄櫍瓆觶騭鯯礩豑騺驇躓鷙鑕豒中伀汷刣妐彸迚忠泈炂终柊盅衳钟舯衷終鈡幒蔠锺螤鴤螽鍾鼨蹱鐘籦肿种冢喠尰塚歱煄腫瘇種踵仲众妕狆祌祍茽衶重蚛偅眾堹媑筗衆諥州舟诌侜周洀洲炿诪烐珘辀郮婤徟淍矪週鸼喌粥赒輈銂賙輖霌駲嚋盩謅鵃騆譸妯轴軸碡肘帚疛菷晭睭箒鯞纣伷呪咒宙绉冑咮昼紂胄荮晝皱酎粙葤詋甃僽皺駎噣縐骤籀籕籒驟朱劯侏诛邾洙茱株㈱珠诸猪硃袾铢絑蛛誅跦槠潴蝫銖橥諸豬駯鮢鴸瀦藸櫧櫫鼄鯺蠩竹泏竺炢笁茿烛窋逐笜舳瘃蓫燭蠋躅鱁劚孎灟斸曯欘爥蠾钃丶主宔拄砫罜陼渚煑煮詝嘱濐麈瞩屬囑矚伫佇住助纻芧苎坾杼注苧贮迬驻壴柱柷殶炷祝疰眝祩竚莇秼紵紸羜著蛀嵀筑註貯跓軴铸筯鉒飳馵墸箸翥樦鋳駐築篫霔麆鑄抓檛膼簻髽爪拽跩专叀専砖專鄟嫥瑼甎膞颛磚諯蟤顓鱄转孨転竱轉灷啭堟蒃瑑僎赚撰篆馔縳襈賺譔饌囀籑妆庄妝庒荘娤桩莊湷粧装裝樁糚丬壮壯状狀壵梉焋幢撞戅隹追骓椎锥錐騅鵻沝坠笍娷缀惴甀缒畷硾膇墜綴赘縋諈醊錣餟礈贅轛鑆宒迍肫窀谆諄衠准埻凖準綧訰稕卓拙炪倬捉桌棁涿棳琸窧槕穛穱蠿圴彴犳灼叕妰茁斫浊丵浞烵诼酌啄啅娺梲着斮晫椓琢斱硺窡罬撯擆斲禚劅諁諑鋜濁篧擢斀斵濯櫡謶镯鐯鵫灂蠗鐲籗鷟籱仔孖孜茊兹咨姕姿茲栥玆紎赀资崰淄秶缁谘赼嗞孳嵫椔湽滋粢葘辎鄑孶禌觜貲資趑锱稵緇鈭镃龇輜鼒澬諮趦輺錙髭鲻鍿鎡頾頿鯔鶅齍鰦齜籽子吇姉姊杍矷秄胏呰秭耔虸笫梓釨啙紫滓訾訿榟橴字自芓茡倳剚恣牸渍眥眦胔胾漬唨宗倧综骔堫嵏嵕惾棕猣腙葼朡椶嵸稯綜緃熧緵翪艐蝬踨踪磫豵蹤騌鬃騣鬉鬷鯮鯼鑁总偬捴惣愡揔搃傯蓗摠総縂燪總鍯鏓纵昮疭倊猔碂粽糉瘲縦錝縱邹驺诹郰陬掫菆棷棸鄒箃緅諏鄹鲰鯫黀騶齺赱走鯐奏揍媰租菹葅蒩卆足卒哫崒崪族傶稡箤踤踿镞鏃诅阻组俎爼珇祖組詛靻鎺謯劗躜鑚躦鑽繤缵纂纉籫纘钻揝攥厜朘嗺樶蟕纗嶊嘴噿濢璻枠栬絊酔晬最祽罪辠酻蕞醉嶵檇鋷錊檌穝欈尊嶟遵樽繜罇鶎鐏鳟鱒鷷僔噂撙譐捘銌昨秨莋捽椊葃稓筰鈼左佐繓作坐阼岝岞怍侳柞祚胙唑座袏做葄蓙飵糳咗</pc>
+      </rules>
+    </collation>
+
+    <!-- some unsupported tags -->
+    <collation name="utf8_5624_2" id="355">
+      <settings strength="tertiary"/>
+      <rules>
+      </rules>
+    </collation>
+
+    <!-- reset before primary ignorable -->
+    <collation name="utf8_5624_3" id="356">
+      <rules>
+        <reset before="primary"><first_secondary_ignorable/></reset><p>lb-fsi</p>
+      </rules>
+    </collation>
+
+    <!-- \u without hex digits -->
+    <collation name="utf8_5624_4" id="357">
+      <rules>
+        <reset>\u</reset><i>x</i>
+      </rules>
+    </collation>
+
+    <!-- shift after using expansion -->
+    <collation name="utf8_5624_5" id="368" shift-after-method="expand">
+      <rules>
+        <!--
+           Put small basic Latin letters between 0 and 1.
+           Simple shift method would not work, because there is no
+           weight space between 0 and 1 in DUCET.
+           Also, to test it works with contractions, put some after 'z'.
+        -->
+        <reset>0</reset>
+        <pc>abcdefghijklmnopqrstuvwxyz</pc><p>aa</p><p>aaa</p>
+        <reset before="primary">1</reset>
+        <pc>ABCDEFGHIJKLMNOPQRSTUVWXYZ</pc><p>AA</p><p>AAA</p>
+      </rules>
+    </collation>
+
    <collation name="utf8_hugeid_ci" id="2047000000">
       <rules>
         <reset>a</reset>
@@ -41,6 +144,10 @@
         <s>b</s>
       </rules>
     </collation>
+    <collation name="utf8mb4_test_400_ci" id="328" version="4.0.0">
+      <rules>
+      </rules>
+    </collation>
   </charset>
 
   <charset name="utf16">
@@ -119,6 +226,74 @@
 
     </collation>
 
+    <collation name="ucs2_5624_1" id="360">
+      <rules>
+        <!-- long contractions and expansions -->
+        <reset>12345</reset><q>012345</q><q>12345</q>
+        <reset>1234</reset><q>001234</q><q>01234</q>
+        <reset>123</reset><q>000123</q><q>00123</q><q>0123</q>
+        <reset>12</reset><q>000012</q><q>00012</q><q>0012</q><q>012</q>
+        <reset>1</reset><q>000001</q><q>00001</q><q>0001</q><q>001</q><q>01</q>
+        <!-- some non-latin contractions and expansions -->
+        <reset>ГАИ</reset><i>ГИБДД</i>
+
+        <!-- reset before: Maltese -->
+        <reset before="primary">d</reset><p>ÄŠ</p><t>Ä‹</t>
+        <reset before="primary">g</reset><p>Ä </p><t>Ä¡</t>
+        <reset before="primary">h</reset><p>GĦ</p><t>Għ</t><t>gĦ</t><t>għ</t>
+        <reset before="primary">i</reset><p>Ħ</p><t>ħ</t>
+        <reset before="primary">z</reset><p>Ż</p><t>ż</t>
+        <!-- higher levels  -->
+        <reset before="secondary">b</reset><s>ā</s><t>Ā</t>
+        <reset before="tertiary">b</reset><t>á</t><t>Á</t>
+        <reset before="quaternary">b</reset><q>à</q><q>À</q>
+
+        <!-- abbreviated syntax: put some punctuation immediately before a -->
+        <reset before="primary">a</reset><pc>~!@#$%^*()+:;"'?</pc>
+        <reset>d</reset><sc>ēé</sc>
+        <reset>d</reset><tc>ĒÉ</tc>
+        <reset>d</reset><qc>ěê</qc>
+        <reset>d</reset><ic>ĚÊ</ic>
+
+        <!-- normal expansion syntax -->
+        <reset>c</reset><x><s>k</s><extend>h</extend></x>
+        <reset>cs</reset><x><t>ccs</t><extend>cs</extend></x>
+
+        <!-- previous context -->
+        <reset>a</reset><x><context>b</context><p>-</p></x>
+        <reset>c</reset><x><context>c</context><s>-</s></x>
+        <reset>d</reset><x><context>d</context><t>-</t></x>
+        <reset>e</reset><x><context>e</context><q>-</q></x>
+        <reset>f</reset><x><context>f</context><i>-</i></x>
+
+        <!-- logical reset positions -->
+        <reset><first_non_ignorable/></reset><p>lp-fni</p>
+        <reset><last_non_ignorable/></reset><p>lp-lni</p>
+        <reset><first_primary_ignorable/></reset><p>lp-fpi</p>
+        <reset><last_primary_ignorable/></reset><p>lp-lpi</p>
+        <reset><first_secondary_ignorable/></reset><p>lp-fsi</p>
+        <reset><last_secondary_ignorable/></reset><p>lp-lsi</p>
+        <reset><first_tertiary_ignorable/></reset><p>lp-fti</p>
+        <reset><last_tertiary_ignorable/></reset><p>lp-lti</p>
+        <reset><first_trailing/></reset><p>lp-ft</p>
+        <reset><last_trailing/></reset><p>lp-lt</p>
+        <reset><first_variable/></reset><p>lp-fv</p>
+        <reset><last_variable/></reset><p>lp-lv</p>
+
+        <!-- logical positions and reset before -->
+        <reset before="primary"><first_non_ignorable/></reset><p>lb-fni</p>
+        <reset before="primary"><last_non_ignorable/></reset><p>lb-lni</p>
+        <reset before="primary"><first_variable/></reset><p>lb-fv</p>
+        <reset before="primary"><last_variable/></reset><p>lb-lv</p>
+
+        <!-- long tailoring: pinyin order from CLDR's zh.xml  -->
+        <reset><last_non_ignorable/></reset>
+        <pc>ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩ吖阿啊锕錒嗄厑哎哀唉埃挨欸溾锿鎄啀捱皑凒嵦溰嘊敱敳皚癌毐昹娾嗳矮蔼躷噯濭﨟藹譪霭靄艾伌爱砹硋隘嗌塧嫒愛碍叆暧瑷僾壒嬡懓薆懝曖璦賹餲鴱皧瞹馤礙譺鑀鱫靉安侒峖桉氨庵菴谙媕萻葊痷腤鹌蓭誝鞌鞍盦諳闇馣鮟盫鵪韽鶕玵啽雸垵俺唵埯铵隌揞晻罯銨犴岸按洝荌案胺豻堓婩暗貋儑錌黯肮骯岇昂昻枊盎醠凹坳垇柪軪爊敖厫隞嗷嗸嶅廒滶獒獓遨摮熬璈蔜磝翱聱螯翶謷翺鳌鏖鰲鷔鼇抝芺拗袄媪镺媼襖岙扷岰傲奡奥嫯慠骜奧澚墺嶴澳懊擙謸鏊驁八仈巴叭扒朳玐吧夿岜芭疤哵捌笆粑紦羓蚆釟豝鲃魞叐犮抜坺妭拔茇炦癹胈釛菝詙跋軷颰魃墢鼥把钯鈀靶坝弝爸垻罢跁鲅罷鮁覇矲霸壩灞欛挀掰白百佰柏栢捭竡粨絔摆擺襬呗庍拝败拜唄敗猈稗粺鞁薭贁韛兡瓸扳攽朌班般颁斑搬斒頒瘢螁螌褩癍辬阪坂岅昄板版瓪钣粄舨鈑蝂魬闆办半伴扮姅怑拌绊秚湴絆鉡靽辦瓣邦峀垹帮捠梆浜邫幇幚縍幫鞤绑綁榜牓膀玤蚌傍棒棓硥谤塝徬稖蒡蜯磅镑艕謗鎊勹包佨孢苞胞剝笣煲龅蕔褒闁襃齙窇嫑雹宝怉饱保鸨珤堡堢媬葆寚飹飽褓駂鳵緥鴇賲藵寳寶靌勽报抱豹趵铇菢袌報鉋鲍靤骲暴髱虣鮑儤曓爆忁鑤萡陂卑杯盃桮悲揹碑鹎藣鵯喺北鉳贝狈貝邶备昁牬苝背钡俻倍悖狽被偝偹梖珼鄁備僃惫焙琲軰辈愂碚禙蓓蛽犕褙誖骳輩鋇憊糒鞴鐾奔泍贲倴渀逩犇賁锛錛本苯奙畚楍坌捹桳笨撪獖輽伻祊奟崩绷絣閍嵭痭嘣綳繃甭埄埲菶琣琫鞛泵迸逬跰塴甏镚蹦鏰皀屄偪毴逼豍螕鲾鎞鵖鰏柲荸鼻嬶匕比夶朼佊吡妣沘疕彼柀秕俾笔粃粊舭啚筆鄙聛貏匂币必毕闭佖坒庇诐邲妼怭枈畀畁苾哔毖珌疪胇荜陛毙狴畢袐铋婢庳敝梐萆萞閇閉堛弻弼愊愎湢皕禆筚詖貱赑嗶彃楅滗滭煏痹痺腷蓖蓽蜌裨跸辟鉍閟飶幣弊熚獙碧稫箅箆綼蔽鄪馝幤潷獘罼襅駜髲壁嬖廦篦篳縪薜觱避鮅斃濞臂蹕鞞髀奰璧鄨饆繴襞襣鏎鞸韠躃躄魓贔鐴驆鷝鷩鼊边砭笾猵编萹煸牑甂箯編蝙獱邉鍽鳊邊鞭鯾鯿籩炞贬扁窆匾貶惼碥稨褊糄鴘藊卞弁忭抃汳汴苄釆峅拚便变変昪覍徧揙缏遍閞辡緶艑頨辧辨辩辪辫辮辯變灬杓彪标飑骉髟淲猋脿墂幖滮蔈颮骠標熛膘麃瘭镖飙飚儦颷瀌藨謤爂臕贆鏢穮镳飆飇飈飊驃鑣驫表婊裱諘褾錶檦俵摽鳔鰾憋鳖鱉鼈虌龞別别咇莂蛂徶襒蟞蹩瘪癟彆汃邠砏宾彬傧斌椕滨缤槟瑸豩賓賔镔儐濒濱濵虨豳璸瀕霦繽蠙鑌顮氞摈殡膑髩擯鬂殯臏髌鬓髕鬢冫仌氷冰兵栟掤梹鋲檳丙邴陃怲抦秉苪昞昺柄炳饼眪窉蛃棅禀鈵鉼鞆餅餠燷并並併幷垪庰倂栤病竝偋傡寎摒誁鮩靐癶拨波癷玻剥盋砵袚袯钵饽啵紴缽脖菠袰碆鉢僠嶓撥播餑磻蹳驋鱍仢伯孛犻驳帛泊狛瓝苩侼勃柭胉郣亳挬浡瓟秡钹铂桲淿舶博渤湐葧鹁愽搏猼鈸鉑馎鲌僰煿牔箔膊艊馛駁踣鋍镈壆薄馞駮鮊襏豰嚗懪礡簙鎛餺鵓犦髆髉欂襮礴鑮蚾跛箥簸孹擘檗糪譒蘗蔔峬庯逋钸晡鈽誧餔轐醭卜卟补哺捕補鳪獛鵏鸔不布佈吥步咘怖歨歩钚勏埗悑捗荹部埠瓿鈈廍蔀踄郶篰餢簿嚓擦攃礤礸遪囃偲猜才材财財戝裁纔采倸埰婇寀彩採睬跴綵踩菜棌蔡縩乲参參叄飡骖叅喰湌傪嬠餐驂残蚕惭殘慚蝅慙蠶蠺惨朁慘噆憯穇黪黲灿粲儏澯薒燦璨謲爘仓仺伧沧苍鸧倉舱傖凔嵢滄獊蒼濸艙螥罉鶬匨蔵藏欌鑶賶撡操糙曺曹嘈嶆漕蓸槽褿艚螬鏪艹艸草愺懆騲肏鄵襙鼜冊册侧厕恻拺测荝敇畟側厠笧粣萗廁惻測策萴筞筴蓛墄箣憡簎嵾膥岑梣涔笒噌层層嶒竲驓蹭硛硳岾猠乽叉扠扱芆杈肞臿挿訍偛嗏插揷馇銟锸艖疀鍤鎈餷秅垞查査茬茶嵖搽猹靫槎詧察碴褨檫衩蹅镲鑔奼汊岔侘诧剎姹差紁詫拆钗釵犲侪柴祡豺喍儕茝虿勑袃瘥蠆囆辿觇梴掺搀覘裧摻鋓幨襜攙婵谗孱棎湹禅馋嬋煘缠僝獑蝉蝊誗鋋儃廛潹潺緾磛禪毚鄽镡瀍蟬儳劖繵蟾酁嚵壥巉瀺欃纏纒躔镵艬讒鑱饞产刬旵丳浐剗谄產産铲阐蒇剷嵼摌滻幝蕆諂閳燀簅冁繟醦譂鏟闡囅灛讇忏硟摲懴颤懺羼韂顫伥昌倀娼淐猖菖阊晿椙琩裮锠錩閶鲳鯧鼚长仧兏肠苌長镸尝偿常徜瓺萇甞腸嘗塲嫦瑺膓鋿償嚐蟐鲿鏛鱨厂场昶惝場敞僘厰廠氅鋹怅玚畅倡鬯唱悵瑒暢畼誯韔抄弨怊欩钞訬焯超鈔繛牊晁巢巣朝鄛鼌漅嘲樔潮窲罺轈鼂謿吵炒眧煼麨巐仦仯耖觘车伡車俥砗唓莗硨蛼扯偖撦奲屮彻坼迠烢烲聅掣硩頙徹撤澈勶瞮爡抻郴棽琛嗔綝瞋諃賝謓尘臣忱沉辰陈迧茞宸烥莀莐陳敐晨訦谌軙愖揨鈂煁蔯塵樄瘎霃螴諶薼麎曟鷐趻硶碜墋夦磣踸贂闯衬疢称龀趁趂榇稱齓齔儭嚫谶櫬襯讖阷泟虰柽爯棦浾偁蛏铛牚琤赪憆摚靗撐撑緽橕瞠赬頳檉竀穪蟶鏳鏿饓鐺丞成朾呈承枨诚郕乗城娍宬峸洆荿乘埕挰珹脀掁珵窚脭铖堘惩棖椉程筬絾裎塍塖溗碀誠畻酲鋮憕澂澄橙檙鯎瀓懲騬侱徎悜逞骋庱睈騁秤吃妛杘侙哧彨胵蚩鸱瓻眵笞粚喫訵嗤媸摛痴絺噄瞝誺螭鴟鵄癡魑齝攡麶彲黐弛池驰坘迟岻泜茌持竾荎俿歭匙淔耛蚳赿筂貾遅趍遟馳墀漦踟遲篪謘尺叺呎肔侈卶齿垑拸胣恥耻蚇袳豉欼歯袲裭鉹褫齒彳叱斥灻赤饬抶迣勅恜炽翄翅敕烾痓啻湁飭傺痸腟跮鉓雴憏翤遫銐慗瘛翨熾懘糦趩饎鶒鷘充冲忡沖茺浺珫翀舂嘃摏徸憃憧衝罿艟蹖虫崇崈隀漴褈緟蝩蟲爞宠埫寵铳揰銃抽紬搊瘳篘犨犫仇俦帱栦惆绸菗椆畴絒愁皗稠筹裯詶酧酬綢踌儔雔嬦幬懤薵燽雠疇籌躊醻讎讐丑丒吜杽侴偢瞅醜矁魗臭臰遚殠出岀初摴樗貙齣刍除芻厨滁蒢豠锄榋耡蒭蜍趎鉏雏犓蕏廚篨鋤橱懨幮櫉蟵躇雛櫥蹰鶵躕杵础椘储楮禇楚褚濋儲檚璴礎齭齼亍処处竌怵拀绌豖欪竐俶敊埱珿絀處傗琡鄐搐滀触踀閦儊嘼諔憷橻斶歜臅黜觸矗搋膗揣啜嘬踹巛川氚穿剶瑏传舡舩船圌猭遄傳椽歂暷篅輲舛荈喘僢汌串玔钏釧賗鶨刅囱疮窓窗牎摐牕瘡窻床牀噇傸漺磢闖创怆刱剏剙創愴吹炊龡垂倕埀桘陲捶菙搥棰腄槌锤箠錘鎚顀旾杶春萅堾媋暙椿槆瑃箺蝽橁輴櫄鰆鶞纯陙唇浱純莼淳脣湻犉滣蒓鹑漘蓴醇醕錞鯙鶉偆萶惷睶賰踳蠢踔戳辶辵娕娖惙涰绰逴腏辍酫綽趠輟龊擉磭歠嚽齪鑡齱呲玼疵趀偨縒骴词珁垐柌祠茈茨堲瓷詞辝慈甆辞鈶磁雌鹚糍辤飺餈嬨濨薋鴜礠蠀辭鶿鷀此佌泚皉跐朿次佽刺刾庛茦栨莿絘蛓赐螆賜嗭从匆囪苁忩枞茐怱從悤棇焧葱楤漗聡蓯蔥骢暰樅樬熜瑽璁緫聦聪瞛篵聰蟌繱鏦騘驄丛従婃孮徖悰淙琮慒漎潀潈潨誴賨賩樷藂叢灇欉爜憁謥凑湊楱腠辏輳粗觕麁麄麤徂殂促猝媨酢瘄蔟誎趗噈憱踧醋瘯簇縬蹙鼀蹴蹵顣汆撺镩蹿攛躥鑹攅櫕巑欑穳窜熶篡殩篹簒竄爨崔催凗缞墔嶉慛摧榱槯獕磪縗鏙乼漼璀趡皠伜忰疩倅紣翆脃脆啐啛悴淬萃毳焠瘁粹綷翠膵膬竁襊顇臎邨村皴墫澊竴存拵踆刌忖寸吋籿搓瑳遳磋撮蹉醝髊虘嵯嵳痤睉矬蒫蔖鹾鹺齹脞剉剒厝夎挫莝莡措逪棤锉蓌错銼錯咑哒耷畣搭嗒褡噠墶撘鎝达迏迖呾妲怛沓垯炟羍荅荙剳匒笪逹溚答詚達跶瘩靼薘鞑燵繨蟽鎉躂鐽韃龖龘打大亣眔橽呆呔獃懛歹傣代汏轪侢垈岱帒甙绐迨带待怠柋殆玳贷帯軑埭帶紿蚮袋軚逮貸軩瑇廗叇曃緿鮘鴏戴艜黛簤蹛瀻霴襶黱靆丹妉单担単眈砃耼耽郸聃躭酖單媅殚瘅匰箪褝鄲頕儋勯擔殫癉襌簞聸伔刐狚玬瓭胆衴疸紞掸亶馾撣澸黕膽旦但帎沊泹诞柦疍訑啖啗弹惮淡萏蛋啿氮腅蜑觛窞誕僤噉髧嘾彈憚憺澹禫餤駳鴠甔癚嚪贉霮饏当珰裆筜當儅噹澢璫襠簹艡蟷挡党谠擋譡黨攩灙欓讜氹凼圵宕砀垱荡档菪婸瓽逿雼潒碭瞊蕩趤壋檔璗盪礑簜蘯闣刀刂叨屶忉朷氘舠釖鱽魛捯导岛陦倒宲島捣祷禂搗隝嶋嶌槝導隯壔嶹擣蹈禱到悼焘盗菿椡盜道稲翢噵稻衜檤衟燾翿軇瓙纛恴得淂悳惪锝嘚徳德鍀的揼扥扽灯登豋噔嬁燈璒竳簦艠覴蹬等戥邓僜凳鄧隥墱嶝瞪磴镫櫈鐙仾低奃彽袛啲埞羝隄堤趆嘀滴镝磾鍉鞮鏑廸狄肑籴苖迪唙敌涤荻梑笛觌靮滌髢嫡蔋蔐頔魡敵篴嚁藡豴糴覿鸐氐厎诋邸阺呧坻底弤抵拞柢牴砥掋菧觝詆軧聜骶鯳地弚坔弟旳杕玓怟枤苐俤帝埊娣递逓偙啇梊焍眱祶第菂谛釱媂棣睇缔蒂僀禘腣遞鉪馰墑墬摕碲蔕蝃遰慸甋締嶳諦踶螮嗲敁掂傎厧嵮滇槙瘨颠蹎巅顚顛癫巓巔攧癲齻典奌点婰敟椣碘蒧蕇踮點电佃甸阽坫店垫扂玷钿唸婝惦淀奠琔殿蜔鈿電墊壂橂澱靛磹癜簟驔刁叼汈刟虭凋奝弴彫蛁琱貂碉鳭殦瞗雕鮉鲷簓鼦鯛鵰扚屌弔伄吊钓窎訋调掉釣铞鈟竨蓧銱雿調瘹窵鋽藋鑃爹跌褺苵迭垤峌恎挕绖胅瓞眣耊啑戜谍喋堞幉惵揲畳絰耋臷詄趃叠殜牃牒镻嵽碟蜨褋艓蝶疂諜蹀鲽曡曢鰈疉疊氎哋昳眰嚸丁仃叮帄玎甼疔盯钉耵酊釘靪奵顶頂鼎嵿鼑薡鐤订忊饤矴定訂飣啶萣椗腚碇锭碠聢聣錠磸顁丟丢铥颩銩东冬咚岽東苳昸氡倲鸫埬娻崬涷笗菄氭蝀鮗鼕鯟鶇鶫董墥嬞懂箽蕫諌动冻侗垌姛峒峝恫挏栋洞胨迵凍戙胴動崠硐棟湩腖働詷駧霘吺剅唗都兜兠蔸橷篼艔斗乧阧抖枓钭陡蚪鈄豆郖浢荳逗饾鬥梪毭脰酘痘閗窦鬦鋀餖斣闘竇鬪鬬鬭剢阇嘟督醏闍毒涜读渎椟牍犊裻読蝳獨錖凟匵嬻瀆櫝殰牘犢瓄皾騳黩讀豄贕韣髑鑟韇韥黷讟厾独笃堵帾琽赌睹覩賭篤芏妒杜肚妬度荰秺渡靯镀螙殬鍍蠧蠹耑偳媏端褍鍴短段断塅缎葮椴煅瑖腶碫锻緞毈簖鍛斷躖籪叾垖堆塠嵟痽磓頧鴭鐜队对兊兌兑対祋怼陮隊碓綐對憝濧薱镦懟瀩譈鐓譵吨惇敦蜳墩墪壿撴獤噸撉橔犜礅蹲蹾驐盹趸躉伅囤庉沌炖盾砘逇钝顿遁鈍腞頓碷遯憞潡燉踲多夛咄哆茤剟崜敠毲裰嚉仛夺铎剫掇敓敚喥敪痥鈬奪凙踱鮵鐸朵朶哚垛挅挆埵缍椯趓躱躲綞亸軃鬌嚲刴剁沲陊陏饳垜尮柮桗堕舵惰跢跥跺飿墮嶞憜墯鵽妸妿娿屙讹吪囮迗俄娥峨峩涐莪珴訛皒睋鈋锇鹅蛾磀誐鋨頟额魤額鵝鵞譌枙砈婀惡噁騀鵈厄歺屵戹岋阨呃扼苊阸呝砐轭咢咹垩姶峉匎恶砨蚅饿偔卾堊悪硆谔軛鄂阏堮崿愕湂萼豟軶遌遏廅搤搹琧腭詻僫蝁锷鹗蕚遻頞颚餓噩擜覨諤閼餩鍔鳄歞顎櫮鰐鶚讍鑩齶鱷奀恩蒽煾峎摁鞥仒乻旕儿而児侕兒陑峏洏耏荋栭胹唲袻鸸粫聏輀鲕隭髵鮞鴯轜尒尓尔耳迩洱饵栮毦珥铒爾鉺餌駬薾邇趰二弍弐佴刵咡贰貮衈貳誀樲发沷発發彂髪橃醗乏伐姂垡疺罚茷阀栰傠筏瞂罰閥罸藅佱法砝鍅灋珐琺髮帆忛犿番勫噃墦嬏幡憣旙旛翻藩轓颿籓飜鱕凡凢凣匥杋柉矾籵钒舤烦舧笲釩棥煩緐樊蕃橎燔璠膰薠繁襎繙羳蹯瀿礬蘩鐇蠜鷭反仮払辺返氾犯奿汎泛饭范贩畈訉軓梵盕笵販軬飯飰滼嬎範嬔瀪匚方邡坊芳枋牥钫淓蚄堏趽鈁錺鴋防妨房肪埅鲂魴仿访彷纺昉昘瓬眆倣旊紡舫訪髣鶭放飞妃非飛啡婓婔渄绯菲扉猆靟裶緋蜚霏鲱餥馡騑騛鯡飝肥淝暃腓蜰蟦朏胐匪诽奜悱斐棐榧翡蕜誹篚吠废杮沸狒肺昲费俷剕厞疿屝萉廃費痱镄廢蕟曊癈鼣濷櫠鐨靅分吩帉纷芬昐氛玢竕衯紛翂棻訜躮酚鈖雰朆餴饙坆坟妢岎汾枌炃肦梤羒蚠蚡棼焚蒶馚隫墳幩蕡魵鳻橨燌燓豮鼢羵鼖豶轒鐼馩黂粉瞓黺份坋弅奋忿秎偾愤粪僨憤奮膹糞鲼瀵鱝丰风仹凨凬妦沣沨凮枫封疯盽砜風峯峰偑桻烽琒崶渢溄猦葑锋楓犎蜂瘋碸僼篈鄷鋒檒豐鎽鏠酆寷灃蘴靊飌麷冯夆捀浲逢堸馮摓綘缝艂縫讽覂唪諷凤奉甮俸湗焨煈赗鳯鳳鴌賵蘕瓰覅仏佛坲梻垺紑缶否妚缹缻雬鴀夫伕邞呋妋姇枎玞肤怤柎砆胕荂衭娐尃荴旉紨趺酜麸稃跗鈇筟綒鄜孵豧敷膚鳺麩糐麬麱懯乀巿弗伏凫甶冹刜孚扶芙芣芾咈岪帗彿怫拂服泭绂绋苻茀俘垘枹柫氟洑炥玸畉畐祓罘茯郛韨鳬哹栿浮畗砩莩蚨匐桴涪烰琈符笰紱紼翇艴菔虙袱幅棴絥罦葍福粰綍艀蜉辐鉘鉜颫鳧榑稪箙複韍幞澓蝠髴鴔諨踾輻鮄癁襆鮲黻襥鵩鶝呒抚甫府弣拊斧俌郙俯釜釡捬脯辅椨焤盙腑滏蜅腐輔撫鬴簠黼阝父讣付妇负附咐坿竎阜驸复峊祔訃負赴蚥袝陚偩冨副婏婦蚹傅媍富復秿萯蛗覄詂赋椱缚腹鲋禣褔赙緮蕧蝜蝮賦駙縛輹鮒賻鍑鍢鳆覆馥鰒猤旮伽嘠钆尜釓嘎噶錷尕玍尬魀侅该郂陔垓姟峐荄晐赅畡祴絯隑該豥賅賌忋改絠鎅丐乢匃匄杚钙盖摡溉葢鈣戤概蓋槩槪漑瓂干甘忓芉迀攼杆玕肝坩泔苷柑竿疳酐粓亁凲尲尴筸漧鳱尶尷魐仠皯秆衦赶敢桿笴稈感澉趕橄擀簳鳡鱤旰汵盰矸绀倝凎淦紺詌骭幹榦檊赣贛灨冈罓冮刚阬岗纲肛岡牨疘矼缸钢剛罡堈掆釭棡犅堽綱罁鋼鎠崗港杠焵筻槓戆戇皋羔羙高皐髙臯滜睪槔睾膏槹橰篙糕餻櫜韟鷎鼛鷱夰杲菒稁搞缟槀槁獔稾稿镐縞藁檺藳鎬吿告勂诰郜峼祮祰锆筶暠禞誥鋯戈圪犵纥戓肐牫疙牱紇哥胳袼鸽割搁彁歌滒戨閤鴐鴚擱謌鴿鎶呄佮匌挌茖阁革敋格鬲愅臵葛蛒蛤裓隔嗝塥滆觡搿槅膈閣镉鞈韐骼諽輵鮯櫊鎘韚轕鞷騔鰪哿舸个各虼個硌铬箇鉻獦给給根跟哏亘艮茛揯搄更刯庚畊浭耕掶菮椩焿絚赓鹒緪縆羮賡羹鶊郠哽埂峺挭绠耿莄梗綆鲠骾鯁亙堩啹喼嗰工弓公厷功攻杛供糼肱宫宮恭蚣躬龚匑塨幊愩觥躳匔碽篢髸觵龏龔廾巩汞拱唝拲栱珙輁鞏共贡羾貢慐熕贑兝兣勾佝沟钩袧缑鈎溝鉤緱褠篝簼鞲韝岣狗苟枸玽耇耉笱耈蚼豿坸构诟购垢姤茩冓够夠訽媾彀搆詬遘雊構煹觏撀覯購估咕姑孤沽泒柧轱唂唃罛鸪笟菇菰蛄蓇觚軱軲辜酤毂鈲箍箛嫴篐橭鮕鴣轂鹘鶻古夃扢汩诂谷股峠牯骨罟羖逧钴傦啒淈脵蛊蛌尳愲焸硲詁馉鹄榾鈷鼓鼔嘏榖皷穀縎糓薣濲臌餶瀔盬瞽鵠蠱固怘故凅顾堌崓崮梏牿棝祻雇痼稒锢頋僱錮鲴鯝顧瓜刮苽胍鸹歄焻煱颪趏劀緺銽颳鴰騧冎叧呱剐剮啩寡卦坬诖挂掛罣絓罫褂詿乖拐枴柺箉夬叏怪恠关观官冠覌倌萖棺蒄窤関瘝癏観闗鳏關鰥觀鱞馆琯痯筦管輨舘錧館躀鳤卝毌丱贯泴悺惯掼涫貫悹祼慣摜潅遦樌盥罆雚鏆灌爟瓘矔礶鹳罐鑵鸛鱹光灮侊炗炚炛咣垙姯洸茪桄烡珖胱硄僙輄銧黆欟广広犷廣獷臩俇逛臦撗归圭妫龟规邽皈茥闺帰珪胿亀硅窐袿規媯椝瑰郌嫢摫閨鲑嬀嶲槻槼璝瞡膭鮭龜巂歸鬶騩瓌鬹櫷宄氿轨庋佹匦诡陒垝姽恑癸軌鬼庪祪匭晷湀蛫觤詭厬簋蟡刽刿攰昋柜炅攱贵桂椢筀貴溎蓕跪瞆劊劌撌槶瞶禬簂櫃襘鳜鞼鱖鱥丨衮惃绲袞辊滚蓘裷滾緄蔉磙緷輥鲧鮌鯀棍棞睔睴璭謴呙咼埚郭啯堝崞楇聒鈛锅墎瘑嘓彉濄蝈鍋彍蟈囯囶囻国圀國帼掴腘幗慖摑漍聝蔮膕虢馘果惈淉猓菓馃椁褁槨粿綶蜾裹輠餜鐹过過腂妎铪鉿丷哈咍嗨孩骸海胲烸塰酼醢亥骇害氦嗐餀駭駴嚡饚乤兯佄顸哻蚶酣頇嫨谽憨馠魽鼾邗含邯函咁肣凾虷唅圅娢浛崡晗梒涵焓寒嵅韩甝筨爳蜬澏鋡韓厈罕浫喊蔊豃鬫汉屽扞汗闬旱垾悍捍晘涆猂莟晥淊焊琀菡釬閈皔睅傼蛿颔馯撖漢蜭暵熯銲鋎憾撼翰螒頷顄駻譀雗瀚蘫鶾夯魧妔苀迒斻杭垳绗笐航蚢颃貥筕絎頏沆茠蒿嚆薅薧竓蚝毫椃嗥獆噑豪嘷獋儫曍嚎壕濠籇蠔譹好郝号昊昦秏哠恏悎浩耗晧淏傐皓滈聕號暤暭澔皜皞皡薃皥颢灏顥鰝灝兞诃呵抲欱喝訶嗬蠚禾合何劾咊和姀河郃峆曷柇狢盇籺阂饸哬敆核盉盍荷啝涸渮盒秴菏萂蚵龁惒粭訸颌楁毼詥貈貉鉌阖鲄熆閡鹖麧澕頜篕翮螛魺礉闔鞨齕覈鶡皬鑉龢佫垎贺袔隺寉焃湼賀嗃煂碋熇褐赫鹤翯壑癋燺爀鶴齃靍靎鸖靏黒黑嘿潶嬒拫痕鞎佷很狠詪恨亨哼悙涥脝姮恆恒桁烆珩胻鸻横橫衡鴴鵆蘅鑅啈堼囍乊乥叿灴轰哄訇烘軣揈渹焢硡谾薨輷嚝鍧轟仜弘妅红吰宏汯玒纮闳宖泓玜苰垬娂洪竑紅荭虹浤紘翃耾硔紭谹鸿渱竤粠葒葓鈜閎綋翝谼潂鉷鞃魟篊鋐彋蕻霐黉霟鴻黌晎嗊讧訌閧撔澋澒銾闀闂鬨齁侯矦喉帿猴葔瘊睺銗篌糇翭骺鍭餱鯸吼吽犼后郈厚垕後洉逅候鄇堠豞鲎鲘鮜鱟乎匢虍呼垀忽昒曶泘苸恗烀轷匫唿惚淴虖軤雽嘑寣滹雐幠歑膴謼囫抇弧狐瓳胡壶壷斛焀喖壺媩搰湖猢絗葫楜煳瑚嘝蔛鹕槲箶糊蝴衚魱縠螜醐頶觳鍸餬瀫鬍鰗鶘鶦鶮乕汻虎浒唬萀琥虝滸箎錿鯱互弖戶户戸冱冴芐帍护沍沪岵怙戽昈枑祜笏粐婟扈瓠綔鄠嫭嫮摢滬蔰槴熩鳸簄鍙嚛鹱護鳠韄頀鱯鸌花芲埖婲椛硴糀誮錵蘤华哗姡骅華铧滑猾嘩撶璍磆蕐螖鋘譁鏵驊鷨化划杹画话崋桦婳畫嬅畵觟話劃摦槬樺嫿澅諙諣黊繣舙蘳怀徊淮槐褢踝懐褱懷瀤櫰耲蘹坏咶壊壞蘾欢欥歓鴅懁鵍酄嚾懽獾歡貛讙驩还环郇峘洹狟荁桓萈萑堚寏絙雈綄羦貆锾阛寰澴缳還環豲鍰镮鹮糫繯轘闤鐶鬟瓛睆缓輐緩攌幻奂肒奐宦唤换浣涣烉患梙焕逭喚喛嵈愌換渙痪煥瑍豢漶瘓槵鲩擐澣瞣藧鯇鯶鰀巟肓荒衁朚塃慌皇偟凰隍黃黄喤堭媓崲徨惶揘湟葟遑楻煌瑝墴潢獚锽熿璜篁艎蝗癀磺穔諻簧蟥鍠餭鳇趪韹鐄騜鰉鱑鷬怳恍炾宺晃晄奛谎幌愰詤熀縨謊櫎皩兤滉榥曂皝鎤灰灳诙咴恢拻挥洃虺袆晖烣珲豗婎媈揮翚辉隓暉楎煇琿禈詼幑睳褘噅噕撝翬輝麾徽隳瀈鰴囘回囬佪廻廽恛洄茴迴烠蚘逥痐蛔蛕蜖鮰悔螝毇檓燬譭卉屷汇会讳泋哕浍绘芔荟诲恚恵桧烩烪贿彗晦秽喙惠湏絵缋翙阓匯彙彚會毀毁滙詯賄僡嘒瘣蔧誨圚寭慧憓暳槥潓蕙噦徻橞澮獩璤薈薉諱頮檅檜燴璯篲藱餯嚖懳瞺穢繢蟪櫘繪翽譓儶譮鏸闠孈鐬靧韢譿顪昏昬荤婚惛涽阍惽棔殙葷睧睯閽忶浑馄渾魂餛繉轋鼲诨俒倱圂掍混焝溷慁觨諢吙耠锪劐鍃豁攉騞佸活秮秳火伙邩钬鈥漷夥沎或货咟俰捇眓获閄剨掝祸貨惑旤湱禍嗀蒦嚄奯擭濩獲霍檴謋雘矆穫镬嚯瀖耯艧藿蠖嚿曤臛癨矐鑊靃夻丌讥击刉叽饥乩刏圾机玑肌芨矶鸡枅咭迹剞唧姬屐积笄飢基绩喞嵆嵇攲敧犄筓缉赍勣嗘畸稘跻鳮僟毄箕銈嘰撃槣樭畿稽緝觭賫躸齑墼憿機激璣禨積錤隮擊磯簊績羁賷鄿櫅耭雞譏韲鶏譤鐖饑癪躋鞿鷄齎羇虀鑇覉鑙齏羈鸄覊亼及伋吉岌彶忣汲级即极亟佶郆卽叝姞急狤皍笈級揤疾觙偮卙庴楖焏脨谻戢棘極殛湒集塉嫉愱楫蒺蝍趌辑槉耤膌銡嶯潗瘠箿蕀蕺踖鞊鹡橶檝濈螏輯襋蹐鍓艥籍轚鏶霵鶺鷑躤雦雧几己丮妀犱泲虮挤脊掎鱾幾戟嵴麂魢撠擠穖蟣彐彑旡计记伎纪坖妓忌技芰芶际剂季哜垍峜既洎济紀茍計剤紒继觊記偈寂寄徛悸旣梞済祭萕惎臮葪蔇兾痵継蓟裚跡際墍暨漃漈禝稩穊誋跽霁鲚暩稷諅鲫冀劑曁穄縘薊襀髻嚌檕濟繋罽覬鮆檵璾蹟鯽鵋齌廭懻癠穧糭繫蘎骥鯚瀱繼蘮鱀蘻霽鰶鰿鱭驥加夹夾宊抸佳拁泇迦枷毠浃珈埉家浹痂梜笳耞袈袷傢猳葭裌跏犌腵鉫嘉镓糘豭貑鎵麚圿扴岬郏荚郟唊恝莢戛脥铗戞蛱颊蛺跲餄鋏頬頰鴶鵊甲叚玾胛斚贾钾婽徦斝椵賈鉀榎槚瘕檟价驾架假嫁幏榢價稼駕嗧戋奸尖幵坚歼间冿戔玪肩艰姦姧兼监堅惤猏笺菅菺豜湔牋犍缄葌葏間靬搛椷椾煎瑊睷碊缣蒹豣監箋樫熞緘蕑蕳鲣鳽鹣熸篯縑鋻艱鞬餰馢麉瀐鞯鳒殱礛覸鵳瀸鰔櫼殲譼鰜鶼籛韀鰹囏虃鑯韉囝拣枧俭柬茧倹挸捡笕减剪帴梘检湕趼揀揃検減睑硷裥詃锏弿暕瑐筧简絸谫彅戩戬碱儉翦撿檢藆襇襉謇蹇瞼礆簡繭謭鬋鰎鹸瀽蠒鐗鐧鹻譾襺鹼见件見侟建饯剑洊牮荐贱俴健剣栫涧珔舰剱徤渐袸谏釼寋旔楗毽溅腱臶葥跈践閒賎鉴键僭榗槛漸劍劎墹澗箭糋諓賤趝踐踺劒劔橺薦諫鍵餞瞯瞷磵礀螹鍳擶檻濺繝瀳覵鏩聻艦轞鑑鑒鑬鑳江姜将茳浆畕豇葁摪翞僵漿螀壃彊缰薑橿殭螿鳉疅礓疆繮韁鱂讲奖桨傋蒋勥奨奬蔣槳獎耩膙講顜匞匠夅弜杢降洚绛將弶袶絳畺酱摾滰嵹犟糡醤糨醬櫤謽艽芁交郊姣娇峧浇茭茮骄胶椒焦焳蛟跤僬嘄虠鲛嬌嶕嶣憍澆膠蕉燋膲礁穚鮫鵁鹪簥蟭轇鐎驕鷦鷮櫵臫角佼侥挢狡绞饺捁晈烄笅皎矫脚铰搅湫筊絞剿勦敫湬煍腳賋僥摷暞踋鉸餃儌劋撟撹徼敽敿缴曒璬矯皦蟜鵤繳譑孂纐攪灚鱎叫呌峤挍訆珓窌轿较敎教窖滘較嘂嘦斠漖酵噍嶠潐噭嬓獥藠趭轎醮譥皭釂阶疖皆接掲痎秸菨階喈嗟堦媘嫅揭椄湝脻街煯稭鞂蝔擑癤鶛卩卪孑尐节讦刦刧劫岊昅刼劼杰疌衱诘拮洁结迼倢桀桝莭訐偼婕崨捷袺傑媫結蛣颉嵥楬楶滐睫節蜐詰鉣魝截榤碣竭蓵鲒潔羯誱踕頡幯擳嶻擮礍鍻鮚巀櫭蠞蠘蠽她姐毑媎解觧飷檞丯介吤岕庎忦戒芥屆届斺玠界畍疥砎衸诫借悈蚧徣堺楐琾蛶骱犗誡褯魪藉繲巾今斤钅兓金釒津矜砛荕衿觔埐珒紟惍琎堻琻筋嶜璡鹶黅襟仅卺巹紧堇菫僅厪谨锦嫤廑漌盡緊蓳馑槿瑾錦謹饉伒劤尽劲妗近进侭枃勁浕荩晉晋浸烬赆祲進煡缙寖搢溍禁靳墐慬瑨僸凚歏殣觐儘噤濅縉賮嚍壗嬧濜藎燼璶覲贐齽坕坙巠京泾经茎亰秔荆荊涇莖婛惊旌旍猄経菁晶稉腈睛粳經兢精聙橸鲸鵛鯨鶁鶄麖鼱驚麠井丼阱刭坓宑汫汬肼剄穽颈景儆幜憬璄憼暻燝燞璟璥頸蟼警妌净弪径迳俓浄胫倞凈弳徑痉竞逕婙婧桱梷淨竟竫脛敬痙竧靓傹靖境獍誩踁静頚靚曔镜靜瀞鏡競竸冂冋坰扃埛絅駉駫蘏冏囧泂迥侰炯逈浻烱煚窘颎綗僒煛熲澃燑燛褧顈蘔丩勼纠朻牞究糺鸠糾赳阄萛啾揂揪揫鳩摎樛鬏鬮九久乆乣奺汣杦灸玖舏韭紤酒镹韮匛旧臼咎畂疚柩柾倃桕厩救就廄匓舅僦廏廐慦殧舊鹫鯦麔匶齨鷲欍凥圧抅匊居拘泃狙苴驹倶挶捄疽痀眗砠罝陱娵婅婮崌掬梮涺椐琚腒趄跔锔裾雎艍蜛諊踘鋦駒鮈鴡鞠鞫鶋局泦侷狊桔毩淗焗菊郹椈毱湨犑輂僪粷蓻跼趜躹閰橘檋駶鵙蹫鵴巈蘜鶪鼰鼳驧咀弆沮举矩莒挙椇筥榉榘蒟龃聥舉踽擧櫸齟欅襷句巨讵姖岠怇拒洰苣邭具怚拠昛歫炬秬钜俱倨冣剧粔耟蚷袓埧埾惧据詎距焣犋跙鉅飓虡豦锯寠愳窭聚駏劇勮屦踞鮔壉懅據澽窶遽鋸屨颶瞿貗簴躆醵懼鐻爠姢娟捐涓脧裐鹃勬鋑鋗镌鎸鵑鐫蠲卷呟帣埍捲菤锩臇錈奆劵弮倦勌桊狷绢隽淃瓹眷鄄睊絭罥雋睠絹飬慻蔨餋獧羂噘撅撧屩屫亅孒孓决刔氒诀妜抉決芵泬玦玨挗珏砄绝虳觉倔捔欮蚗崛掘斍桷殌焆覐觖訣赽趹逫傕厥絕絶覚趉鈌劂勪瑴谲駃嶡嶥憰潏熦爴獗瘚蕝蕨鴂鴃噱憠橛橜镼爵臄镢蟨蟩爑譎蹶蹷鶌嚼矍覺鐍鐝灍爝觼彏戄攫玃鷢欔矡龣貜躩钁军君均汮姰袀軍钧莙蚐桾皲菌鈞碅筠皸皹覠銁銞鲪麇鍕鮶麏麕呁俊郡陖埈峻捃晙浚馂骏焌珺畯竣箘箟蜠儁寯懏餕燇濬駿鵔鵕鵘攈咔咖喀卡佧垰胩裃鉲开奒揩衉锎開鐦凯剀垲恺闿铠凱剴慨蒈塏愷楷輆暟锴鍇鎧闓颽忾炌炏欬烗勓嘅愾鎎乫刊栞勘龛堪嵁戡龕冚坎侃砍莰偘埳惂堿欿塪歁輡轁顑竷轗看衎崁墈阚瞰磡闞矙忼砊粇康嫝嵻慷漮槺穅糠躿鏮鱇扛摃亢伉匟邟囥抗犺闶炕钪鈧閌尻髛丂攷考拷洘栲烤铐犒銬鲓靠鮳鯌匼坷苛柯牁珂科胢轲疴趷钶嵙棵痾萪軻颏搕犐稞窠鈳榼薖颗樖瞌磕蝌頦醘顆髁礚壳咳殻揢翗嶱可岢炣渇嵑敤渴克刻剋勀勊客峇恪娔尅课堁氪骒缂嗑愙溘锞碦緙課錁礊騍肎肯肻垦恳啃豤貇墾錹懇掯裉褃劥吭坈坑挳硁牼硜铿硻誙銵鍞鏗巪乬唟厼怾空倥埪崆悾涳硿箜躻躼錓鵼孔恐控鞚廤抠芤眍剾彄摳瞘口劶叩扣怐敂冦宼寇釦窛筘滱蔲蔻瞉簆鷇扝刳矻郀枯哭桍堀崫圐跍窟骷鮬狜苦楛库俈绔庫秙焅袴喾絝裤瘔酷褲嚳夸姱晇舿誇侉咵垮銙挎胯跨骻蒯擓巜凷圦块快侩郐哙狯脍塊筷鲙儈墤鄶噲廥獪膾旝糩鱠宽寛寬髋鑧髖梡欵款歀窽窾匡劻诓邼匩哐恇洭筐筺誆軭抂狂狅诳軖軠誑鵟夼儣懭邝圹纩况旷岲況矿昿贶框眖砿眶絋絖貺軦鉱鋛鄺壙黋懬曠爌矌礦穬纊鑛亏刲岿悝盔窥聧窺虧闚顝巋蘬奎晆逵鄈頄馗喹揆葵骙戣暌楏楑魁睽蝰頯櫆藈鍨鍷騤夔蘷虁巙躨卼傀煃跬頍磈蹞尯匮欳喟媿愦愧溃蒉蒊馈匱嘳嬇憒潰篑聩聭蕢樻殨謉餽簣聵籄鐀饋鑎坤昆晜堃堒婫崐崑猑菎裈焜琨髠裩锟髡鹍尡潉蜫褌髨熴瑻醌錕鲲臗騉鯤鵾鶤悃捆阃壸梱祵硱稇裍壼稛綑閫閸困涃睏扩拡括挄栝桰筈萿葀蛞阔廓噋頢髺擴濶闊鞟韕懖霩鞹鬠穒垃拉柆啦翋菈搚邋旯砬揦磖喇藞嚹剌溂腊揧楋瘌蜡蝋辢辣蝲臈攋爉臘鬎櫴瓎镴鯻蠟鑞鞡来來俫倈崃徕涞莱郲婡崍庲徠梾淶猍萊逨棶琜筙铼箂錸騋鯠鶆麳唻赉睐睞赖賚濑賴頼顂癞鵣瀨瀬籁藾癩襰籟兰岚拦栏婪嵐葻阑蓝蓞谰厱澜褴儖斓篮懢燣藍襕镧闌璼襤譋幱攔瀾灆籃繿蘭斕欄礷襴囒灡籣欗讕躝襽鑭钄韊览浨揽缆榄漤罱醂壈懒覧擥嬾懶孄覽孏攬欖爦纜烂滥燗嚂壏濫爁爛爤瓓灠糷啷勆郎郞欴狼莨嫏廊桹琅蓈榔瑯硠稂锒筤艆蜋郒螂躴鋃鎯駺悢朗阆朖烺塱蓢樃誏閬朤埌崀浪蒗唥捞粩撈劳労牢狫窂哰唠崂浶勞痨铹僗嘮嶗憥朥癆磱簩蟧醪鐒顟髝耂老佬咾姥恅荖栳珯硓铑蛯銠潦橑鮱轑涝烙嗠耢酪嫪憦澇橯耮軂仂阞乐叻忇扐氻艻玏泐竻砳勒楽韷樂簕鳓鰳饹餎雷嫘缧蔂樏畾檑縲镭櫑瓃羸礧纍罍蘲鐳轠壨鑘靁虆鱩欙纝鼺厽耒诔垒塁絫傫誄磊蕌磥蕾儡壘癗藟櫐矋礨灅蠝蘽讄儽鑸鸓肋泪洡类涙淚累酹銇頛頪擂錑攂礌颣類纇蘱禷嘞脷塄棱楞碐稜踜薐冷倰堎愣睖唎刕厘剓梨狸离荲莉骊悡梸犁菞喱棃犂鹂剺漓睝筣缡艃蓠蜊嫠孷樆璃盠竰貍氂犛糎蔾褵鋫鲡黎篱縭罹錅蟍謧醨嚟藜邌釐離鯏斄鏫鯬鵹黧囄灕蘺蠡蠫孋廲劙鑗穲籬驪鱺鸝礼李里俚峛哩娌峲浬逦理裡锂粴裏豊鋰鲤澧禮鯉蟸醴鳢邐鱧欚力历厉屴立吏朸丽利励呖坜沥苈例岦戾枥沴疠苙隶俐俪栃栎疬砅茘荔赲轹郦娳悧栗栛栵涖猁珕砺砾秝莅唳婯悷琍笠粒粝蚸蛎傈凓厤棙痢蛠詈跞雳塛慄搮溧蒚蒞鉝鳨厯厲暦歴瑮綟蜧勵曆歷篥隷鴗巁檪濿癘磿隸鬁儮曞櫔爄犡禲蠇嚦壢攊櫟瀝瓅礪藶麗櫪爏瓑皪盭礫糲蠣儷癧礰酈鷅麜囇攦躒轢欐讈轣攭瓥靂鱱靋瓈俩倆嫾奁连帘怜涟莲連梿联裢亷嗹廉慩溓漣蓮匲奩熑覝劆匳噒憐磏聨聫褳鲢濂濓縺翴聮薕螊櫣燫聯臁蹥謰鎌镰簾蠊譧鬑鐮鰱籢籨敛琏脸裣摙槤璉蔹嬚斂歛臉鄻襝羷蘝蘞练娈炼恋浰殓堜媡湅萰链僆楝煉瑓潋稴練澰錬殮鍊鏈瀲鰊戀纞簗良俍凉梁涼椋辌粮粱墚綡踉樑輬糧両两兩唡啢掚脼裲緉蜽魉魎亮哴谅辆喨晾湸量煷輌諒輛鍄蹽辽疗聊僚寥嵺廖憀漻膋嘹嫽寮嶚嶛憭撩敹獠缭遼暸燎璙窷膫療竂镣鹩屪廫簝繚蟟豂賿蹘爎鐐髎飉鷯钌釕鄝蓼爒镽了尥尦炓料尞撂瞭咧毟挘埓列劣冽劽姴峢挒洌茢迾埒浖烈烮捩猎猟脟蛚裂煭睙聗趔巤颲儠鮤鴷擸獵犣躐鬛鬣鱲厸邻林临啉崊惏淋晽琳粦痳碄箖粼鄰隣嶙潾獜遴斴暽燐璘辚霖瞵磷臨繗翷麐轔壣瀶鏻鳞驎麟鱗菻亃稟僯凛凜撛廩廪懍懔澟檁檩癛癝顲吝恡悋赁焛賃蔺橉甐膦閵疄藺蹸躏躙躪轥拎伶刢灵囹坽夌姈岭岺彾泠狑苓昤朎柃玲瓴凌皊砱秢竛铃陵鸰婈崚掕棂淩琌笭紷绫羚翎聆舲菱蛉衑祾詅跉軨蓤裬鈴閝零龄綾蔆輘霊駖澪蕶錂霗魿鲮鴒鹷燯霛霝齢瀮酃鯪孁蘦齡櫺醽靈欞爧麢龗阾袊领領嶺令另呤炩溜熘刘沠畄浏流留旈琉畱硫裗媹嵧旒蒥蓅遛馏骝榴瑠飗劉瑬瘤磂镏駠鹠橊璢疁镠癅蟉駵嚠懰瀏藰鎏鎦餾麍鏐飀鐂騮飅鰡鶹驑柳栁桞珋桺绺锍綹熮罶鋶橮羀嬼六翏塯廇澑磟鹨蹓霤雡飂鬸鷚瓼甅囖咯龙屸咙泷茏昽栊珑胧眬砻竜笼聋隆湰嶐槞漋蕯癃窿篭龍嚨巃巄瀧蘢鏧霳曨朧櫳爖瓏矓礱礲襱龒籠聾蠪蠬龓豅躘鑨靇驡鸗陇垄垅拢儱隴壟壠攏竉哢梇硦衖徿贚娄偻婁喽溇蒌僂楼嘍廔慺蔞遱樓熡耧蝼瞜耬艛螻謱軁髅鞻髏嵝搂塿嶁摟漊甊篓簍陋屚漏瘘镂瘺瘻鏤露噜撸嚕擼卢庐芦垆枦泸炉栌胪轳舮鸬玈舻颅鈩鲈魲盧嚧壚廬攎瀘獹璷蘆櫨爐瓐臚矑籚纑罏艫蠦轤鑪顱髗鱸鸕黸卤虏挔捛掳鹵硵鲁虜塷滷蓾樐澛魯擄橹磠镥瀂櫓氌艣鏀艪鐪鑥圥甪陆侓坴彔录峍勎赂辂陸娽淕淥渌硉菉逯鹿椂琭祿禄僇剹勠滤盝睩碌稑賂路輅塶廘摝漉箓粶蔍戮樚熝膔膟觮趢踛辘醁潞穋蕗錄録錴璐簏螰鴼濾簶蹗轆騄鹭簬簵鏕鯥鵦鵱麓鏴騼籙觻虂鷺氇驴闾榈閭馿氀膢櫚藘曥鷜驢吕呂侣郘侶旅梠焒祣稆铝屡絽缕屢膂膐褛鋁履褸儢穞縷穭寽垏律哷虑率绿嵂氯葎綠緑慮箻勴繂櫖爈鑢孪峦挛栾鸾脔滦銮鵉圝奱孌孿巒攣曫欒灓羉臠圞灤虊鑾癴癵鸞卵乱釠亂掠略畧锊稤稥圙鋝鋢擽抡掄仑伦囵沦纶侖轮倫陯圇婨崘崙惀淪菕棆腀碖綸蜦踚輪磮錀鯩稐耣论埨溣論捋頱囉罗啰猡脶萝逻椤腡锣箩骡镙螺羅覶鏍儸覼騾玀蘿邏欏鸁籮鑼饠驘剆倮砢蓏裸躶瘰蠃臝攞曪癳泺峈洛络荦骆洜珞笿絡落摞漯犖雒駱鮥鵅濼纙鱳嘸呣妈媽嬤嬷麻痲嫲蔴犘蟆蟇马犸玛码蚂馬溤獁遤瑪碼螞鎷鷌鰢亇杩祃閁骂唛傌睰嘜榪禡罵駡礣鬕吗嗎嘛埋薶霾买荬買嘪蕒鷶劢迈佅売麦卖脉脈麥衇勱賣邁霡霢颟顢姏悗蛮慲摱馒槾樠瞒瞞鞔饅鳗鬗鬘鰻蠻屘満睌满滿螨襔蟎鏋矕曼僈谩鄤墁嫚幔慢漫獌缦蔄蔓熳澫澷镘縵蟃謾鏝蘰牤邙吂忙汒芒尨杗杧盲厖恾笀茫哤娏浝狵牻硭釯铓痝蛖鋩駹蘉莽莾茻壾漭蟒蠎匁猫貓毛矛毜毝枆牦茅旄渵軞酕堥蛑锚緢髦蝥髳錨蟊鶜冇卯夘戼峁泖茆昴铆笷蓩鉚冃皃芼冐茂冒眊贸耄袤覒媢帽貿鄚愗暓楙毷瑁瞀貌鄮蝐懋唜庅嚒濹嚰么癦呅沒没枚玫苺栂眉脄莓梅珻脢郿堳媒嵋湄湈猸睂葿楣楳煤瑂禖腜塺槑酶镅鹛鋂霉徾鎇矀攗蘪鶥攟黴毎每凂美挴浼媄嵄渼媺镁嬍燘躾鎂黣妹抺沬昧祙袂眛媚寐痗跊鬽煝睸韎魅篃蝞嚜椚门扪玣钔門閅捫菛璊穈鍆虋闷焖悶暪燜懑懣们們掹擝氓甿虻冡庬罞莔萌萠夢溕盟雺甍儚橗瞢蕄蝱鄳鄸幪懞濛獴曚朦檬氋矇礞鯍艨鹲矒靀饛顭鸏勐猛瓾蒙锰艋蜢錳懵蠓鯭鼆孟梦夣懜霥霿踎咪瞇冞弥祢迷袮猕谜蒾詸謎醚彌擟糜縻麊麋禰靡獼麛爢戂攠瓕蘼镾醾醿鸍釄米羋芈侎沵弭洣敉眫粎脒眯渳葞蝆蔝銤濔瀰孊灖冖糸汨沕宓泌觅峚祕宻秘密淧覓覔幂谧塓幎覛嘧榓滵漞熐蔤蜜鼏冪樒幦濗藌謐櫁簚羃宀芇眠婂绵媔棉綿緜臱蝒嬵檰櫋矈矊矏丏汅免沔黾俛勉眄娩偭冕勔喕愐湎缅葂腼緬鮸靣面糆麪麫麺麵喵苗媌描瞄鹋嫹鶓鱙杪眇秒淼渺缈篎緲藐邈妙庙玅竗庿廟乜吀咩哶孭灭覕搣滅蔑薎鴓幭懱瀎篾櫗蠛衊鑖鱴瓱民垊姄岷忞怋旻旼玟苠珉盿冧罠崏捪琘琝缗暋瑉痻碈鈱緍緡賯錉鴖鍲皿冺刡闵抿泯勄敃闽悯敏笢笽湣閔愍敯黽閩僶慜憫潣簢鳘蠠鰵名明鸣洺眀茗冥朙眳铭鄍嫇溟猽蓂暝榠銘鳴瞑螟覭佲姳凕慏酩命掵詺谬缪繆謬摸嚤尛谟嫫馍摹模膜麼麽摩魹橅磨糢謨謩擵饃嚩蘑譕髍魔劘饝抹懡麿末劰圽妺帓怽歾歿殁沫茉陌帞昩枺皌眜眿砞秣莈莫眽粖絈袹蛨貃嗼塻寞漠蓦貊銆靺墨嫼暯瘼瞐瞙镆魩黙縸默貘藦蟔鏌爅驀礳纆耱乮哞牟侔劺恈洠桙眸谋鉾謀瞴鍪鴾麰蟱某母毪獏墲氁亩牡姆拇峔牳畆畒胟娒畝畞砪畮鉧踇木仫目凩沐狇坶炑牧苜毣莯蚞钼募萺雮墓幕幙慔楘睦鉬慕暮樢艒霂穆鞪旀丆椧拏拿挐誽镎鎿乸哪雫内那吶妠纳肭娜衲钠納袦捺笝豽軜貀鈉嗱蒳靹魶腉熋摨孻乃奶艿氖疓妳廼迺倷釢嬭奈柰耐萘渿鼐褦螚錼囡男抩枏枬侽南柟娚畘莮难喃遖暔楠煵諵難赧揇湳萳腩蝻戁婻囔乪嚢囊蠰鬞馕欜饢擃曩攮灢儾齉孬檂呶怓挠峱硇铙猱蛲詉碙撓嶩獶蟯夒譊鐃巎獿垴恼悩脑匘脳堖惱嫐瑙腦碯闹婥淖閙鬧臑疒讷呐抐眲訥呢娞馁腇餒鮾鯘內氝焾嫩能莻嗯鈪銰啱妮尼坭怩泥籾倪屔秜郳铌埿婗淣猊蚭棿跜鈮蜺觬貎輗霓鲵鯢麑齯臡伱伲你拟抳狔苨柅掜旎晲孴鉨馜儗儞隬擬薿檷鑈屰氼迡昵胒逆匿痆眤堄惄嫟愵溺睨腻暱縌膩嬺拈年秊哖秥鲇鮎鲶鵇黏鯰涊捻淰辇撚撵碾輦簐攆蹨躎卄廿念姩埝艌娘嬢孃酿醸釀鸟茑茒袅鳥嫋裊蔦嬝褭嬲尿脲捏揑肀帇圼苶枿陧涅聂臬啮惗菍隉喦敜嗫嵲鉩踂噛摰槷踗踙镊镍嶭篞臲錜颞蹑嚙聶鎳闑孼孽櫱籋蘖囁齧巕糱糵蠥囓讘躡鑷顳钀脌囜您拰宁咛拧狞柠聍寍寕寜寧儜凝嚀嬣擰獰薴檸聹鑏鬡鸋橣矃佞侫泞甯寗澝濘妞牛牜汼忸扭沑狃纽杻炄钮紐莥鈕靵农侬哝浓脓秾農儂辳噥憹濃蕽禯膿穠襛醲欁繷弄挊挵癑齈羺譨啂槈耨獳檽鎒鐞譳奴伖孥驽笯駑伮努弩砮胬怒傉搙女钕籹釹衂恧朒衄疟虐瘧奻渜暖煖煗餪硸黁燶郍挪梛傩搻儺橠诺喏掿逽搦锘榒稬諾蹃糑鍩懦懧糥穤糯桛噢哦筽毮夞乯鞰讴欧殴瓯鸥塸歐毆熰甌膒鴎櫙藲謳鏂鷗齵吘呕偶腢嘔耦蕅藕怄沤慪漚妑皅趴舥啪葩杷爬耙掱琶筢潖帊帕怕袙拍俳徘排猅棑牌箄輫簰犤哌派湃蒎鎃磗眅畨潘攀爿柈盘跘媻幋蒰搫槃盤磐縏蹒瀊蟠蹣鎜鞶坢冸判沜泮炍叛牉盼畔袢詊溿頖鋬鵥襻鑻乓汸沗肨胮雱滂膖霶厐庞逄旁舽嫎篣螃鳑龎龐鰟蠭嗙耪覫髈炐胖抛拋脬刨咆垉庖狍炮炰爮袍匏蚫軳鞄褜麅跑奅泡疱皰砲萢麭礟礮呸怌肧柸胚衃醅阫陪陫培毰赔锫裴裵賠錇俖伂沛佩帔姵斾旆浿珮配笩蓜辔馷嶏霈轡喷噴濆歕瓫盆湓葐呠翉翸喯匉怦抨泙恲胓砰梈烹硑軯閛漰嘭駍磞芃朋挷竼倗莑堋弸彭棚椖傰塜塳搒漨硼稝蓬鹏槰樥熢憉澎輣篷膨錋韸髼蟚蟛鬅纄韼鵬騯鬔鑝捧淎皏剻掽椪碰踫浌巼闏乶喸丕伓伾批纰邳坯怶披抷炋狉狓砒悂秛秠紕铍旇翍耚豾釽鈚鈹鉟銔劈磇駓髬噼錃錍魾憵礔礕闢霹皮阰芘岯枇毞肶毗毘疲笓蚍郫陴啤埤崥蚽豼椑焷琵脾腗榌鲏罴膍蜱隦魮壀鮍篺螷貔簲羆鵧朇鼙蠯匹庀仳圮苉脴痞銢諀鴄擗噽癖嚭屁淠渒揊媲嫓睤睥潎僻澼嚊甓疈譬鷿鸊片囨偏媥犏篇翩鶣骈胼腁楄楩賆諚骿蹁駢騈覑谝貵諞骗魸騗騙剽彯漂缥飘磦旚縹翲螵犥飃飄魒瓢薸闝殍瞟篻醥皫顠票僄勡嘌嫖徱慓氕撇撆暼瞥丿苤鐅嫳姘拼礗穦馪驞玭贫貧琕嫔频頻嬪薲嚬矉颦顰品榀朩牝汖娉聘乒甹俜涄砯艵竮頩平评凭呯坪岼苹郱屏帡枰洴玶荓娦瓶屛帲淜萍蚲塀幈焩甁缾聠蓱蛢評軿鲆凴慿箳輧憑鮃檘簈蘋钋坡岥泼娝釙颇溌酦潑醱鏺婆嘙蔢鄱皤謈櫇叵尀钷笸鉕駊廹岶迫敀昢洦珀哱烞破砶粕奤蒪頗魄剖颒抔抙捊掊裒箁咅哣婄堷犃兺哛仆攴攵扑抪炇巬巭柨陠痡铺駇噗撲鋪擈鯆圤匍莆菩菐葡蒱蒲僕酺墣璞濮瞨穙镤贌纀鏷朴圃埔浦烳普圑溥暜谱潽樸氆諩檏镨譜蹼鐠舖舗瀑曝七迉沏妻恓柒倛凄栖桤缼郪娸悽戚捿桼淒萋朞期棲欺紪褄僛嘁慽榿槭漆緀慼磎諆踦諿霋蹊魌鏚鶈亓祁齐圻岐岓忯芪亝其奇斉歧祇祈肵疧竒剘斊旂耆脐蚑蚔蚚颀埼崎帺掑淇渏猉畦萁跂軝釮骐骑嵜棊棋琦琪祺蛴愭碁碕褀锜頎鬾鬿旗粸綥綦綨緕蜝蜞齊璂禥蕲踑螧錡鲯懠濝藄檱櫀簱臍騎騏鳍蘄鯕鵸鶀麒籏纃艩蠐鬐騹魕鰭玂麡乞邔企屺岂芑启呇杞玘盀唘豈起啓啔啟婍绮晵棨裿綮綺諬簯闙气讫気汔迄弃汽矵芞呮泣炁盵咠契砌荠栔氣訖唭欫夡愒棄湆湇葺碛摖暣甈碶噐憇器憩磜磧磩薺礘罊蟿掐葜拤跒酠鞐圶冾帢恰洽殎硈愘髂千仟阡圱圲奷扦汘芊迁佥岍杄汧茾欦竏臤钎拪牵粁悭蚈谸铅婜孯牽釺掔谦鈆雃僉愆签鉛骞鹐慳搴摼撁箞諐遷褰謙顅檶攐攑櫏簽鏲鵮攓騫鐱鬜鬝籤韆仱岒忴扲拑乹前荨钤歬虔钱钳乾偂掮揵軡媊鈐鉆鉗墘榩箝銭潜羬蕁橬錢黔鎆黚騝濳騚灊籖鰬凵浅肷淺嵰慊遣槏膁蜸潛谴缱繾譴鑓欠刋伣芡俔茜倩悓堑傔嵌棈椠嗛皘蒨塹歉綪蔳儙槧篏輤篟壍嬱縴呛羌戕戗斨枪玱羗猐琷跄嗴椌獇腔嗆溬蜣锖嶈戧槍牄瑲羫锵篬錆蹌镪蹡鎗鏘鏹強强墙嫱蔷樯漒蔃墻嬙廧薔檣牆謒艢蘠抢羟搶羥墏摤繈襁繦炝唴熗羻兛瓩悄硗郻鄗嵪跷鄡鄥劁敲踍锹墝碻頝骹墽幧橇燆缲磽鍫鍬繑繰趬蹺蹻鐰乔侨荍荞桥硚菬喬睄僑槗谯嘺嫶憔蕎鞒樵橋犞癄瞧礄藮譙趫鐈鞽顦巧釥愀髜俏诮陗峭帩窍殼翘誚髚僺撬撽鞘韒竅翹鞩躈切苆癿茄聺且厒妾怯匧窃倿悏挈洯惬淁笡愜蛪朅箧緁锲魥篋踥穕藒鍥鯜鐑竊籡亲侵钦衾骎菳媇嵚綅誛嶔親顉駸鮼寴庈芩芹埁珡矝秦耹菦蚙捦琴琹禽鈙雂勤嗪嫀溱靲噙擒斳鳹懄檎澿瘽螓懃蠄坅昑笉梫赺赾寑锓寝寢鋟螼吢吣抋沁唚菣揿欽搇撳瀙藽靑青氢轻倾卿郬圊埥氫淸清軽傾廎蜻輕鲭鯖鑋夝甠剠勍情殑硘晴棾氰葝暒擏樈擎檠黥苘顷请庼頃漀請檾謦庆凊掅殸碃箐靘慶磬儬濪罄櫦宆跫銎卭邛穷穹茕桏笻筇赹惸焪焭琼舼蛩蛬煢熍睘瞏窮儝憌橩璚藑瓊竆藭瓗丘丠邱坵恘秋秌寈蚯媝萩楸蓲鹙篍緧蝵穐趥鳅蟗鞦鞧蘒鰌鰍鶖鱃龝叴囚扏犰玌朹汓肍求虬泅虯俅觓訄訅酋唒浗紌莍逎逑釚梂殏毬球赇釻崷巯渞湭皳盚遒煪絿蛷裘巰觩賕璆蝤銶醔鮂鼽鯄鵭蠤鰽搝糗区曲伹佉匤岖诎阹驱坥屈岨岴抾浀祛胠袪區蛆躯筁粬蛐詘趋嶇駆憈敺誳駈麹髷魼趨麯軀麴黢驅鰸鱋佢劬斪朐朑胊菃衐鸲淭渠絇翑葋軥蕖璖磲螶鴝璩翵蟝鼩蘧匷忂灈戵欋氍籧臞癯蠷衢躣蠼鑺鸜取竘娶紶詓竬蝺龋齲厺去刞呿迲郥耝阒觑趣閴麮闃覰覷鼁覻峑恮悛圈圏棬駩騡鐉全权佺诠姾泉洤荃拳牷辁啳埢婘惓痊硂铨湶犈筌絟腃葲搼楾瑔觠詮跧輇蜷銓権踡縓醛闎鳈鬈孉巏鰁權齤蠸颧顴犭犬汱甽畎烇绻綣虇劝券巻牶椦勧韏勸炔缺蒛瘸却卻埆崅悫雀硞确舃阕塙搉皵碏阙鹊愨榷墧慤毃確趞燩闋礐闕鵲礭夋囷峮逡輑宭帬裙羣群裠亽罖囕呥肰衻袇蚦袡蚺然髥嘫髯燃繎冄冉姌苒染珃媣蒅橪穣儴勷瀼獽蘘禳瓤穰躟鬤壌嚷壤攘爙纕让懹譲讓荛饶桡蕘橈襓饒犪扰娆隢嬈擾绕遶繞惹热熱人亻仁壬忈朲忎秂芢鈓魜銋鵀忍荏栠栣荵秹棯稔綛躵刃刄认仞仭讱任屻扨纫妊杒牣纴肕轫韧饪姙紉衽恁紝訒軔梕袵絍腍葚靭靱韌飪認餁扔仍辸礽芿陾日驲囸釰鈤馹戎肜栄狨绒茙茸荣容峵毧烿媶嵘絨羢嫆嵤搈搑摉榵溶蓉榕榮熔瑢穁蝾褣镕氄縙融螎駥髶嬫嶸爃鎔瀜曧蠑冗宂傇軵穃厹禸柔粈媃揉渘葇瑈腬糅蝚蹂輮鍒鞣瓇騥鰇鶔楺煣韖肉宍嶿邚如侞帤茹桇袽铷渪筎蒘銣蕠儒鴑嚅嬬孺濡薷鴽曘燸襦繻蠕颥醹顬鱬汝肗乳辱鄏入扖込杁洳嗕媷溽缛蓐鳰褥縟擩堧撋壖阮朊软耎偄軟媆愞瑌腝嫰碝緛蝡輭瓀礝桵甤緌蕤蕊蕋橤繠蘂蘃汭芮枘蚋锐瑞蜹睿銳鋭叡壡闰润閏閠潤橍挼捼叒若偌弱鄀婼渃焫楉嵶蒻箬篛爇鰙鰯鶸仨桬撒洒訯靸潵灑卅钑飒脎萨鈒摋隡馺颯薩櫒栍毢愢揌塞毸腮嘥噻鳃顋鰓嗮赛僿賽簺虄三弎叁毵毶厁毿犙鬖壭伞傘散糁糂馓橵糝糣糤繖鏒饊俕閐桒桑槡嗓搡磉褬颡鎟顙丧喪掻慅搔溞骚缫繅臊鳋颾騒騷鰠鱢扫掃嫂埽瘙氉矂髞色洓栜涩啬渋铯雭歮琗嗇瑟歰銫澁懎擌濇濏瘷穑澀璱瀒穡繬穯轖鏼譅飋裇聓森槮襂篸僧鬙閪縇杀沙纱乷刹砂唦挱殺猀粆紗莎铩痧硰蔱裟榝樧魦鲨閷鎩鯊鯋繺傻儍繌倽唼啥帹萐喢歃煞翜箑翣閯霎筛篩簁簛晒曬山彡邖圸删刪杉杣芟姍姗衫钐埏挻狦珊舢烻痁脠軕笘釤閊跚剼搧嘇幓煽蔪潸澘曑檆縿膻鯅羴羶闪陕炶陝閃晱煔睒熌覢讪汕疝苫剡扇訕赸傓善椫銏骟僐鄯墠墡缮嬗擅敾樿膳磰謆赡繕蟮蟺譱贍鐥饍騸鳝灗鱓鱔伤殇商愓觞傷墒慯滳漡蔏殤熵螪觴謪鬺裳垧扄晌赏賞鑜丄上仩尙尚恦绱緔弰捎梢烧莦焼焽稍旓筲艄蛸輎蕱燒颵髾鮹勺芍苕柖玿萔韶少劭卲邵绍哨娋袑紹綤潲奢猞赊畲輋賒賖檨舌佘虵蛇蛥舍捨厍设社舎厙射涉涻渉設赦弽慑摂摄滠慴摵蔎蠂韘騇懾攝灄麝欇申屾扟伸身侁呻妽籶绅罙诜姺柛氠珅穼籸娠峷甡眒砷堔深紳兟椮葠裑訷罧蓡詵甧蔘燊薓駪鲹鯓鵢鯵鰺神榊鉮鰰邥弞抌沈审矤哂矧宷谂谉婶渖訠審諗頣魫曋瞫嬸瀋覾讅肾侺昚甚胂涁眘渗祳脤腎愼慎椹瘆蜃滲鋠瘮升生阩呏声斘昇枡泩苼殅牲珄竔胜陞曻陹笙湦焺甥鉎聲鍟鼪鵿渑绳縄憴澠繩譝鱦省眚偗渻圣晟晠剰盛剩勝琞貹嵊聖墭榺蕂橳賸尸失师呞虱虲诗邿鸤屍施浉狮師絁釶湤湿葹溮溼獅蒒蓍詩鉇瑡酾鳲箷蝨鳾褷鲺濕鍦鯴鰤鶳襹籭釃十饣什石辻佦时竍识实実旹飠姼峕拾炻祏蚀食埘時莳寔湜遈塒嵵溡蒔鉐實榯蝕鉽篒鲥鮖鼫識鼭鰣史矢乨豕使始驶兘宩屎笶榁鉂駛士氏礻世丗仕市示卋式忕亊叓戺事侍势呩柹视试饰冟室恀恃拭是昰枾柿眂贳适栻烒眎眡舐轼逝铈笹視釈崼弑徥揓谥貰释勢嗜弒煶睗筮觢試軾鈰鉃飾舓褆誓適奭銴噬嬕澨諟諡遾餝檡螫謚簭籂襫釋鰘齛兙瓧収收手扌守垨首艏寿受狩兽售授涭绶痩膄壽瘦綬夀獣獸鏉书殳抒纾叔杸枢陎姝柕倏倐書殊紓掓梳淑焂菽軗鄃疎疏舒摅毹毺綀输瑹跾踈樞蔬輸橾鮛儵攄瀭鵨尗秫婌孰赎塾熟璹贖暏暑黍署鼠属鼡蜀潻薥薯曙癙藷襡糬襩籔蠴鱪鸀鱰朮术戍束沭述侸咰怷树竖荗恕庶庻絉蒁術尌裋数竪腧鉥墅漱潄數澍豎樹濖錰鏣鶐鶑虪刷唰耍誜衰摔甩帅帥蟀卛闩拴閂栓涮腨双滝霜雙孀骦孇騻欆礵鷞鹴艭驦鸘爽塽慡樉縔鏯灀谁脽誰氵水氺閖帨涗涚祱稅税裞睡吮楯顺舜順蕣橓瞚瞤瞬鬊说哾說説妁烁朔铄欶硕矟嗍搠蒴嗽槊碩獡箾鎙爍鑠厶纟丝司糹私咝泀俬思恖虒鸶媤斯絲缌蛳楒禗鉰飔凘厮榹禠罳蜤銯锶嘶噝廝撕澌磃緦蕬鋖燍螄鍶蟖蟴颸騦鐁鷥鼶死巳亖四罒寺汜伺似佀兕姒泤祀価孠泗饲驷俟娰枱柶牭梩洍涘肂飤笥耜釲竢覗嗣肆貄鈻飼禩駟蕼儩騃瀃螦乺忪松枀枩娀柗倯凇梥崧庺淞菘嵩硹蜙憽檧濍鬆怂悚捒耸竦傱愯嵷慫聳駷讼宋诵送颂訟頌誦餸鎹凁捜鄋嗖廀廋搜溲獀蒐蓃馊飕摗锼艘螋醙鎪餿颼騪叜叟傁嗾瞍擞薮擻藪櫢瘶苏甦酥稣窣穌鯂蘇蘓櫯囌俗玊夙诉泝肃洬涑珟素速宿梀殐粛骕傃粟訴谡嗉塐塑嫊愫溯溸肅遡鹔僳愬榡膆蔌觫趚遬憟樎樕潥碿鋉餗潚縤橚璛簌藗謖蹜驌鱐鷫狻痠酸匴祘笇筭蒜算夊芕虽倠哸浽荽荾眭葰滖睢熣濉鞖雖绥隋随遀綏隨瓍膸瀡髄髓亗岁砕祟粋谇埣嵗脺遂歲歳煫睟碎隧嬘澻穂誶賥檖燧璲禭穗穟繀襚邃旞繐繸鐆譢鐩孙狲荪孫飧搎猻蓀飱槂蕵薞畃损笋隼筍損榫箰簨鎨鶽巺潠唆娑莏傞挲桫梭睃嗦羧蓑摍缩趖簑簔縮髿鮻所唢索琐琑惢锁嗩暛溑瑣鎍鎖鎻鎼鏁逤溹蜶他它牠祂咜趿铊塌榙溻鉈褟蹹侤塔墖獭鮙鳎獺鰨挞狧闼崉涾搨遝遢阘榻毾禢撻澾誻踏嚃錔嚺濌蹋鞜闒鞳闥譶躢襨囼孡骀珆胎駘台旲邰坮抬苔炱炲菭跆鲐箈臺颱儓鮐嬯擡薹檯籉太冭夳忲汰态肽钛泰粏舦酞鈦溙態燤坍贪怹啴痑舑貪摊滩嘽潬瘫擹攤灘癱坛昙倓谈郯婒惔弾覃榃痰锬谭墰墵憛潭談醈壇曇橝錟檀顃罈藫壜譚貚醰譠罎鷤忐坦袒钽菼毯鉭嗿憳憻暺醓璮襢叹炭埮探傝湠赕僋嘆碳舕撢歎賧汤铴湯嘡劏羰蝪薚镗蹚鏜鐋鞺鼞饧坣唐堂傏啺棠鄌塘嵣搪溏蓎隚榶漟煻瑭禟膅樘磄糃膛橖篖糖螗踼糛螳赯醣餳鎕餹闛饄鶶帑倘偒淌傥耥躺镋鎲儻戃曭爣矘钂烫摥趟燙仐夲弢涛绦掏絛詜嫍幍慆搯滔槄瑫韬飸縚縧濤謟鞱韜饕匋迯咷洮逃桃陶啕梼淘绹萄祹裪綯蜪鞀醄鞉鋾錭駣檮饀騊鼗讨套討畓忑忒特貣脦犆铽慝鋱蟘膯鼟疼痋幐腾誊漛滕邆縢螣駦謄儯藤騰籐鰧籘虅驣霯唞朰剔梯锑踢銻鷈鷉厗绨偍珶啼媞崹惿提渧稊缇罤遆鹈嗁瑅綈碮徲漽緹蕛蝭题趧蹄醍謕蹏鍗鳀鴺題鮷鵜騠鯷鶗鶙体挮躰骵軆體戻屉剃洟倜悌涕逖屜悐惕掦逷惖揥替楴裼褅歒殢髰薙嚏鬀嚔瓋鬄籊鐟趯天兲婖添酟靔黇靝田屇沺恬畋畑盷胋畠甛甜菾湉塡填搷阗碵緂磌窴鴫璳闐鷆鷏忝殄倎唺悿捵淟晪琠腆觍痶睓舔餂覥賟錪靦掭瑱睼舚旫佻庣恌挑祧聎芀条岧岹迢祒條笤蓚蓨龆樤蜩鋚鞗髫鲦螩鯈鎥齠鰷宨晀朓脁窕誂窱嬥眺粜铫絩覜趒跳頫糶怗贴萜聑貼跕铁蛈鉄僣銕鴩鐡鐢鐵驖呫帖飻餮厅庁汀艼听町耓厛烃桯烴綎鞓聴聼廰聽廳邒廷亭庭莛停婷嵉渟筳葶蜓楟榳閮霆聤蝏諪鼮圢侹娗挺涏梃烶珽脡铤艇颋艈誔鋌頲濎乭囲炵通痌嗵蓪樋熥仝同佟彤峂庝哃狪茼晍桐浵烔砼蚒眮秱铜童粡絧衕赨酮鉖僮勭鉵銅餇鲖潼獞曈朣橦氃犝膧瞳穜鮦统捅桶筒統筩綂恸痛慟憅偷偸婾媮鍮亠头投骰緰頭妵紏敨殕斢黈蘣透凸禿秃怢突唋涋捸堗湥痜葖嶀鋵鵚鼵図图凃峹庩徒悇捈涂荼途屠梌揬稌塗嵞瘏筡腯蒤鈯圖圗廜潳跿酴馟鍎駼鵌鶟鷋鷵土圡吐汢钍釷兎迌兔莵堍菟鵵湍猯煓貒团団抟剬剸團塼慱摶槫漙篿檲鏄糰鷒鷻圕疃彖湪褖推蓷藬颓隤尵頹頺頽魋穨蘈蹪俀脮腿僓蹆骽退娧煺蛻蜕褪駾吞呑旽涒啍朜焞暾黗屯忳芚饨豘豚軘飩鲀魨霕臀臋氽畽坉乇讬托扡汑饦杔侂咃拕拖沰侻挩捝莌袥託涶脫脱飥馲魠驝驮佗陀陁坨岮沱狏迱驼柁砣砤袉鸵紽堶詑跎酡碢馱槖駄踻駝駞橐鮀鴕鼧騨鼍驒鼉彵妥毤庹媠椭楕嫷撱橢鵎鰖拓柝唾萚跅毻箨蘀籜屲劸哇娃徍挖洼娲畖窊啘媧嗗蛙搲溛漥窪鼃攨瓦佤邷咓瓲砙袜聉嗢腽膃襪韈韤歪喎竵崴外顡乛弯剜婠帵塆湾睕蜿潫豌彎壪灣丸刓汍纨芄完岏忨抏玩笂紈捖顽烷琓貦頑邜宛倇唍挽晚盌莞埦婉惋晩梚涴绾脘菀晼椀琬皖畹碗綩綰輓踠鋔鍐万卍卐妧杤捥腕萬翫鋄薍錽贃鎫贎尣尩尪尫汪亡亾兦王仼彺莣蚟网忹往徃枉罔惘菵暀棢焹蛧辋網蝄誷輞瀇魍妄忘迋旺盳望朢危威烓偎逶隇隈喴媁媙愄揋揻渨煀葨葳微椳楲溦煨詴縅蝛覣嶶薇燰鳂癐巍鰃鰄囗为韦圩围帏沩违闱峗峞洈為韋桅涠唯帷惟维喡圍嵬幃湋溈爲琟違潍維蓶鄬潙潿醀濰鍏闈鮠癓覹犩霺霻厃伟伪尾纬芛苇委炜玮洧娓捤浘荱诿偉偽崣梶痏硊萎隗骩嵔廆徫愇猥葦蒍骪骫暐椲煒瑋痿腲艉韪僞碨蜲蜼鲔寪緯蔿諉踓韑頠薳儰濻鍡鮪壝韙颹瀢韡亹斖卫未位味苿畏胃叞軎尉硙菋谓喂媦渭猬煟墛蔚慰熭犚磑緭蝟衛懀濊璏罻衞謂錗餧鮇螱褽餵魏藯轊鏏霨鳚蘶饖讆躗讏躛昷塭温榅殟溫瑥辒榲瘟豱輼轀鳁鎾饂鰛鰮文彣纹芠炆砇闻紋蚉蚊珳阌鈫雯瘒聞馼魰鳼鴍螡閺閿蟁闅鼤闦闧刎吻呚忟抆呡肳紊桽脗稳穏穩问妏汶莬問渂脕揾搵絻顐璺翁嗡鹟螉鎓鶲勜奣塕嵡滃蓊暡瞈聬瓮蕹甕罋齆挝倭涡莴唩涹渦猧萵喔窝窩蜗撾蝸踒我婐婑捰仴沃肟卧臥偓捾媉幄握渥焥硪楃腛斡瞃濣瓁臒龌齷乌圬弙汙汚污邬呜杇巫屋洿诬钨烏趶剭窏釫鄔嗚誈歍誣箼螐鴮鎢鰞无毋吳吴吾呉芜郚唔娪梧洖浯茣莁珸祦鹀無禑蜈蕪璑鵐鯃鼯鷡乄五午仵伍坞妩庑忤怃迕旿武玝侮俉倵捂啎娬牾珷塢摀熓碔鹉瑦舞嫵廡憮潕錻儛橆甒鵡躌兀勿务戊阢伆屼扤岉杌芴忢物矹敄误務悞悟悮粅逜晤焐焑婺嵍痦隖靰骛奦嵨溩雾寤熃誤鹜鋈窹霚鼿霧齀蘁騖鶩夕兮忚汐西覀吸希扸卥昔析矽穸肸肹俙徆怸诶郗饻唏奚娭屖屗息悕晞氥浠牺狶莃唽悉惜桸欷淅渓烯焁焈琋硒菥赥釸傒惁晰晳焟焬犀睎稀粞翕翖舾鄎厀嵠徯溪煕皙蒠锡僖榽熄熈熙緆蜥誒豨餏嘻噏嬆嬉瘜膝餙凞樨橀歙歚熹熺熻窸羲螅螇錫燨犠瞦礂蟋谿豀豯貕繥雟鯑鵗觹譆醯鏭隵巇曦爔犧酅觽鼷蠵鸂觿鑴习郋席習袭觋媳椺蒵蓆嶍漝覡趘槢蝷薂隰檄謵鎴霫鳛飁騱騽襲鰼驨杫枲洗玺徙铣喜徚葈葸鈢屣漇蓰銑憘憙暿橲歖禧諰壐縰謑蟢蹝璽鱚矖纚躧匸卌戏屃系饩呬忥怬细郄係咥恄盻郤欯绤細釳阋塈椞舄趇隙慀滊禊綌赩隟熂犔稧戯潝潟澙蕮覤戱黖戲磶虩餼鬩嚱闟霼衋呷疨虾谺傄閕敮煆颬瞎蝦鰕匣侠狎俠峡柙炠狭陜峽烚狹珨祫硖笚翈舺陿溊硤遐搳暇瑕筪碬舝辖磍縀蕸縖赮魻轄鍜霞鎋黠騢鶷閜丅下吓圷疜夏梺厦廈睱諕嚇懗罅夓鏬仙仚屳先奾纤佡忺氙杴祆秈苮枮籼珗莶掀铦跹酰锨僊僲嘕銛鲜暹韯嬐憸薟鍁鍂繊褼韱鮮馦蹮孅廯攕譣纎鶱襳躚纖鱻伭咞闲妶弦贤咸唌挦涎胘娴娹婱絃舷蚿衔啣湺痫蛝閑鹇嫌衘甉銜嫺嫻憪撏澖誸賢諴輱醎癇癎藖鹹礥贒鑦鷳鷴鷼冼狝显险崄毨烍猃蚬険赻筅尟尠搟禒蜆跣箲藔險嶮獫獮藓鍌燹顕幰攇櫶蘚玁韅顯灦县岘苋现线臽限姭宪県陥哯垷娊娨峴晛涀莧陷現硍馅睍絤缐羡献粯羨腺僩僴綫誢撊線鋧憲橌縣錎餡豏麲瀗臔獻糮鏾霰鼸乡芗相香郷厢啌鄉鄊廂湘缃葙鄕楿薌箱緗膷襄忀骧麘欀瓖镶鱜鑲驤瓨佭详庠栙祥絴翔詳跭享亯响蚃饷晑飨想銄餉鲞嚮蠁鮝鯗響饗饟鱶向姠巷项珦象缿萫項像勨嶑曏橡襐蟓鐌鱌灱灲呺枭侾削哓枵骁宯宵庨恷消绡虓逍鸮啋婋梟焇猇萧痚痟硝硣窙翛萷销揱綃嘐歊潇箫踃嘵憢撨獢銷霄彇膮蕭魈鴞穘簘藃蟂蟏謞鴵嚣瀟簫蟰髇嚻囂櫹髐鷍蠨驍毊虈洨郩崤淆訤誵小晓暁筱筿皛曉篠謏皢孝肖効咲恔俲哮效校涍笑啸傚敩滧詨嘋嘨誟嘯歗熽斅斆些楔歇蝎蠍劦协旪邪協胁垥奊峫恊拹挟挾脅脇脋衺偕斜谐猲絜翓嗋愶携瑎綊熁膎勰撷擕緳缬蝢鞋諧燲擷鞵襭鐷攜纈讗龤写冩寫藛伳灺泄泻祄绁缷卸洩炧炨卨娎屑屓偰徢械焎禼紲亵媟屟揳渫絏絬谢僁塮榍榭褉噧屧暬緤韰嶰廨懈澥獬糏薢薤邂燮褻謝夑瀉鞢瀣爕蟹蠏齘齥齂躠屭躞忄心邤妡忻芯辛昕杺欣盺俽莘惞訢鈊锌新歆廞鋅噷噺嬜薪馨鑫馫枔鬵鐔伈潃阠伩囟孞炘信軐脪衅訫焮馸舋顖釁兴狌星垶骍惺猩煋瑆腥蛵觪箵篂興謃鮏曐觲騂皨鯹刑行邢形陉侀郉哘型洐钘陘娙硎裄铏鈃鉶銒鋞睲醒擤杏姓幸性荇倖莕婞悻涬塂緈嬹臖凶兄兇匈芎讻忷汹哅恟洶胷胸訩詾雄熊诇詗夐敻休俢修咻庥烋烌羞脩脙鸺臹貅馐樇銝髤髹鎀鮴鵂饈鏅飍苬朽綇滫糔秀岫珛绣袖琇锈溴綉璓裦褎褏銹螑繍繡鏥鏽齅戌旴疞盱欨砉胥须訏顼虗虚谞媭幁揟欻虛須楈窢頊嘘稰需魆噓墟嬃歔縃蕦蝑歘諝譃魖驉鑐鬚俆徐蒣许呴姁诩冔栩珝偦許湑暊詡鄦糈醑盨旭伵序汿侐卹沀叙恤昫洫垿欰殈烅珬畜勖勗敍敘烼绪续酗喣壻婿朂溆絮訹嗅慉煦続蓄賉槒漵潊盢瞁緒聟銊獝稸緖藇瞲藚續鱮蓿吅轩昍咺宣晅軒梋谖喧塇媗愃愋揎萱萲暄煊瑄蓒睻儇禤箮翧蝖嬛蕿諠諼鍹駽矎翾藼蘐蠉譞鰚讂玄玹痃悬旋琁蜁嫙漩暶璇檈璿懸选烜暅選癣癬怰泫昡炫绚眩袨铉琄眴衒渲絢楥楦鉉碹蔙镟鞙颴縼繏鏇贙疶蒆靴薛辥鞾穴斈乴坹学岤峃茓泶袕鸴踅學嶨澩燢觷雤鷽雪樰膤艝轌鳕鱈血吷怴泧狘疦桖烕谑趐謔瀥坃勋埙焄勛塤熏窨蔒勲勳薫駨嚑壎獯薰曛燻臐矄蘍壦爋纁醺廵寻巡旬驯杊询峋恂洵浔紃荀栒桪毥珣偱尋循揗詢馴鄩鲟噚潯攳樳燂燅燖璕襑蟳鱏鱘灥卂训讯伨汛迅侚徇狥迿逊殉訊訓訙奞巽殾遜愻賐噀蕈顨鑂丫压呀庘押鸦桠鸭孲铔椏鴉錏鴨壓鵶鐚牙伢岈芽厓枒琊笌蚜堐崕崖涯猚瑘睚衙漄齖疋厊庌哑唖啞痖雅瘂蕥劜圠亚穵襾讶亜犽迓亞玡垭娅挜砑俹氩埡婭掗訝揠氬猰聐圔稏窫齾咽恹剦烟珚胭偣崦淹焉菸阉湮腌傿煙鄢嫣漹蔫嶖樮醃閹嬮篶懕臙黫讠円延闫严妍芫言訁岩昖沿炎郔姸娫狿研莚娮盐琂硏訮閆阎嵒嵓筵綖蜒塩揅楌詽碞蔅颜虤閻厳檐顏顔嚴壛巌簷櫩麙壧孍巖巗巚欕礹鹽麣夵抁沇乵兖奄俨兗匽弇衍偃厣掩眼萒郾酓嵃愝扊揜棪渰渷琰遃隒椼硽罨裺演褗戭蝘魇噞躽縯檿黡厴甗鰋鶠黤齞龑儼黬黭顩鼴巘曮魘鼹齴黶厌妟觃牪姲彥彦砚唁宴晏艳覎验偐掞焔谚隁喭堰敥焰焱猒硯葕雁椻滟鳫厭墕暥熖酽嬊谳餍鴈燄燕諺赝鬳曕鴳酀騐験嚥嬿艶贋軅爓醶騴鷃灔贗贘觾讌醼饜驗鷰艷灎釅驠灧讞豓豔灩央咉姎抰泱殃胦眏秧鸯鉠雵鞅鍈鴦扬羊阦阳旸杨炀佯劷氜疡钖飏垟徉昜洋羏烊珜眻陽崵崸揚蛘敭暘楊煬禓瘍諹輰鍚鴹颺鐊鰑霷鸉卬仰佒坱奍岟养炴氧痒紻傟楧軮慃氱羪養駚懩攁瀁癢礢怏柍恙样羕詇様漾樣幺夭吆妖枖祅訞喓葽楆腰鴁邀爻尧尭肴垚姚峣轺倄烑珧窑傜堯揺殽谣軺嗂媱徭愮搖摇猺遙遥摿暚榣瑤瑶銚飖餆嶢嶤徺磘窯窰餚繇謠謡鎐鳐颻蘨顤鰩仸宎岆抭杳殀狕苭咬柼眑窅窈舀偠婹崾溔蓔榚鴢闄騕齩鷕穾药要袎窔筄葯詏熎覞靿獟鹞薬鼼曜燿艞藥矅曣耀纅鷂讑鑰倻椰暍噎潱蠮爷耶捓揶铘爺釾鋣鎁擨也吔亪冶埜野嘢漜壄业叶曳页邺夜抴亱枼洂頁捙晔枽烨偞掖液谒堨殗腋葉鄓墷楪業馌僷曄曅歋燁擖擛皣瞱鄴靥嶪嶫澲謁餣嚈擫曗瞸鍱擪爗礏鎑饁鵺靨驜鸈膶岃一弌辷衤伊衣医吚壱依祎咿洢猗畩郼铱壹揖欹蛜禕嫛漪稦銥嬄噫夁瑿鹥繄檹毉醫黟譩鷖黳乁仪匜圯夷冝宐杝沂诒侇宜怡沶狋衪迤饴咦姨峓弬恞柂瓵荑贻迻宧巸扅栘桋眙胰袘酏痍移萓媐椬羠蛦詒貽遗暆椸誃跠頉颐飴疑儀熪遺嶬彛彜螔頤頥寲嶷簃顊鮧彝彞謻鏔籎觺讉鸃乙已以迆钇佁攺矣苡苢庡舣蚁釔倚扆笖逘偯崺旑椅鈘鉯鳦旖輢敼螘檥礒艤蟻顗轙齮乂义亿弋刈忆艺仡匇肊议阣亦伇屹异忔芅伿佚劮呓坄役抑曵杙耴苅译邑佾呭呹妷峄怈怿易枍泆炈秇绎诣驿俋奕帟帠弈枻浂玴疫羿衵轶唈垼悒挹栧栺欭浥浳益袣谊貤陭勚埶埸悘悥殹異羛翊翌萟訲訳豙豛逸釴隿幆敡晹棭殔湙焲蛡詍跇軼鈠骮亄兿意溢獈痬竩缢義肄裔裛詣勩嫕廙榏潩瘗膉蓺蜴靾駅億撎槸毅熠熤熼瘞誼镒鹝鹢黓劓圛墿嬑嬟嶧憶懌曀殪澺燚瘱瞖穓縊艗薏螠褹寱斁曎檍歝燡燱翳翼臆貖鮨癔藙藝贀鎰镱繶繹豷霬鯣鶂鶃鶍瀷蘙譯議醳醷饐囈鐿鷁鷊懿襼驛鷧虉鷾讛齸乚囙因阥阴侌垔姻洇茵荫音骃栶殷氤陰凐秵裀铟陻隂喑堙婣愔筃絪歅溵禋蒑蔭慇瘖銦磤緸鞇諲霒駰噾濦闉霠韾冘乑吟犾苂斦垠泿圁峾烎狺珢粌荶訔唫婬寅崟崯淫訡银鈝龂滛碒鄞夤蔩訚誾銀龈噖殥璌嚚檭蟫霪齗齦鷣廴尹引吲饮蚓隐淾釿鈏飲隠靷飮朄趛檃瘾隱嶾濥螾蘟櫽癮讔印茚洕胤垽湚猌廕酳慭癊憖憗鮣懚檼应応英偀桜珱莺啨婴媖愥渶绬朠煐瑛嫈碤锳嘤撄滎甇緓缨罂蝧賏樱璎噟罃褮霙鴬鹦嬰應膺韺甖鎣鹰鶧嚶孆孾攖瀴罌蘡櫻瓔礯譻鶯鑍纓蠳鷪軈鷹鸎鸚盁迎茔盈荥荧莹萤营萦蛍営溁溋萾僌塋楹滢蓥潆熒蝇瑩蝿嬴營縈螢濙濚濴藀覮謍赢巆攍攚瀛瀠瀯蠅櫿灐籝灜贏籯矨郢浧梬颍颕颖摬影潁瘿穎頴巊廮鐛癭映暎硬媵膡鞕瀅譍哟唷喲佣拥痈邕庸傭嗈鄘雍墉嫞慵滽槦牅銿噰壅擁澭郺镛臃癕雝鏞鳙廱灉饔鱅鷛癰喁颙顒鰫永甬咏怺泳俑勇勈栐埇悀柡涌恿傛惥愑湧硧詠塎嵱彮愹蛹慂踊禜鲬踴鯒用苚砽醟优忧攸呦怮泑幽悠麀滺憂優鄾嚘懮瀀櫌纋耰尢尤由沋犹邮怞油肬怣斿柚疣峳浟秞莜莤莸逌郵铀偤蚰訧逰游猶遊鱿楢猷鈾鲉輏駀蕕蝣魷輶鮋櫾邎友有丣卣苃酉羑庮羐莠梄聈脜铕湵蒏禉蜏銪槱牖牗黝又右幼佑侑孧狖糿哊囿姷宥峟牰祐诱迶唀梎蚴亴貁釉酭誘鼬扜纡迂迃穻陓紆虶唹淤盓渝瘀箊于亐予邘伃余妤扵杅欤玗玙於盂臾衧鱼俞兪禺竽舁茰荢娛娯娱狳谀酑馀渔萸釪隃隅雩魚堣堬崳嵎嵛愉揄楰湡畬畭硢腴逾骬愚楡榆歈牏瑜艅虞觎漁睮窬舆褕歶羭蕍蝓諛雓餘魣嬩懙澞覦踰歟璵螸輿鍝礖謣髃鮽旟籅騟鯲鰅鷠鸆与伛宇屿羽雨俁俣挧禹语圄峿祤偊匬圉庾敔鄅萭萮铻傴寙斞楀瑀瘐與語窳鋙龉噳嶼貐斔麌蘌齬玉驭吁圫聿芋芌妪忬饫育郁彧昱狱秗茟俼峪栯浴砡钰预喐域堉悆惐欲淢淯袬谕逳阈喅喩喻媀寓庽御棛棜棫焴琙矞裕遇飫馭鹆愈滪煜稢罭蒮蓣誉鈺預嫗嶎戫毓獄瘉緎蜟蜮輍銉隩噊慾稶蓹薁豫遹鋊鳿澦燏燠蕷諭錥閾鴥鴧鴪儥礇禦魊鹬癒礜穥篽繘醧鵒櫲饇蘛譽轝鐭霱欎驈鬻籞鱊鷸鸒欝軉鬰鬱灪籲爩囦鸢剈冤弲悁眢鸳寃渁渆渊渕惌淵葾棩蒬蜎鹓箢鳶蜵駌鋺鴛嬽鵷灁鼘鼝元贠邧员园沅杬垣爰貟原員圆笎蚖袁厡酛圎援湲猨缘鈨鼋園圓塬媴嫄源溒猿獂蒝榞榬辕緣縁蝝蝯魭圜橼羱薗螈謜轅黿鎱櫞邍騵鶢鶰厵远盶逺遠夗肙妴苑怨院垸衏傆媛掾瑗禐愿裫褑褤噮願曰曱约約箹矱彟彠月戉刖汋岄抈礿岳枂玥恱钥悅悦蚎蚏軏钺阅捳跀跃粤越鈅粵鉞閱閲嬳樾篗嶽龠籆瀹蘥黦爚禴躍籥鸑籰龥鸙蒀煴蒕熅奫蝹赟頵馧贇云勻匀伝呍囩妘抣沄纭芸昀畇眃秐郧涢紜耘耺鄖雲愪氲溳筼蒷氳熉澐蕓鋆橒篔縜繧允阭夽抎狁玧陨荺殒喗鈗隕殞褞馻磒霣齫齳孕运枟郓恽晕鄆酝傊惲愠缊運慍暈腪韫韵熨緼蕰蕴縕薀賱醖醞餫藴韗韞蘊韻帀匝沞咂拶沯桚紥紮鉔魳臜臢杂砸韴雑磼襍雜囐雥災灾甾哉栽烖菑渽溨睵賳宰载崽載再在扗洅傤酨儎縡兂糌簪簮鐕咱偺喒昝寁撍儧攒儹攢趱趲暂暫賛赞錾鄼濽蹔酂瓉贊鏨瓒酇囋灒讃瓚禶襸讚饡牂羘赃賍臧賘贓髒贜驵駔奘弉脏塟葬銺臓臟傮遭糟蹧醩凿鑿早枣栆蚤棗璅澡璪薻藻灶皁皂唕唣造梍喿慥煰艁噪簉燥竃譟趮躁竈啫伬则択沢择泎泽责迮則唶啧帻笮舴責溭矠嘖嫧幘箦蔶樍歵諎赜擇澤皟瞔簀耫礋襗謮賾蠌齚齰鸅仄夨庂汄昃昗捑崱稄贼賊鲗蠈鰂鱡怎谮譖譛囎曽曾増鄫增憎缯橧熷璔矰磳罾繒譄鱛锃鋥甑赠贈吒迊咋抯挓柤哳偧喳揸渣溠楂劄皶箚樝觰皻皼譇齄齇扎札甴轧軋闸蚻铡煠牐閘霅鍘譗厏苲眨砟搩鲊鲝踷鮓鮺乍灹诈咤奓柵栅炸宱痄蚱詐搾摣榨膪醡夈粂捚斋斎斏摘榸齋宅翟窄鉙债砦債寨瘵沾毡旃栴粘蛅飦惉詀趈詹閚谵噡嶦澶薝邅霑氈氊瞻鹯旜譫饘鳣驙魙鱣鸇讝拃斩飐展盏崭斬琖搌盞嶃嶄榐辗颭嫸醆橏蹍輾皽黵占佔战栈桟站偡绽菚棧湛戦綻嶘輚骣戰虥虦覱轏蘸驏张弡張章傽鄣嫜彰慞漳獐粻蔁遧暲樟璋餦蟑鏱騿鱆麞仉涨涱掌漲幥礃鞝鐣丈仗扙帐杖胀账粀帳脹痮障墇嶂幛賬瘬瘴瞕佋钊妱巶招昭炤盄釗啁鉊駋窼鍣爫找沼瑵召兆诏枛垗狣赵笊肁旐棹罀詔照罩箌肇肈趙曌燳鮡櫂瞾羄蜇嫬遮厇折歽矺砓籷虴哲埑粍袩啠悊晢晣辄喆棏蛰詟谪摺輒樀磔輙銸辙蟄嚞謫謺鮿轍讁襵讋者锗赭褶鍺这柘浙這淛嗻蔗樜鹧蟅鷓贞针侦浈珍珎貞帪栕桢眞真砧祯針偵敒桭酙寊湞葴遉搸斟楨獉甄禎蒖蓁鉁靕榛槇殝瑧碪禛潧箴樼澵臻薽錱轃鍖鍼籈鱵屒诊抮枕姫弫昣胗轸畛疹眕袗紾聄萙裖覙診軫嫃缜稹駗縝縥辴鬒黰圳阵纼侲挋陣鸩振朕栚紖眹赈塦揕絼蜄敶誫賑鋴镇震鴆鎭鎮黮凧争佂姃征怔爭峥挣炡狰烝眐钲埩崝崢掙猙睁聇铮媜揁筝徰睜蒸鉦徴箏徵踭篜錚鬇癥氶抍糽拯掟塣晸愸撜整正㊣证诤郑帧政症幀証鄭諍鴊證之支卮汁芝吱巵汥枝知织肢徔栀祗秓秖胑胝衹衼倁疷祬秪脂隻梔戠椥臸搘禔綕榰蜘馶鳷謢鴲織蘵鼅禵执侄坧直姪値值聀聁釞埴執职植殖禃絷跖瓡墌摭馽嬂慹漐踯樴膱縶職蟙蹠蹢軄躑夂止只凪劧旨阯址坁帋扺汦沚纸芷抧祉茋咫恉指枳洔砋轵淽疻紙訨趾軹黹酯藢襧阤至芖志忮扻豸制厔垁帙帜治炙质郅俧峙庢庤挃柣栉洷祑陟娡徏挚晊桎狾秩致袟贽轾乿偫徝掷梽猘畤痔秲秷窒紩翐袠觗貭铚鸷傂崻彘智滞痣蛭骘寘廌搱滍稙稚筫置跱輊锧雉墆槜滯潌疐瘈製覟誌銍幟憄摯潪熫稺膣觯質踬鋕旘瀄緻隲駤鴙儨劕懥擲擿櫛穉螲懫贄櫍瓆觶騭鯯礩豑騺驇躓鷙鑕豒中伀汷刣妐彸迚忠泈炂终柊盅衳钟舯衷終鈡幒蔠锺螤鴤螽鍾鼨蹱鐘籦肿种冢喠尰塚歱煄腫瘇種踵仲众妕狆祌祍茽衶重蚛偅眾堹媑筗衆諥州舟诌侜周洀洲炿诪烐珘辀郮婤徟淍矪週鸼喌粥赒輈銂賙輖霌駲嚋盩謅鵃騆譸妯轴軸碡肘帚疛菷晭睭箒鯞纣伷呪咒宙绉冑咮昼紂胄荮晝皱酎粙葤詋甃僽皺駎噣縐骤籀籕籒驟朱劯侏诛邾洙茱株㈱珠诸猪硃袾铢絑蛛誅跦槠潴蝫銖橥諸豬駯鮢鴸瀦藸櫧櫫鼄鯺蠩竹泏竺炢笁茿烛窋逐笜舳瘃蓫燭蠋躅鱁劚孎灟斸曯欘爥蠾钃丶主宔拄砫罜陼渚煑煮詝嘱濐麈瞩屬囑矚伫佇住助纻芧苎坾杼注苧贮迬驻壴柱柷殶炷祝疰眝祩竚莇秼紵紸羜著蛀嵀筑註貯跓軴铸筯鉒飳馵墸箸翥樦鋳駐築篫霔麆鑄抓檛膼簻髽爪拽跩专叀専砖專鄟嫥瑼甎膞颛磚諯蟤顓鱄转孨転竱轉灷啭堟蒃瑑僎赚撰篆馔縳襈賺譔饌囀籑妆庄妝庒荘娤桩莊湷粧装裝樁糚丬壮壯状狀壵梉焋幢撞戅隹追骓椎锥錐騅鵻沝坠笍娷缀惴甀缒畷硾膇墜綴赘縋諈醊錣餟礈贅轛鑆宒迍肫窀谆諄衠准埻凖準綧訰稕卓拙炪倬捉桌棁涿棳琸窧槕穛穱蠿圴彴犳灼叕妰茁斫浊丵浞烵诼酌啄啅娺梲着斮晫椓琢斱硺窡罬撯擆斲禚劅諁諑鋜濁篧擢斀斵濯櫡謶镯鐯鵫灂蠗鐲籗鷟籱仔孖孜茊兹咨姕姿茲栥玆紎赀资崰淄秶缁谘赼嗞孳嵫椔湽滋粢葘辎鄑孶禌觜貲資趑锱稵緇鈭镃龇輜鼒澬諮趦輺錙髭鲻鍿鎡頾頿鯔鶅齍鰦齜籽子吇姉姊杍矷秄胏呰秭耔虸笫梓釨啙紫滓訾訿榟橴字自芓茡倳剚恣牸渍眥眦胔胾漬唨宗倧综骔堫嵏嵕惾棕猣腙葼朡椶嵸稯綜緃熧緵翪艐蝬踨踪磫豵蹤騌鬃騣鬉鬷鯮鯼鑁总偬捴惣愡揔搃傯蓗摠総縂燪總鍯鏓纵昮疭倊猔碂粽糉瘲縦錝縱邹驺诹郰陬掫菆棷棸鄒箃緅諏鄹鲰鯫黀騶齺赱走鯐奏揍媰租菹葅蒩卆足卒哫崒崪族傶稡箤踤踿镞鏃诅阻组俎爼珇祖組詛靻鎺謯劗躜鑚躦鑽繤缵纂纉籫纘钻揝攥厜朘嗺樶蟕纗嶊嘴噿濢璻枠栬絊酔晬最祽罪辠酻蕞醉嶵檇鋷錊檌穝欈尊嶟遵樽繜罇鶎鐏鳟鱒鷷僔噂撙譐捘銌昨秨莋捽椊葃稓筰鈼左佐繓作坐阼岝岞怍侳柞祚胙唑座袏做葄蓙飵糳咗</pc>
+
+      </rules>
+    </collation>
+
+
   </charset>
 
   <charset name="latin1">
@@ -134,4 +309,791 @@
     <collation name="latin1_test" id="99" order="test"/>
   </charset>
 
+  <charset name="utf8">
+    <collation name="utf8_bengali_standard_ci" id="336">
+      <rules>
+        <reset>\u9FA</reset>
+        <p>\u9F8</p>
+        <p>\u9F9</p>
+        <p>\u9F2</p>
+        <p>\u9F3</p>
+        <p>\u985</p>
+        <p>\u986</p>
+        <p>\u987</p>
+        <p>\u988</p>
+        <p>\u989</p>
+        <p>\u98A</p>
+        <p>\u98B</p>
+        <p>\u9E0</p>
+        <p>\u98C</p>
+        <p>\u9E1</p>
+        <p>\u98F</p>
+        <p>\u990</p>
+        <p>\u993</p>
+        <p>\u994</p>
+        <p>\u9BC</p>
+        <p>\u982</p>
+        <p>\u983</p>
+        <p>\u981</p>
+        <p>\u995</p>
+        <p>\u996</p>
+        <p>\u997</p>
+        <p>\u998</p>
+        <p>\u999</p>
+        <p>\u99A</p>
+        <p>\u99B</p>
+        <p>\u99C</p>
+        <p>\u99D</p>
+        <p>\u99E</p>
+        <p>\u99F</p>
+        <p>\u9A0</p>
+        <p>\u9A1</p>
+        <p>\u9DC</p>
+        <i>\u9A1\u9BC</i>
+        <p>\u9A2</p>
+        <p>\u9DD</p>
+        <i>\u9A2\u9BC</i>
+        <p>\u9A3</p>
+        <p>\u9CE</p>
+        <p>\u9A4</p>
+        <p>\u9A5</p>
+        <p>\u9A6</p>
+        <p>\u9A7</p>
+        <p>\u9A8</p>
+        <p>\u9AA</p>
+        <p>\u9AB</p>
+        <p>\u9AC</p>
+        <p>\u9AD</p>
+        <p>\u9AE</p>
+        <p>\u9AF</p>
+        <p>\u9DF</p>
+        <i>\u9AF\u9BC</i>
+        <p>\u9B0</p>
+        <p>\u9F0</p>
+        <p>\u9B2</p>
+        <p>\u9F1</p>
+        <p>\u9B6</p>
+        <p>\u9B7</p>
+        <p>\u9B8</p>
+        <p>\u9B9</p>
+        <p>\u9BD</p>
+        <p>\u9BE</p>
+        <p>\u9BF</p>
+        <p>\u9C0</p>
+        <p>\u9C1</p>
+        <p>\u9C2</p>
+        <p>\u9C3</p>
+        <p>\u9C4</p>
+        <p>\u9E2</p>
+        <p>\u9E3</p>
+        <p>\u9C7</p>
+        <p>\u9C8</p>
+        <p>\u9CB</p>
+        <i>\u9C7\u9BE</i>
+        <p>\u9CC</p>
+        <i>\u9C7\u9D7</i>
+        <p>\u9CD</p>
+        <p>\u9D7</p>
+      </rules>
+    </collation>
+
+    <collation name="utf8_bengali_traditional_ci" id="337">
+      <rules>
+        <reset>\u994</reset>
+        <p>\u982</p>
+        <p>\u983</p>
+        <p>\u981</p>
+        <p>\u995\u9CD</p>
+        <p>\u996\u9CD</p>
+        <p>\u997\u9CD</p>
+        <p>\u998\u9CD</p>
+        <p>\u999\u9CD</p>
+        <p>\u99A\u9CD</p>
+        <p>\u99B\u9CD</p>
+        <p>\u99C\u9CD</p>
+        <p>\u99D\u9CD</p>
+        <p>\u99E\u9CD</p>
+        <p>\u99F\u9CD</p>
+        <p>\u9A0\u9CD</p>
+        <p>\u9A1\u9CD</p>
+        <p>\u9A2\u9CD</p>
+        <p>\u9A3\u9CD</p>
+        <p>\u9CE</p><i>\u9A4\u9CD\u200D</i><s>\u9A4\u9CD</s>
+        <p>\u9A5\u9CD</p>
+        <p>\u9A6\u9CD</p>
+        <p>\u9A7\u9CD</p>
+        <p>\u9A8\u9CD</p>
+        <p>\u9AA\u9CD</p>
+        <p>\u9AB\u9CD</p>
+        <p>\u9AC\u9CD</p>
+        <p>\u9AD\u9CD</p>
+        <p>\u9AE\u9CD</p>
+        <p>\u9AF\u9CD</p>
+        <p>\u9B0\u9CD</p>
+        <p>\u9F0\u9CD</p>
+        <p>\u9B2\u9CD</p>
+        <p>\u9F1\u9CD</p>
+        <p>\u9B6\u9CD</p>
+        <p>\u9B7\u9CD</p>
+        <p>\u9B8\u9CD</p>
+        <p>\u9B9\u9CD</p>
+
+        <reset>\u995\u9CD\u985</reset><i>\u995</i>
+        <reset>\u995\u9CD\u986</reset><i>\u995\u9BE</i>
+        <reset>\u995\u9CD\u987</reset><i>\u995\u9BF</i>
+        <reset>\u995\u9CD\u988</reset><i>\u995\u9C0</i>
+        <reset>\u995\u9CD\u989</reset><i>\u995\u9C1</i>
+        <reset>\u995\u9CD\u98A</reset><i>\u995\u9C2</i>
+        <reset>\u995\u9CD\u98B</reset><i>\u995\u9C3</i>
+        <reset>\u995\u9CD\u9E0</reset><i>\u995\u9C4</i>
+        <reset>\u995\u9CD\u98C</reset><i>\u995\u9E2</i>
+        <reset>\u995\u9CD\u9E1</reset><i>\u995\u9E3</i>
+        <reset>\u995\u9CD\u98F</reset><i>\u995\u9C7</i>
+        <reset>\u995\u9CD\u990</reset><i>\u995\u9C8</i>
+        <reset>\u995\u9CD\u993</reset><i>\u995\u9CB</i>
+        <reset>\u995\u9CD\u994</reset><i>\u995\u9CC</i>
+
+        <reset>\u996\u9CD\u985</reset><i>\u996</i>
+        <reset>\u996\u9CD\u986</reset><i>\u996\u9BE</i>
+        <reset>\u996\u9CD\u987</reset><i>\u996\u9BF</i>
+        <reset>\u996\u9CD\u988</reset><i>\u996\u9C0</i>
+        <reset>\u996\u9CD\u989</reset><i>\u996\u9C1</i>
+        <reset>\u996\u9CD\u98A</reset><i>\u996\u9C2</i>
+        <reset>\u996\u9CD\u98B</reset><i>\u996\u9C3</i>
+        <reset>\u996\u9CD\u9E0</reset><i>\u996\u9C4</i>
+        <reset>\u996\u9CD\u98C</reset><i>\u996\u9E2</i>
+        <reset>\u996\u9CD\u9E1</reset><i>\u996\u9E3</i>
+        <reset>\u996\u9CD\u98F</reset><i>\u996\u9C7</i>
+        <reset>\u996\u9CD\u990</reset><i>\u996\u9C8</i>
+        <reset>\u996\u9CD\u993</reset><i>\u996\u9CB</i>
+        <reset>\u996\u9CD\u994</reset><i>\u996\u9CC</i>
+
+        <reset>\u997\u9CD\u985</reset><i>\u997</i>
+        <reset>\u997\u9CD\u986</reset><i>\u997\u9BE</i>
+        <reset>\u997\u9CD\u987</reset><i>\u997\u9BF</i>
+        <reset>\u997\u9CD\u988</reset><i>\u997\u9C0</i>
+        <reset>\u997\u9CD\u989</reset><i>\u997\u9C1</i>
+        <reset>\u997\u9CD\u98A</reset><i>\u997\u9C2</i>
+        <reset>\u997\u9CD\u98B</reset><i>\u997\u9C3</i>
+        <reset>\u997\u9CD\u9E0</reset><i>\u997\u9C4</i>
+        <reset>\u997\u9CD\u98C</reset><i>\u997\u9E2</i>
+        <reset>\u997\u9CD\u9E1</reset><i>\u997\u9E3</i>
+        <reset>\u997\u9CD\u98F</reset><i>\u997\u9C7</i>
+        <reset>\u997\u9CD\u990</reset><i>\u997\u9C8</i>
+        <reset>\u997\u9CD\u993</reset><i>\u997\u9CB</i>
+        <reset>\u997\u9CD\u994</reset><i>\u997\u9CC</i>
+
+        <reset>\u998\u9CD\u985</reset><i>\u998</i>
+        <reset>\u998\u9CD\u986</reset><i>\u998\u9BE</i>
+        <reset>\u998\u9CD\u987</reset><i>\u998\u9BF</i>
+        <reset>\u998\u9CD\u988</reset><i>\u998\u9C0</i>
+        <reset>\u998\u9CD\u989</reset><i>\u998\u9C1</i>
+        <reset>\u998\u9CD\u98A</reset><i>\u998\u9C2</i>
+        <reset>\u998\u9CD\u98B</reset><i>\u998\u9C3</i>
+        <reset>\u998\u9CD\u9E0</reset><i>\u998\u9C4</i>
+        <reset>\u998\u9CD\u98C</reset><i>\u998\u9E2</i>
+        <reset>\u998\u9CD\u9E1</reset><i>\u998\u9E3</i>
+        <reset>\u998\u9CD\u98F</reset><i>\u998\u9C7</i>
+        <reset>\u998\u9CD\u990</reset><i>\u998\u9C8</i>
+        <reset>\u998\u9CD\u993</reset><i>\u998\u9CB</i>
+        <reset>\u998\u9CD\u994</reset><i>\u998\u9CC</i>
+
+        <reset>\u999\u9CD\u985</reset><i>\u999</i>
+        <reset>\u999\u9CD\u986</reset><i>\u999\u9BE</i>
+        <reset>\u999\u9CD\u987</reset><i>\u999\u9BF</i>
+        <reset>\u999\u9CD\u988</reset><i>\u999\u9C0</i>
+        <reset>\u999\u9CD\u989</reset><i>\u999\u9C1</i>
+        <reset>\u999\u9CD\u98A</reset><i>\u999\u9C2</i>
+        <reset>\u999\u9CD\u98B</reset><i>\u999\u9C3</i>
+        <reset>\u999\u9CD\u9E0</reset><i>\u999\u9C4</i>
+        <reset>\u999\u9CD\u98C</reset><i>\u999\u9E2</i>
+        <reset>\u999\u9CD\u9E1</reset><i>\u999\u9E3</i>
+        <reset>\u999\u9CD\u98F</reset><i>\u999\u9C7</i>
+        <reset>\u999\u9CD\u990</reset><i>\u999\u9C8</i>
+        <reset>\u999\u9CD\u993</reset><i>\u999\u9CB</i>
+        <reset>\u999\u9CD\u994</reset><i>\u999\u9CC</i>
+
+        <reset>\u99A\u9CD\u985</reset><i>\u99A</i>
+        <reset>\u99A\u9CD\u986</reset><i>\u99A\u9BE</i>
+        <reset>\u99A\u9CD\u987</reset><i>\u99A\u9BF</i>
+        <reset>\u99A\u9CD\u988</reset><i>\u99A\u9C0</i>
+        <reset>\u99A\u9CD\u989</reset><i>\u99A\u9C1</i>
+        <reset>\u99A\u9CD\u98A</reset><i>\u99A\u9C2</i>
+        <reset>\u99A\u9CD\u98B</reset><i>\u99A\u9C3</i>
+        <reset>\u99A\u9CD\u9E0</reset><i>\u99A\u9C4</i>
+        <reset>\u99A\u9CD\u98C</reset><i>\u99A\u9E2</i>
+        <reset>\u99A\u9CD\u9E1</reset><i>\u99A\u9E3</i>
+        <reset>\u99A\u9CD\u98F</reset><i>\u99A\u9C7</i>
+        <reset>\u99A\u9CD\u990</reset><i>\u99A\u9C8</i>
+        <reset>\u99A\u9CD\u993</reset><i>\u99A\u9CB</i>
+        <reset>\u99A\u9CD\u994</reset><i>\u99A\u9CC</i>
+
+        <reset>\u99B\u9CD\u985</reset><i>\u99B</i>
+        <reset>\u99B\u9CD\u986</reset><i>\u99B\u9BE</i>
+        <reset>\u99B\u9CD\u987</reset><i>\u99B\u9BF</i>
+        <reset>\u99B\u9CD\u988</reset><i>\u99B\u9C0</i>
+        <reset>\u99B\u9CD\u989</reset><i>\u99B\u9C1</i>
+        <reset>\u99B\u9CD\u98A</reset><i>\u99B\u9C2</i>
+        <reset>\u99B\u9CD\u98B</reset><i>\u99B\u9C3</i>
+        <reset>\u99B\u9CD\u9E0</reset><i>\u99B\u9C4</i>
+        <reset>\u99B\u9CD\u98C</reset><i>\u99B\u9E2</i>
+        <reset>\u99B\u9CD\u9E1</reset><i>\u99B\u9E3</i>
+        <reset>\u99B\u9CD\u98F</reset><i>\u99B\u9C7</i>
+        <reset>\u99B\u9CD\u990</reset><i>\u99B\u9C8</i>
+        <reset>\u99B\u9CD\u993</reset><i>\u99B\u9CB</i>
+        <reset>\u99B\u9CD\u994</reset><i>\u99B\u9CC</i>
+
+        <reset>\u99C\u9CD\u985</reset><i>\u99C</i>
+        <reset>\u99C\u9CD\u986</reset><i>\u99C\u9BE</i>
+        <reset>\u99C\u9CD\u987</reset><i>\u99C\u9BF</i>
+        <reset>\u99C\u9CD\u988</reset><i>\u99C\u9C0</i>
+        <reset>\u99C\u9CD\u989</reset><i>\u99C\u9C1</i>
+        <reset>\u99C\u9CD\u98A</reset><i>\u99C\u9C2</i>
+        <reset>\u99C\u9CD\u98B</reset><i>\u99C\u9C3</i>
+        <reset>\u99C\u9CD\u9E0</reset><i>\u99C\u9C4</i>
+        <reset>\u99C\u9CD\u98C</reset><i>\u99C\u9E2</i>
+        <reset>\u99C\u9CD\u9E1</reset><i>\u99C\u9E3</i>
+        <reset>\u99C\u9CD\u98F</reset><i>\u99C\u9C7</i>
+        <reset>\u99C\u9CD\u990</reset><i>\u99C\u9C8</i>
+        <reset>\u99C\u9CD\u993</reset><i>\u99C\u9CB</i>
+        <reset>\u99C\u9CD\u994</reset><i>\u99C\u9CC</i>
+
+        <reset>\u99D\u9CD\u985</reset><i>\u99D</i>
+        <reset>\u99D\u9CD\u986</reset><i>\u99D\u9BE</i>
+        <reset>\u99D\u9CD\u987</reset><i>\u99D\u9BF</i>
+        <reset>\u99D\u9CD\u988</reset><i>\u99D\u9C0</i>
+        <reset>\u99D\u9CD\u989</reset><i>\u99D\u9C1</i>
+        <reset>\u99D\u9CD\u98A</reset><i>\u99D\u9C2</i>
+        <reset>\u99D\u9CD\u98B</reset><i>\u99D\u9C3</i>
+        <reset>\u99D\u9CD\u9E0</reset><i>\u99D\u9C4</i>
+        <reset>\u99D\u9CD\u98C</reset><i>\u99D\u9E2</i>
+        <reset>\u99D\u9CD\u9E1</reset><i>\u99D\u9E3</i>
+        <reset>\u99D\u9CD\u98F</reset><i>\u99D\u9C7</i>
+        <reset>\u99D\u9CD\u990</reset><i>\u99D\u9C8</i>
+        <reset>\u99D\u9CD\u993</reset><i>\u99D\u9CB</i>
+        <reset>\u99D\u9CD\u994</reset><i>\u99D\u9CC</i>
+
+        <reset>\u99E\u9CD\u985</reset><i>\u99E</i>
+        <reset>\u99E\u9CD\u986</reset><i>\u99E\u9BE</i>
+        <reset>\u99E\u9CD\u987</reset><i>\u99E\u9BF</i>
+        <reset>\u99E\u9CD\u988</reset><i>\u99E\u9C0</i>
+        <reset>\u99E\u9CD\u989</reset><i>\u99E\u9C1</i>
+        <reset>\u99E\u9CD\u98A</reset><i>\u99E\u9C2</i>
+        <reset>\u99E\u9CD\u98B</reset><i>\u99E\u9C3</i>
+        <reset>\u99E\u9CD\u9E0</reset><i>\u99E\u9C4</i>
+        <reset>\u99E\u9CD\u98C</reset><i>\u99E\u9E2</i>
+        <reset>\u99E\u9CD\u9E1</reset><i>\u99E\u9E3</i>
+        <reset>\u99E\u9CD\u98F</reset><i>\u99E\u9C7</i>
+        <reset>\u99E\u9CD\u990</reset><i>\u99E\u9C8</i>
+        <reset>\u99E\u9CD\u993</reset><i>\u99E\u9CB</i>
+        <reset>\u99E\u9CD\u994</reset><i>\u99E\u9CC</i>
+
+        <reset>\u99F\u9CD\u985</reset><i>\u99F</i>
+        <reset>\u99F\u9CD\u986</reset><i>\u99F\u9BE</i>
+        <reset>\u99F\u9CD\u987</reset><i>\u99F\u9BF</i>
+        <reset>\u99F\u9CD\u988</reset><i>\u99F\u9C0</i>
+        <reset>\u99F\u9CD\u989</reset><i>\u99F\u9C1</i>
+        <reset>\u99F\u9CD\u98A</reset><i>\u99F\u9C2</i>
+        <reset>\u99F\u9CD\u98B</reset><i>\u99F\u9C3</i>
+        <reset>\u99F\u9CD\u9E0</reset><i>\u99F\u9C4</i>
+        <reset>\u99F\u9CD\u98C</reset><i>\u99F\u9E2</i>
+        <reset>\u99F\u9CD\u9E1</reset><i>\u99F\u9E3</i>
+        <reset>\u99F\u9CD\u98F</reset><i>\u99F\u9C7</i>
+        <reset>\u99F\u9CD\u990</reset><i>\u99F\u9C8</i>
+        <reset>\u99F\u9CD\u993</reset><i>\u99F\u9CB</i>
+        <reset>\u99F\u9CD\u994</reset><i>\u99F\u9CC</i>
+
+        <reset>\u9A0\u9CD\u985</reset><i>\u9A0</i>
+        <reset>\u9A0\u9CD\u986</reset><i>\u9A0\u9BE</i>
+        <reset>\u9A0\u9CD\u987</reset><i>\u9A0\u9BF</i>
+        <reset>\u9A0\u9CD\u988</reset><i>\u9A0\u9C0</i>
+        <reset>\u9A0\u9CD\u989</reset><i>\u9A0\u9C1</i>
+        <reset>\u9A0\u9CD\u98A</reset><i>\u9A0\u9C2</i>
+        <reset>\u9A0\u9CD\u98B</reset><i>\u9A0\u9C3</i>
+        <reset>\u9A0\u9CD\u9E0</reset><i>\u9A0\u9C4</i>
+        <reset>\u9A0\u9CD\u98C</reset><i>\u9A0\u9E2</i>
+        <reset>\u9A0\u9CD\u9E1</reset><i>\u9A0\u9E3</i>
+        <reset>\u9A0\u9CD\u98F</reset><i>\u9A0\u9C7</i>
+        <reset>\u9A0\u9CD\u990</reset><i>\u9A0\u9C8</i>
+        <reset>\u9A0\u9CD\u993</reset><i>\u9A0\u9CB</i>
+        <reset>\u9A0\u9CD\u994</reset><i>\u9A0\u9CC</i>
+
+        <reset>\u9A1\u9CD\u985</reset><i>\u9A1</i>
+        <reset>\u9A1\u9CD\u986</reset><i>\u9A1\u9BE</i>
+        <reset>\u9A1\u9CD\u987</reset><i>\u9A1\u9BF</i>
+        <reset>\u9A1\u9CD\u988</reset><i>\u9A1\u9C0</i>
+        <reset>\u9A1\u9CD\u989</reset><i>\u9A1\u9C1</i>
+        <reset>\u9A1\u9CD\u98A</reset><i>\u9A1\u9C2</i>
+        <reset>\u9A1\u9CD\u98B</reset><i>\u9A1\u9C3</i>
+        <reset>\u9A1\u9CD\u9E0</reset><i>\u9A1\u9C4</i>
+        <reset>\u9A1\u9CD\u98C</reset><i>\u9A1\u9E2</i>
+        <reset>\u9A1\u9CD\u9E1</reset><i>\u9A1\u9E3</i>
+        <reset>\u9A1\u9CD\u98F</reset><i>\u9A1\u9C7</i>
+        <reset>\u9A1\u9CD\u990</reset><i>\u9A1\u9C8</i>
+        <reset>\u9A1\u9CD\u993</reset><i>\u9A1\u9CB</i>
+        <reset>\u9A1\u9CD\u994</reset><i>\u9A1\u9CC</i>
+
+        <reset>\u9A2\u9CD\u985</reset><i>\u9A2</i>
+        <reset>\u9A2\u9CD\u986</reset><i>\u9A2\u9BE</i>
+        <reset>\u9A2\u9CD\u987</reset><i>\u9A2\u9BF</i>
+        <reset>\u9A2\u9CD\u988</reset><i>\u9A2\u9C0</i>
+        <reset>\u9A2\u9CD\u989</reset><i>\u9A2\u9C1</i>
+        <reset>\u9A2\u9CD\u98A</reset><i>\u9A2\u9C2</i>
+        <reset>\u9A2\u9CD\u98B</reset><i>\u9A2\u9C3</i>
+        <reset>\u9A2\u9CD\u9E0</reset><i>\u9A2\u9C4</i>
+        <reset>\u9A2\u9CD\u98C</reset><i>\u9A2\u9E2</i>
+        <reset>\u9A2\u9CD\u9E1</reset><i>\u9A2\u9E3</i>
+        <reset>\u9A2\u9CD\u98F</reset><i>\u9A2\u9C7</i>
+        <reset>\u9A2\u9CD\u990</reset><i>\u9A2\u9C8</i>
+        <reset>\u9A2\u9CD\u993</reset><i>\u9A2\u9CB</i>
+        <reset>\u9A2\u9CD\u994</reset><i>\u9A2\u9CC</i>
+
+        <reset>\u9A3\u9CD\u985</reset><i>\u9A3</i>
+        <reset>\u9A3\u9CD\u986</reset><i>\u9A3\u9BE</i>
+        <reset>\u9A3\u9CD\u987</reset><i>\u9A3\u9BF</i>
+        <reset>\u9A3\u9CD\u988</reset><i>\u9A3\u9C0</i>
+        <reset>\u9A3\u9CD\u989</reset><i>\u9A3\u9C1</i>
+        <reset>\u9A3\u9CD\u98A</reset><i>\u9A3\u9C2</i>
+        <reset>\u9A3\u9CD\u98B</reset><i>\u9A3\u9C3</i>
+        <reset>\u9A3\u9CD\u9E0</reset><i>\u9A3\u9C4</i>
+        <reset>\u9A3\u9CD\u98C</reset><i>\u9A3\u9E2</i>
+        <reset>\u9A3\u9CD\u9E1</reset><i>\u9A3\u9E3</i>
+        <reset>\u9A3\u9CD\u98F</reset><i>\u9A3\u9C7</i>
+        <reset>\u9A3\u9CD\u990</reset><i>\u9A3\u9C8</i>
+        <reset>\u9A3\u9CD\u993</reset><i>\u9A3\u9CB</i>
+        <reset>\u9A3\u9CD\u994</reset><i>\u9A3\u9CC</i>
+
+        <reset>\u9A4\u9CD\u985</reset><i>\u9A4</i>
+        <reset>\u9A4\u9CD\u986</reset><i>\u9A4\u9BE</i>
+        <reset>\u9A4\u9CD\u987</reset><i>\u9A4\u9BF</i>
+        <reset>\u9A4\u9CD\u988</reset><i>\u9A4\u9C0</i>
+        <reset>\u9A4\u9CD\u989</reset><i>\u9A4\u9C1</i>
+        <reset>\u9A4\u9CD\u98A</reset><i>\u9A4\u9C2</i>
+        <reset>\u9A4\u9CD\u98B</reset><i>\u9A4\u9C3</i>
+        <reset>\u9A4\u9CD\u9E0</reset><i>\u9A4\u9C4</i>
+        <reset>\u9A4\u9CD\u98C</reset><i>\u9A4\u9E2</i>
+        <reset>\u9A4\u9CD\u9E1</reset><i>\u9A4\u9E3</i>
+        <reset>\u9A4\u9CD\u98F</reset><i>\u9A4\u9C7</i>
+        <reset>\u9A4\u9CD\u990</reset><i>\u9A4\u9C8</i>
+        <reset>\u9A4\u9CD\u993</reset><i>\u9A4\u9CB</i>
+        <reset>\u9A4\u9CD\u994</reset><i>\u9A4\u9CC</i>
+
+        <reset>\u9A5\u9CD\u985</reset><i>\u9A5</i>
+        <reset>\u9A5\u9CD\u986</reset><i>\u9A5\u9BE</i>
+        <reset>\u9A5\u9CD\u987</reset><i>\u9A5\u9BF</i>
+        <reset>\u9A5\u9CD\u988</reset><i>\u9A5\u9C0</i>
+        <reset>\u9A5\u9CD\u989</reset><i>\u9A5\u9C1</i>
+        <reset>\u9A5\u9CD\u98A</reset><i>\u9A5\u9C2</i>
+        <reset>\u9A5\u9CD\u98B</reset><i>\u9A5\u9C3</i>
+        <reset>\u9A5\u9CD\u9E0</reset><i>\u9A5\u9C4</i>
+        <reset>\u9A5\u9CD\u98C</reset><i>\u9A5\u9E2</i>
+        <reset>\u9A5\u9CD\u9E1</reset><i>\u9A5\u9E3</i>
+        <reset>\u9A5\u9CD\u98F</reset><i>\u9A5\u9C7</i>
+        <reset>\u9A5\u9CD\u990</reset><i>\u9A5\u9C8</i>
+        <reset>\u9A5\u9CD\u993</reset><i>\u9A5\u9CB</i>
+        <reset>\u9A5\u9CD\u994</reset><i>\u9A5\u9CC</i>
+
+        <reset>\u9A6\u9CD\u985</reset><i>\u9A6</i>
+        <reset>\u9A6\u9CD\u986</reset><i>\u9A6\u9BE</i>
+        <reset>\u9A6\u9CD\u987</reset><i>\u9A6\u9BF</i>
+        <reset>\u9A6\u9CD\u988</reset><i>\u9A6\u9C0</i>
+        <reset>\u9A6\u9CD\u989</reset><i>\u9A6\u9C1</i>
+        <reset>\u9A6\u9CD\u98A</reset><i>\u9A6\u9C2</i>
+        <reset>\u9A6\u9CD\u98B</reset><i>\u9A6\u9C3</i>
+        <reset>\u9A6\u9CD\u9E0</reset><i>\u9A6\u9C4</i>
+        <reset>\u9A6\u9CD\u98C</reset><i>\u9A6\u9E2</i>
+        <reset>\u9A6\u9CD\u9E1</reset><i>\u9A6\u9E3</i>
+        <reset>\u9A6\u9CD\u98F</reset><i>\u9A6\u9C7</i>
+        <reset>\u9A6\u9CD\u990</reset><i>\u9A6\u9C8</i>
+        <reset>\u9A6\u9CD\u993</reset><i>\u9A6\u9CB</i>
+        <reset>\u9A6\u9CD\u994</reset><i>\u9A6\u9CC</i>
+
+        <reset>\u9A7\u9CD\u985</reset><i>\u9A7</i>
+        <reset>\u9A7\u9CD\u986</reset><i>\u9A7\u9BE</i>
+        <reset>\u9A7\u9CD\u987</reset><i>\u9A7\u9BF</i>
+        <reset>\u9A7\u9CD\u988</reset><i>\u9A7\u9C0</i>
+        <reset>\u9A7\u9CD\u989</reset><i>\u9A7\u9C1</i>
+        <reset>\u9A7\u9CD\u98A</reset><i>\u9A7\u9C2</i>
+        <reset>\u9A7\u9CD\u98B</reset><i>\u9A7\u9C3</i>
+        <reset>\u9A7\u9CD\u9E0</reset><i>\u9A7\u9C4</i>
+        <reset>\u9A7\u9CD\u98C</reset><i>\u9A7\u9E2</i>
+        <reset>\u9A7\u9CD\u9E1</reset><i>\u9A7\u9E3</i>
+        <reset>\u9A7\u9CD\u98F</reset><i>\u9A7\u9C7</i>
+        <reset>\u9A7\u9CD\u990</reset><i>\u9A7\u9C8</i>
+        <reset>\u9A7\u9CD\u993</reset><i>\u9A7\u9CB</i>
+        <reset>\u9A7\u9CD\u994</reset><i>\u9A7\u9CC</i>
+
+        <reset>\u9A8\u9CD\u985</reset><i>\u9A8</i>
+        <reset>\u9A8\u9CD\u986</reset><i>\u9A8\u9BE</i>
+        <reset>\u9A8\u9CD\u987</reset><i>\u9A8\u9BF</i>
+        <reset>\u9A8\u9CD\u988</reset><i>\u9A8\u9C0</i>
+        <reset>\u9A8\u9CD\u989</reset><i>\u9A8\u9C1</i>
+        <reset>\u9A8\u9CD\u98A</reset><i>\u9A8\u9C2</i>
+        <reset>\u9A8\u9CD\u98B</reset><i>\u9A8\u9C3</i>
+        <reset>\u9A8\u9CD\u9E0</reset><i>\u9A8\u9C4</i>
+        <reset>\u9A8\u9CD\u98C</reset><i>\u9A8\u9E2</i>
+        <reset>\u9A8\u9CD\u9E1</reset><i>\u9A8\u9E3</i>
+        <reset>\u9A8\u9CD\u98F</reset><i>\u9A8\u9C7</i>
+        <reset>\u9A8\u9CD\u990</reset><i>\u9A8\u9C8</i>
+        <reset>\u9A8\u9CD\u993</reset><i>\u9A8\u9CB</i>
+        <reset>\u9A8\u9CD\u994</reset><i>\u9A8\u9CC</i>
+
+        <reset>\u9AA\u9CD\u985</reset><i>\u9AA</i>
+        <reset>\u9AA\u9CD\u986</reset><i>\u9AA\u9BE</i>
+        <reset>\u9AA\u9CD\u987</reset><i>\u9AA\u9BF</i>
+        <reset>\u9AA\u9CD\u988</reset><i>\u9AA\u9C0</i>
+        <reset>\u9AA\u9CD\u989</reset><i>\u9AA\u9C1</i>
+        <reset>\u9AA\u9CD\u98A</reset><i>\u9AA\u9C2</i>
+        <reset>\u9AA\u9CD\u98B</reset><i>\u9AA\u9C3</i>
+        <reset>\u9AA\u9CD\u9E0</reset><i>\u9AA\u9C4</i>
+        <reset>\u9AA\u9CD\u98C</reset><i>\u9AA\u9E2</i>
+        <reset>\u9AA\u9CD\u9E1</reset><i>\u9AA\u9E3</i>
+        <reset>\u9AA\u9CD\u98F</reset><i>\u9AA\u9C7</i>
+        <reset>\u9AA\u9CD\u990</reset><i>\u9AA\u9C8</i>
+        <reset>\u9AA\u9CD\u993</reset><i>\u9AA\u9CB</i>
+        <reset>\u9AA\u9CD\u994</reset><i>\u9AA\u9CC</i>
+
+        <reset>\u9AB\u9CD\u985</reset><i>\u9AB</i>
+        <reset>\u9AB\u9CD\u986</reset><i>\u9AB\u9BE</i>
+        <reset>\u9AB\u9CD\u987</reset><i>\u9AB\u9BF</i>
+        <reset>\u9AB\u9CD\u988</reset><i>\u9AB\u9C0</i>
+        <reset>\u9AB\u9CD\u989</reset><i>\u9AB\u9C1</i>
+        <reset>\u9AB\u9CD\u98A</reset><i>\u9AB\u9C2</i>
+        <reset>\u9AB\u9CD\u98B</reset><i>\u9AB\u9C3</i>
+        <reset>\u9AB\u9CD\u9E0</reset><i>\u9AB\u9C4</i>
+        <reset>\u9AB\u9CD\u98C</reset><i>\u9AB\u9E2</i>
+        <reset>\u9AB\u9CD\u9E1</reset><i>\u9AB\u9E3</i>
+        <reset>\u9AB\u9CD\u98F</reset><i>\u9AB\u9C7</i>
+        <reset>\u9AB\u9CD\u990</reset><i>\u9AB\u9C8</i>
+        <reset>\u9AB\u9CD\u993</reset><i>\u9AB\u9CB</i>
+        <reset>\u9AB\u9CD\u994</reset><i>\u9AB\u9CC</i>
+
+        <reset>\u9AC\u9CD\u985</reset><i>\u9AC</i>
+        <reset>\u9AC\u9CD\u986</reset><i>\u9AC\u9BE</i>
+        <reset>\u9AC\u9CD\u987</reset><i>\u9AC\u9BF</i>
+        <reset>\u9AC\u9CD\u988</reset><i>\u9AC\u9C0</i>
+        <reset>\u9AC\u9CD\u989</reset><i>\u9AC\u9C1</i>
+        <reset>\u9AC\u9CD\u98A</reset><i>\u9AC\u9C2</i>
+        <reset>\u9AC\u9CD\u98B</reset><i>\u9AC\u9C3</i>
+        <reset>\u9AC\u9CD\u9E0</reset><i>\u9AC\u9C4</i>
+        <reset>\u9AC\u9CD\u98C</reset><i>\u9AC\u9E2</i>
+        <reset>\u9AC\u9CD\u9E1</reset><i>\u9AC\u9E3</i>
+        <reset>\u9AC\u9CD\u98F</reset><i>\u9AC\u9C7</i>
+        <reset>\u9AC\u9CD\u990</reset><i>\u9AC\u9C8</i>
+        <reset>\u9AC\u9CD\u993</reset><i>\u9AC\u9CB</i>
+        <reset>\u9AC\u9CD\u994</reset><i>\u9AC\u9CC</i>
+
+        <reset>\u9AD\u9CD\u985</reset><i>\u9AD</i>
+        <reset>\u9AD\u9CD\u986</reset><i>\u9AD\u9BE</i>
+        <reset>\u9AD\u9CD\u987</reset><i>\u9AD\u9BF</i>
+        <reset>\u9AD\u9CD\u988</reset><i>\u9AD\u9C0</i>
+        <reset>\u9AD\u9CD\u989</reset><i>\u9AD\u9C1</i>
+        <reset>\u9AD\u9CD\u98A</reset><i>\u9AD\u9C2</i>
+        <reset>\u9AD\u9CD\u98B</reset><i>\u9AD\u9C3</i>
+        <reset>\u9AD\u9CD\u9E0</reset><i>\u9AD\u9C4</i>
+        <reset>\u9AD\u9CD\u98C</reset><i>\u9AD\u9E2</i>
+        <reset>\u9AD\u9CD\u9E1</reset><i>\u9AD\u9E3</i>
+        <reset>\u9AD\u9CD\u98F</reset><i>\u9AD\u9C7</i>
+        <reset>\u9AD\u9CD\u990</reset><i>\u9AD\u9C8</i>
+        <reset>\u9AD\u9CD\u993</reset><i>\u9AD\u9CB</i>
+        <reset>\u9AD\u9CD\u994</reset><i>\u9AD\u9CC</i>
+
+        <reset>\u9AE\u9CD\u985</reset><i>\u9AE</i>
+        <reset>\u9AE\u9CD\u986</reset><i>\u9AE\u9BE</i>
+        <reset>\u9AE\u9CD\u987</reset><i>\u9AE\u9BF</i>
+        <reset>\u9AE\u9CD\u988</reset><i>\u9AE\u9C0</i>
+        <reset>\u9AE\u9CD\u989</reset><i>\u9AE\u9C1</i>
+        <reset>\u9AE\u9CD\u98A</reset><i>\u9AE\u9C2</i>
+        <reset>\u9AE\u9CD\u98B</reset><i>\u9AE\u9C3</i>
+        <reset>\u9AE\u9CD\u9E0</reset><i>\u9AE\u9C4</i>
+        <reset>\u9AE\u9CD\u98C</reset><i>\u9AE\u9E2</i>
+        <reset>\u9AE\u9CD\u9E1</reset><i>\u9AE\u9E3</i>
+        <reset>\u9AE\u9CD\u98F</reset><i>\u9AE\u9C7</i>
+        <reset>\u9AE\u9CD\u990</reset><i>\u9AE\u9C8</i>
+        <reset>\u9AE\u9CD\u993</reset><i>\u9AE\u9CB</i>
+        <reset>\u9AE\u9CD\u994</reset><i>\u9AE\u9CC</i>
+
+        <reset>\u9AF\u9CD\u985</reset><i>\u9AF</i>
+        <reset>\u9AF\u9CD\u986</reset><i>\u9AF\u9BE</i>
+        <reset>\u9AF\u9CD\u987</reset><i>\u9AF\u9BF</i>
+        <reset>\u9AF\u9CD\u988</reset><i>\u9AF\u9C0</i>
+        <reset>\u9AF\u9CD\u989</reset><i>\u9AF\u9C1</i>
+        <reset>\u9AF\u9CD\u98A</reset><i>\u9AF\u9C2</i>
+        <reset>\u9AF\u9CD\u98B</reset><i>\u9AF\u9C3</i>
+        <reset>\u9AF\u9CD\u9E0</reset><i>\u9AF\u9C4</i>
+        <reset>\u9AF\u9CD\u98C</reset><i>\u9AF\u9E2</i>
+        <reset>\u9AF\u9CD\u9E1</reset><i>\u9AF\u9E3</i>
+        <reset>\u9AF\u9CD\u98F</reset><i>\u9AF\u9C7</i>
+        <reset>\u9AF\u9CD\u990</reset><i>\u9AF\u9C8</i>
+        <reset>\u9AF\u9CD\u993</reset><i>\u9AF\u9CB</i>
+        <reset>\u9AF\u9CD\u994</reset><i>\u9AF\u9CC</i>
+
+        <reset>\u9B0\u9CD\u985</reset><i>\u9B0</i>
+        <reset>\u9B0\u9CD\u986</reset><i>\u9B0\u9BE</i>
+        <reset>\u9B0\u9CD\u987</reset><i>\u9B0\u9BF</i>
+        <reset>\u9B0\u9CD\u988</reset><i>\u9B0\u9C0</i>
+        <reset>\u9B0\u9CD\u989</reset><i>\u9B0\u9C1</i>
+        <reset>\u9B0\u9CD\u98A</reset><i>\u9B0\u9C2</i>
+        <reset>\u9B0\u9CD\u98B</reset><i>\u9B0\u9C3</i>
+        <reset>\u9B0\u9CD\u9E0</reset><i>\u9B0\u9C4</i>
+        <reset>\u9B0\u9CD\u98C</reset><i>\u9B0\u9E2</i>
+        <reset>\u9B0\u9CD\u9E1</reset><i>\u9B0\u9E3</i>
+        <reset>\u9B0\u9CD\u98F</reset><i>\u9B0\u9C7</i>
+        <reset>\u9B0\u9CD\u990</reset><i>\u9B0\u9C8</i>
+        <reset>\u9B0\u9CD\u993</reset><i>\u9B0\u9CB</i>
+        <reset>\u9B0\u9CD\u994</reset><i>\u9B0\u9CC</i>
+
+        <reset>\u9F0\u9CD\u985</reset><i>\u9F0</i>
+        <reset>\u9F0\u9CD\u986</reset><i>\u9F0\u9BE</i>
+        <reset>\u9F0\u9CD\u987</reset><i>\u9F0\u9BF</i>
+        <reset>\u9F0\u9CD\u988</reset><i>\u9F0\u9C0</i>
+        <reset>\u9F0\u9CD\u989</reset><i>\u9F0\u9C1</i>
+        <reset>\u9F0\u9CD\u98A</reset><i>\u9F0\u9C2</i>
+        <reset>\u9F0\u9CD\u98B</reset><i>\u9F0\u9C3</i>
+        <reset>\u9F0\u9CD\u9E0</reset><i>\u9F0\u9C4</i>
+        <reset>\u9F0\u9CD\u98C</reset><i>\u9F0\u9E2</i>
+        <reset>\u9F0\u9CD\u9E1</reset><i>\u9F0\u9E3</i>
+        <reset>\u9F0\u9CD\u98F</reset><i>\u9F0\u9C7</i>
+        <reset>\u9F0\u9CD\u990</reset><i>\u9F0\u9C8</i>
+        <reset>\u9F0\u9CD\u993</reset><i>\u9F0\u9CB</i>
+        <reset>\u9F0\u9CD\u994</reset><i>\u9F0\u9CC</i>
+
+        <reset>\u9B2\u9CD\u985</reset><i>\u9B2</i>
+        <reset>\u9B2\u9CD\u986</reset><i>\u9B2\u9BE</i>
+        <reset>\u9B2\u9CD\u987</reset><i>\u9B2\u9BF</i>
+        <reset>\u9B2\u9CD\u988</reset><i>\u9B2\u9C0</i>
+        <reset>\u9B2\u9CD\u989</reset><i>\u9B2\u9C1</i>
+        <reset>\u9B2\u9CD\u98A</reset><i>\u9B2\u9C2</i>
+        <reset>\u9B2\u9CD\u98B</reset><i>\u9B2\u9C3</i>
+        <reset>\u9B2\u9CD\u9E0</reset><i>\u9B2\u9C4</i>
+        <reset>\u9B2\u9CD\u98C</reset><i>\u9B2\u9E2</i>
+        <reset>\u9B2\u9CD\u9E1</reset><i>\u9B2\u9E3</i>
+        <reset>\u9B2\u9CD\u98F</reset><i>\u9B2\u9C7</i>
+        <reset>\u9B2\u9CD\u990</reset><i>\u9B2\u9C8</i>
+        <reset>\u9B2\u9CD\u993</reset><i>\u9B2\u9CB</i>
+        <reset>\u9B2\u9CD\u994</reset><i>\u9B2\u9CC</i>
+
+        <reset>\u9F1\u9CD\u985</reset><i>\u9F1</i>
+        <reset>\u9F1\u9CD\u986</reset><i>\u9F1\u9BE</i>
+        <reset>\u9F1\u9CD\u987</reset><i>\u9F1\u9BF</i>
+        <reset>\u9F1\u9CD\u988</reset><i>\u9F1\u9C0</i>
+        <reset>\u9F1\u9CD\u989</reset><i>\u9F1\u9C1</i>
+        <reset>\u9F1\u9CD\u98A</reset><i>\u9F1\u9C2</i>
+        <reset>\u9F1\u9CD\u98B</reset><i>\u9F1\u9C3</i>
+        <reset>\u9F1\u9CD\u9E0</reset><i>\u9F1\u9C4</i>
+        <reset>\u9F1\u9CD\u98C</reset><i>\u9F1\u9E2</i>
+        <reset>\u9F1\u9CD\u9E1</reset><i>\u9F1\u9E3</i>
+        <reset>\u9F1\u9CD\u98F</reset><i>\u9F1\u9C7</i>
+        <reset>\u9F1\u9CD\u990</reset><i>\u9F1\u9C8</i>
+        <reset>\u9F1\u9CD\u993</reset><i>\u9F1\u9CB</i>
+        <reset>\u9F1\u9CD\u994</reset><i>\u9F1\u9CC</i>
+
+        <reset>\u9B6\u9CD\u985</reset><i>\u9B6</i>
+        <reset>\u9B6\u9CD\u986</reset><i>\u9B6\u9BE</i>
+        <reset>\u9B6\u9CD\u987</reset><i>\u9B6\u9BF</i>
+        <reset>\u9B6\u9CD\u988</reset><i>\u9B6\u9C0</i>
+        <reset>\u9B6\u9CD\u989</reset><i>\u9B6\u9C1</i>
+        <reset>\u9B6\u9CD\u98A</reset><i>\u9B6\u9C2</i>
+        <reset>\u9B6\u9CD\u98B</reset><i>\u9B6\u9C3</i>
+        <reset>\u9B6\u9CD\u9E0</reset><i>\u9B6\u9C4</i>
+        <reset>\u9B6\u9CD\u98C</reset><i>\u9B6\u9E2</i>
+        <reset>\u9B6\u9CD\u9E1</reset><i>\u9B6\u9E3</i>
+        <reset>\u9B6\u9CD\u98F</reset><i>\u9B6\u9C7</i>
+        <reset>\u9B6\u9CD\u990</reset><i>\u9B6\u9C8</i>
+        <reset>\u9B6\u9CD\u993</reset><i>\u9B6\u9CB</i>
+        <reset>\u9B6\u9CD\u994</reset><i>\u9B6\u9CC</i>
+
+        <reset>\u9B7\u9CD\u985</reset><i>\u9B7</i>
+        <reset>\u9B7\u9CD\u986</reset><i>\u9B7\u9BE</i>
+        <reset>\u9B7\u9CD\u987</reset><i>\u9B7\u9BF</i>
+        <reset>\u9B7\u9CD\u988</reset><i>\u9B7\u9C0</i>
+        <reset>\u9B7\u9CD\u989</reset><i>\u9B7\u9C1</i>
+        <reset>\u9B7\u9CD\u98A</reset><i>\u9B7\u9C2</i>
+        <reset>\u9B7\u9CD\u98B</reset><i>\u9B7\u9C3</i>
+        <reset>\u9B7\u9CD\u9E0</reset><i>\u9B7\u9C4</i>
+        <reset>\u9B7\u9CD\u98C</reset><i>\u9B7\u9E2</i>
+        <reset>\u9B7\u9CD\u9E1</reset><i>\u9B7\u9E3</i>
+        <reset>\u9B7\u9CD\u98F</reset><i>\u9B7\u9C7</i>
+        <reset>\u9B7\u9CD\u990</reset><i>\u9B7\u9C8</i>
+        <reset>\u9B7\u9CD\u993</reset><i>\u9B7\u9CB</i>
+        <reset>\u9B7\u9CD\u994</reset><i>\u9B7\u9CC</i>
+
+        <reset>\u9B8\u9CD\u985</reset><i>\u9B8</i>
+        <reset>\u9B8\u9CD\u986</reset><i>\u9B8\u9BE</i>
+        <reset>\u9B8\u9CD\u987</reset><i>\u9B8\u9BF</i>
+        <reset>\u9B8\u9CD\u988</reset><i>\u9B8\u9C0</i>
+        <reset>\u9B8\u9CD\u989</reset><i>\u9B8\u9C1</i>
+        <reset>\u9B8\u9CD\u98A</reset><i>\u9B8\u9C2</i>
+        <reset>\u9B8\u9CD\u98B</reset><i>\u9B8\u9C3</i>
+        <reset>\u9B8\u9CD\u9E0</reset><i>\u9B8\u9C4</i>
+        <reset>\u9B8\u9CD\u98C</reset><i>\u9B8\u9E2</i>
+        <reset>\u9B8\u9CD\u9E1</reset><i>\u9B8\u9E3</i>
+        <reset>\u9B8\u9CD\u98F</reset><i>\u9B8\u9C7</i>
+        <reset>\u9B8\u9CD\u990</reset><i>\u9B8\u9C8</i>
+        <reset>\u9B8\u9CD\u993</reset><i>\u9B8\u9CB</i>
+        <reset>\u9B8\u9CD\u994</reset><i>\u9B8\u9CC</i>
+
+        <reset>\u9B9\u9CD\u985</reset><i>\u9B9</i>
+        <reset>\u9B9\u9CD\u986</reset><i>\u9B9\u9BE</i>
+        <reset>\u9B9\u9CD\u987</reset><i>\u9B9\u9BF</i>
+        <reset>\u9B9\u9CD\u988</reset><i>\u9B9\u9C0</i>
+        <reset>\u9B9\u9CD\u989</reset><i>\u9B9\u9C1</i>
+        <reset>\u9B9\u9CD\u98A</reset><i>\u9B9\u9C2</i>
+        <reset>\u9B9\u9CD\u98B</reset><i>\u9B9\u9C3</i>
+        <reset>\u9B9\u9CD\u9E0</reset><i>\u9B9\u9C4</i>
+        <reset>\u9B9\u9CD\u98C</reset><i>\u9B9\u9E2</i>
+        <reset>\u9B9\u9CD\u9E1</reset><i>\u9B9\u9E3</i>
+        <reset>\u9B9\u9CD\u98F</reset><i>\u9B9\u9C7</i>
+        <reset>\u9B9\u9CD\u990</reset><i>\u9B9\u9C8</i>
+        <reset>\u9B9\u9CD\u993</reset><i>\u9B9\u9CB</i>
+        <reset>\u9B9\u9CD\u994</reset><i>\u9B9\u9CC</i>
+
+        <reset>\u995</reset><t>\u995\u9BC</t>
+        <reset>\u995\u9BE</reset><t>\u995\u9BC\u9BE</t>
+        <reset>\u995\u9BF</reset><t>\u995\u9BC\u9BF</t>
+        <reset>\u995\u9C0</reset><t>\u995\u9BC\u9C0</t>
+        <reset>\u995\u9C1</reset><t>\u995\u9BC\u9C1</t>
+        <reset>\u995\u9C2</reset><t>\u995\u9BC\u9C2</t>
+        <reset>\u995\u9C3</reset><t>\u995\u9BC\u9C3</t>
+        <reset>\u995\u9C4</reset><t>\u995\u9BC\u9C4</t>
+        <reset>\u995\u9E2</reset><t>\u995\u9BC\u9E2</t>
+        <reset>\u995\u9E3</reset><t>\u995\u9BC\u9E3</t>
+        <reset>\u995\u9C7</reset><t>\u995\u9BC\u9C7</t>
+        <reset>\u995\u9C8</reset><t>\u995\u9BC\u9C8</t>
+        <reset>\u995\u9CB</reset><t>\u995\u9BC\u9CB</t>
+        <reset>\u995\u9CC</reset><t>\u995\u9BC\u9CC</t>
+        <reset>\u995\u9CD</reset><t>\u995\u9BC\u9CD</t>
+
+        <reset>\u996</reset><t>\u996\u9BC</t>
+        <reset>\u996\u9BE</reset><t>\u996\u9BC\u9BE</t>
+        <reset>\u996\u9BF</reset><t>\u996\u9BC\u9BF</t>
+        <reset>\u996\u9C0</reset><t>\u996\u9BC\u9C0</t>
+        <reset>\u996\u9C1</reset><t>\u996\u9BC\u9C1</t>
+        <reset>\u996\u9C2</reset><t>\u996\u9BC\u9C2</t>
+        <reset>\u996\u9C3</reset><t>\u996\u9BC\u9C3</t>
+        <reset>\u996\u9C4</reset><t>\u996\u9BC\u9C4</t>
+        <reset>\u996\u9E2</reset><t>\u996\u9BC\u9E2</t>
+        <reset>\u996\u9E3</reset><t>\u996\u9BC\u9E3</t>
+        <reset>\u996\u9C7</reset><t>\u996\u9BC\u9C7</t>
+        <reset>\u996\u9C8</reset><t>\u996\u9BC\u9C8</t>
+        <reset>\u996\u9CB</reset><t>\u996\u9BC\u9CB</t>
+        <reset>\u996\u9CC</reset><t>\u996\u9BC\u9CC</t>
+        <reset>\u996\u9CD</reset><t>\u996\u9BC\u9CD</t>
+
+        <reset>\u997</reset><t>\u997\u9BC</t>
+        <reset>\u997\u9BE</reset><t>\u997\u9BC\u9BE</t>
+        <reset>\u997\u9BF</reset><t>\u997\u9BC\u9BF</t>
+        <reset>\u997\u9C0</reset><t>\u997\u9BC\u9C0</t>
+        <reset>\u997\u9C1</reset><t>\u997\u9BC\u9C1</t>
+        <reset>\u997\u9C2</reset><t>\u997\u9BC\u9C2</t>
+        <reset>\u997\u9C3</reset><t>\u997\u9BC\u9C3</t>
+        <reset>\u997\u9C4</reset><t>\u997\u9BC\u9C4</t>
+        <reset>\u997\u9E2</reset><t>\u997\u9BC\u9E2</t>
+        <reset>\u997\u9E3</reset><t>\u997\u9BC\u9E3</t>
+        <reset>\u997\u9C7</reset><t>\u997\u9BC\u9C7</t>
+        <reset>\u997\u9C8</reset><t>\u997\u9BC\u9C8</t>
+        <reset>\u997\u9CB</reset><t>\u997\u9BC\u9CB</t>
+        <reset>\u997\u9CC</reset><t>\u997\u9BC\u9CC</t>
+        <reset>\u997\u9CD</reset><t>\u997\u9BC\u9CD</t>
+
+        <reset>\u99C</reset><t>\u99C\u9BC</t>
+        <reset>\u99C\u9BE</reset><t>\u99C\u9BC\u9BE</t>
+        <reset>\u99C\u9BF</reset><t>\u99C\u9BC\u9BF</t>
+        <reset>\u99C\u9C0</reset><t>\u99C\u9BC\u9C0</t>
+        <reset>\u99C\u9C1</reset><t>\u99C\u9BC\u9C1</t>
+        <reset>\u99C\u9C2</reset><t>\u99C\u9BC\u9C2</t>
+        <reset>\u99C\u9C3</reset><t>\u99C\u9BC\u9C3</t>
+        <reset>\u99C\u9C4</reset><t>\u99C\u9BC\u9C4</t>
+        <reset>\u99C\u9E2</reset><t>\u99C\u9BC\u9E2</t>
+        <reset>\u99C\u9E3</reset><t>\u99C\u9BC\u9E3</t>
+        <reset>\u99C\u9C7</reset><t>\u99C\u9BC\u9C7</t>
+        <reset>\u99C\u9C8</reset><t>\u99C\u9BC\u9C8</t>
+        <reset>\u99C\u9CB</reset><t>\u99C\u9BC\u9CB</t>
+        <reset>\u99C\u9CC</reset><t>\u99C\u9BC\u9CC</t>
+        <reset>\u99C\u9CD</reset><t>\u99C\u9BC\u9CD</t>
+
+        <reset>\u9A1</reset><t>\u9A1\u9BC</t>
+        <reset>\u9A1\u9BE</reset><t>\u9A1\u9BC\u9BE</t>
+        <reset>\u9A1\u9BF</reset><t>\u9A1\u9BC\u9BF</t>
+        <reset>\u9A1\u9C0</reset><t>\u9A1\u9BC\u9C0</t>
+        <reset>\u9A1\u9C1</reset><t>\u9A1\u9BC\u9C1</t>
+        <reset>\u9A1\u9C2</reset><t>\u9A1\u9BC\u9C2</t>
+        <reset>\u9A1\u9C3</reset><t>\u9A1\u9BC\u9C3</t>
+        <reset>\u9A1\u9C4</reset><t>\u9A1\u9BC\u9C4</t>
+        <reset>\u9A1\u9E2</reset><t>\u9A1\u9BC\u9E2</t>
+        <reset>\u9A1\u9E3</reset><t>\u9A1\u9BC\u9E3</t>
+        <reset>\u9A1\u9C7</reset><t>\u9A1\u9BC\u9C7</t>
+        <reset>\u9A1\u9C8</reset><t>\u9A1\u9BC\u9C8</t>
+        <reset>\u9A1\u9CB</reset><t>\u9A1\u9BC\u9CB</t>
+        <reset>\u9A1\u9CC</reset><t>\u9A1\u9BC\u9CC</t>
+        <reset>\u9A1\u9CD</reset><t>\u9A1\u9BC\u9CD</t>
+
+        <reset>\u9A2</reset><t>\u9A2\u9BC</t>
+        <reset>\u9A2\u9BE</reset><t>\u9A2\u9BC\u9BE</t>
+        <reset>\u9A2\u9BF</reset><t>\u9A2\u9BC\u9BF</t>
+        <reset>\u9A2\u9C0</reset><t>\u9A2\u9BC\u9C0</t>
+        <reset>\u9A2\u9C1</reset><t>\u9A2\u9BC\u9C1</t>
+        <reset>\u9A2\u9C2</reset><t>\u9A2\u9BC\u9C2</t>
+        <reset>\u9A2\u9C3</reset><t>\u9A2\u9BC\u9C3</t>
+        <reset>\u9A2\u9C4</reset><t>\u9A2\u9BC\u9C4</t>
+        <reset>\u9A2\u9E2</reset><t>\u9A2\u9BC\u9E2</t>
+        <reset>\u9A2\u9E3</reset><t>\u9A2\u9BC\u9E3</t>
+        <reset>\u9A2\u9C7</reset><t>\u9A2\u9BC\u9C7</t>
+        <reset>\u9A2\u9C8</reset><t>\u9A2\u9BC\u9C8</t>
+        <reset>\u9A2\u9CB</reset><t>\u9A2\u9BC\u9CB</t>
+        <reset>\u9A2\u9CC</reset><t>\u9A2\u9BC\u9CC</t>
+        <reset>\u9A2\u9CD</reset><t>\u9A2\u9BC\u9CD</t>
+
+        <reset>\u9AB</reset><t>\u9AB\u9BC</t>
+        <reset>\u9AB\u9BE</reset><t>\u9AB\u9BC\u9BE</t>
+        <reset>\u9AB\u9BF</reset><t>\u9AB\u9BC\u9BF</t>
+        <reset>\u9AB\u9C0</reset><t>\u9AB\u9BC\u9C0</t>
+        <reset>\u9AB\u9C1</reset><t>\u9AB\u9BC\u9C1</t>
+        <reset>\u9AB\u9C2</reset><t>\u9AB\u9BC\u9C2</t>
+        <reset>\u9AB\u9C3</reset><t>\u9AB\u9BC\u9C3</t>
+        <reset>\u9AB\u9C4</reset><t>\u9AB\u9BC\u9C4</t>
+        <reset>\u9AB\u9E2</reset><t>\u9AB\u9BC\u9E2</t>
+        <reset>\u9AB\u9E3</reset><t>\u9AB\u9BC\u9E3</t>
+        <reset>\u9AB\u9C7</reset><t>\u9AB\u9BC\u9C7</t>
+        <reset>\u9AB\u9C8</reset><t>\u9AB\u9BC\u9C8</t>
+        <reset>\u9AB\u9CB</reset><t>\u9AB\u9BC\u9CB</t>
+        <reset>\u9AB\u9CC</reset><t>\u9AB\u9BC\u9CC</t>
+        <reset>\u9AB\u9CD</reset><t>\u9AB\u9BC\u9CD</t>
+
+        <reset>\u9AC</reset><t>\u9AC\u9BC</t>
+        <reset>\u9AC\u9BE</reset><t>\u9AC\u9BC\u9BE</t>
+        <reset>\u9AC\u9BF</reset><t>\u9AC\u9BC\u9BF</t>
+        <reset>\u9AC\u9C0</reset><t>\u9AC\u9BC\u9C0</t>
+        <reset>\u9AC\u9C1</reset><t>\u9AC\u9BC\u9C1</t>
+        <reset>\u9AC\u9C2</reset><t>\u9AC\u9BC\u9C2</t>
+        <reset>\u9AC\u9C3</reset><t>\u9AC\u9BC\u9C3</t>
+        <reset>\u9AC\u9C4</reset><t>\u9AC\u9BC\u9C4</t>
+        <reset>\u9AC\u9E2</reset><t>\u9AC\u9BC\u9E2</t>
+        <reset>\u9AC\u9E3</reset><t>\u9AC\u9BC\u9E3</t>
+        <reset>\u9AC\u9C7</reset><t>\u9AC\u9BC\u9C7</t>
+        <reset>\u9AC\u9C8</reset><t>\u9AC\u9BC\u9C8</t>
+        <reset>\u9AC\u9CB</reset><t>\u9AC\u9BC\u9CB</t>
+        <reset>\u9AC\u9CC</reset><t>\u9AC\u9BC\u9CC</t>
+        <reset>\u9AC\u9CD</reset><t>\u9AC\u9BC\u9CD</t>
+
+        <reset>\u9AF</reset><t>\u9AF\u9BC</t>
+        <reset>\u9AF\u9BE</reset><t>\u9AF\u9BC\u9BE</t>
+        <reset>\u9AF\u9BF</reset><t>\u9AF\u9BC\u9BF</t>
+        <reset>\u9AF\u9C0</reset><t>\u9AF\u9BC\u9C0</t>
+        <reset>\u9AF\u9C1</reset><t>\u9AF\u9BC\u9C1</t>
+        <reset>\u9AF\u9C2</reset><t>\u9AF\u9BC\u9C2</t>
+        <reset>\u9AF\u9C3</reset><t>\u9AF\u9BC\u9C3</t>
+        <reset>\u9AF\u9C4</reset><t>\u9AF\u9BC\u9C4</t>
+        <reset>\u9AF\u9E2</reset><t>\u9AF\u9BC\u9E2</t>
+        <reset>\u9AF\u9E3</reset><t>\u9AF\u9BC\u9E3</t>
+        <reset>\u9AF\u9C7</reset><t>\u9AF\u9BC\u9C7</t>
+        <reset>\u9AF\u9C8</reset><t>\u9AF\u9BC\u9C8</t>
+        <reset>\u9AF\u9CB</reset><t>\u9AF\u9BC\u9CB</t>
+        <reset>\u9AF\u9CC</reset><t>\u9AF\u9BC\u9CC</t>
+        <reset>\u9AF\u9CD</reset><t>\u9AF\u9BC\u9CD</t>
+      </rules>
+    </collation>
+
+  </charset>
+  
 </charsets>

=== modified file 'mysql-test/t/ctype_ldml-master.opt'
--- mysql-test/t/ctype_ldml-master.opt	2007-06-07 12:55:55 +0000
+++ mysql-test/t/ctype_ldml-master.opt	2013-09-17 16:21:42 +0000
@@ -1,2 +1,2 @@
 --character-sets-dir=$MYSQL_TEST_DIR/std_data/
-
+--log-error=$MYSQLTEST_VARDIR/tmp/ctype_ldml_log.err

=== modified file 'mysql-test/t/ctype_ldml.test'
--- mysql-test/t/ctype_ldml.test	2010-03-24 15:03:44 +0000
+++ mysql-test/t/ctype_ldml.test	2013-09-17 16:20:17 +0000
@@ -61,7 +61,6 @@ insert into t1 values ('a');
 select * from t1 where c1='b';
 drop table t1;
 
-
 #
 # Bug#41084 full-text index added to custom UCA collation not working
 #
@@ -181,3 +180,188 @@ DROP TABLE t1;
 SET NAMES utf8 COLLATE utf8_phone_ci;
 SHOW COLLATION LIKE 'utf8_phone_ci';
 SET NAMES utf8;
+
+# make sure utf8mb4_test_400_ci is Unicode-4.0.0 based
+SELECT hex(@a:=convert(_utf32 0x10400 using utf8mb4) collate utf8mb4_test_400_ci), hex(lower(@a));
+SELECT hex(@a:=convert(_utf32 0x10428 using utf8mb4) collate utf8mb4_test_400_ci), hex(upper(@a));
+SELECT hex(@a:=convert(_utf32 0x2C00 using utf8mb4) collate utf8mb4_test_400_ci), hex(lower(@a));
+SELECT hex(@a:=convert(_utf32 0x2C30 using utf8mb4) collate utf8mb4_test_400_ci), hex(upper(@a));
+
+--echo #
+--echo # WL#5624 Collation customization improvements
+--echo #
+SET NAMES utf8 COLLATE utf8_5624_1;
+CREATE TABLE t1 AS SELECT REPEAT(' ', 16) AS a LIMIT 0;
+# Part 1,2,3: long contractions and expansions
+# Part 7: Quarternary difference
+INSERT INTO t1 VALUES ('012345'),('001234'),('000123'),('000012'),('000001');
+INSERT INTO t1 VALUES ('12345'),('01234'),('00123'),('00012'),('00001');
+INSERT INTO t1 VALUES ('1234'),('0123'),('0012'),('0001');
+INSERT INTO t1 VALUES ('123'),('012'),('001');
+INSERT INTO t1 VALUES ('12'),('01');
+INSERT INTO t1 VALUES ('1'),('9');
+INSERT INTO t1 VALUES ('ГАИ'),('ГИБДД');
+# Part 4: reset before
+# Part 6: characters rather than escape sequences
+INSERT INTO t1 VALUES ('a'),('b'),('c'),('d'),('e');
+INSERT INTO t1 VALUES ('cz'),('ÄŠ'),('Ä‹');
+INSERT INTO t1 VALUES ('f'),('fz'),('g'),('Ä '),('Ä¡');
+INSERT INTO t1 VALUES ('h'),('hz'),('GĦ'),('Għ'),('gĦ'),('għ');
+INSERT INTO t1 VALUES ('i'),('iz'),('Ħ'),('ħ');
+INSERT INTO t1 VALUES ('y'),('yz'),('z'),('Ż'),('ż');
+INSERT INTO t1 VALUES ('ā'),('Ā'),('á'),('Á'),('à'),('À');
+INSERT INTO t1 VALUES ('ē'),('é'),('ě'),('ê'),('Ē'),('É'),('Ě'),('Ê');
+# Part 8: Abbreviated shift syntax
+INSERT INTO t1 VALUES ('a'),('~'),('!'),('@'),('#'),('$'),('%'),('^');
+INSERT INTO t1 VALUES ('('),(')'),('-'),('+'),('|'),('='),(':'),(';');
+INSERT INTO t1 VALUES ('"'),('\''),('?');
+# Part 9: Normal expansion syntax
+INSERT INTO t1 VALUES ('ch'),('k'),('cs'),('ccs'),('cscs');
+# Part 10: Previous context
+INSERT INTO t1 VALUES ('aa-'),('ab-'),('ac-'),('ad-'),('ae-'),('af-'),('az-');
+# Part 12: Logical reset positions
+INSERT INTO t1 VALUES ('lp-fni'),('lp-lni');
+INSERT INTO t1 VALUES ('lp-fpi'),('lp-lpi');
+INSERT INTO t1 VALUES ('lp-fsi'),('lp-lsi');
+INSERT INTO t1 VALUES ('lp-fti'),('lp-lti');
+INSERT INTO t1 VALUES ('lp-ft'),('lp-lt');
+INSERT INTO t1 VALUES ('lp-fv'),('lp-lv');
+# Logical positions with reset before
+INSERT INTO t1 VALUES ('lb-fni'),('lb-lni');
+INSERT INTO t1 VALUES ('lb-fv'),('lb-lv');
+# Part 5: Long tailoring
+INSERT INTO t1 VALUES (_ucs2 0x3106),(_ucs2 0x3110), (_ucs2 0x3111), (_ucs2 0x3112);
+INSERT INTO t1 VALUES (_ucs2 0x32A3), (_ucs2 0x3231);
+INSERT INTO t1 VALUES (_ucs2 0x84D9), (_ucs2 0x98F5), (_ucs2 0x7CF3), (_ucs2 0x5497);
+SELECT a FROM t1 ORDER BY a, LENGTH(a), BINARY a;
+--echo #
+--echo # WL#5624, the same test with UCS2
+--echo #
+ALTER TABLE t1 CONVERT TO CHARACTER SET ucs2 COLLATE ucs2_5624_1;
+SELECT a FROM t1 ORDER BY a, LENGTH(a), BINARY(a);
+DROP TABLE t1;
+
+--echo #
+--echo # WL#5624, unsupported features
+--echo #
+# Part 13: More verbosity
+--error ER_UNKNOWN_COLLATION
+SET NAMES utf8 COLLATE utf8_5624_2;
+SHOW WARNINGS;
+
+--echo #
+--echo # WL#5624, reset before primary ignorable
+--echo #
+--error ER_UNKNOWN_COLLATION
+SET NAMES utf8 COLLATE utf8_5624_3;
+SHOW WARNINGS;
+
+--echo #
+--echo # WL#5624, \u without hex digits is equal to {'\\', 'u'}
+--echo #
+SET NAMES utf8 COLLATE utf8_5624_4;
+CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES ('\\'),('u'),('x'),('X');
+SELECT a FROM t1 ORDER BY a, LENGTH(a), BINARY(a);
+DROP TABLE t1;
+
+--echo #
+--echo # WL#5624, testing Bengali collations
+--echo #
+SET NAMES utf8, collation_connection=utf8_bengali_standard_ci;
+CREATE TABLE t1 AS SELECT REPEAT (' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES (_ucs2 0x09FA), (_ucs2 0x09F8), (_ucs2 0x09F9), (_ucs2 0x09F2);
+INSERT INTO t1 VALUES (_ucs2 0x09DC), (_ucs2 0x09A109BC);
+INSERT INTO t1 VALUES (_ucs2 0x09A2), (_ucs2 0x09DD), (_ucs2 0x09A209BC);
+INSERT INTO t1 VALUES (_ucs2 0x09A3);
+SELECT HEX(CONVERT(a USING ucs2)), HEX(a)
+FROM t1 ORDER BY a, BINARY a;
+DROP TABLE t1;
+
+SET NAMES utf8, collation_connection=utf8_bengali_traditional_ci;
+CREATE TABLE t1 AS SELECT REPEAT (' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES
+(_ucs2 0x0985),(_ucs2 0x0986),(_ucs2 0x0987),(_ucs2 0x0988),
+(_ucs2 0x0989),(_ucs2 0x098A),(_ucs2 0x098B),(_ucs2 0x09E0),
+(_ucs2 0x098C),(_ucs2 0x09E1),(_ucs2 0x098F),(_ucs2 0x0990),
+(_ucs2 0x0993);
+
+INSERT INTO t1 VALUES
+(_ucs2 0x0994),(_ucs2 0x0982),(_ucs2 0x0983),(_ucs2 0x0981),
+(_ucs2 0x099509CD), (_ucs2 0x099609CD), (_ucs2 0x099709CD), (_ucs2 0x099809CD),
+(_ucs2 0x099909CD), (_ucs2 0x099A09CD), (_ucs2 0x099B09CD), (_ucs2 0x099C09CD),
+(_ucs2 0x099D09CD), (_ucs2 0x099E09CD), (_ucs2 0x099F09CD), (_ucs2 0x09A009CD),
+(_ucs2 0x09A109CD), (_ucs2 0x09A209CD), (_ucs2 0x09A309CD),
+(_ucs2 0x09CE), (_ucs2 0x09A409CD200D), (_ucs2 0x09A409CD),
+(_ucs2 0x09A509CD),(_ucs2 0x09A609CD),
+(_ucs2 0x09A709CD), (_ucs2 0x09A809CD), (_ucs2 0x09AA09CD), (_ucs2 0x09AB09CD),
+(_ucs2 0x09AC09CD), (_ucs2 0x09AD09CD), (_ucs2 0x09AE09CD), (_ucs2 0x09AF09CD),
+(_ucs2 0x09B009CD), (_ucs2 0x09F009CD), (_ucs2 0x09B209CD), (_ucs2 0x09F109CD),
+(_ucs2 0x09B609CD), (_ucs2 0x09B709CD), (_ucs2 0x09B809CD), (_ucs2 0x09B909CD);
+
+INSERT INTO t1 VALUES 
+ (_ucs2 0x099509CD0985),(_ucs2 0x0995),
+ (_ucs2 0x099509CD0986),(_ucs2 0x099509BE),
+ (_ucs2 0x099509CD0987),(_ucs2 0x099509BF),
+ (_ucs2 0x099509CD0988),(_ucs2 0x099509C0),
+ (_ucs2 0x099509CD0989),(_ucs2 0x099509C1),
+ (_ucs2 0x099509CD098A),(_ucs2 0x099509C2),
+ (_ucs2 0x099509CD098B),(_ucs2 0x099509C3),
+ (_ucs2 0x099509CD09E0),(_ucs2 0x099509C4),
+ (_ucs2 0x099509CD098C),(_ucs2 0x099509E2),
+ (_ucs2 0x099509CD09E1),(_ucs2 0x099509E3),
+ (_ucs2 0x099509CD098F),(_ucs2 0x099509C7),
+ (_ucs2 0x099509CD0990),(_ucs2 0x099509C8),
+ (_ucs2 0x099509CD0993),(_ucs2 0x099509CB),
+ (_ucs2 0x099509CD0994),(_ucs2 0x099509CC);
+
+SELECT HEX(CONVERT(a USING ucs2)), HEX(a)
+FROM t1 ORDER BY a, BINARY(a);
+SELECT
+GROUP_CONCAT(HEX(CONVERT(a USING ucs2)) ORDER BY LENGTH(a), BINARY a)
+FROM t1 GROUP BY a ORDER BY a;
+DROP TABLE t1;
+
+--echo #
+--echo # WL#5624, shift after, using expansion
+--echo #
+SET NAMES utf8 COLLATE utf8_5624_5;
+CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES ('0'),('1'),('0z'),(_ucs2 0x0030FF9D);
+INSERT INTO t1 VALUES ('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),('i');
+INSERT INTO t1 VALUES ('j'),('k'),('l'),('m'),('n'),('o'),('p'),('q'),('r');
+INSERT INTO t1 VALUES ('s'),('t'),('u'),('v'),('w'),('x'),('y'),('z');
+INSERT INTO t1 VALUES ('aa'),('aaa');
+INSERT INTO t1 VALUES ('A'),('B'),('C'),('D'),('E'),('F'),('G'),('H'),('I');
+INSERT INTO t1 VALUES ('J'),('K'),('L'),('M'),('N'),('O'),('P'),('Q'),('R');
+INSERT INTO t1 VALUES ('S'),('T'),('U'),('V'),('W'),('X'),('Y'),('Z');
+INSERT INTO t1 VALUES ('AA'),('AAA');
+
+SELECT a FROM t1 ORDER BY a, LENGTH(a), BINARY(a);
+DROP TABLE t1;
+
+
+--echo #
+--echo # End of WL#5624
+--echo #
+
+
+--echo #
+--echo # Bug#14197426 PARSE ERRORS IN LOADABLE UCA / LDML COLLATIONS ARE SILENTLY IGNORED
+--echo #
+
+--let $out_file= $MYSQLTEST_VARDIR/tmp/ctype_ldml_log.err
+--let OUTF= $out_file
+# Error messages are not seen in error log in embedded version
+--let EMBEDDED=`SELECT version() LIKE '%embedded%'`
+--echo # Search for occurrences of [ERROR] Syntax error at '[strength tertiary]'
+
+perl;
+  use strict;
+  my $outf= $ENV{'OUTF'} or die "OUTF not set";
+  open(FILE, "$outf") or die("Unable to open $outf: $!\n");
+  my $count_error= grep(/\[ERROR\] Syntax error at '\[strength tertiary\]'/gi,<FILE>);
+  my $count_error= $count_error + $ENV{"EMBEDDED"};
+  print "Occurances : $count_error\n";
+  close(FILE);
+EOF

=== modified file 'mysql-test/t/ctype_uca.test'
--- mysql-test/t/ctype_uca.test	2011-07-04 08:42:17 +0000
+++ mysql-test/t/ctype_uca.test	2013-08-29 12:47:22 +0000
@@ -215,6 +215,7 @@ select group_concat(c1 order by c1) from
 select group_concat(c1 order by c1) from t1 group by c1 collate utf8_esperanto_ci;
 select group_concat(c1 order by c1) from t1 group by c1 collate utf8_hungarian_ci;
 select group_concat(c1 order by c1) from t1 group by c1 collate utf8_croatian_ci;
+select group_concat(c1 order by c1) from t1 group by c1 collate utf8_german2_ci;
 
 drop table t1;
 
@@ -580,3 +581,14 @@ drop table t1;
 --echo #
 --echo # End of 5.5 tests
 --echo #
+
+--echo #
+--echo # WL#4013 Unicode german2 collation
+--echo #
+SET collation_connection=utf8_german2_ci;
+--source include/ctype_german.inc
+
+
+--echo #
+--echo # End of 5.6 tests
+--echo #

=== modified file 'mysys/charset-def.c'
--- mysys/charset-def.c	2013-07-18 14:46:57 +0000
+++ mysys/charset-def.c	2013-09-04 14:10:55 +0000
@@ -24,6 +24,7 @@
 #ifdef HAVE_UCA_COLLATIONS
 
 #ifdef HAVE_CHARSET_ucs2
+extern struct charset_info_st my_charset_ucs2_german2_uca_ci;
 extern struct charset_info_st my_charset_ucs2_icelandic_uca_ci;
 extern struct charset_info_st my_charset_ucs2_latvian_uca_ci;
 extern struct charset_info_st my_charset_ucs2_romanian_uca_ci;
@@ -48,6 +49,7 @@ extern struct charset_info_st my_charset
 
 
 #ifdef HAVE_CHARSET_utf32
+extern struct charset_info_st my_charset_utf32_german2_uca_ci;
 extern struct charset_info_st my_charset_utf32_icelandic_uca_ci;
 extern struct charset_info_st my_charset_utf32_latvian_uca_ci;
 extern struct charset_info_st my_charset_utf32_romanian_uca_ci;
@@ -72,6 +74,7 @@ extern struct charset_info_st my_charset
 
 
 #ifdef HAVE_CHARSET_utf16
+extern struct charset_info_st my_charset_utf16_german2_uca_ci;
 extern struct charset_info_st my_charset_utf16_icelandic_uca_ci;
 extern struct charset_info_st my_charset_utf16_latvian_uca_ci;
 extern struct charset_info_st my_charset_utf16_romanian_uca_ci;
@@ -96,6 +99,7 @@ extern struct charset_info_st my_charset
 
 
 #ifdef HAVE_CHARSET_utf8
+extern struct charset_info_st my_charset_utf8_german2_uca_ci;
 extern struct charset_info_st my_charset_utf8_icelandic_uca_ci;
 extern struct charset_info_st my_charset_utf8_latvian_uca_ci;
 extern struct charset_info_st my_charset_utf8_romanian_uca_ci;
@@ -122,6 +126,7 @@ extern struct charset_info_st my_charset
 #endif
 
 #ifdef HAVE_CHARSET_utf8mb4
+extern struct charset_info_st my_charset_utf8mb4_german2_uca_ci;
 extern struct charset_info_st my_charset_utf8mb4_icelandic_uca_ci;
 extern struct charset_info_st my_charset_utf8mb4_latvian_uca_ci;
 extern struct charset_info_st my_charset_utf8mb4_romanian_uca_ci;
@@ -211,6 +216,7 @@ my_bool init_compiled_charsets(myf flags
   add_compiled_collation(&my_charset_ucs2_general_mysql500_ci);
 #ifdef HAVE_UCA_COLLATIONS
   add_compiled_collation(&my_charset_ucs2_unicode_ci);
+  add_compiled_collation(&my_charset_ucs2_german2_uca_ci);
   add_compiled_collation(&my_charset_ucs2_icelandic_uca_ci);
   add_compiled_collation(&my_charset_ucs2_latvian_uca_ci);
   add_compiled_collation(&my_charset_ucs2_romanian_uca_ci);
@@ -248,6 +254,7 @@ my_bool init_compiled_charsets(myf flags
 #endif
 #ifdef HAVE_UCA_COLLATIONS
   add_compiled_collation(&my_charset_utf8_unicode_ci);
+  add_compiled_collation(&my_charset_utf8_german2_uca_ci);
   add_compiled_collation(&my_charset_utf8_icelandic_uca_ci);
   add_compiled_collation(&my_charset_utf8_latvian_uca_ci);
   add_compiled_collation(&my_charset_utf8_romanian_uca_ci);
@@ -277,6 +284,7 @@ my_bool init_compiled_charsets(myf flags
   add_compiled_collation(&my_charset_utf8mb4_bin);
 #ifdef HAVE_UCA_COLLATIONS
   add_compiled_collation(&my_charset_utf8mb4_unicode_ci);
+  add_compiled_collation(&my_charset_utf8mb4_german2_uca_ci);
   add_compiled_collation(&my_charset_utf8mb4_icelandic_uca_ci);
   add_compiled_collation(&my_charset_utf8mb4_latvian_uca_ci);
   add_compiled_collation(&my_charset_utf8mb4_romanian_uca_ci);
@@ -308,6 +316,7 @@ my_bool init_compiled_charsets(myf flags
   add_compiled_collation(&my_charset_utf16le_bin);
 #ifdef HAVE_UCA_COLLATIONS
   add_compiled_collation(&my_charset_utf16_unicode_ci);
+  add_compiled_collation(&my_charset_utf16_german2_uca_ci);
   add_compiled_collation(&my_charset_utf16_icelandic_uca_ci);
   add_compiled_collation(&my_charset_utf16_latvian_uca_ci);
   add_compiled_collation(&my_charset_utf16_romanian_uca_ci);
@@ -337,6 +346,7 @@ my_bool init_compiled_charsets(myf flags
   add_compiled_collation(&my_charset_utf32_bin);
 #ifdef HAVE_UCA_COLLATIONS
   add_compiled_collation(&my_charset_utf32_unicode_ci);
+  add_compiled_collation(&my_charset_utf32_german2_uca_ci);
   add_compiled_collation(&my_charset_utf32_icelandic_uca_ci);
   add_compiled_collation(&my_charset_utf32_latvian_uca_ci);
   add_compiled_collation(&my_charset_utf32_romanian_uca_ci);

=== modified file 'mysys/charset.c'
--- mysys/charset.c	2012-08-14 14:23:34 +0000
+++ mysys/charset.c	2013-09-17 11:14:49 +0000
@@ -214,6 +214,8 @@ copy_uca_collation(struct charset_info_s
   to->max_sort_char= from->max_sort_char;
   to->mbminlen= from->mbminlen;
   to->mbmaxlen= from->mbmaxlen;
+  to->caseup_multiply= from->caseup_multiply;
+  to->casedn_multiply= from->casedn_multiply;
   to->state|= MY_CS_AVAILABLE | MY_CS_LOADED |
               MY_CS_STRNXFRM  | MY_CS_UNICODE;
 }
@@ -349,6 +351,7 @@ static int add_collation(struct charset_
   return MY_XML_OK;
 }
 
+
 /**
   Report character set initialization errors and warnings.
   Be silent by default: no warnings on the client side.
@@ -361,13 +364,53 @@ default_reporter(enum loglevel level  __
 }
 my_error_reporter my_charset_error_reporter= default_reporter;
 
+
+/**
+  Wrappers for memory functions my_malloc (and friends)
+  with C-compatbile API without extra "myf" argument.
+*/
+static void *
+my_once_alloc_c(size_t size)
+{ return my_once_alloc(size, MYF(MY_WME)); }
+
+
+static void *
+my_malloc_c(size_t size)
+{ return my_malloc(size, MYF(MY_WME)); }
+
+
+static void *
+my_realloc_c(void *old, size_t size)
+{ return my_realloc(old, size, MYF(MY_WME|MY_ALLOW_ZERO_PTR)); }
+
+
+/**
+  Initialize character set loader to use mysys memory management functions.
+  @param loader  Loader to initialize
+*/
+void
+my_charset_loader_init_mysys(MY_CHARSET_LOADER *loader)
+{
+  loader->error[0]= '\0';
+  loader->once_alloc= my_once_alloc_c;
+  loader->malloc= my_malloc_c;
+  loader->realloc= my_realloc_c;
+  loader->free= my_free;
+  loader->reporter= my_charset_error_reporter;
+  loader->add_collation= add_collation;
+}
+
+
 #define MY_MAX_ALLOWED_BUF 1024*1024
 #define MY_CHARSET_INDEX "Index.xml"
 
 const char *charsets_dir= NULL;
 
 
-static my_bool my_read_charset_file(const char *filename, myf myflags)
+static my_bool
+my_read_charset_file(MY_CHARSET_LOADER *loader,
+                     const char *filename,
+                     myf myflags)
 {
   uchar *buf;
   int  fd;
@@ -386,14 +429,11 @@ static my_bool my_read_charset_file(cons
   if (tmp_len != len)
     goto error;
   
-  if (my_parse_charset_xml((char*) buf,len,add_collation))
+  if (my_parse_charset_xml(loader, (char *) buf, len))
   {
-#ifdef NOT_YET
-    printf("ERROR at line %d pos %d '%s'\n",
-	   my_xml_error_lineno(&p)+1,
-	   my_xml_error_pos(&p),
-	   my_xml_error_string(&p));
-#endif
+    my_printf_error(EE_UNKNOWN_CHARSET, "Error while parsing '%s': %s\n",
+                    MYF(0), filename, loader->error);
+    goto error;
   }
   
   my_free(buf);
@@ -437,11 +477,6 @@ void add_compiled_collation(struct chars
   cs->state|= MY_CS_AVAILABLE;
 }
 
-static void *cs_alloc(size_t size)
-{
-  return my_once_alloc(size, MYF(MY_WME));
-}
-
 
 static my_pthread_once_t charsets_initialized= MY_PTHREAD_ONCE_INIT;
 static my_pthread_once_t charsets_template= MY_PTHREAD_ONCE_INIT;
@@ -450,6 +485,7 @@ static void init_available_charsets(void
 {
   char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
   struct charset_info_st **cs;
+  MY_CHARSET_LOADER loader;
 
   bzero((char*) &all_charsets,sizeof(all_charsets));
   init_compiled_charsets(MYF(0));
@@ -468,8 +504,9 @@ static void init_available_charsets(void
     }
   }
 
+  my_charset_loader_init_mysys(&loader);
   strmov(get_charsets_dir(fname), MY_CHARSET_INDEX);
-  my_read_charset_file(fname, MYF(0));
+  my_read_charset_file(&loader, fname, MYF(0));
 }
 
 
@@ -558,7 +595,8 @@ const char *get_charset_name(uint charse
 }
 
 
-static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
+static CHARSET_INFO *
+get_internal_charset(MY_CHARSET_LOADER *loader, uint cs_number, myf flags)
 {
   char  buf[FN_REFLEN];
   struct charset_info_st *cs;
@@ -578,17 +616,21 @@ static CHARSET_INFO *get_internal_charse
 
     if (!(cs->state & (MY_CS_COMPILED|MY_CS_LOADED))) /* if CS is not in memory */
     {
+      MY_CHARSET_LOADER loader;
       strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS);
-      my_read_charset_file(buf,flags);
+      my_charset_loader_init_mysys(&loader);
+      my_read_charset_file(&loader, buf, flags);
     }
 
     if (cs->state & MY_CS_AVAILABLE)
     {
       if (!(cs->state & MY_CS_READY))
       {
-        if ((cs->cset->init && cs->cset->init(cs, cs_alloc)) ||
-            (cs->coll->init && cs->coll->init(cs, cs_alloc)))
+        if ((cs->cset->init && cs->cset->init(cs, loader)) ||
+            (cs->coll->init && cs->coll->init(cs, loader)))
+        {
           cs= NULL;
+        }
         else
           cs->state|= MY_CS_READY;
       }
@@ -605,6 +647,8 @@ static CHARSET_INFO *get_internal_charse
 CHARSET_INFO *get_charset(uint cs_number, myf flags)
 {
   CHARSET_INFO *cs;
+  MY_CHARSET_LOADER loader;
+
   if (cs_number == default_charset_info->number)
     return default_charset_info;
 
@@ -612,8 +656,9 @@ CHARSET_INFO *get_charset(uint cs_number
  
   if (cs_number >= array_elements(all_charsets)) 
     return NULL;
-  
-  cs=get_internal_charset(cs_number, flags);
+
+  my_charset_loader_init_mysys(&loader);
+  cs= get_internal_charset(&loader, cs_number, flags);
 
   if (!cs && (flags & MY_WME))
   {
@@ -626,29 +671,58 @@ CHARSET_INFO *get_charset(uint cs_number
   return cs;
 }
 
-CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags)
+
+/**
+  Find collation by name: extended version of get_charset_by_name()
+  to return error messages to the caller.
+  @param   loader  Character set loader
+  @param   name    Collation name
+  @param   flags   Flags
+  @return          NULL on error, pointer to collation on success
+*/
+
+CHARSET_INFO *
+my_collation_get_by_name(MY_CHARSET_LOADER *loader,
+                         const char *name, myf flags)
 {
   uint cs_number;
   CHARSET_INFO *cs;
   my_pthread_once(&charsets_initialized, init_available_charsets);
 
-  cs_number=get_collation_number(cs_name);
-  cs= cs_number ? get_internal_charset(cs_number,flags) : NULL;
+  cs_number= get_collation_number(name);
+  my_charset_loader_init_mysys(loader);
+  cs= cs_number ? get_internal_charset(loader, cs_number, flags) : NULL;
 
   if (!cs && (flags & MY_WME))
   {
     char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
     strmov(get_charsets_dir(index_file),MY_CHARSET_INDEX);
-    my_error(EE_UNKNOWN_COLLATION, MYF(ME_BELL), cs_name, index_file);
+    my_error(EE_UNKNOWN_COLLATION, MYF(ME_BELL), name, index_file);
   }
-
   return cs;
 }
 
 
-CHARSET_INFO *get_charset_by_csname(const char *cs_name,
-				    uint cs_flags,
-				    myf flags)
+CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags)
+{
+  MY_CHARSET_LOADER loader;
+  my_charset_loader_init_mysys(&loader);
+  return my_collation_get_by_name(&loader, cs_name, flags);
+}
+
+
+/**
+  Find character set by name: extended version of get_charset_by_csname()
+  to return error messages to the caller.
+  @param   loader   Character set loader
+  @param   name     Collation name
+  @param   cs_flags Character set flags (e.g. default or binary collation)
+  @param   flags    Flags
+  @return           NULL on error, pointer to collation on success
+*/
+CHARSET_INFO *
+my_charset_get_by_name(MY_CHARSET_LOADER *loader,
+                       const char *cs_name, uint cs_flags, myf flags)
 {
   uint cs_number;
   CHARSET_INFO *cs;
@@ -658,7 +732,7 @@ CHARSET_INFO *get_charset_by_csname(cons
   my_pthread_once(&charsets_initialized, init_available_charsets);
 
   cs_number= get_charset_number(cs_name, cs_flags);
-  cs= cs_number ? get_internal_charset(cs_number, flags) : NULL;
+  cs= cs_number ? get_internal_charset(loader, cs_number, flags) : NULL;
 
   if (!cs && (flags & MY_WME))
   {
@@ -671,6 +745,15 @@ CHARSET_INFO *get_charset_by_csname(cons
 }
 
 
+CHARSET_INFO *
+get_charset_by_csname(const char *cs_name, uint cs_flags, myf flags)
+{
+  MY_CHARSET_LOADER loader;
+  my_charset_loader_init_mysys(&loader);
+  return my_charset_get_by_name(&loader, cs_name, cs_flags, flags);
+}
+
+
 /**
   Resolve character set by the character set name (utf8, latin1, ...).
 
@@ -868,8 +951,11 @@ CHARSET_INFO *fs_character_set()
       As we're now interested in cp932 only,
       let's just detect it using strcmp().
     */
-    fs_cset_cache= !strcmp(buf, "cp932") ?
-                   &my_charset_cp932_japanese_ci : &my_charset_bin;
+    fs_cset_cache= 
+                #ifdef HAVE_CHARSET_cp932
+                        !strcmp(buf, "cp932") ? &my_charset_cp932_japanese_ci : 
+                #endif
+                        &my_charset_bin;
   }
   return fs_cset_cache;
 }

=== modified file 'sql/mysqld.cc'
--- sql/mysqld.cc	2013-08-14 08:48:50 +0000
+++ sql/mysqld.cc	2013-09-17 18:30:13 +0000
@@ -1287,7 +1287,7 @@ struct my_rnd_struct sql_rand; ///< used
   @param level          log message level
   @param format         log message format string
 */
-
+C_MODE_START
 static void buffered_option_error_reporter(enum loglevel level,
                                            const char *format, ...)
 {
@@ -1300,6 +1300,33 @@ static void buffered_option_error_report
   buffered_logs.buffer(level, buffer);
 }
 
+
+/**
+  Character set and collation error reporter that prints to sql error log.
+  @param level          log message level
+  @param format         log message format string
+
+  This routine is used to print character set and collation
+  warnings and errors inside an already running mysqld server,
+  e.g. when a character set or collation is requested for the very first time
+  and its initialization does not go well for some reasons.
+
+  Note: At early mysqld initialization stage,
+  when error log is not yet available,
+  we use buffered_option_error_reporter() instead,
+  to print general character set subsystem initialization errors,
+  such as Index.xml syntax problems, bad XML tag hierarchy, etc.
+*/
+static void charset_error_reporter(enum loglevel level,
+                                   const char *format, ...)
+{
+  va_list args;
+  va_start(args, format);
+  vprint_msg_to_log(level, format, args);
+  va_end(args);                      
+}
+C_MODE_END
+
 struct passwd *user_info;
 static pthread_t select_thread;
 #endif
@@ -4544,6 +4571,15 @@ static int init_server_components()
   buffered_logs.cleanup();
 #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
 
+#ifndef EMBEDDED_LIBRARY
+  /*
+    Now that the logger is available, redirect character set
+    errors directly to the logger
+    (instead of the buffered_logs used at the server startup time).
+  */
+  my_charset_error_reporter= charset_error_reporter;
+#endif
+
   if (xid_cache_init())
   {
     sql_print_error("Out of memory");

=== modified file 'sql/sql_class.h'
--- sql/sql_class.h	2013-08-12 20:05:23 +0000
+++ sql/sql_class.h	2013-09-17 12:34:19 +0000
@@ -744,6 +744,35 @@ typedef struct system_status_var
 
 void mark_transaction_to_rollback(THD *thd, bool all);
 
+
+/**
+  Get collation by name, send error to client on failure.
+  @param name     Collation name
+  @param name_cs  Character set of the name string
+  @return
+  @retval         NULL on error
+  @retval         Pointter to CHARSET_INFO with the given name on success
+*/
+inline CHARSET_INFO *
+mysqld_collation_get_by_name(const char *name,
+                             CHARSET_INFO *name_cs= system_charset_info)
+{
+  CHARSET_INFO *cs;
+  MY_CHARSET_LOADER loader;
+  my_charset_loader_init_mysys(&loader);
+  if (!(cs= my_collation_get_by_name(&loader, name, MYF(0))))
+  {
+    ErrConvString err(name, name_cs);
+    my_error(ER_UNKNOWN_COLLATION, MYF(0), err.ptr());
+    if (loader.error[0])
+      push_warning_printf(current_thd,
+                          Sql_condition::WARN_LEVEL_WARN,
+                          ER_UNKNOWN_COLLATION, "%s", loader.error);
+  }
+  return cs;
+}
+
+
 #ifdef MYSQL_SERVER
 
 void free_tmp_table(THD *thd, TABLE *entry);

=== modified file 'sql/sql_error.h'
--- sql/sql_error.h	2013-08-15 11:24:34 +0000
+++ sql/sql_error.h	2013-09-17 12:40:50 +0000
@@ -565,6 +565,8 @@ class ErrConvString : public ErrConv
 public:
   ErrConvString(const char *str_arg, size_t len_arg, CHARSET_INFO *cs_arg)
     : ErrConv(), str(str_arg), len(len_arg), cs(cs_arg) {}
+  ErrConvString(const char *str_arg, CHARSET_INFO *cs_arg)
+    : ErrConv(), str(str_arg), len(strlen(str_arg)), cs(cs_arg) {}
   ErrConvString(String *s)
     : ErrConv(), str(s->ptr()), len(s->length()), cs(s->charset()) {}
   const char *ptr() const

=== modified file 'sql/sql_yacc.yy'
--- sql/sql_yacc.yy	2013-08-13 11:35:36 +0000
+++ sql/sql_yacc.yy	2013-09-17 12:44:41 +0000
@@ -6530,11 +6530,8 @@ old_or_new_charset_name_or_default:
 collation_name:
           ident_or_text
           {
-            if (!($$=get_charset_by_name($1.str,MYF(0))))
-            {
-              my_error(ER_UNKNOWN_COLLATION, MYF(0), $1.str);
+            if (!($$= mysqld_collation_get_by_name($1.str)))
               MYSQL_YYABORT;
-            }
           }
         ;
 
@@ -6578,19 +6575,13 @@ unicode:
           }
         | UNICODE_SYM BINARY
           {
-            if (!(Lex->charset=get_charset_by_name("ucs2_bin", MYF(0))))
-            {
+            if (!(Lex->charset= mysqld_collation_get_by_name("ucs2_bin")))
               my_error(ER_UNKNOWN_COLLATION, MYF(0), "ucs2_bin");
-              MYSQL_YYABORT;
-            }
           }
         | BINARY UNICODE_SYM
           {
-            if (!(Lex->charset=get_charset_by_name("ucs2_bin", MYF(0))))
-            {
-              my_error(ER_UNKNOWN_COLLATION, MYF(0), "ucs2_bin");
+            if (!(Lex->charset= mysqld_collation_get_by_name("ucs2_bin")))
               MYSQL_YYABORT;
-            }
           }
         ;
 

=== modified file 'strings/CMakeLists.txt'
--- strings/CMakeLists.txt	2012-01-13 14:50:02 +0000
+++ strings/CMakeLists.txt	2013-09-04 13:42:15 +0000
@@ -32,3 +32,6 @@ ENDIF()
 # Avoid dependencies on perschema data defined in mysys
 ADD_DEFINITIONS(-DDISABLE_MYSQL_THREAD_H)
 ADD_CONVENIENCE_LIBRARY(strings ${STRINGS_SOURCES})
+
+ADD_EXECUTABLE(conf_to_src EXCLUDE_FROM_ALL conf_to_src.c)
+TARGET_LINK_LIBRARIES(conf_to_src strings)

=== modified file 'strings/conf_to_src.c'
--- strings/conf_to_src.c	2012-01-13 14:50:02 +0000
+++ strings/conf_to_src.c	2013-09-04 13:40:56 +0000
@@ -145,12 +145,35 @@ static int add_collation(struct charset_
 }
 
 
+static void
+default_reporter(enum loglevel level  __attribute__ ((unused)),
+                 const char *format  __attribute__ ((unused)),
+                 ...)
+{
+}
+
+
+static void
+my_charset_loader_init(MY_CHARSET_LOADER *loader)
+{
+  loader->error[0]= '\0';
+  loader->once_alloc= malloc;
+  loader->malloc= malloc;
+  loader->realloc= realloc;
+  loader->free= free;
+  loader->reporter= default_reporter;
+  loader->add_collation= add_collation;
+}
+
+
 static int my_read_charset_file(const char *filename)
 {
   char buf[MAX_BUF];
   int  fd;
   uint len;
+  MY_CHARSET_LOADER loader;
   
+  my_charset_loader_init(&loader);
   if ((fd=open(filename,O_RDONLY)) < 0)
   {
     fprintf(stderr,"Can't open '%s'\n",filename);
@@ -161,14 +184,10 @@ static int my_read_charset_file(const ch
   DBUG_ASSERT(len < MAX_BUF);
   close(fd);
   
-  if (my_parse_charset_xml(buf,len,add_collation))
+  if (my_parse_charset_xml(&loader, buf, len))
   {
-#if 0
-    printf("ERROR at line %d pos %d '%s'\n",
-	   my_xml_error_lineno(&p)+1,
-	   my_xml_error_pos(&p),
-	   my_xml_error_string(&p));
-#endif
+    fprintf(stderr, "Error while parsing '%s': %s\n", filename, loader.error);
+    exit(1);
   }
   
   return FALSE;
@@ -207,8 +226,7 @@ void dispcset(FILE *f,CHARSET_INFO *cs)
       fprintf(f,"  sort_order_%s,            /* sort_order    */\n",cs->name);
     else
       fprintf(f,"  NULL,                     /* sort_order    */\n");
-    fprintf(f,"  NULL,                       /* contractions  */\n");
-    fprintf(f,"  NULL,                       /* sort_order_big*/\n");
+    fprintf(f,"  NULL,                       /* uca           */\n");
     fprintf(f,"  to_uni_%s,                  /* to_uni        */\n",cs->name);
   }
   else
@@ -221,13 +239,12 @@ void dispcset(FILE *f,CHARSET_INFO *cs)
     fprintf(f,"  NULL,                       /* lower         */\n");
     fprintf(f,"  NULL,                       /* upper         */\n");
     fprintf(f,"  NULL,                       /* sort order    */\n");
-    fprintf(f,"  NULL,                       /* contractions  */\n");
-    fprintf(f,"  NULL,                       /* sort_order_big*/\n");
+    fprintf(f,"  NULL,                       /* uca           */\n");
     fprintf(f,"  NULL,                       /* to_uni        */\n");
   }
 
   fprintf(f,"  NULL,                       /* from_uni      */\n");
-  fprintf(f,"  my_unicase_default,         /* caseinfo      */\n");
+  fprintf(f,"  &my_unicase_default,        /* caseinfo      */\n");
   fprintf(f,"  NULL,                       /* state map     */\n");
   fprintf(f,"  NULL,                       /* ident map     */\n");
   fprintf(f,"  1,                          /* strxfrm_multiply*/\n");

=== modified file 'strings/ctype-big5.c'
--- strings/ctype-big5.c	2013-03-25 22:03:13 +0000
+++ strings/ctype-big5.c	2013-08-29 08:19:23 +0000
@@ -29,6 +29,7 @@
 
 #include "strings_def.h"
 #include <m_ctype.h>
+#include <my_sys.h>
 
 #ifdef HAVE_CHARSET_big5
 
@@ -177,7 +178,7 @@ static const uchar sort_order_big5[]=
 };
 
 
-static MY_UNICASE_INFO cA2[256]=
+static MY_UNICASE_CHARACTER cA2[256]=
 {
   /* A200-A20F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -370,7 +371,7 @@ static MY_UNICASE_INFO cA2[256]=
 };
 
 
-static MY_UNICASE_INFO cA3[256]=
+static MY_UNICASE_CHARACTER cA3[256]=
 {
   /* A300-A30F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -563,7 +564,7 @@ static MY_UNICASE_INFO cA3[256]=
 };
 
 
-static MY_UNICASE_INFO cC7[256]=
+static MY_UNICASE_CHARACTER cC7[256]=
 {
   /* C700-C70F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -756,7 +757,7 @@ static MY_UNICASE_INFO cC7[256]=
 };
 
 
-static MY_UNICASE_INFO *my_caseinfo_big5[256]=
+static MY_UNICASE_CHARACTER *my_caseinfo_pages_big5[256]=
 {
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0 */
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -793,6 +794,13 @@ static MY_UNICASE_INFO *my_caseinfo_big5
 };
 
 
+static MY_UNICASE_INFO my_caseinfo_big5=
+{
+  0xFFFF,
+  my_caseinfo_pages_big5
+};
+
+
 static uint16 big5strokexfrm(uint16 i)
 {
   if ((i == 0xA440) || (i == 0xA441))  return 0xA440;
@@ -6926,11 +6934,10 @@ struct charset_info_st my_charset_big5_c
     to_lower_big5,
     to_upper_big5,
     sort_order_big5,
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_big5,   /* caseinfo     */
+    &my_caseinfo_big5,  /* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */
@@ -6959,11 +6966,10 @@ struct charset_info_st my_charset_big5_b
     to_lower_big5,
     to_upper_big5,
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_big5,   /* caseinfo     */
+    &my_caseinfo_big5,  /* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */

=== modified file 'strings/ctype-bin.c'
--- strings/ctype-bin.c	2013-07-21 14:39:19 +0000
+++ strings/ctype-bin.c	2013-08-29 07:42:03 +0000
@@ -69,7 +69,7 @@ static const uchar bin_char_array[] =
 
 static my_bool 
 my_coll_init_8bit_bin(struct charset_info_st *cs,
-                      void *(*alloc)(size_t) __attribute__((unused)))
+                      MY_CHARSET_LOADER *loader __attribute__((unused)))
 {
   cs->max_sort_char=255; 
   return FALSE;
@@ -571,11 +571,10 @@ struct charset_info_st my_charset_bin =
     bin_char_array,		/* to_lower      */
     bin_char_array,		/* to_upper      */
     NULL,			/* sort_order    */
-    NULL,			/* contractions */
-    NULL,			/* sort_order_big*/
+    NULL,			/* uca           */
     NULL,			/* tab_to_uni    */
     NULL,			/* tab_from_uni  */
-    my_unicase_default,         /* caseinfo     */
+    &my_unicase_default,        /* caseinfo     */
     NULL,			/* state_map    */
     NULL,			/* ident_map    */
     1,				/* strxfrm_multiply */

=== modified file 'strings/ctype-cp932.c'
--- strings/ctype-cp932.c	2012-01-13 14:50:02 +0000
+++ strings/ctype-cp932.c	2013-08-29 08:06:52 +0000
@@ -197,7 +197,7 @@ static uint mbcharlen_cp932(CHARSET_INFO
 #define cp932code(c,d)	((((uint) (uchar)(c)) << 8) | (uint) (uchar) (d))
 
 
-static MY_UNICASE_INFO c81[256]=
+static MY_UNICASE_CHARACTER c81[256]=
 {
   /* 8100-810F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -407,7 +407,7 @@ static MY_UNICASE_INFO c81[256]=
 };
 
 
-static MY_UNICASE_INFO c82[256]=
+static MY_UNICASE_CHARACTER c82[256]=
 {
   /* 8200-820F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -615,7 +615,7 @@ static MY_UNICASE_INFO c82[256]=
 };
 
 
-static MY_UNICASE_INFO c83[256]=
+static MY_UNICASE_CHARACTER c83[256]=
 {
   /* 8300-830F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -825,7 +825,7 @@ static MY_UNICASE_INFO c83[256]=
 };
 
 
-static MY_UNICASE_INFO c84[256]=
+static MY_UNICASE_CHARACTER c84[256]=
 {
   /* 8400-840F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1035,7 +1035,7 @@ static MY_UNICASE_INFO c84[256]=
 };
 
 
-static MY_UNICASE_INFO c87[256]=
+static MY_UNICASE_CHARACTER c87[256]=
 {
   /* 8700-870F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1245,7 +1245,7 @@ static MY_UNICASE_INFO c87[256]=
 };
 
 
-static MY_UNICASE_INFO cEE[256]=
+static MY_UNICASE_CHARACTER cEE[256]=
 {
   /* EE00-EE0F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1456,7 +1456,7 @@ static MY_UNICASE_INFO cEE[256]=
 };
 
 
-static MY_UNICASE_INFO cFA[256]=
+static MY_UNICASE_CHARACTER cFA[256]=
 {
   /* FA00-FA0F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1666,7 +1666,7 @@ static MY_UNICASE_INFO cFA[256]=
 };
 
 
-static MY_UNICASE_INFO *my_caseinfo_cp932[256]=
+static MY_UNICASE_CHARACTER *my_caseinfo_pages_cp932[256]=
 {
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0 */
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -1703,7 +1703,13 @@ static MY_UNICASE_INFO *my_caseinfo_cp93
 };
 
 
-static int my_strnncoll_cp932_internal(CHARSET_INFO *cs,
+MY_UNICASE_INFO my_caseinfo_cp932=
+{
+  0xFFFF,
+  my_caseinfo_pages_cp932
+};
+
+static int my_strnncoll_cp932_internal(const CHARSET_INFO *cs,
 				      const uchar **a_res, size_t a_length,
 				      const uchar **b_res, size_t b_length)
 {
@@ -34834,11 +34840,10 @@ struct charset_info_st my_charset_cp932_
     to_lower_cp932,
     to_upper_cp932,
     sort_order_cp932,
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_cp932,  /* caseinfo     */
+    &my_caseinfo_cp932, /* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */
@@ -34866,11 +34871,10 @@ struct charset_info_st my_charset_cp932_
     to_lower_cp932,
     to_upper_cp932,
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_cp932,  /* caseinfo     */
+    &my_caseinfo_cp932, /* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */

=== modified file 'strings/ctype-czech.c'
--- strings/ctype-czech.c	2012-01-13 14:50:02 +0000
+++ strings/ctype-czech.c	2013-08-29 07:45:28 +0000
@@ -613,11 +613,10 @@ struct charset_info_st my_charset_latin2
     to_lower_czech,
     to_upper_czech,
     sort_order_czech,
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     tab_8859_2_uni,	/* tab_to_uni   */
     idx_uni_8859_2,	/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     4,			/* strxfrm_multiply */

=== modified file 'strings/ctype-euc_kr.c'
--- strings/ctype-euc_kr.c	2012-01-13 14:50:02 +0000
+++ strings/ctype-euc_kr.c	2013-08-29 07:47:51 +0000
@@ -216,7 +216,7 @@ static uint mbcharlen_euc_kr(CHARSET_INF
 }
 
 
-static MY_UNICASE_INFO cA3[256]=
+static MY_UNICASE_CHARACTER cA3[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -421,7 +421,7 @@ static MY_UNICASE_INFO cA3[256]=
 };
 
 
-static MY_UNICASE_INFO cA5[256]=
+static MY_UNICASE_CHARACTER cA5[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -626,7 +626,7 @@ static MY_UNICASE_INFO cA5[256]=
 };
 
 
-static MY_UNICASE_INFO cA7[256]=
+static MY_UNICASE_CHARACTER cA7[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -831,7 +831,7 @@ static MY_UNICASE_INFO cA7[256]=
 };
 
 
-static MY_UNICASE_INFO cA8[256]=
+static MY_UNICASE_CHARACTER cA8[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1036,7 +1036,7 @@ static MY_UNICASE_INFO cA8[256]=
 };
 
 
-static MY_UNICASE_INFO cA9[256]=
+static MY_UNICASE_CHARACTER cA9[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1241,7 +1241,7 @@ static MY_UNICASE_INFO cA9[256]=
 };  
 
 
-static MY_UNICASE_INFO cAC[256]=
+static MY_UNICASE_CHARACTER cAC[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1446,7 +1446,7 @@ static MY_UNICASE_INFO cAC[256]=
 };
 
 
-static MY_UNICASE_INFO *my_caseinfo_euckr[256]=
+static MY_UNICASE_CHARACTER *my_caseinfo_pages_euckr[256]=
 {
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0 */
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -1483,6 +1483,13 @@ static MY_UNICASE_INFO *my_caseinfo_euck
 };
 
 
+static MY_UNICASE_INFO my_caseinfo_euckr=
+{
+  0xFFFF,
+  my_caseinfo_pages_euckr
+};
+
+
 /* page 0 0x8141-0xC8FE */
 static const uint16 tab_ksc5601_uni0[]={
 0xAC02,0xAC03,0xAC05,0xAC06,0xAC0B,0xAC0C,0xAC0D,0xAC0E,
@@ -10016,11 +10023,10 @@ struct charset_info_st my_charset_euckr_
     to_lower_euc_kr,
     to_upper_euc_kr,
     sort_order_euc_kr,
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_euckr,  /* caseinfo     */
+    &my_caseinfo_euckr, /* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */
@@ -10049,11 +10055,10 @@ struct charset_info_st my_charset_euckr_
     to_lower_euc_kr,
     to_upper_euc_kr,
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_euckr,  /* caseinfo     */
+    &my_caseinfo_euckr, /* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */

=== modified file 'strings/ctype-eucjpms.c'
--- strings/ctype-eucjpms.c	2013-07-16 17:09:54 +0000
+++ strings/ctype-eucjpms.c	2013-08-29 07:49:51 +0000
@@ -203,7 +203,7 @@ static uint mbcharlen_eucjpms(CHARSET_IN
 
 /* Case info pages for JIS-X-0208 range */
 
-static MY_UNICASE_INFO cA2[256]=
+static MY_UNICASE_CHARACTER cA2[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -324,7 +324,7 @@ static MY_UNICASE_INFO cA2[256]=
 };
 
 
-static MY_UNICASE_INFO cA3[256]=
+static MY_UNICASE_CHARACTER cA3[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -445,7 +445,7 @@ static MY_UNICASE_INFO cA3[256]=
 };
 
 
-static MY_UNICASE_INFO cA6[256]=
+static MY_UNICASE_CHARACTER cA6[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -566,7 +566,7 @@ static MY_UNICASE_INFO cA6[256]=
 };
 
 
-static MY_UNICASE_INFO cA7[256]=
+static MY_UNICASE_CHARACTER cA7[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -687,7 +687,7 @@ static MY_UNICASE_INFO cA7[256]=
 };
 
 
-static MY_UNICASE_INFO cAD[256]=
+static MY_UNICASE_CHARACTER cAD[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -810,7 +810,7 @@ static MY_UNICASE_INFO cAD[256]=
 
 /* Case info pages for JIS-X-0212 range */
 
-static MY_UNICASE_INFO c8FA6[256]=
+static MY_UNICASE_CHARACTER c8FA6[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -931,7 +931,7 @@ static MY_UNICASE_INFO c8FA6[256]=
 };
 
 
-static MY_UNICASE_INFO c8FA7[256]=
+static MY_UNICASE_CHARACTER c8FA7[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1052,7 +1052,7 @@ static MY_UNICASE_INFO c8FA7[256]=
 };
 
 
-static MY_UNICASE_INFO c8FA9[256]=
+static MY_UNICASE_CHARACTER c8FA9[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1173,7 +1173,7 @@ static MY_UNICASE_INFO c8FA9[256]=
 };
 
 
-static MY_UNICASE_INFO c8FAA[256]=
+static MY_UNICASE_CHARACTER c8FAA[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1294,7 +1294,7 @@ static MY_UNICASE_INFO c8FAA[256]=
 };
 
 
-static MY_UNICASE_INFO c8FAB[256]=
+static MY_UNICASE_CHARACTER c8FAB[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1415,7 +1415,7 @@ static MY_UNICASE_INFO c8FAB[256]=
 };
 
 
-static MY_UNICASE_INFO c8FF3[256]=
+static MY_UNICASE_CHARACTER c8FF3[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1536,7 +1536,7 @@ static MY_UNICASE_INFO c8FF3[256]=
 };
 
 
-static MY_UNICASE_INFO c8FF4[256]=
+static MY_UNICASE_CHARACTER c8FF4[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1657,7 +1657,7 @@ static MY_UNICASE_INFO c8FF4[256]=
 };
 
 
-static MY_UNICASE_INFO *my_caseinfo_eucjpms[512]=
+static MY_UNICASE_CHARACTER *my_caseinfo_pages_eucjpms[512]=
 {
   /* JIS-X-0208 */
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0 */
@@ -1729,7 +1729,14 @@ static MY_UNICASE_INFO *my_caseinfo_eucj
 };
 
 
-static const uint16 jisx0208_eucjpms_to_unicode[65536]=
+static MY_UNICASE_INFO my_caseinfo_eucjpms=
+{
+  0x0FFFF,
+  my_caseinfo_pages_eucjpms
+};
+
+
+static uint16 jisx0208_eucjpms_to_unicode[65536]=
 {
       0x0000,      0x0001,      0x0002,      0x0003, /* 0000 */
       0x0004,      0x0005,      0x0006,      0x0007,
@@ -67559,11 +67566,10 @@ struct charset_info_st my_charset_eucjpm
     to_lower_eucjpms,
     to_upper_eucjpms,
     sort_order_eucjpms,
-    NULL,		/* sort_order_big*/
-    NULL,		/* contractions */
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_eucjpms,/* caseinfo     */
+    &my_caseinfo_eucjpms,/* caseinfo    */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */
@@ -67592,11 +67598,10 @@ struct charset_info_st my_charset_eucjpm
     to_lower_eucjpms,
     to_upper_eucjpms,
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_eucjpms,/* caseinfo     */
+    &my_caseinfo_eucjpms,/* caseinfo    */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */

=== modified file 'strings/ctype-extra.c'
--- strings/ctype-extra.c	2012-01-13 14:50:02 +0000
+++ strings/ctype-extra.c	2013-08-29 07:55:47 +0000
@@ -6616,11 +6616,10 @@ struct charset_info_st compiled_charsets
   to_lower_dec8_swedish_ci,                /* lower         */
   to_upper_dec8_swedish_ci,                /* upper         */
   sort_order_dec8_swedish_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_dec8_swedish_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -6649,11 +6648,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp850_general_ci,                /* lower         */
   to_upper_cp850_general_ci,                /* upper         */
   sort_order_cp850_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp850_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -6682,11 +6680,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin1_german1_ci,                /* lower         */
   to_upper_latin1_german1_ci,                /* upper         */
   sort_order_latin1_german1_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin1_german1_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -6715,11 +6712,10 @@ struct charset_info_st compiled_charsets
   to_lower_hp8_english_ci,                /* lower         */
   to_upper_hp8_english_ci,                /* upper         */
   sort_order_hp8_english_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_hp8_english_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -6748,11 +6744,10 @@ struct charset_info_st compiled_charsets
   to_lower_koi8r_general_ci,                /* lower         */
   to_upper_koi8r_general_ci,                /* upper         */
   sort_order_koi8r_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_koi8r_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -6781,11 +6776,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin2_general_ci,                /* lower         */
   to_upper_latin2_general_ci,                /* upper         */
   sort_order_latin2_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin2_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -6814,11 +6808,10 @@ struct charset_info_st compiled_charsets
   to_lower_swe7_swedish_ci,                /* lower         */
   to_upper_swe7_swedish_ci,                /* upper         */
   sort_order_swe7_swedish_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_swe7_swedish_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -6847,11 +6840,10 @@ struct charset_info_st compiled_charsets
   to_lower_ascii_general_ci,                /* lower         */
   to_upper_ascii_general_ci,                /* upper         */
   sort_order_ascii_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_ascii_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -6880,11 +6872,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1251_bulgarian_ci,                /* lower         */
   to_upper_cp1251_bulgarian_ci,                /* upper         */
   sort_order_cp1251_bulgarian_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1251_bulgarian_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -6913,11 +6904,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin1_danish_ci,                /* lower         */
   to_upper_latin1_danish_ci,                /* upper         */
   sort_order_latin1_danish_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin1_danish_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -6946,11 +6936,10 @@ struct charset_info_st compiled_charsets
   to_lower_hebrew_general_ci,                /* lower         */
   to_upper_hebrew_general_ci,                /* upper         */
   sort_order_hebrew_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_hebrew_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -6979,11 +6968,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin7_estonian_cs,                /* lower         */
   to_upper_latin7_estonian_cs,                /* upper         */
   sort_order_latin7_estonian_cs,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin7_estonian_cs,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7012,11 +7000,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin2_hungarian_ci,                /* lower         */
   to_upper_latin2_hungarian_ci,                /* upper         */
   sort_order_latin2_hungarian_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin2_hungarian_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7045,11 +7032,10 @@ struct charset_info_st compiled_charsets
   to_lower_koi8u_general_ci,                /* lower         */
   to_upper_koi8u_general_ci,                /* upper         */
   sort_order_koi8u_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_koi8u_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7078,11 +7064,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1251_ukrainian_ci,                /* lower         */
   to_upper_cp1251_ukrainian_ci,                /* upper         */
   sort_order_cp1251_ukrainian_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1251_ukrainian_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7111,11 +7096,10 @@ struct charset_info_st compiled_charsets
   to_lower_greek_general_ci,                /* lower         */
   to_upper_greek_general_ci,                /* upper         */
   sort_order_greek_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_greek_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7144,11 +7128,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1250_general_ci,                /* lower         */
   to_upper_cp1250_general_ci,                /* upper         */
   sort_order_cp1250_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1250_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7177,11 +7160,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin2_croatian_ci,                /* lower         */
   to_upper_latin2_croatian_ci,                /* upper         */
   sort_order_latin2_croatian_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin2_croatian_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7210,11 +7192,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1257_lithuanian_ci,                /* lower         */
   to_upper_cp1257_lithuanian_ci,                /* upper         */
   sort_order_cp1257_lithuanian_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1257_lithuanian_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7243,11 +7224,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin5_turkish_ci,                /* lower         */
   to_upper_latin5_turkish_ci,                /* upper         */
   sort_order_latin5_turkish_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin5_turkish_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7276,11 +7256,10 @@ struct charset_info_st compiled_charsets
   to_lower_armscii8_general_ci,                /* lower         */
   to_upper_armscii8_general_ci,                /* upper         */
   sort_order_armscii8_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_armscii8_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7309,11 +7288,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp866_general_ci,                /* lower         */
   to_upper_cp866_general_ci,                /* upper         */
   sort_order_cp866_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp866_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7342,11 +7320,10 @@ struct charset_info_st compiled_charsets
   to_lower_keybcs2_general_ci,                /* lower         */
   to_upper_keybcs2_general_ci,                /* upper         */
   sort_order_keybcs2_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_keybcs2_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7375,11 +7352,10 @@ struct charset_info_st compiled_charsets
   to_lower_macce_general_ci,                /* lower         */
   to_upper_macce_general_ci,                /* upper         */
   sort_order_macce_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_macce_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7408,11 +7384,10 @@ struct charset_info_st compiled_charsets
   to_lower_macroman_general_ci,                /* lower         */
   to_upper_macroman_general_ci,                /* upper         */
   sort_order_macroman_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_macroman_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7441,11 +7416,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp852_general_ci,                /* lower         */
   to_upper_cp852_general_ci,                /* upper         */
   sort_order_cp852_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp852_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7474,11 +7448,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin7_general_ci,                /* lower         */
   to_upper_latin7_general_ci,                /* upper         */
   sort_order_latin7_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin7_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7507,11 +7480,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin7_general_cs,                /* lower         */
   to_upper_latin7_general_cs,                /* upper         */
   sort_order_latin7_general_cs,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin7_general_cs,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7540,11 +7512,10 @@ struct charset_info_st compiled_charsets
   to_lower_macce_bin,                /* lower         */
   to_upper_macce_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_macce_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7573,11 +7544,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1250_croatian_ci,                /* lower         */
   to_upper_cp1250_croatian_ci,                /* upper         */
   sort_order_cp1250_croatian_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1250_croatian_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7606,11 +7576,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin1_general_ci,                /* lower         */
   to_upper_latin1_general_ci,                /* upper         */
   sort_order_latin1_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin1_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7639,11 +7608,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin1_general_cs,                /* lower         */
   to_upper_latin1_general_cs,                /* upper         */
   sort_order_latin1_general_cs,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin1_general_cs,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7672,11 +7640,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1251_bin,                /* lower         */
   to_upper_cp1251_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1251_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7705,11 +7672,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1251_general_ci,                /* lower         */
   to_upper_cp1251_general_ci,                /* upper         */
   sort_order_cp1251_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1251_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7738,11 +7704,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1251_general_cs,                /* lower         */
   to_upper_cp1251_general_cs,                /* upper         */
   sort_order_cp1251_general_cs,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1251_general_cs,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7771,11 +7736,10 @@ struct charset_info_st compiled_charsets
   to_lower_macroman_bin,                /* lower         */
   to_upper_macroman_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_macroman_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7804,11 +7768,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1256_general_ci,                /* lower         */
   to_upper_cp1256_general_ci,                /* upper         */
   sort_order_cp1256_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1256_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7837,11 +7800,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1257_bin,                /* lower         */
   to_upper_cp1257_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1257_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7870,11 +7832,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1257_general_ci,                /* lower         */
   to_upper_cp1257_general_ci,                /* upper         */
   sort_order_cp1257_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1257_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7903,11 +7864,10 @@ struct charset_info_st compiled_charsets
   to_lower_armscii8_bin,                /* lower         */
   to_upper_armscii8_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_armscii8_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7936,11 +7896,10 @@ struct charset_info_st compiled_charsets
   to_lower_ascii_bin,                /* lower         */
   to_upper_ascii_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_ascii_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -7969,11 +7928,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1250_bin,                /* lower         */
   to_upper_cp1250_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1250_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8002,11 +7960,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1256_bin,                /* lower         */
   to_upper_cp1256_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1256_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8035,11 +7992,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp866_bin,                /* lower         */
   to_upper_cp866_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp866_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8068,11 +8024,10 @@ struct charset_info_st compiled_charsets
   to_lower_dec8_bin,                /* lower         */
   to_upper_dec8_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_dec8_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8101,11 +8056,10 @@ struct charset_info_st compiled_charsets
   to_lower_greek_bin,                /* lower         */
   to_upper_greek_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_greek_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8134,11 +8088,10 @@ struct charset_info_st compiled_charsets
   to_lower_hebrew_bin,                /* lower         */
   to_upper_hebrew_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_hebrew_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8167,11 +8120,10 @@ struct charset_info_st compiled_charsets
   to_lower_hp8_bin,                /* lower         */
   to_upper_hp8_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_hp8_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8200,11 +8152,10 @@ struct charset_info_st compiled_charsets
   to_lower_keybcs2_bin,                /* lower         */
   to_upper_keybcs2_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_keybcs2_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8233,11 +8184,10 @@ struct charset_info_st compiled_charsets
   to_lower_koi8r_bin,                /* lower         */
   to_upper_koi8r_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_koi8r_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8266,11 +8216,10 @@ struct charset_info_st compiled_charsets
   to_lower_koi8u_bin,                /* lower         */
   to_upper_koi8u_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_koi8u_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8299,11 +8248,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin2_bin,                /* lower         */
   to_upper_latin2_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin2_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8332,11 +8280,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin5_bin,                /* lower         */
   to_upper_latin5_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin5_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8365,11 +8312,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin7_bin,                /* lower         */
   to_upper_latin7_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin7_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8398,11 +8344,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp850_bin,                /* lower         */
   to_upper_cp850_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp850_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8431,11 +8376,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp852_bin,                /* lower         */
   to_upper_cp852_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp852_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8464,11 +8408,10 @@ struct charset_info_st compiled_charsets
   to_lower_swe7_bin,                /* lower         */
   to_upper_swe7_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_swe7_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8497,11 +8440,10 @@ struct charset_info_st compiled_charsets
   to_lower_geostd8_general_ci,                /* lower         */
   to_upper_geostd8_general_ci,                /* upper         */
   sort_order_geostd8_general_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_geostd8_general_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8530,11 +8472,10 @@ struct charset_info_st compiled_charsets
   to_lower_geostd8_bin,                /* lower         */
   to_upper_geostd8_bin,                /* upper         */
   NULL,                     /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_geostd8_bin,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8563,11 +8504,10 @@ struct charset_info_st compiled_charsets
   to_lower_latin1_spanish_ci,                /* lower         */
   to_upper_latin1_spanish_ci,                /* upper         */
   sort_order_latin1_spanish_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_latin1_spanish_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8596,11 +8536,10 @@ struct charset_info_st compiled_charsets
   to_lower_cp1250_polish_ci,                /* lower         */
   to_upper_cp1250_polish_ci,                /* upper         */
   sort_order_cp1250_polish_ci,            /* sort_order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   to_uni_cp1250_polish_ci,                  /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/
@@ -8628,11 +8567,10 @@ struct charset_info_st compiled_charsets
   NULL,                       /* lower         */
   NULL,                       /* upper         */
   NULL,                       /* sort order    */
-  NULL,                       /* contractions  */
-  NULL,                       /* sort_order_big*/
+  NULL,                       /* uca           */
   NULL,                       /* to_uni        */
   NULL,                       /* from_uni      */
-  my_unicase_default,         /* caseinfo      */
+  &my_unicase_default,        /* caseinfo      */
   NULL,                       /* state map     */
   NULL,                       /* ident map     */
   1,                          /* strxfrm_multiply*/

=== modified file 'strings/ctype-gb2312.c'
--- strings/ctype-gb2312.c	2012-01-13 14:50:02 +0000
+++ strings/ctype-gb2312.c	2013-08-29 08:00:35 +0000
@@ -177,7 +177,7 @@ static uint mbcharlen_gb2312(CHARSET_INF
 }
 
 
-static MY_UNICASE_INFO cA2[256]=
+static MY_UNICASE_CHARACTER cA2[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -298,7 +298,7 @@ static MY_UNICASE_INFO cA2[256]=
 };
 
 
-static MY_UNICASE_INFO cA3[256]=
+static MY_UNICASE_CHARACTER cA3[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -419,7 +419,7 @@ static MY_UNICASE_INFO cA3[256]=
 };
 
 
-static MY_UNICASE_INFO cA6[256]=
+static MY_UNICASE_CHARACTER cA6[256]=
 { 
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -540,7 +540,7 @@ static MY_UNICASE_INFO cA6[256]=
 };
   
 
-static MY_UNICASE_INFO cA7[256]=
+static MY_UNICASE_CHARACTER cA7[256]=
 {  
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -661,7 +661,7 @@ static MY_UNICASE_INFO cA7[256]=
 };
   
 
-static MY_UNICASE_INFO cA8[256]=
+static MY_UNICASE_CHARACTER cA8[256]=
 { 
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -782,7 +782,7 @@ static MY_UNICASE_INFO cA8[256]=
 };
 
 
-static MY_UNICASE_INFO *my_caseinfo_gb2312[256]=
+static MY_UNICASE_CHARACTER *my_caseinfo_pages_gb2312[256]=
 {
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0 */
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -819,6 +819,13 @@ static MY_UNICASE_INFO *my_caseinfo_gb23
 };
 
 
+static MY_UNICASE_INFO my_caseinfo_gb2312=
+{
+  0xFFFF,
+  my_caseinfo_pages_gb2312
+};
+
+
 /* page 0 0x2121-0x2658 */
 static const uint16 tab_gb2312_uni0[]={
 0x3000,0x3001,0x3002,0x30FB,0x02C9,0x02C7,0x00A8,0x3003,
@@ -6419,11 +6426,10 @@ struct charset_info_st my_charset_gb2312
     to_lower_gb2312,
     to_upper_gb2312,
     sort_order_gb2312,
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_gb2312, /* caseinfo     */
+    &my_caseinfo_gb2312,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */
@@ -6451,11 +6457,10 @@ struct charset_info_st my_charset_gb2312
     to_lower_gb2312,
     to_upper_gb2312,
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_gb2312, /* caseinfo     */
+    &my_caseinfo_gb2312,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */

=== modified file 'strings/ctype-gbk.c'
--- strings/ctype-gbk.c	2013-03-25 22:03:13 +0000
+++ strings/ctype-gbk.c	2013-08-29 08:01:57 +0000
@@ -136,7 +136,8 @@ static const uchar to_upper_gbk[]=
   (uchar) '\370',(uchar) '\371',(uchar) '\372',(uchar) '\373',(uchar) '\374',(uchar) '\375',(uchar) '\376',(uchar) '\377',
 };
 
-static MY_UNICASE_INFO cA2[256]=
+
+static MY_UNICASE_CHARACTER cA2[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -340,7 +341,7 @@ static MY_UNICASE_INFO cA2[256]=
   {0xA2FF,0xA2FF,0xA2FF}
 };
 
-static MY_UNICASE_INFO cA3[256]=
+static MY_UNICASE_CHARACTER cA3[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -545,7 +546,7 @@ static MY_UNICASE_INFO cA3[256]=
 };
 
 
-static MY_UNICASE_INFO cA6[256]=
+static MY_UNICASE_CHARACTER cA6[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -750,7 +751,7 @@ static MY_UNICASE_INFO cA6[256]=
 };
 
 
-static MY_UNICASE_INFO cA7[256]=
+static MY_UNICASE_CHARACTER cA7[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -955,7 +956,7 @@ static MY_UNICASE_INFO cA7[256]=
 };
 
 
-static MY_UNICASE_INFO *my_caseinfo_gbk[256]=
+static MY_UNICASE_CHARACTER *my_caseinfo_pages_gbk[256]=
 {
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0 */
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -991,7 +992,15 @@ static MY_UNICASE_INFO *my_caseinfo_gbk[
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 
-static const uchar sort_order_gbk[]=
+
+static MY_UNICASE_INFO my_caseinfo_gbk=
+{
+  0xFFFF,
+  my_caseinfo_pages_gbk
+};
+
+
+static uchar sort_order_gbk[]=
 {
   '\000','\001','\002','\003','\004','\005','\006','\007',
   '\010','\011','\012','\013','\014','\015','\016','\017',
@@ -10809,11 +10818,10 @@ struct charset_info_st my_charset_gbk_ch
     to_lower_gbk,
     to_upper_gbk,
     sort_order_gbk,
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_gbk,    /* caseinfo     */
+    &my_caseinfo_gbk,   /* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */
@@ -10841,11 +10849,10 @@ struct charset_info_st my_charset_gbk_bi
     to_lower_gbk,
     to_upper_gbk,
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_gbk,    /* caseinfo     */
+    &my_caseinfo_gbk,   /* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */

=== modified file 'strings/ctype-latin1.c'
--- strings/ctype-latin1.c	2013-04-15 13:09:22 +0000
+++ strings/ctype-latin1.c	2013-08-29 08:07:30 +0000
@@ -437,11 +437,10 @@ struct charset_info_st my_charset_latin1
     to_lower_latin1,
     to_upper_latin1,
     sort_order_latin1,
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     cs_to_uni,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */
@@ -736,11 +735,10 @@ struct charset_info_st my_charset_latin1
   to_lower_latin1,
   to_upper_latin1,
   sort_order_latin1_de,
-  NULL,					/* contractions */
-  NULL,					/* sort_order_big*/
+  NULL,					/* uca          */
   cs_to_uni,				/* tab_to_uni   */
   NULL,					/* tab_from_uni */
-  my_unicase_default,                   /* caseinfo     */
+  &my_unicase_default,                  /* caseinfo     */
   NULL,					/* state_map    */
   NULL,					/* ident_map    */
   2,					/* strxfrm_multiply */
@@ -769,11 +767,10 @@ struct charset_info_st my_charset_latin1
   to_lower_latin1,
   to_upper_latin1,
   NULL,					/* sort_order   */
-  NULL,					/* contractions */
-  NULL,					/* sort_order_big*/
+  NULL,					/* uca          */
   cs_to_uni,				/* tab_to_uni   */
   NULL,					/* tab_from_uni */
-  my_unicase_default,                   /* caseinfo     */
+  &my_unicase_default,                  /* caseinfo     */
   NULL,					/* state_map    */
   NULL,					/* ident_map    */
   1,					/* strxfrm_multiply */

=== modified file 'strings/ctype-mb.c'
--- strings/ctype-mb.c	2013-07-21 14:39:19 +0000
+++ strings/ctype-mb.c	2013-08-29 10:07:40 +0000
@@ -62,11 +62,11 @@ size_t my_casedn_str_mb(CHARSET_INFO * c
 }
 
 
-static inline MY_UNICASE_INFO*
-get_case_info_for_ch(CHARSET_INFO *cs, uint page, uint offs)
+static inline MY_UNICASE_CHARACTER*
+get_case_info_for_ch(const CHARSET_INFO *cs, uint page, uint offs)
 {
-  MY_UNICASE_INFO *p;
-  return cs->caseinfo ? ((p= cs->caseinfo[page]) ? &p[offs] : NULL) :  NULL;
+  MY_UNICASE_CHARACTER *p;
+  return cs->caseinfo ? ((p= cs->caseinfo->page[page]) ? &p[offs] : NULL) :  NULL;
 }
 
 
@@ -89,7 +89,7 @@ size_t my_caseup_mb(CHARSET_INFO * cs, c
   {
     if ((l=my_ismbchar(cs, src, srcend)))
     {
-      MY_UNICASE_INFO *ch;
+      MY_UNICASE_CHARACTER *ch;
       if ((ch= get_case_info_for_ch(cs, (uchar) src[0], (uchar) src[1])))
       {
         *src++= ch->toupper >> 8;
@@ -124,7 +124,7 @@ size_t my_casedn_mb(CHARSET_INFO * cs, c
   {
     if ((l= my_ismbchar(cs, src, srcend)))
     {
-      MY_UNICASE_INFO *ch;
+      MY_UNICASE_CHARACTER *ch;
       if ((ch= get_case_info_for_ch(cs, (uchar) src[0], (uchar) src[1])))
       {
         *src++= ch->tolower >> 8;
@@ -168,7 +168,7 @@ my_casefold_mb_varlen(CHARSET_INFO *cs,
     size_t mblen= my_ismbchar(cs, src, srcend);
     if (mblen)
     {
-      MY_UNICASE_INFO *ch;
+      MY_UNICASE_CHARACTER *ch;
       if ((ch= get_case_info_for_ch(cs, (uchar) src[0], (uchar) src[1])))
       {
         int code= is_upper ? ch->toupper : ch->tolower;
@@ -696,7 +696,7 @@ my_bool my_like_range_mb(CHARSET_INFO *c
   char *min_end= min_str + res_length;
   char *max_end= max_str + res_length;
   size_t maxcharlen= res_length / cs->mbmaxlen;
-  my_bool have_contractions= my_cs_have_contractions(cs);
+  const MY_CONTRACTIONS *contractions= my_charset_get_contractions(cs, 0);
 
   for (; ptr != end && min_str != min_end && maxcharlen ; maxcharlen--)
   {
@@ -764,8 +764,8 @@ my_bool my_like_range_mb(CHARSET_INFO *c
         'ab\min\min\min\min' and 'ab\max\max\max\max'.
 
       */
-      if (have_contractions && ptr + 1 < end &&
-          my_cs_can_be_contraction_head(cs, (uchar) *ptr))
+      if (contractions && ptr + 1 < end &&
+          my_uca_can_be_contraction_head(contractions, (uchar) *ptr))
       {
         /* Ptr[0] is a contraction head. */
         
@@ -787,8 +787,8 @@ my_bool my_like_range_mb(CHARSET_INFO *c
           is not a contraction, then we put only ptr[0],
           and continue with ptr[1] on the next loop.
         */
-        if (my_cs_can_be_contraction_tail(cs, (uchar) ptr[1]) &&
-            my_cs_contraction2_weight(cs, (uchar) ptr[0], (uchar) ptr[1]))
+        if (my_uca_can_be_contraction_tail(contractions, (uchar) ptr[1]) &&
+            my_uca_contraction2_weight(contractions, (uchar) ptr[0], ptr[1]))
         {
           /* Contraction found */
           if (maxcharlen == 1 || min_str + 1 >= min_end)
@@ -853,7 +853,7 @@ my_like_range_generic(CHARSET_INFO *cs,
   char *max_end= max_str + res_length;
   size_t charlen= res_length / cs->mbmaxlen;
   size_t res_length_diff;
-  my_bool have_contractions= my_cs_have_contractions(cs);
+  const MY_CONTRACTIONS *contractions= my_charset_get_contractions(cs, 0);
 
   for ( ; charlen > 0; charlen--)
   {
@@ -921,8 +921,8 @@ my_like_range_generic(CHARSET_INFO *cs,
       goto pad_min_max;
     }
 
-    if (have_contractions &&
-        my_cs_can_be_contraction_head(cs, wc) &&
+    if (contractions &&
+        my_uca_can_be_contraction_head(contractions, wc) &&
         (res= cs->cset->mb_wc(cs, &wc2, (uchar*) ptr, (uchar*) end)) > 0)
     {
       const uint16 *weight;
@@ -933,8 +933,8 @@ my_like_range_generic(CHARSET_INFO *cs,
         goto pad_min_max;
       }
 
-      if (my_cs_can_be_contraction_tail(cs, wc2) &&
-          (weight= my_cs_contraction2_weight(cs, wc, wc2)) && weight[0])
+      if (my_uca_can_be_contraction_tail(contractions, wc2) &&
+          (weight= my_uca_contraction2_weight(contractions, wc, wc2)) && weight[0])
       {
         /* Contraction found */
         if (charlen == 1)

=== modified file 'strings/ctype-simple.c'
--- strings/ctype-simple.c	2013-07-21 14:39:19 +0000
+++ strings/ctype-simple.c	2013-09-17 11:41:12 +0000
@@ -1163,12 +1163,12 @@ static int pcmp(const void * f, const vo
   return res;
 }
 
-static my_bool create_fromuni(struct charset_info_st *cs,
-                              void *(*alloc)(size_t))
+static my_bool
+create_fromuni(struct charset_info_st *cs,
+               MY_CHARSET_LOADER *loader)
 {
   uni_idx	idx[PLANE_NUM];
   int		i,n;
-  struct my_uni_idx_st *tab_from_uni;
   
   /*
     Check that Unicode map is loaded.
@@ -1217,7 +1217,8 @@ static my_bool create_fromuni(struct cha
     
     numchars=idx[i].uidx.to-idx[i].uidx.from+1;
     if (!(idx[i].uidx.tab= tab= (uchar*)
-          alloc(numchars * sizeof(*idx[i].uidx.tab))))
+                                (loader->once_alloc) (numchars *
+                                                      sizeof(*idx[i].uidx.tab))))
       return TRUE;
     
     bzero(tab,numchars*sizeof(*tab));
@@ -1235,25 +1236,25 @@ static my_bool create_fromuni(struct cha
   
   /* Allocate and fill reverse table for each plane */
   n=i;
-  if (!(cs->tab_from_uni= tab_from_uni= (struct my_uni_idx_st*)
-        alloc(sizeof(MY_UNI_IDX)*(n+1))))
+  if (!(cs->tab_from_uni= (MY_UNI_IDX *)
+                          (loader->once_alloc)(sizeof(MY_UNI_IDX) * (n + 1))))
     return TRUE;
 
   for (i=0; i< n; i++)
-    tab_from_uni[i]= idx[i].uidx;
+    ((struct my_uni_idx_st*)cs->tab_from_uni)[i]= idx[i].uidx;
   
   /* Set end-of-list marker */
-  bzero(&tab_from_uni[i],sizeof(MY_UNI_IDX));
+  bzero((char*) &cs->tab_from_uni[i],sizeof(MY_UNI_IDX));
   return FALSE;
 }
 
-static my_bool my_cset_init_8bit(struct charset_info_st *cs,
-                                 void *(*alloc)(size_t))
+static my_bool
+my_cset_init_8bit(struct charset_info_st *cs, MY_CHARSET_LOADER *loader)
 {
   cs->caseup_multiply= 1;
   cs->casedn_multiply= 1;
   cs->pad_char= ' ';
-  return create_fromuni(cs, alloc);
+  return create_fromuni(cs, loader);
 }
 
 static void set_max_sort_char(struct charset_info_st *cs)
@@ -1276,7 +1277,7 @@ static void set_max_sort_char(struct cha
 }
 
 static my_bool my_coll_init_simple(struct charset_info_st *cs,
-                                   void *(*alloc)(size_t) __attribute__((unused)))
+                                   MY_CHARSET_LOADER *loader __attribute__((unused)))
 {
   set_max_sort_char(cs);
   return FALSE;

=== modified file 'strings/ctype-sjis.c'
--- strings/ctype-sjis.c	2012-01-13 14:50:02 +0000
+++ strings/ctype-sjis.c	2013-08-29 08:09:16 +0000
@@ -197,7 +197,7 @@ static uint mbcharlen_sjis(CHARSET_INFO
 #define sjiscode(c,d)	((((uint) (uchar)(c)) << 8) | (uint) (uchar) (d))
 
 
-static MY_UNICASE_INFO c81[256]=
+static MY_UNICASE_CHARACTER c81[256]=
 {
   /* 8100-810F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -407,7 +407,7 @@ static MY_UNICASE_INFO c81[256]=
 };
 
 
-static MY_UNICASE_INFO c82[256]=
+static MY_UNICASE_CHARACTER c82[256]=
 {
   /* 8200-820F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -615,7 +615,7 @@ static MY_UNICASE_INFO c82[256]=
 };
 
 
-static MY_UNICASE_INFO c83[256]=
+static MY_UNICASE_CHARACTER c83[256]=
 {
   /* 8300-830F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -825,7 +825,7 @@ static MY_UNICASE_INFO c83[256]=
 };
 
 
-static MY_UNICASE_INFO c84[256]=
+static MY_UNICASE_CHARACTER c84[256]=
 {
   /* 8400-840F */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -1035,7 +1035,7 @@ static MY_UNICASE_INFO c84[256]=
 };
 
 
-static MY_UNICASE_INFO *my_caseinfo_sjis[256]=
+static MY_UNICASE_CHARACTER *my_caseinfo_pages_sjis[256]=
 {
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0 */
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -1072,7 +1072,14 @@ static MY_UNICASE_INFO *my_caseinfo_sjis
 };
 
 
-static int my_strnncoll_sjis_internal(CHARSET_INFO *cs,
+static MY_UNICASE_INFO my_caseinfo_sjis=
+{
+  0xFFFF,
+  my_caseinfo_pages_sjis
+};
+
+
+static int my_strnncoll_sjis_internal(const CHARSET_INFO *cs,
 				      const uchar **a_res, size_t a_length,
 				      const uchar **b_res, size_t b_length)
 {
@@ -34204,11 +34211,10 @@ struct charset_info_st my_charset_sjis_j
     to_lower_sjis,
     to_upper_sjis,
     sort_order_sjis,
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_sjis,   /* caseinfo     */
+    &my_caseinfo_sjis,  /* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */
@@ -34236,11 +34242,10 @@ struct charset_info_st my_charset_sjis_b
     to_lower_sjis,
     to_upper_sjis,
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_sjis,   /* caseinfo     */
+    &my_caseinfo_sjis,  /* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */

=== modified file 'strings/ctype-tis620.c'
--- strings/ctype-tis620.c	2013-03-25 22:03:13 +0000
+++ strings/ctype-tis620.c	2013-08-29 08:10:04 +0000
@@ -894,11 +894,10 @@ struct charset_info_st my_charset_tis620
     to_lower_tis620,
     to_upper_tis620,
     sort_order_tis620,
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     4,			/* strxfrm_multiply */
@@ -926,11 +925,10 @@ struct charset_info_st my_charset_tis620
     to_lower_tis620,
     to_upper_tis620,
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */

=== modified file 'strings/ctype-uca.c'
--- strings/ctype-uca.c	2013-07-21 14:39:19 +0000
+++ strings/ctype-uca.c	2013-09-17 13:16:55 +0000
@@ -46,7 +46,6 @@
 #define MY_UCA_NCHARS 256
 #define MY_UCA_CMASK  255
 #define MY_UCA_PSHIFT 8
-#define MAX_UCA_CHAR_WITH_EXPLICIT_WEIGHT 0xFFFF
 
 static const uint16 page000data[]= { /* 0000 (4 weights per char) */
 0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,
@@ -6526,6 +6525,59 @@ NULL       ,page0F9data,page0FAdata,page
 page0FCdata,page0FDdata,page0FEdata,page0FFdata
 };
 
+
+MY_UCA_INFO my_uca_v400=
+{
+  {
+    {
+      0xFFFF,    /* maxchar           */
+      (uchar *) uca_length,
+      (uint16 **) uca_weight,
+      {          /* Contractions:     */
+        0,       /*   nitems          */
+        NULL,    /*   item            */
+        NULL     /*   flags           */
+      }
+    },
+  },
+
+  /* Logical positions */
+  0x0009,    /* first_non_ignorable       p != ignore                  */
+  0xA48C,    /* last_non_ignorable        Not a CJK and not UNASSIGNED */
+
+  0x0332,    /* first_primary_ignorable   p == 0                       */
+  0x20EA,    /* last_primary_ignorable                                 */
+
+  0x0000,    /* first_secondary_ignorable p,s == 0                     */
+  0xFE73,    /* last_secondary_ignorable  p,s == 0                     */
+
+  0x0000,    /* first_tertiary_ignorable  p,s,t == 0                   */
+  0xFE73,    /* last_tertiary_ignorable   p,s,t == 0                   */
+
+  0x0000,    /* first_trailing            */
+  0x0000,    /* last_trailing             */
+
+  0x0009,    /* first_variable            */
+  0x2183,    /* last_variable             */
+};
+
+/******************************************************/
+
+#define MY_UCA_CMASK  255
+#define MY_UCA_PSHIFT 8
+
+
+/******************************************************/
+
+/*
+  German Phonebook
+*/
+static const char german2[]=
+    "&AE << \\u00E6 <<< \\u00C6 << \\u00E4 <<< \\u00C4 "
+    "&OE << \\u0153 <<< \\u0152 << \\u00F6 <<< \\u00D6 "
+    "&UE << \\u00FC <<< \\u00DC ";
+
+
 /*
   Some sources treat LETTER A WITH DIARESIS (00E4,00C4)
   secondary greater than LETTER AE (00E6,00C6).
@@ -6686,7 +6738,13 @@ static const char persian[]=
     "& \\u0642 < \\u06A9 < \\u0643"
     "& \\u0648 < \\u0647 < \\u0629 < \\u06C0 < \\u06CC < \\u0649 < \\u064A"
     "& \\uFE80 < \\uFE81 < \\uFE82 < \\uFE8D < \\uFE8E < \\uFB50 < \\uFB51"
-             " < \\uFE80 < \\uFE83 < \\uFE84 < \\uFE87 < \\uFE88 < \\uFE85"
+             " < \\uFE80 "
+    /*
+      FE80 appears both in reset and shift.
+      We need to break the rule here and reset to *new* FE80 again,
+      so weight for FE83 is calculated as P[FE80]+1, not as P[FE80]+8.
+    */
+             " & \\uFE80 < \\uFE83 < \\uFE84 < \\uFE87 < \\uFE88 < \\uFE85"
              " < \\uFE86 < \\u0689 < \\u068A"
     "& \\uFEAE < \\uFDFC"
     "& \\uFED8 < \\uFB8E < \\uFB8F < \\uFB90 < \\uFB91 < \\uFED9 < \\uFEDA"
@@ -6747,7 +6805,6 @@ static const char sinhala[]=
 
 
 static const char croatian[]=
-
 "&C <  \\u010D <<< \\u010C < \\u0107 <<< \\u0106 "
 "&D <  d\\u017E <<< \\u01C6 <<< D\\u017E <<< \\u01C5 <<< D\\u017D <<< \\u01C4 "
 "   <  \\u0111 <<< \\u0110 "
@@ -6755,7 +6812,6 @@ static const char croatian[]=
 "&N < nj <<< \\u01CC <<< Nj <<< \\u01CB <<< NJ <<< \\u01CA "
 "&S < \\u0161 <<< \\u0160 "
 "&Z < \\u017E <<< \\u017D";
-
 /*
   Unicode Collation Algorithm:
   Collation element (weight) scanner, 
@@ -6767,9 +6823,7 @@ typedef struct my_uca_scanner_st
   const uint16 *wbeg;	/* Beginning of the current weight string */
   const uchar  *sbeg;	/* Beginning of the input string          */
   const uchar  *send;	/* End of the input string                */
-  const uchar *uca_length;
-  const uint16 * const *uca_weight;
-  const MY_CONTRACTIONS *contractions;
+  const MY_UCA_WEIGHT_LEVEL *level;
   uint16 implicit[2];
   int page;
   int code;
@@ -6782,51 +6836,81 @@ typedef struct my_uca_scanner_st
 */
 typedef struct my_uca_scanner_handler_st 
 {
-  void (*init)(my_uca_scanner *scanner, CHARSET_INFO *cs, 
+  void (*init)(my_uca_scanner *scanner, CHARSET_INFO *cs,
+               const MY_UCA_WEIGHT_LEVEL *level,
                const uchar *str, size_t length);
   int (*next)(my_uca_scanner *scanner);
 } my_uca_scanner_handler;
 
 static const uint16 nochar[]= {0,0};
 
+
+#define MY_UCA_CNT_FLAG_SIZE 4096
+#define MY_UCA_CNT_FLAG_MASK 4095
+
+#define MY_UCA_CNT_HEAD  1
+#define MY_UCA_CNT_TAIL  2
+#define MY_UCA_CNT_MID1  4
+#define MY_UCA_CNT_MID2  8
+#define MY_UCA_CNT_MID3  16
+#define MY_UCA_CNT_MID4  32
+
+#define MY_UCA_PREVIOUS_CONTEXT_HEAD 64
+#define MY_UCA_PREVIOUS_CONTEXT_TAIL 128
+
 /********** Helper functions to handle contraction ************/
 
 
 /**
   Mark a character as a contraction part
   
-  @cs       Pointer to CHARSET_INFO data
-  @wc       Unicode code point
-  @flag     flag: "is contraction head", "is contraction tail"
+  @param uca      Pointer to UCA data
+  @param wc       Unicode code point
+  @param flag     flag: "is contraction head", "is contraction tail"
 */
 
-static void
-my_uca_add_contraction_flag(CHARSET_INFO *cs, my_wc_t wc, int flag)
+static inline void
+my_uca_add_contraction_flag(MY_CONTRACTIONS *list, my_wc_t wc, int flag)
 {
-  cs->contractions->flags[wc & MY_UCA_CNT_FLAG_MASK]|= flag;
+  list->flags[wc & MY_UCA_CNT_FLAG_MASK]|= flag;
 }
 
 
 /**
   Add a new contraction into contraction list
   
-  @cs       Pointer to CHARSET_INFO data
-  @wc       Unicode code points of the characters
-  @len      Number of characters
+  @param uca      Pointer to UCA data
+  @param wc       Unicode code points of the characters
+  @param len      Number of characters
   
   @return   New contraction
   @retval   Pointer to a newly added contraction
 */
 
 static MY_CONTRACTION *
-my_uca_add_contraction(struct charset_info_st *cs,
-                       my_wc_t *wc, int len __attribute__((unused)))
+my_uca_add_contraction(MY_CONTRACTIONS *list, my_wc_t *wc, size_t len,
+                       my_bool with_context)
 {
-  MY_CONTRACTIONS *list= (MY_CONTRACTIONS*) cs->contractions;
   MY_CONTRACTION *next= &list->item[list->nitems];
-  DBUG_ASSERT(len == 2); /* We currently support only contraction2 */
-  next->ch[0]= wc[0];
-  next->ch[1]= wc[1];
+  size_t i;
+  /*
+    Contraction is always at least 2 characters.
+    Contraction is never longer than MY_UCA_MAX_CONTRACTION,
+    which is guaranteed by using my_coll_rule_expand() with proper limit.
+  */
+  DBUG_ASSERT(len > 1 && len <= MY_UCA_MAX_CONTRACTION);
+  for (i= 0; i < len; i++)
+  {
+    /*
+      We don't support contractions with U+0000.
+      my_coll_rule_expand() guarantees there're no U+0000 in a contraction.
+    */
+    DBUG_ASSERT(wc[i] != 0);
+    next->ch[i]= wc[i];
+  }
+  if (i < MY_UCA_MAX_CONTRACTION)
+    next->ch[i]= 0; /* Add end-of-line marker */
+  next->with_context= with_context;
   list->nitems++;
   return next;
 }
@@ -6835,9 +6919,9 @@ my_uca_add_contraction(struct charset_in
 /**
   Allocate and initialize memory for contraction list and flags
   
-  @cs       Pointer to CHARSET_INFO data
-  @alloc    Memory allocation function (typically points to my_alloc_once)
-  @n        Number of contractions
+  @param uca      Pointer to UCA data
+  @param alloc    Memory allocation function (typically points to my_alloc_once)
+  @param n        Number of contractions
   
   @return   Error code
   @retval   0 - memory allocated successfully
@@ -6845,171 +6929,318 @@ my_uca_add_contraction(struct charset_in
 */
 
 static my_bool
-my_uca_alloc_contractions(struct charset_info_st *cs,
-                          void *(*alloc)(size_t), size_t n)
+my_uca_alloc_contractions(MY_CONTRACTIONS *contractions,
+                          MY_CHARSET_LOADER *loader, size_t n)
 {
   uint size= n * sizeof(MY_CONTRACTION);
-  MY_CONTRACTIONS *contractions;
-
-  if (!(cs->contractions= contractions= (*alloc)(sizeof(MY_CONTRACTIONS))))
-    return 1;
-  bzero(contractions, sizeof(MY_CONTRACTIONS));
-  if (!(contractions->item= (*alloc)(size)) ||
-      !(contractions->flags= (char*) (*alloc)(MY_UCA_CNT_FLAG_SIZE)))
+  if (!(contractions->item= (loader->once_alloc)(size)) ||
+      !(contractions->flags= (char *) (loader->once_alloc)(MY_UCA_CNT_FLAG_SIZE)))
     return 1;
-  bzero(contractions->item, size);
-  bzero(contractions->flags, MY_UCA_CNT_FLAG_SIZE);
+  memset(contractions->item, 0, size);
+  memset(contractions->flags, 0, MY_UCA_CNT_FLAG_SIZE);
   return 0;
 }
 
 
-#ifdef HAVE_CHARSET_ucs2
-/*
-  Initialize collation weight scanner
+/**
+  Return UCA contraction data for a CHARSET_INFO structure.
 
-  SYNOPSIS:
-    my_uca_scanner_init()
-    scanner	Pointer to an initialized scanner structure
-    cs		Character set + collation information
-    str		Beginning of the string
-    length	Length of the string.
-    
-  NOTES:
-    Optimized for UCS2
+  @param cs       Pointer to CHARSET_INFO structure
+  @retval         Pointer to contraction data
+  @retval         NULL, if this collation does not have UCA contraction
+*/
 
-  RETURN
-    N/A
+const MY_CONTRACTIONS *
+my_charset_get_contractions(const CHARSET_INFO *cs, int level)
+{
+  return (cs->uca != NULL) && (cs->uca->level[level].contractions.nitems > 0) ?
+          &cs->uca->level[level].contractions : NULL;
+}
+
+
+/**
+  Check if UCA level data has contractions (static version)
+  Static quick version of my_uca_have_contractions(),
+  optimized for performance purposes, also marked as "inline".
+  
+  @param level    Pointer to UCA level data
+  
+  @return   Flags indicating if UCA with contractions
+  @retval   0 - no contractions
+  @retval   1 - there are some contractions
 */
 
-static void my_uca_scanner_init_ucs2(my_uca_scanner *scanner,
-                                     CHARSET_INFO *cs,
-                                     const uchar *str, size_t length)
+static inline my_bool
+my_uca_have_contractions_quick(const MY_UCA_WEIGHT_LEVEL *level)
 {
-  scanner->wbeg= nochar; 
-  if (length)
+  return (level->contractions.nitems > 0);
+}
+
+
+
+/**
+  Check if a character can be contraction head
+  
+  @param c        Pointer to UCA contraction data
+  @param wc       Code point
+  
+  @retval   0 - cannot be contraction head
+  @retval   1 - can be contraction head
+*/
+
+my_bool
+my_uca_can_be_contraction_head(const MY_CONTRACTIONS *c, my_wc_t wc)
+{
+  return c->flags[wc & MY_UCA_CNT_FLAG_MASK] & MY_UCA_CNT_HEAD;
+}
+
+
+/**
+  Check if a character can be contraction tail
+  
+  @param c        Pointer to UCA contraction data
+  @param wc       Code point
+  
+  @retval   0 - cannot be contraction tail
+  @retval   1 - can be contraction tail
+*/
+
+my_bool
+my_uca_can_be_contraction_tail(const MY_CONTRACTIONS *c, my_wc_t wc)
+{
+  return c->flags[wc & MY_UCA_CNT_FLAG_MASK] & MY_UCA_CNT_TAIL;
+}
+
+
+/**
+  Check if a character can be contraction part
+
+  @param c        Pointer to UCA contraction data
+  @param wc       Code point
+
+  @retval   0 - cannot be contraction part
+  @retval   1 - can be contraction part
+*/
+
+static inline my_bool
+my_uca_can_be_contraction_part(const MY_CONTRACTIONS *c, my_wc_t wc, int flag)
+{
+  return c->flags[wc & MY_UCA_CNT_FLAG_MASK] & flag;
+}
+
+
+/**
+  Find a contraction consisting of two characters and return its weight array
+
+  @param list     Pointer to UCA contraction data
+  @param wc1      First character
+  @param wc2      Second character
+
+  @return   Weight array
+  @retval   NULL - no contraction found
+  @retval   ptr  - contraction weight array
+*/
+
+uint16 *
+my_uca_contraction2_weight(const MY_CONTRACTIONS *list, my_wc_t wc1, my_wc_t wc2)
+{
+  MY_CONTRACTION *c, *last;
+  for (c= list->item, last= c + list->nitems; c < last; c++)
   {
-    scanner->sbeg= str;
-    scanner->send= str + length - 2;
-    scanner->uca_length= cs->sort_order;
-    scanner->uca_weight= cs->sort_order_big;
-    scanner->contractions= cs->contractions;
-    scanner->cs= cs;
-    return;
+    if (c->ch[0] == wc1 && c->ch[1] == wc2 && c->ch[2] == 0)
+    {
+      return c->weight;
+    }
   }
+  return NULL;
+}
 
-  /*
-    Sometimes this function is called with
-    str=NULL and length=0, which should be
-    considered as an empty string.
-    
-    The above initialization is unsafe for such cases,
-    because scanner->send is initialized to (NULL-2), which is 0xFFFFFFFE.
-    Then we fall into an endless loop in my_uca_scanner_next_ucs2().
-      
-    Do special initialization for the case when length=0.
-    Initialize scanner->sbeg to an address greater than scanner->send.
-    Next call of my_uca_scanner_next_ucs2() will correctly return with -1.
-  */
-  scanner->sbeg= (uchar*) &nochar[1];
-  scanner->send= (uchar*) &nochar[0];
+
+/**
+  Check if a character can be previous context head
+
+  @param list     Pointer to UCA contraction data
+  @param wc       Code point
+
+  @return
+  @retval   FALSE - cannot be previous context head
+  @retval   TRUE  - can be previous context head
+*/
+
+my_bool
+my_uca_can_be_previous_context_head(const MY_CONTRACTIONS *list, my_wc_t wc)
+{
+  return list->flags[wc & MY_UCA_CNT_FLAG_MASK] & MY_UCA_PREVIOUS_CONTEXT_HEAD;
 }
 
 
-/*
-  Read next collation element (weight), i.e. converts
-  a stream of characters into a stream of their weights.
-  
-  SYNOPSIS:
-    my_uca_scanner_next()
-    scanner	Address of a previously initialized scanner strucuture
-    
-  NOTES:
-    Optimized for UCS2
-    
-    Checks if the current character's weight string has been fully scanned,
-    if no, then returns the next weight for this character,
-    else scans the next character and returns its first weight.
+/**
+  Check if a character can be previois context tail
 
-    Each character can have number weights from 0 to 8.
-    
-    Some characters do not have weights at all, 0 weights. 
-    It means they are ignored during comparison.
-    
-    Examples:
-    1. 0x0001 START OF HEADING, has no weights, ignored, does
-       not produce any weights.
-    2. 0x0061 LATIN SMALL LETTER A, has one weight.
-       0x0E33 will be returned
-    3. 0x00DF LATIN SMALL LETTER SHARP S, aka SZ ligature,
-       has two weights. It will return 0x0FEA twice for two
-       consequent calls.
-    4. 0x247D PATENTHESIZED NUMBER TEN, has four weights,
-       this function will return these numbers in four 
-       consequent calls: 0x0288, 0x0E2A, 0x0E29, 0x0289
-    5. A string consisting of the above characters:
-       0x0001 0x0061 0x00DF 0x247D
-       will return the following weights, one weight per call:
-       0x0E33 0x0FEA 0x0FEA 0x0288, 0x0E2A, 0x0E29, 0x0289
-    
-  RETURN
-    Next weight, a number between 0x0000 and 0xFFFF
-    Or -1 on error (END-OF-STRING or ILLEGAL MULTIBYTE SEQUENCE)
+  @param uca      Pointer to UCA contraction data
+  @param wc       Code point
+
+  @return
+  @retval   FALSE - cannot be contraction tail
+  @retval   TRUE - can be contraction tail
 */
 
-static int my_uca_scanner_next_ucs2(my_uca_scanner *scanner)
+my_bool
+my_uca_can_be_previous_context_tail(const MY_CONTRACTIONS *list, my_wc_t wc)
 {
-  
-  /* 
-    Check if the weights for the previous character have been
-    already fully scanned. If yes, then get the next character and 
-    initialize wbeg and wlength to its weight string.
-  */
-  
-  if (scanner->wbeg[0])
-    return *scanner->wbeg++;
-  
-  do 
+  return list->flags[wc & MY_UCA_CNT_FLAG_MASK] & MY_UCA_PREVIOUS_CONTEXT_TAIL;
+}
+
+
+/**
+  Compare two wide character strings, wide analog to strncmp().
+
+  @param a      Pointer to the first string
+  @param b      Pointer to the second string
+  @param len    Length of the strings
+
+  @return
+  @retval       0 - strings are equal
+  @retval       non-zero - strings are different
+*/
+
+static int
+my_wmemcmp(my_wc_t *a, my_wc_t *b, size_t len)
+{
+  return memcmp(a, b, len * sizeof(my_wc_t));
+}
+
+
+/**
+  Check if a string is a contraction,
+  and return its weight array on success.
+
+  @param list   Pointer to UCA contraction data
+  @param wc     Pointer to wide string
+  @param len    String length
+
+  @return       Weight array
+  @retval       NULL - Input string is not a known contraction
+  @retval       ptr  - contraction weight array
+*/
+
+static inline uint16 *
+my_uca_contraction_weight(const MY_CONTRACTIONS *list, my_wc_t *wc, size_t len)
+{
+  MY_CONTRACTION *c, *last;
+  for (c= list->item, last= c + list->nitems; c < last; c++)
   {
-    const uint16 *const *ucaw= scanner->uca_weight;
-    const uchar *ucal= scanner->uca_length;
-    
-    if (scanner->sbeg > scanner->send)
-      return -1;
-    
-    scanner->page= (uchar)scanner->sbeg[0];
-    scanner->code= (uchar)scanner->sbeg[1];
-    scanner->sbeg+= 2;
-    
-    if (scanner->contractions && (scanner->sbeg <= scanner->send))
+    if ((len == MY_UCA_MAX_CONTRACTION || c->ch[len] == 0) &&
+        !c->with_context &&
+        !my_wmemcmp(c->ch, wc, len))
+      return c->weight;
+  }
+  return NULL;
+}
+
+
+/**
+  Find a contraction in the input stream and return its weight array
+
+  Scan input characters while their flags tell that they can be
+  a contraction part. Then try to find real contraction among the
+  candidates, starting from the longest.
+
+  @param scanner  Pointer to UCA scanner
+  @param[OUT] *wc Where to store the scanned string
+
+  @return         Weight array
+  @retval         NULL - no contraction found
+  @retval         ptr  - contraction weight array
+*/
+
+static uint16 *
+my_uca_scanner_contraction_find(my_uca_scanner *scanner, my_wc_t *wc)
+{
+  size_t clen= 1;
+  int flag;
+  const uchar *s, *beg[MY_UCA_MAX_CONTRACTION];
+  memset(beg, 0, sizeof(beg));
+
+  /* Scan all contraction candidates */
+  for (s= scanner->sbeg, flag= MY_UCA_CNT_MID1;
+       clen < MY_UCA_MAX_CONTRACTION;
+       flag<<= 1)
+  {
+    int mblen;
+    if ((mblen= scanner->cs->cset->mb_wc(scanner->cs, &wc[clen],
+                                         s, scanner->send)) <= 0)
+      break;
+    beg[clen]= s= s + mblen;
+    if (!my_uca_can_be_contraction_part(&scanner->level->contractions,
+                                        wc[clen++], flag))
+      break;
+  }
+
+  /* Find among candidates the longest real contraction */
+  for ( ; clen > 1; clen--)
+  {
+    uint16 *cweight;
+    if (my_uca_can_be_contraction_tail(&scanner->level->contractions,
+                                       wc[clen - 1]) &&
+        (cweight= my_uca_contraction_weight(&scanner->level->contractions,
+                                            wc, clen)))
     {
-      my_wc_t wc1= ((scanner->page << 8) | scanner->code);
-      
-      if (my_cs_can_be_contraction_head(scanner->cs, wc1))
-      {
-        const uint16 *cweight;
-        my_wc_t wc2= (((my_wc_t) scanner->sbeg[0]) << 8) | scanner->sbeg[1];
-        if (my_cs_can_be_contraction_tail(scanner->cs, wc2) &&
-          (cweight= my_cs_contraction2_weight(scanner->cs,
-                                               scanner->code,
-                                               scanner->sbeg[1])))
-        {
-          scanner->implicit[0]= 0;
-          scanner->wbeg= scanner->implicit;
-          scanner->sbeg+=2;
-          return *cweight;
-        }
-      }
+      scanner->wbeg= cweight + 1;
+      scanner->sbeg= beg[clen - 1];
+      return cweight;
     }
-    
-    if (!ucaw[scanner->page])
-      goto implicit;
-    scanner->wbeg= ucaw[scanner->page] + scanner->code * ucal[scanner->page];
-  } while (!scanner->wbeg[0]);
-  
-  return *scanner->wbeg++;
+  }
+
+  return NULL; /* No contractions were found */
+}
+
+
+/**
+  Find weight for contraction with previous context
+  and return its weight array.
+
+  @param scanner  Pointer to UCA scanner
+  @param wc0      Previous character
+  @param wc1      Current character
+
+  @return   Weight array
+  @retval   NULL - no contraction with context found
+  @retval   ptr  - contraction weight array
+*/
+
+uint16 *
+my_uca_previous_context_find(my_uca_scanner *scanner,
+                             my_wc_t wc0, my_wc_t wc1)
+{
+  const MY_CONTRACTIONS *list= &scanner->level->contractions;
+  MY_CONTRACTION *c, *last;
+  for (c= list->item, last= c + list->nitems; c < last; c++)
+  {
+    if (c->with_context && wc0 == c->ch[0] && wc1 == c->ch[1])
+    {
+      scanner->wbeg= c->weight + 1;
+      return c->weight;
+    }
+  }
+  return NULL;
+}
+
+/****************************************************************/
+
+
+/**
+  Return implicit UCA weight
+  Used for characters that do not have assigned UCA weights.
   
-implicit:
+  @param scanner  UCA weight scanner
   
+  @return   The leading implicit weight.
+*/
+
+static inline int
+my_uca_scanner_next_implicit(my_uca_scanner *scanner)
+{
   scanner->code= (scanner->page << 8) + scanner->code;
   scanner->implicit[0]= (scanner->code & 0x7FFF) | 0x8000;
   scanner->implicit[1]= 0;
@@ -7027,112 +7258,101 @@ static int my_uca_scanner_next_ucs2(my_u
   return scanner->page;
 }
 
-static my_uca_scanner_handler my_ucs2_uca_scanner_handler=
-{
-  my_uca_scanner_init_ucs2,
-  my_uca_scanner_next_ucs2
-};
-
-#endif /* HAVE_CHARSET_ucs2 */
-
 
 /*
   The same two functions for any character set
 */
-static void my_uca_scanner_init_any(my_uca_scanner *scanner,
-				    CHARSET_INFO *cs __attribute__((unused)),
-				    const uchar *str, size_t length)
+static void
+my_uca_scanner_init_any(my_uca_scanner *scanner,
+                        CHARSET_INFO *cs,
+                        const MY_UCA_WEIGHT_LEVEL *level,
+                        const uchar *str, size_t length)
 {
   /* Note, no needs to initialize scanner->wbeg */
   scanner->sbeg= str;
   scanner->send= str + length;
   scanner->wbeg= nochar; 
-  scanner->uca_length= cs->sort_order;
-  scanner->uca_weight= cs->sort_order_big;
-  scanner->contractions= cs->contractions;
+  scanner->level= level;
   scanner->cs= cs;
 }
 
 static int my_uca_scanner_next_any(my_uca_scanner *scanner)
 {
-  
   /* 
     Check if the weights for the previous character have been
     already fully scanned. If yes, then get the next character and 
     initialize wbeg and wlength to its weight string.
   */
-  
-  if (scanner->wbeg[0])
-    return *scanner->wbeg++;
-  
-  do 
+
+  if (scanner->wbeg[0])      /* More weights left from the previous step: */
+    return *scanner->wbeg++; /* return the next weight from expansion     */
+
+  do
   {
-    const uint16 *const *ucaw= scanner->uca_weight;
-    const uchar *ucal= scanner->uca_length;
-    my_wc_t wc;
-    int mb_len;
-    
-    if (((mb_len= scanner->cs->cset->mb_wc(scanner->cs, &wc, 
+    const uint16 *wpage;
+    my_wc_t wc[MY_UCA_MAX_CONTRACTION];
+    int mblen;
+
+    /* Get next character */
+    if (((mblen= scanner->cs->cset->mb_wc(scanner->cs, wc,
                                           scanner->sbeg,
                                           scanner->send)) <= 0))
       return -1;
-    
-    scanner->sbeg+= mb_len;
-    if (wc > MAX_UCA_CHAR_WITH_EXPLICIT_WEIGHT)
+
+    scanner->sbeg+= mblen;
+    if (wc[0] > scanner->level->maxchar)
     {
       /* Return 0xFFFD as weight for all characters outside BMP */
       scanner->wbeg= nochar;
       return 0xFFFD;
     }
-    else
-    {
-      scanner->page= wc >> 8;
-      scanner->code= wc & 0xFF;
-    }
-    
-    if (my_cs_have_contractions(scanner->cs) &&
-        my_cs_can_be_contraction_head(scanner->cs, wc))
+
+    if (my_uca_have_contractions_quick(scanner->level))
     {
-      my_wc_t wc2;
-      const uint16 *cweight;
-      
-      if (((mb_len= scanner->cs->cset->mb_wc(scanner->cs, &wc2,
-                                            scanner->sbeg, 
-                                            scanner->send)) >=0) &&
-           my_cs_can_be_contraction_tail(scanner->cs, wc2) &&
-          (cweight= my_cs_contraction2_weight(scanner->cs, wc, wc2)))
+      uint16 *cweight;
+      /*
+        If we have scanned a character which can have previous context,
+        and there were some more characters already before,
+        then reconstruct codepoint of the previous character
+        from "page" and "code" into w[1], and verify that {wc[1], wc[0]}
+        together form a real previous context pair.
+        Note, we support only 2-character long sequences with previous
+        context at the moment. CLDR does not have longer sequences.
+      */
+      if (my_uca_can_be_previous_context_tail(&scanner->level->contractions,
+                                              wc[0]) &&
+          scanner->wbeg != nochar &&     /* if not the very first character */
+          my_uca_can_be_previous_context_head(&scanner->level->contractions,
+                                              (wc[1]= ((scanner->page << 8) +
+                                                        scanner->code))) &&
+          (cweight= my_uca_previous_context_find(scanner, wc[1], wc[0])))
       {
-        scanner->implicit[0]= 0;
-        scanner->wbeg= scanner->implicit;
-        scanner->sbeg+= mb_len;
+        scanner->page= scanner->code= 0; /* Clear for the next character */
         return *cweight;
       }
+      else if (my_uca_can_be_contraction_head(&scanner->level->contractions,
+                                              wc[0]))
+      {
+        /* Check if w[0] starts a contraction */
+        if ((cweight= my_uca_scanner_contraction_find(scanner, wc)))
+          return *cweight;
+      }
     }
-    
-    if (!ucaw[scanner->page])
-      goto implicit;
-    scanner->wbeg= ucaw[scanner->page] + scanner->code * ucal[scanner->page];
-  } while (!scanner->wbeg[0]);
-  
+
+    /* Process single character */
+    scanner->page= wc[0] >> 8;
+    scanner->code= wc[0] & 0xFF;
+
+    /* If weight page for w[0] does not exist, then calculate algoritmically */
+    if (!(wpage= scanner->level->weights[scanner->page]))
+      return my_uca_scanner_next_implicit(scanner);
+
+    /* Calculate pointer to w[0]'s weight, using page and offset */
+    scanner->wbeg= wpage +
+                   scanner->code * scanner->level->lengths[scanner->page];
+  } while (!scanner->wbeg[0]); /* Skip ignorable characters */
+
   return *scanner->wbeg++;
-  
-implicit:
-  
-  scanner->code= (scanner->page << 8) + scanner->code;
-  scanner->implicit[0]= (scanner->code & 0x7FFF) | 0x8000;
-  scanner->implicit[1]= 0;
-  scanner->wbeg= scanner->implicit;
-  
-  scanner->page= scanner->page >> 7;
-  
-  if (scanner->code >= 0x3400 && scanner->code <= 0x4DB5)
-    scanner->page+= 0xFB80;
-  else if (scanner->code >= 0x4E00 && scanner->code <= 0x9FA5)
-    scanner->page+= 0xFB40;
-  else
-    scanner->page+= 0xFBC0;
-  
-  return scanner->page;
 }
 
 
@@ -7142,7 +7362,6 @@ static my_uca_scanner_handler my_any_uca
   my_uca_scanner_next_any
 };
 
-
 /*
   Compares two strings according to the collation
 
@@ -7195,8 +7414,8 @@ static int my_strnncoll_uca(CHARSET_INFO
   int s_res;
   int t_res;
   
-  scanner_handler->init(&sscanner, cs, s, slen);
-  scanner_handler->init(&tscanner, cs, t, tlen);
+  scanner_handler->init(&sscanner, cs, &cs->uca->level[0], s, slen);
+  scanner_handler->init(&tscanner, cs, &cs->uca->level[0], t, tlen);
   
   do
   {
@@ -7207,7 +7426,39 @@ static int my_strnncoll_uca(CHARSET_INFO
   return  (t_is_prefix && t_res < 0) ? 0 : (s_res - t_res);
 }
 
-/*
+
+static inline int
+my_space_weight(const CHARSET_INFO *cs) /* W3-TODO */
+{
+  return cs->uca->level[0].weights[0][0x20 * cs->uca->level[0].lengths[0]];
+}
+
+
+/**
+  Helper function:
+  Find address of weights of the given character.
+  
+  @param weights  UCA weight array
+  @param lengths  UCA length array
+  @param ch       character Unicode code point
+  
+  @return Weight array
+    @retval  pointer to weight array for the given character,
+             or NULL if this page does not have implicit weights.
+*/
+
+static inline uint16 *
+my_char_weight_addr(const MY_UCA_WEIGHT_LEVEL *level, uint wc)
+{
+  uint page, ofst;
+  return wc > level->maxchar ? NULL :
+         (level->weights[page= (wc >> 8)] ?
+          level->weights[page] + (ofst= (wc & 0xFF)) * level->lengths[page] :
+          NULL);
+}
+
+
+/*
   Compares two strings according to the collation,
   ignoring trailing spaces.
 
@@ -7268,8 +7519,8 @@ static int my_strnncollsp_uca(CHARSET_IN
   diff_if_only_endspace_difference= 0;
 #endif
 
-  scanner_handler->init(&sscanner, cs, s, slen);
-  scanner_handler->init(&tscanner, cs, t, tlen);
+  scanner_handler->init(&sscanner, cs, &cs->uca->level[0], s, slen);
+  scanner_handler->init(&tscanner, cs, &cs->uca->level[0], t, tlen);
   
   do
   {
@@ -7280,7 +7531,7 @@ static int my_strnncollsp_uca(CHARSET_IN
   if (s_res > 0 && t_res < 0)
   { 
     /* Calculate weight for SPACE character */
-    t_res= cs->sort_order_big[0][0x20 * cs->sort_order[0]];
+    t_res= my_space_weight(cs);
       
     /* compare the first string to spaces */
     do
@@ -7295,7 +7546,7 @@ static int my_strnncollsp_uca(CHARSET_IN
   if (s_res < 0 && t_res > 0)
   {
     /* Calculate weight for SPACE character */
-    s_res= cs->sort_order_big[0][0x20 * cs->sort_order[0]];
+    s_res= my_space_weight(cs);
       
     /* compare the second string to spaces */
     do
@@ -7342,7 +7593,7 @@ static void my_hash_sort_uca(CHARSET_INF
   my_uca_scanner scanner;
   
   slen= cs->cset->lengthsp(cs, (char*) s, slen);
-  scanner_handler->init(&scanner, cs, s, slen);
+  scanner_handler->init(&scanner, cs, &cs->uca->level[0], s, slen);
   
   while ((s_res= scanner_handler->next(&scanner)) >0)
   {
@@ -7393,7 +7644,7 @@ static size_t my_strnxfrm_uca(CHARSET_IN
   uchar *de= dst + (dstlen & (size_t) ~1); /* add even length for easier code */
   int   s_res;
   my_uca_scanner scanner;
-  scanner_handler->init(&scanner, cs, src, srclen);
+  scanner_handler->init(&scanner, cs, &cs->uca->level[0], src, srclen);
   
   while (dst < de && (s_res= scanner_handler->next(&scanner)) >0)
   {
@@ -7401,7 +7652,7 @@ static size_t my_strnxfrm_uca(CHARSET_IN
     dst[1]= s_res & 0xFF;
     dst+= 2;
   }
-  s_res= cs->sort_order_big[0][0x20 * cs->sort_order[0]];
+  s_res= my_space_weight(cs);
   while (dst < de)
   {
     dst[0]= s_res >> 8;
@@ -7416,33 +7667,6 @@ static size_t my_strnxfrm_uca(CHARSET_IN
 
 
 
-/**
-  Helper function:
-  Find address of weights of the given character.
-  
-  @param weights  UCA weight array
-  @param lengths  UCA length array
-  @param ch       character Unicode code point
-  
-  @return Weight array
-    @retval  pointer to weight array for the given character,
-             or NULL if this page does not have implicit weights.
-*/
-
-static inline const uint16 *
-my_char_weight_addr(CHARSET_INFO *cs, uint wc)
-{
-  uint page, ofst;
-  const uchar *ucal= cs->sort_order;
-  const uint16 * const *ucaw= cs->sort_order_big;
-
-  return wc > MAX_UCA_CHAR_WITH_EXPLICIT_WEIGHT ? NULL :
-         (ucaw[page= (wc >> 8)] ?
-          ucaw[page] + (ofst= (wc & 0xFF)) * ucal[page] :
-          NULL);
-}
-
-
 /*
   This function compares if two characters are the same.
   The sign +1 or -1 does not matter. The only
@@ -7454,8 +7678,8 @@ my_char_weight_addr(CHARSET_INFO *cs, ui
 static int my_uca_charcmp(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2)
 {
   size_t length1, length2;
-  const uint16 *weight1= my_char_weight_addr(cs, wc1);
-  const uint16 *weight2= my_char_weight_addr(cs, wc2);
+  const uint16 *weight1= my_char_weight_addr(&cs->uca->level[0], wc1);
+  const uint16 *weight2= my_char_weight_addr(&cs->uca->level[0], wc2);
   
   if (!weight1 || !weight2)
     return wc1 != wc2;
@@ -7465,8 +7689,8 @@ static int my_uca_charcmp(CHARSET_INFO *
     return 1;
 
   /* Thoroughly compare all weights */
-  length1= cs->sort_order[wc1 >> MY_UCA_PSHIFT];
-  length2= cs->sort_order[wc2 >> MY_UCA_PSHIFT];
+  length1= cs->uca->level[0].lengths[wc1 >> MY_UCA_PSHIFT]; /* W3-TODO */
+  length2= cs->uca->level[0].lengths[wc2 >> MY_UCA_PSHIFT];
   
   if (length1 > length2)
     return memcmp((const void*)weight1, (const void*)weight2, length2*2) ?
@@ -7632,7 +7856,7 @@ int my_wildcmp_uca(CHARSET_INFO *cs,
 /*
   Collation language is implemented according to
   subset of ICU Collation Customization (tailorings):
-  http://oss.software.ibm.com/icu/userguide/Collate_Customization.html
+  http://icu.sourceforge.net/userguide/Collate_Customization.html
   
   Collation language elements:
   Delimiters:
@@ -7674,16 +7898,47 @@ int my_wildcmp_uca(CHARSET_INFO *cs,
 
 typedef enum my_coll_lexem_num_en
 {
-  MY_COLL_LEXEM_EOF	= 0,
-  MY_COLL_LEXEM_DIFF	= 1, 
-  MY_COLL_LEXEM_SHIFT	= 4,
-  MY_COLL_LEXEM_CHAR	= 5,
-  MY_COLL_LEXEM_ERROR	= 6
+  MY_COLL_LEXEM_EOF     = 0,
+  MY_COLL_LEXEM_SHIFT   = 1,
+  MY_COLL_LEXEM_RESET   = 4,
+  MY_COLL_LEXEM_CHAR    = 5,
+  MY_COLL_LEXEM_ERROR   = 6,
+  MY_COLL_LEXEM_OPTION  = 7,
+  MY_COLL_LEXEM_EXTEND  = 8,
+  MY_COLL_LEXEM_CONTEXT = 9,
 } my_coll_lexem_num;
 
 
+/**
+  Convert collation customization lexem to string,
+  for nice error reporting
+
+  @param term   lexem code
+
+  @return       lexem name
+*/
+
+static const char *
+my_coll_lexem_num_to_str(my_coll_lexem_num term)
+{
+  switch (term)
+  {
+  case MY_COLL_LEXEM_EOF:    return "EOF";
+  case MY_COLL_LEXEM_SHIFT:  return "Shift";
+  case MY_COLL_LEXEM_RESET:  return "&";
+  case MY_COLL_LEXEM_CHAR:   return "Character";
+  case MY_COLL_LEXEM_OPTION: return "Bracket option";
+  case MY_COLL_LEXEM_EXTEND: return "/";
+  case MY_COLL_LEXEM_CONTEXT:return "|";
+  case MY_COLL_LEXEM_ERROR:  return "ERROR";
+  }
+  return NULL;
+}
+
+
 typedef struct my_coll_lexem_st
 {
+  my_coll_lexem_num term;
   const char *beg;
   const char *end;
   const char *prev;
@@ -7717,6 +7972,27 @@ static void my_coll_lexem_init(MY_COLL_L
 }
 
 
+/**
+  Compare lexem to string with length
+
+  @param lexem       lexem
+  @param pattern     string
+  @param patternlen  string length
+
+  @return
+  @retval            0 if lexem is equal to string, non-0 otherwise.
+*/
+
+static int
+lex_cmp(MY_COLL_LEXEM *lexem, const char *pattern, size_t patternlen)
+{
+  size_t lexemlen= lexem->beg - lexem->prev;
+  if (lexemlen < patternlen)
+    return 1; /* Not a prefix */
+  return strncasecmp(lexem->prev, pattern, patternlen);
+}
+
+
 /*
   Print collation customization expression parse error, with context.
   
@@ -7740,7 +8016,8 @@ static void my_coll_lexem_print_error(MY
   size_t len= lexem->end - lexem->prev;
   strmake (tail, lexem->prev, (size_t) MY_MIN(len, sizeof(tail)-1));
   errstr[errsize-1]= '\0';
-  my_snprintf(errstr,errsize-1,"%s at '%s'", txt, tail);
+  my_snprintf(errstr, errsize - 1,
+              "%s at '%s'", txt[0] ? txt : "Syntax error", tail);
 }
 
 
@@ -7791,44 +8068,75 @@ static my_coll_lexem_num my_coll_lexem_n
 {
   const char *beg;
   my_coll_lexem_num rc;
-  
+
   for (beg= lexem->beg ; beg < lexem->end ; beg++)
   {
-    if (*beg == ' ' || *beg == '\t' || *beg == '\r' || *beg == '\n')
-      continue;
-    
-    if (*beg == '&')
+    switch (*beg)
     {
+    case ' ':
+    case '\t':
+    case '\r':
+    case '\n':
+      continue;
+
+    case '[':  /* Bracket expression, e.g. "[optimize [a-z]]" */
+      {
+        size_t nbrackets; /* Indicates nested recursion level */
+        for (beg++, nbrackets= 1 ; beg < lexem->end; beg++)
+        {
+          if (*beg == '[') /* Enter nested bracket expression */
+            nbrackets++;
+          else if (*beg == ']')
+          {
+            if (--nbrackets == 0)
+            {
+              rc= MY_COLL_LEXEM_OPTION;
+              beg++;
+              goto ex;
+            }
+          }
+        }
+        rc= MY_COLL_LEXEM_ERROR;
+        goto ex;
+      }
+
+    case '&':
       beg++;
-      rc= MY_COLL_LEXEM_SHIFT;
+      rc= MY_COLL_LEXEM_RESET;
       goto ex;
-    }
-    
-    if (beg[0] == '=')
-    {
+
+    case '=':
       beg++;
-      rc= MY_COLL_LEXEM_DIFF;
+      lexem->diff= 0;
+      rc= MY_COLL_LEXEM_SHIFT;
       goto ex;
-    }
-    
-    if (beg[0] == '<')
-    {
-      for (beg++, lexem->diff= 1;
-           (beg < lexem->end) && 
-           (*beg == '<') && (lexem->diff<3);
-           beg++, lexem->diff++);
-      rc= MY_COLL_LEXEM_DIFF;
+
+    case '/':
+      beg++;
+      rc= MY_COLL_LEXEM_EXTEND;
       goto ex;
-    }
-    
-    if ((*beg >= 'a' && *beg <= 'z') || (*beg >= 'A' && *beg <= 'Z'))
-    {
-      lexem->code= *beg++;
-      rc= MY_COLL_LEXEM_CHAR;
+
+    case '|':
+      beg++;
+      rc= MY_COLL_LEXEM_CONTEXT;
       goto ex;
+
+    case '<':   /* Shift: '<' or '<<' or '<<<' or '<<<<' */
+      {
+        /* Scan up to 3 additional '<' characters */
+        for (beg++, lexem->diff= 1;
+             (beg < lexem->end) && (*beg == '<') && (lexem->diff <= 3);
+             beg++, lexem->diff++);
+        rc= MY_COLL_LEXEM_SHIFT;
+        goto ex;
+      }
+      default:
+        break;
     }
-    
-    if ((*beg == '\\') && (beg+2 < lexem->end) && (beg[1] == 'u'))
+
+    /* Escaped character, e.g. \u1234 */
+    if ((*beg == '\\') && (beg + 2 < lexem->end) &&
+        (beg[1] == 'u') && my_isxdigit(&my_charset_utf8_general_ci, beg[2]))
     {
       int ch;
       
@@ -7842,159 +8150,1194 @@ static my_coll_lexem_num my_coll_lexem_n
       rc= MY_COLL_LEXEM_CHAR;
       goto ex;
     }
-    
+
+    /*
+      Unescaped single byte character:
+        allow printable ASCII range except SPACE and
+        special characters parsed above []<&/|=
+    */
+    if (*beg >= 0x21 && *beg <= 0x7E)
+    {
+      lexem->code= *beg++;
+      rc= MY_COLL_LEXEM_CHAR;
+      goto ex;
+    }
+
+    if (((uchar) *beg) > 0x7F) /* Unescaped multibyte character */
+    {
+      CHARSET_INFO *cs= &my_charset_utf8_general_ci;
+      my_wc_t wc;
+      int nbytes= cs->cset->mb_wc(cs, &wc,
+                                  (uchar *) beg, (uchar *) lexem->end);
+      if (nbytes > 0)
+      {
+        rc= MY_COLL_LEXEM_CHAR;
+        beg+= nbytes;
+        lexem->code= (int) wc;
+        goto ex;
+      }
+    }
+
     rc= MY_COLL_LEXEM_ERROR;
     goto ex;
   }
-  rc= MY_COLL_LEXEM_EOF;
-  
-ex:
-  lexem->prev= lexem->beg;
-  lexem->beg= beg;
-  return rc;  
+  rc= MY_COLL_LEXEM_EOF;
+
+ex:
+  lexem->prev= lexem->beg;
+  lexem->beg= beg;
+  lexem->term= rc;
+  return rc;  
+}
+
+
+/*
+  Collation rule item
+*/
+
+#define MY_UCA_MAX_EXPANSION  6  /* Maximum expansion length   */
+
+typedef struct my_coll_rule_item_st
+{
+  my_wc_t base[MY_UCA_MAX_EXPANSION];    /* Base character                  */
+  my_wc_t curr[MY_UCA_MAX_CONTRACTION];  /* Current character               */
+  int diff[4];      /* Primary, Secondary, Tertiary, Quaternary difference  */
+  size_t before_level;                   /* "reset before" indicator        */
+  my_bool with_context;
+} MY_COLL_RULE;
+
+
+/**
+  Return length of a 0-terminated wide string, analog to strnlen().
+
+  @param  s       Pointer to wide string
+  @param  maxlen  Mamixum string length
+
+  @return         string length, or maxlen if no '\0' is met.
+*/
+static size_t
+my_wstrnlen(my_wc_t *s, size_t maxlen)
+{
+  size_t i;
+  for (i= 0; i < maxlen; i++)
+  {
+    if (s[i] == 0)
+      return i;
+  }
+  return maxlen;
+}
+
+
+/**
+  Return length of the "reset" string of a rule.
+
+  @param  r  Collation customization rule
+
+  @return    Length of r->base
+*/
+
+static inline size_t
+my_coll_rule_reset_length(MY_COLL_RULE *r)
+{
+  return my_wstrnlen(r->base, MY_UCA_MAX_EXPANSION);
+}
+
+
+/**
+  Return length of the "shift" string of a rule.
+
+  @param  r  Collation customization rule
+
+  @return    Length of r->base
+*/
+
+static inline size_t
+my_coll_rule_shift_length(MY_COLL_RULE *r)
+{
+  return my_wstrnlen(r->curr, MY_UCA_MAX_CONTRACTION);
+}
+
+
+/**
+  Append new character to the end of a 0-terminated wide string.
+
+  @param  wc     Wide string
+  @param  limit  Maximum possible result length
+  @param  code   Character to add
+
+  @return        1 if character was added, 0 if string was too long
+*/
+
+static int
+my_coll_rule_expand(my_wc_t *wc, size_t limit, my_wc_t code)
+{
+  size_t i;
+  for (i= 0; i < limit; i++)
+  {
+    if (wc[i] == 0)
+    {
+      wc[i]= code;
+      return 1;
+    }
+  }
+  return 0;
+}
+
+
+/**
+  Initialize collation customization rule
+
+  @param  wc     Rule
+*/
+
+static void
+my_coll_rule_reset(MY_COLL_RULE *r)
+{
+  memset(r, 0, sizeof(*r));
+}
+
+
+/*
+  Shift methods:
+  Simple: "&B < C" : weight('C') = weight('B') + 1
+  Expand: weght('C') =  { weight('B'), weight(last_non_ignorable) + 1 }
+*/
+typedef enum
+{
+  my_shift_method_simple= 0,
+  my_shift_method_expand
+} my_coll_shift_method;
+
+
+typedef struct my_coll_rules_st
+{
+  uint version;              /* Unicode version, e.g. 400 or 520  */
+  MY_UCA_INFO *uca;          /* Unicode weight data               */
+  size_t nrules;             /* Number of rules in the rule array */
+  size_t mrules;             /* Number of allocated rules         */
+  MY_COLL_RULE *rule;        /* Rule array                        */
+  MY_CHARSET_LOADER *loader;
+  my_coll_shift_method shift_after_method;
+} MY_COLL_RULES;
+
+
+/**
+  Realloc rule array to a new size.
+  Reallocate memory for 128 additional rules at once,
+  to reduce the number of reallocs, which is important
+  for long tailorings (e.g. for East Asian collations).
+
+  @param  rules   Rule container
+  @param  n       new number of rules
+
+  @return         0 on success, -1 on error.
+*/
+
+static int
+my_coll_rules_realloc(MY_COLL_RULES *rules, size_t n)
+{
+  if (rules->nrules < rules->mrules ||
+      (rules->rule= rules->loader->realloc(rules->rule,
+                                           sizeof(MY_COLL_RULE) *
+                                           (rules->mrules= n + 128))))
+    return 0;
+  return -1;
+}
+
+
+/**
+  Append one new rule to a rule array
+
+  @param  rules   Rule container
+  @param  rule    New rule to add
+
+  @return         0 on success, -1 on error.
+*/
+
+static int
+my_coll_rules_add(MY_COLL_RULES *rules, MY_COLL_RULE *rule)
+{
+  if (my_coll_rules_realloc(rules, rules->nrules + 1))
+    return -1;
+  rules->rule[rules->nrules++]= rule[0];
+  return 0;
+}
+
+
+/**
+  Apply difference at level
+
+  @param  r      Rule
+  @param  level  Level (0,1,2,3,4)
+*/
+
+static void
+my_coll_rule_shift_at_level(MY_COLL_RULE *r, int level)
+{
+  switch (level)
+  {
+  case 4: /* Quaternary difference */
+    r->diff[3]++;
+    break;
+  case 3: /* Tertiary difference */
+    r->diff[2]++;
+    r->diff[3]= 0;
+    break;
+  case 2: /* Secondary difference */
+    r->diff[1]++;
+    r->diff[2]= r->diff[3]= 0;
+    break;
+  case 1: /* Primary difference */
+    r->diff[0]++;
+    r->diff[1]= r->diff[2]= r->diff[3]= 0;
+    break;
+  case 0:
+    /* Do nothing for '=': use the previous offsets for all levels */
+    break;
+  default:
+    DBUG_ASSERT(0);
+  }
+}
+
+
+typedef struct my_coll_rule_parser_st
+{
+  MY_COLL_LEXEM tok[2]; /* Current token and next token for look-ahead */
+  MY_COLL_RULE rule;    /* Currently parsed rule */
+  MY_COLL_RULES *rules; /* Rule list pointer     */
+  char errstr[128];     /* Error message         */
+} MY_COLL_RULE_PARSER;
+
+
+/**
+  Current parser token
+
+  @param  p   Collation customization parser
+
+  @return     Pointer to the current token
+*/
+
+static MY_COLL_LEXEM *
+my_coll_parser_curr(MY_COLL_RULE_PARSER *p)
+{
+  return &p->tok[0];
+}
+
+
+/**
+  Next parser token, to look ahead.
+
+  @param  p   Collation customization parser
+
+  @return     Pointer to the next token
+*/
+
+static MY_COLL_LEXEM *
+my_coll_parser_next(MY_COLL_RULE_PARSER *p)
+{
+  return &p->tok[1];
+}
+
+
+/**
+  Scan one token from the input stream
+
+  @param  p   Collation customization parser
+
+  @return     1, for convenience, to use in logical expressions easier.
+*/
+static int
+my_coll_parser_scan(MY_COLL_RULE_PARSER *p)
+{
+  my_coll_parser_curr(p)[0]= my_coll_parser_next(p)[0];
+  my_coll_lexem_next(my_coll_parser_next(p));
+  return 1;
+}
+
+
+/**
+  Initialize collation customization parser
+
+  @param  p        Collation customization parser
+  @param  rules    Where to store rules
+  @param  str      Beginning of a collation customization sting
+  @param  str_end  End of the collation customizations string
+*/
+
+static void
+my_coll_parser_init(MY_COLL_RULE_PARSER *p,
+                    MY_COLL_RULES *rules,
+                    const char *str, const char *str_end)
+{
+  /*
+    Initialize parser to the input buffer and scan two tokens,
+    to make the current token and the next token known.
+  */
+  memset(p, 0, sizeof(*p));
+  p->rules= rules;
+  p->errstr[0]= '\0';
+  my_coll_lexem_init(my_coll_parser_curr(p), str, str_end);
+  my_coll_lexem_next(my_coll_parser_curr(p));
+  my_coll_parser_next(p)[0]= my_coll_parser_curr(p)[0];
+  my_coll_lexem_next(my_coll_parser_next(p));
+}
+
+
+/**
+  Display error when an unexpected token found
+
+  @param  p        Collation customization parser
+  @param  term     Which lexem was expected
+
+  @return          0, to use in "return" and boolean expressions.
+*/
+
+static int
+my_coll_parser_expected_error(MY_COLL_RULE_PARSER *p, my_coll_lexem_num term)
+{
+  my_snprintf(p->errstr, sizeof(p->errstr),
+              "%s expected", my_coll_lexem_num_to_str(term));
+  return 0;
+}
+
+
+/**
+  Display error when a too long character sequence is met
+
+  @param  p        Collation customization parser
+  @param  name     Which kind of sequence: contraction, expansion, etc.
+
+  @return          0, to use in "return" and boolean expressions.
+*/
+
+static int
+my_coll_parser_too_long_error(MY_COLL_RULE_PARSER *p, const char *name)
+{
+  my_snprintf(p->errstr, sizeof(p->errstr), "%s is too long", name);
+  return 0;
+}
+
+
+/**
+  Scan the given lexem from input stream, or display "expected" error.
+
+  @param  p        Collation customization parser
+  @param  term     Which lexem is expected.
+
+  @return
+  @retval          0 if the required term was not found.
+  @retval          1 if the required term was found.
+*/
+static int
+my_coll_parser_scan_term(MY_COLL_RULE_PARSER *p, my_coll_lexem_num term)
+{
+  if (my_coll_parser_curr(p)->term != term)
+    return my_coll_parser_expected_error(p, term);
+  return my_coll_parser_scan(p);
+}
+
+
+/*
+  In the following code we have a few functions to parse
+  various collation customization non-terminal symbols.
+  Unlike our usual coding convension, they return
+  - 0 on "error" (when the rule was not scanned) and
+  - 1 on "success"(when the rule was scanned).
+  This is done intentionally to make body of the functions look easier
+  and repeat the grammar of the rules in straightforward manner.
+  For example:
+
+  // <x> ::= <y> | <z>
+  int parse_x() { return parse_y() || parser_z(); }
+
+  // <x> ::= <y> <z>
+  int parse_x() { return parse_y() && parser_z(); }
+
+  Using 1 on "not found" and 0 on "found" in the parser code would
+  make the code more error prone and harder to read because
+  of having to use inverse boolean logic.
+*/
+
+
+/**
+  Scan a collation setting in brakets, for example UCA version.
+
+  @param  p        Collation customization parser
+
+  @return
+  @retval          0 if setting was scanned.
+  @retval          1 if setting was not scanned.
+*/
+
+static int
+my_coll_parser_scan_setting(MY_COLL_RULE_PARSER *p)
+{
+  MY_COLL_RULES *rules= p->rules;
+  MY_COLL_LEXEM *lexem= my_coll_parser_curr(p);
+
+  if (!lex_cmp(lexem, C_STRING_WITH_LEN("[version 4.0.0]")))
+  {
+    rules->version= 400;
+    rules->uca= &my_uca_v400;
+  }
+#if RESOLVE_CONFLICTS_WITH_MARIA_AND_MYSQL_COLLATION_IDS
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[version 5.2.0]")))
+  {
+    rules->version= 520;
+    rules->uca= &my_uca_v520;
+  }
+#endif
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[shift-after-method expand]")))
+  {
+    rules->shift_after_method= my_shift_method_expand;
+  }
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[shift-after-method simple]")))
+  {
+    rules->shift_after_method= my_shift_method_simple;
+  }
+  else
+  {
+    return 0;
+  }
+  return my_coll_parser_scan(p);
+}
+
+
+/**
+  Scan multiple collation settings
+
+  @param  p        Collation customization parser
+
+  @return
+  @retval          0 if no settings were scanned.
+  @retval          1 if one or more settings were scanned.
+*/
+
+static int
+my_coll_parser_scan_settings(MY_COLL_RULE_PARSER *p)
+{
+  /* Scan collation setting or special purpose command */
+  while (my_coll_parser_curr(p)->term == MY_COLL_LEXEM_OPTION)
+  {
+    if (!my_coll_parser_scan_setting(p))
+      return 0;
+  }
+  return 1;
+}
+
+
+/**
+  Scan [before xxx] reset option
+
+  @param  p        Collation customization parser
+
+  @return
+  @retval          0 if reset option was not scanned.
+  @retval          1 if reset option was scanned.
+*/
+
+static int
+my_coll_parser_scan_reset_before(MY_COLL_RULE_PARSER *p)
+{
+  MY_COLL_LEXEM *lexem= my_coll_parser_curr(p);
+  if (!lex_cmp(lexem, C_STRING_WITH_LEN("[before primary]")) ||
+      !lex_cmp(lexem, C_STRING_WITH_LEN("[before 1]")))
+  {
+    p->rule.before_level= 1;
+  }
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[before secondary]")) ||
+           !lex_cmp(lexem, C_STRING_WITH_LEN("[before 2]")))
+  {
+    p->rule.before_level= 2;
+  }
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[before tertiary]")) ||
+           !lex_cmp(lexem, C_STRING_WITH_LEN("[before 3]")))
+  {
+    p->rule.before_level= 3;
+  }
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[before quaternary]")) ||
+           !lex_cmp(lexem, C_STRING_WITH_LEN("[before 4]")))
+  {
+    p->rule.before_level= 4;
+  }
+  else
+  {
+    p->rule.before_level= 0;
+    return 0; /* Don't scan thr next character */
+  }
+  return my_coll_parser_scan(p);
+}
+
+
+/**
+  Scan logical position and add to the wide string.
+
+  @param  p        Collation customization parser
+  @param  pwc      Wide string to add code to
+  @param  limit    The result string cannot be longer than 'limit' characters
+
+  @return
+  @retval          0 if logical position was not scanned.
+  @retval          1 if logical position was scanned.
+*/
+
+static int
+my_coll_parser_scan_logical_position(MY_COLL_RULE_PARSER *p,
+                                     my_wc_t *pwc, size_t limit)
+{
+  MY_COLL_RULES *rules= p->rules;
+  MY_COLL_LEXEM *lexem= my_coll_parser_curr(p);
+
+  if (!lex_cmp(lexem, C_STRING_WITH_LEN("[first non-ignorable]")))
+    lexem->code= rules->uca->first_non_ignorable;
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[last non-ignorable]")))
+    lexem->code= rules->uca->last_non_ignorable;
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[first primary ignorable]")))
+    lexem->code= rules->uca->first_primary_ignorable;
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[last primary ignorable]")))
+    lexem->code= rules->uca->last_primary_ignorable;
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[first secondary ignorable]")))
+    lexem->code= rules->uca->first_secondary_ignorable;
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[last secondary ignorable]")))
+    lexem->code= rules->uca->last_secondary_ignorable;
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[first tertiary ignorable]")))
+    lexem->code= rules->uca->first_tertiary_ignorable;
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[last tertiary ignorable]")))
+    lexem->code= rules->uca->last_tertiary_ignorable;
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[first trailing]")))
+    lexem->code= rules->uca->first_trailing;
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[last trailing]")))
+    lexem->code= rules->uca->last_trailing;
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[first variable]")))
+    lexem->code= rules->uca->first_variable;
+  else if (!lex_cmp(lexem, C_STRING_WITH_LEN("[last variable]")))
+    lexem->code= rules->uca->last_variable;
+  else
+    return 0; /* Don't scan the next token */
+
+  if (!my_coll_rule_expand(pwc, limit, lexem->code))
+  {
+    /*
+      Logical position can not be in a contraction,
+      so the above call should never fail.
+      Let's assert in debug version and print
+      a nice error message in production version.
+    */
+    DBUG_ASSERT(0);
+    return my_coll_parser_too_long_error(p, "Logical position");
+  }
+  return my_coll_parser_scan(p);
+}
+
+
+/**
+  Scan character list
+
+    <character list> ::= CHAR [ CHAR... ]
+
+  @param  p        Collation customization parser
+  @param  pwc      Character string to add code to
+  @param  limit    The result string cannot be longer than 'limit' characters
+  @param  name     E.g. "contraction", "expansion"
+
+  @return
+  @retval          0 if character sequence was not scanned.
+  @retval          1 if character sequence was scanned.
+*/
+
+static int
+my_coll_parser_scan_character_list(MY_COLL_RULE_PARSER *p,
+                                   my_wc_t *pwc, size_t limit,
+                                   const char *name)
+{
+  if (my_coll_parser_curr(p)->term != MY_COLL_LEXEM_CHAR)
+    return my_coll_parser_expected_error(p, MY_COLL_LEXEM_CHAR);
+
+  if (!my_coll_rule_expand(pwc, limit, my_coll_parser_curr(p)->code))
+    return my_coll_parser_too_long_error(p, name);
+
+  if (!my_coll_parser_scan_term(p, MY_COLL_LEXEM_CHAR))
+    return 0;
+
+  while (my_coll_parser_curr(p)->term == MY_COLL_LEXEM_CHAR)
+  {
+    if (!my_coll_rule_expand(pwc, limit, my_coll_parser_curr(p)->code))
+      return my_coll_parser_too_long_error(p, name);
+    my_coll_parser_scan(p);
+  }
+  return 1;
+}
+
+
+/**
+  Scan reset sequence
+
+  <reset sequence> ::=
+    [ <reset before option> ] <character list>
+  | [ <reset before option> ] <logical reset position>
+
+  @param  p        Collation customization parser
+
+  @return
+  @retval          0 if reset sequence was not scanned.
+  @retval          1 if reset sequence was scanned.
+*/
+
+static int
+my_coll_parser_scan_reset_sequence(MY_COLL_RULE_PARSER *p)
+{
+  my_coll_rule_reset(&p->rule);
+
+  /* Scan "[before x]" option, if exists */
+  if (my_coll_parser_curr(p)->term == MY_COLL_LEXEM_OPTION)
+    my_coll_parser_scan_reset_before(p);
+
+  /* Try logical reset position */
+  if (my_coll_parser_curr(p)->term == MY_COLL_LEXEM_OPTION)
+  {
+    if (!my_coll_parser_scan_logical_position(p, p->rule.base, 1))
+      return 0;
+  }
+  else
+  {
+    /* Scan single reset character or expansion */
+    if (!my_coll_parser_scan_character_list(p, p->rule.base,
+                                            MY_UCA_MAX_EXPANSION, "Expansion"))
+      return 0;
+  }
+
+  if (p->rules->shift_after_method == my_shift_method_expand ||
+      p->rule.before_level == 1) /* Apply "before primary" option  */
+  {
+    /*
+      Suppose we have this rule:  &B[before primary] < C
+      i.e. we need to put C before B, but after A, so
+      the result order is: A < C < B.
+
+      Let primary weight of B be [BBBB].
+
+      We cannot just use [BBBB-1] as weight for C:
+      DUCET does not have enough unused weights between any two characters,
+      so using [BBBB-1] will likely make C equal to the previous character,
+      which is A, so we'll get this order instead of the desired: A = C < B.
+
+      To guarantee that that C is sorted after A, we'll use expansion
+      with a kind of "biggest possible character".
+      As "biggest possible character" we'll use "last_non_ignorable":
+
+      We'll compose weight for C as: [BBBB-1][MMMM+1]
+      where [MMMM] is weight for "last_non_ignorable".
+      
+      We also do the same trick for "reset after" if the collation
+      option says so. E.g. for the rules "&B < C", weight for
+      C will be calculated as: [BBBB][MMMM+1]
+
+      At this point we only need to store codepoints
+      'B' and 'last_non_ignorable'. Actual weights for 'C'
+      will be calculated according to the above formula later,
+      in create_tailoring().
+    */
+    if (!my_coll_rule_expand(p->rule.base, MY_UCA_MAX_EXPANSION,
+                             p->rules->uca->last_non_ignorable))
+      return my_coll_parser_too_long_error(p, "Expansion");
+  }
+  return 1;
+}
+
+
+/**
+  Scan shift sequence
+
+  <shift sequence> ::=
+    <character list>  [ / <character list> ]
+  | <character list>  [ | <character list> ]
+
+  @param  p        Collation customization parser
+
+  @return
+  @retval          0 if shift sequence was not scanned.
+  @retval          1 if shift sequence was scanned.
+*/
+
+static int
+my_coll_parser_scan_shift_sequence(MY_COLL_RULE_PARSER *p)
+{
+  MY_COLL_RULE before_extend;
+
+  memset(&p->rule.curr, 0, sizeof(p->rule.curr));
+
+  /* Scan single shift character or contraction */
+  if (!my_coll_parser_scan_character_list(p, p->rule.curr,
+                                          MY_UCA_MAX_CONTRACTION,
+                                          "Contraction"))
+    return 0;
+
+  before_extend= p->rule; /* Remember the part before "/" */
+
+  /* Append the part after "/" as expansion */
+  if (my_coll_parser_curr(p)->term == MY_COLL_LEXEM_EXTEND)
+  {
+    my_coll_parser_scan(p);
+    if (!my_coll_parser_scan_character_list(p, p->rule.base,
+                                            MY_UCA_MAX_EXPANSION,
+                                            "Expansion"))
+      return 0;
+  }
+  else if (my_coll_parser_curr(p)->term == MY_COLL_LEXEM_CONTEXT)
+  {
+    /*
+      We support 2-character long context sequences only:
+      one character is the previous context, plus the current character.
+      It's OK as Unicode's CLDR does not have longer examples.
+    */
+    my_coll_parser_scan(p);
+    p->rule.with_context= TRUE;
+    if (!my_coll_parser_scan_character_list(p, p->rule.curr + 1, 1, "context"))
+      return 0;
+  }
+
+  /* Add rule to the rule list */
+  if (my_coll_rules_add(p->rules, &p->rule))
+    return 0;
+
+  p->rule= before_extend; /* Restore to the state before "/" */
+
+  return 1;
+}
+
+
+/**
+  Scan shift operator
+
+  <shift> ::=  <  | <<  | <<<  | <<<<  | =
+
+  @param  p        Collation customization parser
+
+  @return
+  @retval          0 if shift operator was not scanned.
+  @retval          1 if shift operator was scanned.
+*/
+static int
+my_coll_parser_scan_shift(MY_COLL_RULE_PARSER *p)
+{
+  if (my_coll_parser_curr(p)->term == MY_COLL_LEXEM_SHIFT)
+  {
+    my_coll_rule_shift_at_level(&p->rule, my_coll_parser_curr(p)->diff);
+    return my_coll_parser_scan(p);
+  }
+  return 0;
 }
 
 
-/*
-  Collation rule item
+/**
+  Scan one rule: reset followed by a number of shifts
+
+  <rule> ::=
+    & <reset sequence>
+    <shift> <shift sequence>
+    [ { <shift> <shift sequence> }... ]
+
+  @param  p        Collation customization parser
+
+  @return
+  @retval          0 if rule was not scanned.
+  @retval          1 if rule was scanned.
 */
+static int
+my_coll_parser_scan_rule(MY_COLL_RULE_PARSER *p)
+{
+  if (!my_coll_parser_scan_term(p, MY_COLL_LEXEM_RESET) ||
+      !my_coll_parser_scan_reset_sequence(p))
+    return 0;
+
+  /* Scan the first required shift command */
+  if (!my_coll_parser_scan_shift(p))
+    return my_coll_parser_expected_error(p, MY_COLL_LEXEM_SHIFT);
+
+  /* Scan the first shift sequence */
+  if (!my_coll_parser_scan_shift_sequence(p))
+    return 0;
 
-typedef struct my_coll_rule_item_st
+  /* Scan subsequent shift rules */
+  while (my_coll_parser_scan_shift(p))
+  {
+    if (!my_coll_parser_scan_shift_sequence(p))
+      return 0;
+  }
+  return 1;
+}
+
+
+/**
+  Scan collation customization: settings followed by rules
+
+  <collation customization> ::=
+    [ <setting> ... ]
+    [ <rule>... ]
+
+  @param  p        Collation customization parser
+
+  @return
+  @retval          0 if collation customozation expression was not scanned.
+  @retval          1 if collation customization expression was scanned.
+*/
+
+static int
+my_coll_parser_exec(MY_COLL_RULE_PARSER *p)
 {
-  my_wc_t base;     /* Base character                             */
-  my_wc_t curr[2];  /* Current character                          */
-  int diff[3];   /* Primary, Secondary and Tertiary difference */
-} MY_COLL_RULE;
+  if (!my_coll_parser_scan_settings(p))
+    return 0;
+
+  while (my_coll_parser_curr(p)->term == MY_COLL_LEXEM_RESET)
+  {
+    if (!my_coll_parser_scan_rule(p))
+      return 0;
+  }
+  /* Make sure no unparsed input data left */
+  return my_coll_parser_scan_term(p, MY_COLL_LEXEM_EOF);
+}
 
 
 /*
   Collation language syntax parser.
   Uses lexical parser.
-  
-  SYNOPSIS
-    my_coll_rule_parse
-    rule                 Collation rule list to load to.
-    str                  A string containin collation language expression.
-    str_end              End of the string.
-  USAGE
-    
-  RETURN VALUES
-    A positive number means the number of rules loaded.
-   -1 means ERROR, e.g. too many items, syntax error, etc.
+
+  @param rules           Collation rule list to load to.
+  @param str             A string with collation customization.
+  @param str_end         End of the string.
+
+  @return
+  @retval                0 on success
+  @retval                1 on error
 */
 
-static int my_coll_rule_parse(MY_COLL_RULE *rule, size_t mitems,
-                              const char *str, const char *str_end,
-                              char *errstr, size_t errsize)
+static int
+my_coll_rule_parse(MY_COLL_RULES *rules,
+                   const char *str, const char *str_end)
 {
-  MY_COLL_LEXEM lexem;
-  my_coll_lexem_num lexnum;
-  my_coll_lexem_num prevlexnum= MY_COLL_LEXEM_ERROR;
-  MY_COLL_RULE item; 
-  int state= 0;
-  size_t nitems= 0;
+  MY_COLL_RULE_PARSER p;
+
+  my_coll_parser_init(&p, rules, str, str_end);
+
+  if (!my_coll_parser_exec(&p))
+  {
+    my_coll_lexem_print_error(my_coll_parser_curr(&p),
+                              rules->loader->error,
+                              sizeof(rules->loader->error) - 1,
+                              p.errstr);
+    return 1;
+  }
+  return 0;
+}
+
+
+/**
+  Helper function:
+  Copies UCA weights for a given "uint" string
+  to the given location.
   
-  /* Init all variables */
-  errstr[0]= '\0';
-  bzero(&item, sizeof(item));
-  my_coll_lexem_init(&lexem, str, str_end);
+  @src_uca    source UCA weight data
+  @dst_uca    destination UCA weight data
+  @to         destination address
+  @to_length  size of destination
+  @str        qide string
+  @len        string length
   
-  while ((lexnum= my_coll_lexem_next(&lexem)))
+  @return    number of weights put
+*/
+
+static size_t
+my_char_weight_put(MY_UCA_WEIGHT_LEVEL *dst,
+                   uint16 *to, size_t to_length,
+                   my_wc_t *str, size_t len)
+{
+  size_t count;
+  if (!to_length)
+    return 0;
+  to_length--; /* Without trailing zero */
+
+  for (count= 0; len; )
   {
-    if (lexnum == MY_COLL_LEXEM_ERROR)
+    size_t chlen;
+    const uint16 *from= NULL;
+
+    for (chlen= len; chlen > 1; chlen--)
     {
-      my_coll_lexem_print_error(&lexem,errstr,errsize-1,"Unknown character");
-      return -1;
-    }
-    
-    switch (state) {
-    case 0:
-      if (lexnum != MY_COLL_LEXEM_SHIFT)
-      {
-        my_coll_lexem_print_error(&lexem,errstr,errsize-1,"& expected");
-        return -1;
-      }
-      prevlexnum= lexnum;
-      state= 2;
-      continue;
-      
-    case 1:
-      if (lexnum != MY_COLL_LEXEM_SHIFT && lexnum != MY_COLL_LEXEM_DIFF)
+      if ((from= my_uca_contraction_weight(&dst->contractions, str, chlen)))
       {
-        my_coll_lexem_print_error(&lexem,errstr,errsize-1,"& or < expected");
-        return -1;
+        str+= chlen;
+        len-= chlen;
+        break;
       }
-      prevlexnum= lexnum;
-      state= 2;
-      continue;
-      
-    case 2:
-      if (lexnum != MY_COLL_LEXEM_CHAR)
+    }
+
+    if (!from)
+    {
+      from= my_char_weight_addr(dst, *str);
+      str++;
+      len--;
+    }
+
+    for ( ; from && *from && count < to_length; )
+    {
+      *to++= *from++;
+      count++;
+    }
+  }
+
+  *to= 0;
+  return count;
+}
+
+
+/**
+  Alloc new page and copy the default UCA weights
+  @param loader   - Character set loader
+  @param src_uca  - Default UCA data to copy from
+  @param dst_uca  - UCA data to copy weights to
+  @param page     - page number
+
+  @return
+  @retval         FALSE on success
+  @retval         TRUE  on error
+*/
+static my_bool
+my_uca_copy_page(MY_CHARSET_LOADER *loader,
+                 const MY_UCA_WEIGHT_LEVEL *src,
+                 MY_UCA_WEIGHT_LEVEL *dst,
+                 size_t page)
+{
+  uint chc, size= 256 * dst->lengths[page] * sizeof(uint16);
+  if (!(dst->weights[page]= (uint16 *) (loader->once_alloc)(size)))
+    return TRUE;
+
+  DBUG_ASSERT(src->lengths[page] <= dst->lengths[page]);
+  memset(dst->weights[page], 0, size);
+  for (chc=0 ; chc < 256; chc++)
+  {
+    memcpy(dst->weights[page] + chc * dst->lengths[page],
+           src->weights[page] + chc * src->lengths[page],
+           src->lengths[page] * sizeof(uint16));
+  }
+  return FALSE;
+}
+
+
+static my_bool
+apply_shift(MY_CHARSET_LOADER *loader,
+            MY_COLL_RULES *rules, MY_COLL_RULE *r, int level,
+            uint16 *to, size_t nweights)
+{
+  /* Apply level difference. */
+  if (nweights)
+  {
+    to[nweights - 1]+= r->diff[level];
+    if (r->before_level == 1) /* Apply "&[before primary]" */
+    {
+      if (nweights >= 2)
       {
-        my_coll_lexem_print_error(&lexem,errstr,errsize-1,"character expected");
-        return -1;
+        to[nweights - 2]--; /* Reset before */
+        if (rules->shift_after_method == my_shift_method_expand)
+        {
+          /*
+            Special case. Don't let characters shifted after X
+            and before next(X) intermix to each other.
+            
+            For example:
+            "[shift-after-method expand] &0 < a &[before primary]1 < A".
+            I.e. we reorder 'a' after '0', and then 'A' before '1'.
+            'a' must be sorted before 'A'.
+            
+            Note, there are no real collations in CLDR which shift
+            after and before two neighbourgh characters. We need this
+            just in case. Reserving 4096 (0x1000) weights for such
+            cases is perfectly enough.
+          */
+          to[nweights - 1]+= 0x1000; /* W3-TODO: const may vary on levels 2,3*/
+        }
       }
-      
-      if (prevlexnum == MY_COLL_LEXEM_SHIFT)
+      else
       {
-        item.base= lexem.code;
-        item.diff[0]= 0;
-        item.diff[1]= 0;
-        item.diff[2]= 0;
+        my_snprintf(loader->error, sizeof(loader->error),
+                    "Can't reset before "
+                    "a primary ignorable character U+%04lX", r->base[0]);
+        return TRUE;
       }
-      else if (prevlexnum == MY_COLL_LEXEM_DIFF)
+    }
+  }
+  else
+  {
+    /* Shift to an ignorable character, e.g.: & \u0000 < \u0001 */
+    DBUG_ASSERT(to[0] == 0);
+    to[0]= r->diff[level];
+  }
+  return FALSE; 
+}
+
+
+static my_bool
+apply_one_rule(MY_CHARSET_LOADER *loader,
+               MY_COLL_RULES *rules, MY_COLL_RULE *r, int level,
+               MY_UCA_WEIGHT_LEVEL *dst)
+{
+  size_t nweights;
+  size_t nreset= my_coll_rule_reset_length(r); /* Length of reset sequence */
+  size_t nshift= my_coll_rule_shift_length(r); /* Length of shift sequence */
+  uint16 *to;
+
+  if (nshift >= 2) /* Contraction */
+  {
+    size_t i;
+    int flag;
+    MY_CONTRACTIONS *contractions= &dst->contractions;
+    /* Add HEAD, MID and TAIL flags for the contraction parts */
+    my_uca_add_contraction_flag(contractions, r->curr[0],
+                                r->with_context ?
+                                MY_UCA_PREVIOUS_CONTEXT_HEAD :
+                                MY_UCA_CNT_HEAD);
+    for (i= 1, flag= MY_UCA_CNT_MID1; i < nshift - 1; i++, flag<<= 1)
+      my_uca_add_contraction_flag(contractions, r->curr[i], flag);
+    my_uca_add_contraction_flag(contractions, r->curr[i],
+                                r->with_context ?
+                                MY_UCA_PREVIOUS_CONTEXT_TAIL :
+                                MY_UCA_CNT_TAIL);
+    /* Add new contraction to the contraction list */
+    to= my_uca_add_contraction(contractions, r->curr, nshift,
+                               r->with_context)->weight;
+    /* Store weights of the "reset to" character */
+    dst->contractions.nitems--; /* Temporarily hide - it's incomplete */
+    nweights= my_char_weight_put(dst, to, MY_UCA_MAX_WEIGHT_SIZE,
+                                 r->base, nreset);
+    dst->contractions.nitems++; /* Activate, now it's complete */
+  }
+  else
+  {
+    my_wc_t pagec= (r->curr[0] >> 8);
+    DBUG_ASSERT(dst->weights[pagec]);
+    to= my_char_weight_addr(dst, r->curr[0]);
+    /* Store weights of the "reset to" character */
+    nweights= my_char_weight_put(dst, to, dst->lengths[pagec], r->base, nreset);
+  }
+
+  /* Apply level difference. */
+  return apply_shift(loader, rules, r, level, to, nweights);
+}
+
+
+/**
+  Check if collation rules are valid,
+  i.e. characters are not outside of the collation suported range.
+*/
+static int
+check_rules(MY_CHARSET_LOADER *loader,
+            const MY_COLL_RULES *rules,
+            const MY_UCA_WEIGHT_LEVEL *dst, const MY_UCA_WEIGHT_LEVEL *src)
+{
+  const MY_COLL_RULE *r, *rlast;
+  for (r= rules->rule, rlast= rules->rule + rules->nrules; r < rlast; r++)
+  {
+    if (r->curr[0] > dst->maxchar)
+    {
+      my_snprintf(loader->error, sizeof(loader->error),
+                  "Shift character out of range: u%04X", (uint) r->curr[0]);
+      return TRUE;
+    }
+    else if (r->base[0] > src->maxchar)
+    {
+      my_snprintf(loader->error, sizeof(loader->error),
+                  "Reset character out of range: u%04X", (uint) r->base[0]);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+
+static my_bool
+init_weight_level(MY_CHARSET_LOADER *loader, MY_COLL_RULES *rules, int level,
+                  MY_UCA_WEIGHT_LEVEL *dst, const MY_UCA_WEIGHT_LEVEL *src)
+{
+  MY_COLL_RULE *r, *rlast;
+  int ncontractions= 0;
+  size_t i, npages= (src->maxchar + 1) / 256;
+
+  dst->maxchar= src->maxchar;
+
+  if (check_rules(loader, rules, dst, src))
+    return TRUE;
+
+  /* Allocate memory for pages and their lengths */
+  if (!(dst->lengths= (uchar *) (loader->once_alloc)(npages)) ||
+      !(dst->weights= (uint16 **) (loader->once_alloc)(npages *
+                                                       sizeof(uint16 *))))
+    return TRUE;
+
+  /* Copy pages lengths and page pointers from the default UCA weights */ 
+  memcpy(dst->lengths, src->lengths, npages);
+  memcpy(dst->weights, src->weights, npages * sizeof(uint16 *));
+
+  /*
+    Calculate maximum lenghts for the pages which will be overwritten.
+    Mark pages that will be otherwriten as NULL.
+    We'll allocate their own memory.
+  */
+  for (r= rules->rule, rlast= rules->rule + rules->nrules; r < rlast; r++)
+  {
+    if (!r->curr[1]) /* If not a contraction */
+    {
+      uint pagec= (r->curr[0] >> 8);
+      if (r->base[1]) /* Expansion */
       {
-        MY_COLL_LEXEM savlex;
-        savlex= lexem;
-        item.curr[0]= lexem.code;
-        if ((lexnum= my_coll_lexem_next(&lexem)) == MY_COLL_LEXEM_CHAR)
-        {
-          item.curr[1]= lexem.code;
-        }
-        else
-        {
-          item.curr[1]= 0;
-          lexem=savlex;   /* Restore previous parser state */
-        }
-        if (lexem.diff == 3)
-        {
-          item.diff[2]++;
-        }
-        else if (lexem.diff == 2)
-        {
-          item.diff[1]++;
-          item.diff[2]= 0;
-        }
-        else if (lexem.diff == 1)
-        {
-          item.diff[0]++;
-          item.diff[1]= 0;
-          item.diff[2]= 0;
-        }
-        else if (lexem.diff == 0)
-        {
-          item.diff[0]= item.diff[1]= item.diff[2]= 0;
-        }
-        if (nitems >= mitems)
-        {
-          my_coll_lexem_print_error(&lexem,errstr,errsize-1,"Too many rules");
-          return -1;
-        }
-        rule[nitems++]= item;
+        /* Reserve space for maximum possible length */
+        dst->lengths[pagec]= MY_UCA_MAX_WEIGHT_SIZE;
       }
       else
       {
-        my_coll_lexem_print_error(&lexem,errstr,errsize-1,"Should never happen");
-        return -1;
+        uint pageb= (r->base[0] >> 8);
+        if (dst->lengths[pagec] < src->lengths[pageb])
+          dst->lengths[pagec]= src->lengths[pageb];
       }
-      state= 1;
-      continue;
+      dst->weights[pagec]= NULL; /* Mark that we'll overwrite this page */
     }
+    else
+      ncontractions++;
   }
-  return (int) nitems;
+
+  /* Allocate pages that we'll overwrite and copy default weights */
+  for (i= 0; i < npages; i++)
+  {
+    my_bool rc;
+    /*
+      Don't touch pages with lengths[i]==0, they have implicit weights
+      calculated algorithmically.
+    */
+    if (!dst->weights[i] && dst->lengths[i] &&
+        (rc= my_uca_copy_page(loader, src, dst, i)))
+      return rc;
+  }
+
+  if (ncontractions)
+  {
+    if (my_uca_alloc_contractions(&dst->contractions, loader, ncontractions))
+      return TRUE;
+  }
+
+  /*
+    Preparatory step is done at this point.
+    Now we have memory allocated for the pages that we'll overwrite,
+    and for contractions, including previous context contractions.
+    Also, for the pages that we'll overwrite, we have copied default weights.
+    Now iterate through the rules, overwrite weights for the characters
+    that appear in the rules, and put all contractions into contraction list.
+  */
+  for (r= rules->rule; r < rlast;  r++)
+  {
+    if (apply_one_rule(loader, rules, r, level, dst))
+      return TRUE;
+  }
+  return FALSE;
 }
 
-#define MY_MAX_COLL_RULE 128
 
 /*
   This function copies an UCS2 collation from
@@ -8013,145 +9356,65 @@ static int my_coll_rule_parse(MY_COLL_RU
   default weights.
 */
 
-static my_bool create_tailoring(struct charset_info_st *cs,
-                                void *(*alloc)(size_t))
+static my_bool
+create_tailoring(struct charset_info_st *cs, MY_CHARSET_LOADER *loader)
 {
-  MY_COLL_RULE rule[MY_MAX_COLL_RULE];
-  MY_COLL_RULE *r, *rfirst, *rlast;
-  char errstr[128];
-  uchar   *newlengths;
-  uint16 **newweights;
-  const uchar *deflengths= uca_length;
-  const uint16 *const *defweights= uca_weight;
-  int rc, i;
-  int ncontractions= 0;
-  
+  MY_COLL_RULES rules;
+  MY_UCA_INFO new_uca, *src_uca= NULL;
+  int rc= 0;
+
+  *loader->error= '\0';
+
   if (!cs->tailoring)
-    return 1;
-  
+    return 0; /* Ok to add a collation without tailoring */
+
+  memset(&rules, 0, sizeof(rules));
+  rules.loader= loader;
+  rules.uca= cs->uca ? cs->uca : &my_uca_v400; /* For logical positions, etc */
+  memset(&new_uca, 0, sizeof(new_uca));
+
   /* Parse ICU Collation Customization expression */
-  if ((rc= my_coll_rule_parse(rule, MY_MAX_COLL_RULE,
+  if ((rc= my_coll_rule_parse(&rules,
                               cs->tailoring,
-                              cs->tailoring + strlen(cs->tailoring),
-                              errstr, sizeof(errstr))) < 0)
-  {
-    /* 
-      TODO: add error message reporting.
-      printf("Error: %d '%s'\n", rc, errstr);
-    */
-    return 1;
-  }
-  
-  rfirst= rule;
-  rlast= rule + rc;
-  
-  if (!cs->caseinfo)
-    cs->caseinfo= my_unicase_default;
-  
-  if (!(newweights= (uint16**) (*alloc)(256*sizeof(uint16*))))
-    return 1;
-  bzero(newweights, 256*sizeof(uint16*));
-  
-  if (!(newlengths= (uchar*) (*alloc)(256)))
-    return 1;
-  
-  memcpy(newlengths, deflengths, 256);
-  
-  /*
-    Calculate maximum lenghts for the pages
-    which will be overwritten.
-  */
-  for (i=0; i < rc; i++)
-  {
-    /* check if the shift or the reset characters are out of range */
-    if (rule[i].curr[0] > MAX_UCA_CHAR_WITH_EXPLICIT_WEIGHT ||
-        rule[i].base > MAX_UCA_CHAR_WITH_EXPLICIT_WEIGHT)
-      return 1;
+                              cs->tailoring + strlen(cs->tailoring))))
+    goto ex;
 
-    if (!rule[i].curr[1]) /* If not a contraction */
-    {
-      uint pageb= (rule[i].base >> 8) & 0xFF;
-      uint pagec= (rule[i].curr[0] >> 8) & 0xFF;
-    
-      if (newlengths[pagec] < deflengths[pageb])
-        newlengths[pagec]= deflengths[pageb];
-    }
-    else
-      ncontractions++;
+#if RESOLVE_CONFLICT_WITH_MYSQL_AND_MARIA_COLLATION_IDS
+  if (rules.version == 520)           /* Unicode-5.2.0 requested */
+  {
+    src_uca= &my_uca_v520;
+    cs->caseinfo= &my_unicase_unicode520;
   }
-  
-  for (i=0; i < rc;  i++)
+  else
+#endif
+  if (rules.version == 400)      /* Unicode-4.0.0 requested */
   {
-    uint pageb= (rule[i].base >> 8) & 0xFF;
-    uint pagec= (rule[i].curr[0] >> 8) & 0xFF;
-    uint chb, chc;
-    
-    if (rule[i].curr[1]) /* Skip contraction */
-      continue;
-    
-    if (!newweights[pagec])
-    {
-      /* Alloc new page and copy the default UCA weights */
-      uint size= 256*newlengths[pagec]*sizeof(uint16);
-      
-      if (!(newweights[pagec]= (uint16*) (*alloc)(size)))
-        return 1;
-      bzero((void*) newweights[pagec], size);
-      
-      for (chc=0 ; chc < 256; chc++)
-      {
-        memcpy(newweights[pagec] + chc*newlengths[pagec],
-               defweights[pagec] + chc*deflengths[pagec],
-               deflengths[pagec]*sizeof(uint16));
-      }
-    }
-    
-    /* 
-      Aply the alternative rule:
-      shift to the base character and primary difference.
-    */
-    chc= rule[i].curr[0] & 0xFF;
-    chb= rule[i].base & 0xFF;
-    memcpy(newweights[pagec] + chc*newlengths[pagec],
-           defweights[pageb] + chb*deflengths[pageb],
-           deflengths[pageb]*sizeof(uint16));
-    /* Apply primary difference */
-    newweights[pagec][chc*newlengths[pagec]]+= rule[i].diff[0];
+    src_uca= &my_uca_v400;
+    cs->caseinfo= &my_unicase_default;
   }
-  
-  /* Copy non-overwritten pages from the default UCA weights */
-  for (i= 0; i < 256 ; i++)
+  else                                /* No Unicode version specified */
   {
-    if (!newweights[i])
-      ((const uint16**) newweights)[i]= defweights[i];
+    src_uca= cs->uca ? cs->uca : &my_uca_v400;
+    if (!cs->caseinfo)
+      cs->caseinfo= &my_unicase_default;
   }
-  
-  cs->sort_order= newlengths;
-  cs->sort_order_big= (const uint16**) newweights;
-  cs->contractions= NULL;
-  
-  /* Now process contractions */
-  if (ncontractions)
+
+  if ((rc= init_weight_level(loader, &rules, 0,
+                             &new_uca.level[0], &src_uca->level[0])))
+    goto ex;
+
+  if (!(cs->uca= (MY_UCA_INFO *) (loader->once_alloc)(sizeof(MY_UCA_INFO))))
   {
-    if (my_uca_alloc_contractions(cs, alloc, ncontractions))
-      return 1;
-    for (r= rfirst; r < rlast; r++)
-    {
-      uint16 *to;
-      if (r->curr[1]) /* Contraction */
-      {
-        /* Mark both letters as "is contraction part" */
-        my_uca_add_contraction_flag(cs, r->curr[0], MY_UCA_CNT_HEAD);
-        my_uca_add_contraction_flag(cs, r->curr[1], MY_UCA_CNT_TAIL);
-        to= my_uca_add_contraction(cs, r->curr, 2)->weight;
-        /* Copy weight from the reset character */
-        to[0]= my_char_weight_addr(cs, r->base)[0];
-        /* Apply primary difference */
-        to[0]+= r->diff[0];
-      }
-    }
+    rc= 1;
+    goto ex;
   }
-  return 0;
+  cs->uca[0]= new_uca;
+
+ex:
+  (loader->free)(rules.rule);
+  if (rc != 0 && loader->error[0])
+    loader->reporter(ERROR_LEVEL, "%s", loader->error);
+  return rc;
 }
 
 
@@ -8161,12 +9424,14 @@ static my_bool create_tailoring(struct c
   Should work for any character set.
 */
 
-static my_bool my_coll_init_uca(struct charset_info_st *cs,
-                                void *(*alloc)(size_t))
+static my_bool
+my_coll_init_uca(struct charset_info_st *cs, MY_CHARSET_LOADER *loader)
 {
   cs->pad_char= ' ';
   cs->ctype= my_charset_utf8_unicode_ci.ctype;
-  return create_tailoring(cs, alloc);
+  if (!cs->caseinfo)
+    cs->caseinfo= &my_unicase_default;
+  return create_tailoring(cs, loader);
 }
 
 static int my_strnncoll_any_uca(CHARSET_INFO *cs,
@@ -8213,7 +9478,7 @@ static int my_strnncoll_ucs2_uca(CHARSET
                                  const uchar *t, size_t tlen,
                                  my_bool t_is_prefix)
 {
-  return my_strnncoll_uca(cs, &my_ucs2_uca_scanner_handler,
+  return my_strnncoll_uca(cs, &my_any_uca_scanner_handler,
                           s, slen, t, tlen, t_is_prefix);
 }
 
@@ -8222,7 +9487,7 @@ static int my_strnncollsp_ucs2_uca(CHARS
                                    const uchar *t, size_t tlen,
                                    my_bool diff_if_only_endspace_difference)
 {
-  return my_strnncollsp_uca(cs, &my_ucs2_uca_scanner_handler,
+  return my_strnncollsp_uca(cs, &my_any_uca_scanner_handler,
                             s, slen, t, tlen,
                             diff_if_only_endspace_difference);
 }   
@@ -8231,14 +9496,14 @@ static void my_hash_sort_ucs2_uca(CHARSE
                                   const uchar *s, size_t slen,
                                   ulong *n1, ulong *n2)
 {
-  my_hash_sort_uca(cs, &my_ucs2_uca_scanner_handler, s, slen, n1, n2); 
+  my_hash_sort_uca(cs, &my_any_uca_scanner_handler, s, slen, n1, n2); 
 }
 
 static size_t my_strnxfrm_ucs2_uca(CHARSET_INFO *cs, 
                                    uchar *dst, size_t dstlen,
                                    const uchar *src, size_t srclen)
 {
-  return my_strnxfrm_uca(cs, &my_ucs2_uca_scanner_handler,
+  return my_strnxfrm_uca(cs, &my_any_uca_scanner_handler,
                          dst, dstlen, src, srclen);
 }
 
@@ -8268,12 +9533,11 @@ struct charset_info_st my_charset_ucs2_u
     NULL,		/* ctype        */
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
-    uca_length,		/* sort_order   */
-    NULL,		/* contractions */
-    uca_weight,		/* sort_order_big*/
+    NULL,		/* sort_order   */
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8301,11 +9565,10 @@ struct charset_info_st my_charset_ucs2_i
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8333,11 +9596,10 @@ struct charset_info_st my_charset_ucs2_l
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8365,11 +9627,10 @@ struct charset_info_st my_charset_ucs2_r
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8397,11 +9658,10 @@ struct charset_info_st my_charset_ucs2_s
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8429,11 +9689,10 @@ struct charset_info_st my_charset_ucs2_p
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8461,11 +9720,10 @@ struct charset_info_st my_charset_ucs2_e
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8493,11 +9751,10 @@ struct charset_info_st my_charset_ucs2_s
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8525,11 +9782,10 @@ struct charset_info_st my_charset_ucs2_s
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8557,11 +9813,10 @@ struct charset_info_st my_charset_ucs2_t
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_turkish, /* caseinfo     */
+    &my_unicase_turkish,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8589,11 +9844,10 @@ struct charset_info_st my_charset_ucs2_c
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8622,11 +9876,10 @@ struct charset_info_st my_charset_ucs2_d
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8654,11 +9907,10 @@ struct charset_info_st my_charset_ucs2_l
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8686,11 +9938,10 @@ struct charset_info_st my_charset_ucs2_s
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8718,11 +9969,10 @@ struct charset_info_st my_charset_ucs2_s
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8751,11 +10001,10 @@ struct charset_info_st my_charset_ucs2_r
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8784,11 +10033,10 @@ struct charset_info_st my_charset_ucs2_p
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8817,11 +10065,10 @@ struct charset_info_st my_charset_ucs2_e
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8850,11 +10097,10 @@ struct charset_info_st my_charset_ucs2_h
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -8870,23 +10116,55 @@ struct charset_info_st my_charset_ucs2_h
     &my_collation_ucs2_uca_handler
 };
 
-struct charset_info_st my_charset_ucs2_sinhala_uca_ci=
+struct charset_info_st my_charset_ucs2_sinhala_uca_ci=
+{
+    147,0,0,             /* number       */
+    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII,
+    "ucs2",              /* csname    */
+    "ucs2_sinhala_ci",   /* name         */
+    "",                  /* comment      */
+    sinhala,             /* tailoring    */
+    NULL,                /* ctype        */
+    NULL,                /* to_lower     */
+    NULL,                /* to_upper     */
+    NULL,                /* sort_order   */
+    NULL,                /* uca          */
+    NULL,                /* tab_to_uni   */
+    NULL,                /* tab_from_uni */
+    &my_unicase_default, /* caseinfo     */
+    NULL,                /* state_map    */
+    NULL,                /* ident_map    */
+    8,                   /* strxfrm_multiply */
+    1,                   /* caseup_multiply  */
+    1,                   /* casedn_multiply  */
+    2,                   /* mbminlen     */
+    2,                   /* mbmaxlen     */
+    9,                   /* min_sort_char */
+    0xFFFF,              /* max_sort_char */
+    ' ',                 /* pad char      */
+    0,                   /* escape_with_backslash_is_dangerous */
+    &my_charset_ucs2_handler,
+    &my_collation_ucs2_uca_handler
+};
+
+
+
+struct charset_info_st my_charset_ucs2_german2_uca_ci=
 {
-    147,0,0,             /* number       */
+    148,0,0,             /* number       */
     MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_NONASCII,
     "ucs2",              /* csname    */
-    "ucs2_sinhala_ci",   /* name         */
+    "ucs2_german2_ci",   /* name         */
     "",                  /* comment      */
-    sinhala,             /* tailoring    */
+    german2,             /* tailoring    */
     NULL,                /* ctype        */
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -8914,11 +10192,10 @@ struct charset_info_st my_charset_ucs2_c
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -8934,6 +10211,7 @@ struct charset_info_st my_charset_ucs2_c
     &my_collation_ucs2_uca_handler
 };
 
+
 #endif
 
 
@@ -8981,10 +10259,12 @@ static uchar ctype_utf8[] = {
 
 extern MY_CHARSET_HANDLER my_charset_utf8_handler;
 
+#define MY_CS_UTF8MB3_UCA_FLAGS  (MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE)
+
 struct charset_info_st my_charset_utf8_unicode_ci=
 {
     192,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_unicode_ci",	/* name         */
     "",			/* comment      */
@@ -8992,12 +10272,11 @@ struct charset_info_st my_charset_utf8_u
     ctype_utf8,		/* ctype        */
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
-    uca_length,		/* sort_order   */
-    NULL,		/* contractions */
-    uca_weight,		/* sort_order_big*/
+    NULL,		/* sort_order   */
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9017,7 +10296,7 @@ struct charset_info_st my_charset_utf8_u
 struct charset_info_st my_charset_utf8_icelandic_uca_ci=
 {
     193,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_icelandic_ci",/* name         */
     "",			/* comment      */
@@ -9026,11 +10305,10 @@ struct charset_info_st my_charset_utf8_i
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9049,7 +10327,7 @@ struct charset_info_st my_charset_utf8_i
 struct charset_info_st my_charset_utf8_latvian_uca_ci=
 {
     194,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_latvian_ci",	/* name         */
     "",			/* comment      */
@@ -9058,11 +10336,10 @@ struct charset_info_st my_charset_utf8_l
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9081,7 +10358,7 @@ struct charset_info_st my_charset_utf8_l
 struct charset_info_st my_charset_utf8_romanian_uca_ci=
 {
     195,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_romanian_ci",	/* name         */
     "",			/* comment      */
@@ -9090,11 +10367,10 @@ struct charset_info_st my_charset_utf8_r
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9113,7 +10389,7 @@ struct charset_info_st my_charset_utf8_r
 struct charset_info_st my_charset_utf8_slovenian_uca_ci=
 {
     196,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_slovenian_ci",/* name         */
     "",			/* comment      */
@@ -9122,11 +10398,10 @@ struct charset_info_st my_charset_utf8_s
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9145,7 +10420,7 @@ struct charset_info_st my_charset_utf8_s
 struct charset_info_st my_charset_utf8_polish_uca_ci=
 {
     197,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_polish_ci",	/* name         */
     "",			/* comment      */
@@ -9154,11 +10429,10 @@ struct charset_info_st my_charset_utf8_p
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9177,7 +10451,7 @@ struct charset_info_st my_charset_utf8_p
 struct charset_info_st my_charset_utf8_estonian_uca_ci=
 {
     198,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_estonian_ci",	/* name         */
     "",			/* comment      */
@@ -9186,11 +10460,10 @@ struct charset_info_st my_charset_utf8_e
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9209,7 +10482,7 @@ struct charset_info_st my_charset_utf8_e
 struct charset_info_st my_charset_utf8_spanish_uca_ci=
 {
     199,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_spanish_ci",	/* name         */
     "",			/* comment      */
@@ -9218,11 +10491,10 @@ struct charset_info_st my_charset_utf8_s
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9241,7 +10513,7 @@ struct charset_info_st my_charset_utf8_s
 struct charset_info_st my_charset_utf8_swedish_uca_ci=
 {
     200,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_swedish_ci",	/* name         */
     "",			/* comment      */
@@ -9250,11 +10522,10 @@ struct charset_info_st my_charset_utf8_s
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9273,7 +10544,7 @@ struct charset_info_st my_charset_utf8_s
 struct charset_info_st my_charset_utf8_turkish_uca_ci=
 {
     201,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_turkish_ci",	/* name         */
     "",			/* comment      */
@@ -9282,11 +10553,10 @@ struct charset_info_st my_charset_utf8_t
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_turkish, /* caseinfo     */
+    &my_unicase_turkish,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9305,7 +10575,7 @@ struct charset_info_st my_charset_utf8_t
 struct charset_info_st my_charset_utf8_czech_uca_ci=
 {
     202,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_czech_ci",	/* name         */
     "",			/* comment      */
@@ -9314,11 +10584,10 @@ struct charset_info_st my_charset_utf8_c
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9338,7 +10607,7 @@ struct charset_info_st my_charset_utf8_c
 struct charset_info_st my_charset_utf8_danish_uca_ci=
 {
     203,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_danish_ci",	/* name         */
     "",			/* comment      */
@@ -9347,11 +10616,10 @@ struct charset_info_st my_charset_utf8_d
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9370,7 +10638,7 @@ struct charset_info_st my_charset_utf8_d
 struct charset_info_st my_charset_utf8_lithuanian_uca_ci=
 {
     204,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_lithuanian_ci",/* name         */
     "",			/* comment      */
@@ -9379,11 +10647,10 @@ struct charset_info_st my_charset_utf8_l
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9402,7 +10669,7 @@ struct charset_info_st my_charset_utf8_l
 struct charset_info_st my_charset_utf8_slovak_uca_ci=
 {
     205,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_slovak_ci",	/* name         */
     "",			/* comment      */
@@ -9411,11 +10678,10 @@ struct charset_info_st my_charset_utf8_s
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9434,7 +10700,7 @@ struct charset_info_st my_charset_utf8_s
 struct charset_info_st my_charset_utf8_spanish2_uca_ci=
 {
     206,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_spanish2_ci",	/* name         */
     "",			/* comment      */
@@ -9443,11 +10709,10 @@ struct charset_info_st my_charset_utf8_s
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9466,7 +10731,7 @@ struct charset_info_st my_charset_utf8_s
 struct charset_info_st my_charset_utf8_roman_uca_ci=
 {
     207,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_roman_ci",	/* name         */
     "",			/* comment      */
@@ -9475,11 +10740,10 @@ struct charset_info_st my_charset_utf8_r
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9498,7 +10762,7 @@ struct charset_info_st my_charset_utf8_r
 struct charset_info_st my_charset_utf8_persian_uca_ci=
 {
     208,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_persian_ci",	/* name         */
     "",			/* comment      */
@@ -9507,11 +10771,10 @@ struct charset_info_st my_charset_utf8_p
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9530,7 +10793,7 @@ struct charset_info_st my_charset_utf8_p
 struct charset_info_st my_charset_utf8_esperanto_uca_ci=
 {
     209,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_esperanto_ci",/* name         */
     "",			/* comment      */
@@ -9539,11 +10802,10 @@ struct charset_info_st my_charset_utf8_e
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9562,7 +10824,7 @@ struct charset_info_st my_charset_utf8_e
 struct charset_info_st my_charset_utf8_hungarian_uca_ci=
 {
     210,0,0,		/* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",		/* cs name    */
     "utf8_hungarian_ci",/* name         */
     "",			/* comment      */
@@ -9571,11 +10833,10 @@ struct charset_info_st my_charset_utf8_h
     NULL,		/* to_lower     */
     NULL,		/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     8,			/* strxfrm_multiply */
@@ -9594,7 +10855,7 @@ struct charset_info_st my_charset_utf8_h
 struct charset_info_st my_charset_utf8_sinhala_uca_ci=
 {
     211,0,0,             /* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
     "utf8",              /* cs name      */
     "utf8_sinhala_ci",   /* name         */
     "",                  /* comment      */
@@ -9603,11 +10864,42 @@ struct charset_info_st my_charset_utf8_s
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
+    NULL,                /* tab_to_uni   */
+    NULL,                /* tab_from_uni */
+    &my_unicase_default, /* caseinfo     */
+    NULL,                /* state_map    */
+    NULL,                /* ident_map    */
+    8,                   /* strxfrm_multiply */
+    1,                   /* caseup_multiply  */
+    1,                   /* casedn_multiply  */
+    1,                   /* mbminlen     */
+    3,                   /* mbmaxlen     */
+    9,                   /* min_sort_char */
+    0xFFFF,              /* max_sort_char */
+    ' ',                 /* pad char      */
+    0,                   /* escape_with_backslash_is_dangerous */
+    &my_charset_utf8_handler,
+    &my_collation_any_uca_handler
+};
+
+
+struct charset_info_st my_charset_utf8_german2_uca_ci=
+{
+    212,0,0,             /* number       */
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
+    MY_UTF8MB3,          /* cs name      */
+    MY_UTF8MB3 "_german2_ci",/* name    */
+    "",                  /* comment      */
+    german2,             /* tailoring    */
+    ctype_utf8,          /* ctype        */
+    NULL,                /* to_lower     */
+    NULL,                /* to_upper     */
+    NULL,                /* sort_order   */
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -9625,36 +10917,36 @@ struct charset_info_st my_charset_utf8_s
 
 struct charset_info_st my_charset_utf8_croatian_uca_ci=
 {
-    213,0,0,            /* number       */
-    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
-    "utf8",             /* cs name    */
-    "utf8_croatian_ci", /* name         */
-    "",                 /* comment      */
-    croatian,           /* tailoring    */
-    ctype_utf8,         /* ctype        */
-    NULL,               /* to_lower     */
-    NULL,               /* to_upper     */
-    NULL,               /* sort_order   */
-    NULL,               /* contractions */
-    NULL,               /* sort_order_big*/
-    NULL,               /* tab_to_uni   */
-    NULL,               /* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
-    NULL,               /* state_map    */
-    NULL,               /* ident_map    */
-    8,                  /* strxfrm_multiply */
-    1,                  /* caseup_multiply  */
-    1,                  /* casedn_multiply  */
-    1,                  /* mbminlen     */
-    3,                  /* mbmaxlen     */
-    9,                  /* min_sort_char */
-    0xFFFF,             /* max_sort_char */
-    ' ',                /* pad char      */
-    0,                  /* escape_with_backslash_is_dangerous */
+    213,0,0,             /* number       */
+    MY_CS_UTF8MB3_UCA_FLAGS,/* flags    */
+    MY_UTF8MB3,          /* cs name      */
+    MY_UTF8MB3 "_croatian_ci",/* name    */
+    "",                  /* comment      */
+    croatian,            /* tailoring    */
+    ctype_utf8,          /* ctype        */
+    NULL,                /* to_lower     */
+    NULL,                /* to_upper     */
+    NULL,                /* sort_order   */
+    NULL,                /* uca          */
+    NULL,                /* tab_to_uni   */
+    NULL,                /* tab_from_uni */
+    &my_unicase_default, /* caseinfo     */
+    NULL,                /* state_map    */
+    NULL,                /* ident_map    */
+    8,                   /* strxfrm_multiply */
+    1,                   /* caseup_multiply  */
+    1,                   /* casedn_multiply  */
+    1,                   /* mbminlen     */
+    3,                   /* mbmaxlen     */
+    9,                   /* min_sort_char */
+    0xFFFF,              /* max_sort_char */
+    ' ',                 /* pad char      */
+    0,                   /* escape_with_backslash_is_dangerous */
     &my_charset_utf8_handler,
     &my_collation_any_uca_handler
 };
 
+
 #endif /* HAVE_CHARSET_utf8 */
 
 
@@ -9675,12 +10967,11 @@ struct charset_info_st my_charset_utf8mb
     ctype_utf8,          /* ctype        */
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
-    uca_length,          /* sort_order   */
-    NULL,                /* contractions */
-    uca_weight,          /* sort_order_big*/
+    NULL,                /* sort_order   */
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -9709,11 +11000,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -9741,11 +11031,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -9773,11 +11062,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -9805,11 +11093,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -9837,11 +11124,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -9869,11 +11155,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -9901,11 +11186,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -9933,11 +11217,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -9965,11 +11248,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_turkish,  /* caseinfo     */
+    &my_unicase_turkish, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -9997,11 +11279,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10030,11 +11311,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10062,11 +11342,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10094,11 +11373,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10126,11 +11404,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10158,11 +11435,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10190,11 +11466,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10222,11 +11497,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10254,11 +11528,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10286,11 +11559,41 @@ struct charset_info_st my_charset_utf8mb
     NULL,               /* to_lower     */
     NULL,               /* to_upper     */
     NULL,               /* sort_order   */
-    NULL,               /* contractions */
-    NULL,               /* sort_order_big*/
+    NULL,               /* uca          */
+    NULL,               /* tab_to_uni   */
+    NULL,               /* tab_from_uni */
+    &my_unicase_default,/* caseinfo     */
+    NULL,               /* state_map    */
+    NULL,               /* ident_map    */
+    8,                  /* strxfrm_multiply */
+    1,                  /* caseup_multiply  */
+    1,                  /* casedn_multiply  */
+    1,                  /* mbminlen      */
+    4,                  /* mbmaxlen      */
+    9,                  /* min_sort_char */
+    0xFFFF,             /* max_sort_char */
+    ' ',                /* pad char      */
+    0,                  /* escape_with_backslash_is_dangerous */
+    &my_charset_utf8mb4_handler,
+    &my_collation_any_uca_handler
+};
+
+struct charset_info_st my_charset_utf8mb4_german2_uca_ci=
+{
+    244,0,0,            /* number       */
+    MY_CS_UTF8MB4_UCA_FLAGS,/* state    */
+    MY_UTF8MB4,         /* csname      */
+    MY_UTF8MB4 "_german2_ci",/* name  */
+    "",                 /* comment      */
+    german2,            /* tailoring    */
+    ctype_utf8,         /* ctype        */
+    NULL,               /* to_lower     */
+    NULL,               /* to_upper     */
+    NULL,               /* sort_order   */
+    NULL,               /* uca          */
     NULL,               /* tab_to_uni   */
     NULL,               /* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,               /* state_map    */
     NULL,               /* ident_map    */
     8,                  /* strxfrm_multiply */
@@ -10318,11 +11621,10 @@ struct charset_info_st my_charset_utf8mb
     NULL,               /* to_lower     */
     NULL,               /* to_upper     */
     NULL,               /* sort_order   */
-    NULL,               /* contractions */
-    NULL,               /* sort_order_big*/
+    NULL,               /* uca          */
     NULL,               /* tab_to_uni   */
     NULL,               /* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,               /* state_map    */
     NULL,               /* ident_map    */
     8,                  /* strxfrm_multiply */
@@ -10373,12 +11675,11 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* ctype        */
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
-    uca_length,          /* sort_order   */
-    NULL,                /* contractions */
-    uca_weight,          /* sort_order_big*/
+    NULL,                /* sort_order   */
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10407,11 +11708,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10439,11 +11739,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10471,11 +11770,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10503,11 +11801,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10535,11 +11832,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10567,11 +11863,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10599,11 +11894,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10631,11 +11925,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10663,11 +11956,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_turkish,  /* caseinfo     */
+    &my_unicase_turkish, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10695,11 +11987,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10728,11 +12019,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10760,11 +12050,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10792,11 +12081,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10824,11 +12112,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10856,11 +12143,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10888,11 +12174,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10920,11 +12205,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10952,11 +12236,10 @@ struct charset_info_st my_charset_utf32_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -10984,11 +12267,41 @@ struct charset_info_st my_charset_utf32_
     NULL,               /* to_lower     */
     NULL,               /* to_upper     */
     NULL,               /* sort_order   */
-    NULL,               /* contractions */
-    NULL,               /* sort_order_big*/
+    NULL,               /* uca          */
+    NULL,               /* tab_to_uni   */
+    NULL,               /* tab_from_uni */
+    &my_unicase_default,/* caseinfo     */
+    NULL,               /* state_map    */
+    NULL,               /* ident_map    */
+    8,                  /* strxfrm_multiply */
+    1,                  /* caseup_multiply  */
+    1,                  /* casedn_multiply  */
+    4,                  /* mbminlen     */
+    4,                  /* mbmaxlen     */
+    9,                  /* min_sort_char */
+    0xFFFF,             /* max_sort_char */
+    ' ',                /* pad char      */
+    0,                  /* escape_with_backslash_is_dangerous */
+    &my_charset_utf32_handler,
+    &my_collation_utf32_uca_handler
+};
+
+struct charset_info_st my_charset_utf32_german2_uca_ci=
+{
+    180,0,0,            /* number       */
+    MY_CS_UTF32_UCA_FLAGS,/* state      */
+    "utf32",            /* csname      */
+    "utf32_german2_ci", /* name         */
+    "",                 /* comment      */
+    german2,            /* tailoring    */
+    NULL,               /* ctype        */
+    NULL,               /* to_lower     */
+    NULL,               /* to_upper     */
+    NULL,               /* sort_order   */
+    NULL,               /* uca          */
     NULL,               /* tab_to_uni   */
     NULL,               /* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,               /* state_map    */
     NULL,               /* ident_map    */
     8,                  /* strxfrm_multiply */
@@ -11007,8 +12320,8 @@ struct charset_info_st my_charset_utf32_
 struct charset_info_st my_charset_utf32_croatian_uca_ci=
 {
     214,0,0,            /* number       */
-    MY_CS_UTF32_UCA_FLAGS /* state      */,
-    "utf32",            /* cs name      */
+    MY_CS_UTF32_UCA_FLAGS,/* state      */
+    "utf32",            /* csname      */
     "utf32_croatian_ci", /* name        */
     "",                 /* comment      */
     croatian,           /* tailoring    */
@@ -11016,11 +12329,10 @@ struct charset_info_st my_charset_utf32_
     NULL,               /* to_lower     */
     NULL,               /* to_upper     */
     NULL,               /* sort_order   */
-    NULL,               /* contractions */
-    NULL,               /* sort_order_big*/
+    NULL,               /* uca          */
     NULL,               /* tab_to_uni   */
     NULL,               /* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,               /* state_map    */
     NULL,               /* ident_map    */
     8,                  /* strxfrm_multiply */
@@ -11035,6 +12347,7 @@ struct charset_info_st my_charset_utf32_
     &my_charset_utf32_handler,
     &my_collation_utf32_uca_handler
 };
+
 #endif /* HAVE_CHARSET_utf32 */
 
 
@@ -11071,12 +12384,11 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* ctype        */
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
-    uca_length,          /* sort_order   */
-    NULL,                /* contractions */
-    uca_weight,          /* sort_order_big*/
+    NULL,                /* sort_order   */
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11105,11 +12417,10 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11137,11 +12448,10 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11169,11 +12479,10 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11201,11 +12510,10 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11233,11 +12541,10 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11265,11 +12572,10 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11297,11 +12603,10 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11329,11 +12634,10 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11361,11 +12665,10 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_turkish,  /* caseinfo     */
+    &my_unicase_turkish, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11393,11 +12696,10 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11426,11 +12728,10 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11458,11 +12759,10 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11490,11 +12790,10 @@ struct charset_info_st my_charset_utf16_
     NULL,                /* to_lower     */
     NULL,                /* to_upper     */
     NULL,                /* sort_order   */
-    NULL,                /* contractions */
-    NULL,                /* sort_order_big*/
+    NULL,                /* uca          */
     NULL,                /* tab_to_uni   */
     NULL,                /* tab_from_uni */
-    my_unicase_default,  /* caseinfo     */
+    &my_unicase_default, /* caseinfo     */
     NULL,                /* state_map    */
     NULL,                /* ident_map    */
     8,                   /* strxfrm_multiply */
@@ -11522,11 +12821,10 @@ struct charset_info_st my_charset_utf16_
     NULL,               /* to_lower     */
     NULL,               /* to_upper     */
     NULL,               /* sort_order   */
-    NULL,               /* contractions */
-    NULL,               /* sort_order_big*/
+    NULL,               /* uca          */
     NULL,               /* tab_to_uni   */
     NULL,               /* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,               /* state_map    */
     NULL,               /* ident_map    */
     8,                  /* strxfrm_multiply */
@@ -11554,11 +12852,10 @@ struct charset_info_st my_charset_utf16_
     NULL,               /* to_lower     */
     NULL,               /* to_upper     */
     NULL,               /* sort_order   */
-    NULL,               /* contractions */
-    NULL,               /* sort_order_big*/
+    NULL,               /* uca          */
     NULL,               /* tab_to_uni   */
     NULL,               /* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,               /* state_map    */
     NULL,               /* ident_map    */
     8,                  /* strxfrm_multiply */
@@ -11586,11 +12883,10 @@ struct charset_info_st my_charset_utf16_
     NULL,               /* to_lower     */
     NULL,               /* to_upper     */
     NULL,               /* sort_order   */
-    NULL,               /* contractions */
-    NULL,               /* sort_order_big*/
+    NULL,               /* uca          */
     NULL,               /* tab_to_uni   */
     NULL,               /* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,               /* state_map    */
     NULL,               /* ident_map    */
     8,                  /* strxfrm_multiply */
@@ -11618,11 +12914,10 @@ struct charset_info_st my_charset_utf16_
     NULL,               /* to_lower     */
     NULL,               /* to_upper     */
     NULL,               /* sort_order   */
-    NULL,               /* contractions */
-    NULL,               /* sort_order_big*/
+    NULL,               /* uca          */
     NULL,               /* tab_to_uni   */
     NULL,               /* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,               /* state_map    */
     NULL,               /* ident_map    */
     8,                  /* strxfrm_multiply */
@@ -11650,11 +12945,10 @@ struct charset_info_st my_charset_utf16_
     NULL,              /* to_lower     */
     NULL,              /* to_upper     */
     NULL,              /* sort_order   */
-    NULL,              /* contractions */
-    NULL,              /* sort_order_big*/
+    NULL,              /* uca          */
     NULL,              /* tab_to_uni   */
     NULL,              /* tab_from_uni */
-    my_unicase_default,/* caseinfo     */
+    &my_unicase_default,/* caseinfo    */
     NULL,              /* state_map    */
     NULL,              /* ident_map    */
     8,                 /* strxfrm_multiply */
@@ -11682,11 +12976,10 @@ struct charset_info_st my_charset_utf16_
     NULL,              /* to_lower     */
     NULL,              /* to_upper     */
     NULL,              /* sort_order   */
-    NULL,              /* contractions */
-    NULL,              /* sort_order_big*/
+    NULL,              /* uca          */
     NULL,              /* tab_to_uni   */
     NULL,              /* tab_from_uni */
-    my_unicase_default,/* caseinfo     */
+    &my_unicase_default,/* caseinfo    */
     NULL,              /* state_map    */
     NULL,              /* ident_map    */
     8,                 /* strxfrm_multiply */
@@ -11702,114 +12995,72 @@ struct charset_info_st my_charset_utf16_
     &my_collation_utf16_uca_handler
 };
 
-struct charset_info_st my_charset_utf16_croatian_uca_ci=
+struct charset_info_st my_charset_utf16_german2_uca_ci=
 {
-    215,0,0,            /* number       */
-    MY_CS_UTF16_UCA_FLAGS /* state      */,
-    "utf16",            /* cs name      */
-    "utf16_croatian_ci", /* name        */
-    "",                 /* comment      */
-    croatian,           /* tailoring    */
-    NULL,               /* ctype        */
-    NULL,               /* to_lower     */
-    NULL,               /* to_upper     */
-    NULL,               /* sort_order   */
-    NULL,               /* contractions */
-    NULL,               /* sort_order_big*/
-    NULL,               /* tab_to_uni   */
-    NULL,               /* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
-    NULL,               /* state_map    */
-    NULL,               /* ident_map    */
-    8,                  /* strxfrm_multiply */
-    1,                  /* caseup_multiply  */
-    1,                  /* casedn_multiply  */
-    2,                  /* mbminlen     */
-    4,                  /* mbmaxlen     */
-    9,                  /* min_sort_char */
-    0xFFFF,             /* max_sort_char */
-    ' ',                /* pad char      */
-    0,                  /* escape_with_backslash_is_dangerous */
+    121,0,0,           /* number       */
+    MY_CS_UTF16_UCA_FLAGS,/* state     */
+    "utf16",           /* cs name    */
+    "utf16_german2_ci",/* name         */
+    "",                /* comment      */
+    german2,           /* tailoring    */
+    NULL,              /* ctype        */
+    NULL,              /* to_lower     */
+    NULL,              /* to_upper     */
+    NULL,              /* sort_order   */
+    NULL,              /* uca          */
+    NULL,              /* tab_to_uni   */
+    NULL,              /* tab_from_uni */
+    &my_unicase_default,/* caseinfo    */
+    NULL,              /* state_map    */
+    NULL,              /* ident_map    */
+    8,                 /* strxfrm_multiply */
+    1,                 /* caseup_multiply  */
+    1,                 /* casedn_multiply  */
+    2,                 /* mbminlen     */
+    4,                 /* mbmaxlen     */
+    9,                 /* min_sort_char */
+    0xFFFF,            /* max_sort_char */
+    ' ',               /* pad char      */
+    0,                 /* escape_with_backslash_is_dangerous */
     &my_charset_utf16_handler,
     &my_collation_utf16_uca_handler
 };
-#endif /* HAVE_CHARSET_utf16 */
-
-
-
-#endif /* HAVE_UCA_COLLATIONS */
-
-/**
-  Check if UCA data has contractions (public version)
-
-  @cs       Pointer to CHARSET_INFO data
-  @retval   0 - no contraction, 1 - have contractions.
-*/
-
-my_bool
-my_cs_have_contractions(CHARSET_INFO *cs)
-{
-  return cs->contractions != NULL;
-}
 
-/**
-  Check if a character can be contraction head
-  
-  @cs       Pointer to CHARSET_INFO data
-  @wc       Code point
-  
-  @retval   0 - cannot be contraction head
-  @retval   1 - can be contraction head
-*/
 
-my_bool
-my_cs_can_be_contraction_head(CHARSET_INFO *cs, my_wc_t wc)
+struct charset_info_st my_charset_utf16_croatian_uca_ci=
 {
-  return cs->contractions->flags[wc & MY_UCA_CNT_FLAG_MASK] & MY_UCA_CNT_HEAD;
-}
-
-
-/**
-  Check if a character can be contraction tail
-  
-  @cs       Pointer to CHARSET_INFO data
-  @wc       Code point
-  
-  @retval   0 - cannot be contraction tail
-  @retval   1 - can be contraction tail
-*/
+    215,0,0,           /* number       */
+    MY_CS_UTF16_UCA_FLAGS,/* state     */
+    "utf16",           /* cs name    */
+    "utf16_croatian_ci",/* name         */
+    "",                /* comment      */
+    croatian,           /* tailoring    */
+    NULL,              /* ctype        */
+    NULL,              /* to_lower     */
+    NULL,              /* to_upper     */
+    NULL,              /* sort_order   */
+    NULL,              /* uca          */
+    NULL,              /* tab_to_uni   */
+    NULL,              /* tab_from_uni */
+    &my_unicase_default,/* caseinfo    */
+    NULL,              /* state_map    */
+    NULL,              /* ident_map    */
+    8,                 /* strxfrm_multiply */
+    1,                 /* caseup_multiply  */
+    1,                 /* casedn_multiply  */
+    2,                 /* mbminlen     */
+    4,                 /* mbmaxlen     */
+    9,                 /* min_sort_char */
+    0xFFFF,            /* max_sort_char */
+    ' ',               /* pad char      */
+    0,                 /* escape_with_backslash_is_dangerous */
+    &my_charset_utf16_handler,
+    &my_collation_utf16_uca_handler
+};
 
-my_bool
-my_cs_can_be_contraction_tail(CHARSET_INFO *cs, my_wc_t wc)
-{
-  return cs->contractions->flags[wc & MY_UCA_CNT_FLAG_MASK] & MY_UCA_CNT_TAIL;
-}
 
+#endif /* HAVE_CHARSET_utf16 */
 
-/**
-  Find a contraction and return its weight array
-  
-  @cs       Pointer to CHARSET data
-  @wc1      First character
-  @wc2      Second character
-  
-  @return   Weight array
-  @retval   NULL - no contraction found
-  @retval   ptr  - contraction weight array
-*/
 
-const uint16 *
-my_cs_contraction2_weight(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2)
-{
-  const MY_CONTRACTIONS *list= cs->contractions;
-  const MY_CONTRACTION *c, *last;
-  for (c= list->item, last= &list->item[list->nitems]; c < last; c++)
-  {
-    if (c->ch[0] == wc1 && c->ch[1] == wc2)
-    {
-      return c->weight;
-    }
-  }
-  return NULL;
-}
 
+#endif /* HAVE_UCA_COLLATIONS */

=== modified file 'strings/ctype-ucs2.c'
--- strings/ctype-ucs2.c	2013-08-02 09:36:25 +0000
+++ strings/ctype-ucs2.c	2013-08-29 08:41:37 +0000
@@ -1161,31 +1161,31 @@ my_uni_utf16(CHARSET_INFO *cs __attribut
 
 
 static inline void
-my_tolower_utf16(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc)
+my_tolower_utf16(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
 {
-  uint page= *wc >> 8;
-  if (page < 256 && uni_plane[page])
-    *wc= uni_plane[page][*wc & 0xFF].tolower;
+  MY_UNICASE_CHARACTER *page;
+  if ((*wc <= uni_plane->maxchar) && (page= uni_plane->page[*wc >> 8]))
+    *wc= page[*wc & 0xFF].tolower;
 }
 
 
 static inline void
-my_toupper_utf16(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc)
+my_toupper_utf16(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
 {
-  uint page= *wc >> 8;
-  if (page < 256 && uni_plane[page])
-    *wc= uni_plane[page][*wc & 0xFF].toupper;
+  MY_UNICASE_CHARACTER *page;
+  if ((*wc <= uni_plane->maxchar) && (page= uni_plane->page[*wc >> 8]))
+    *wc= page[*wc & 0xFF].toupper;
 }
 
 
 static inline void
-my_tosort_utf16(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc)
+my_tosort_utf16(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
 {
-  uint page= *wc >> 8;
-  if (page < 256)
+  if (*wc <= uni_plane->maxchar)
   {
-    if (uni_plane[page])
-      *wc= uni_plane[page][*wc & 0xFF].sort;
+    MY_UNICASE_CHARACTER *page;
+    if ((page= uni_plane->page[*wc >> 8]))
+      *wc= page[*wc & 0xFF].sort;
   }
   else
   {
@@ -1194,6 +1194,7 @@ my_tosort_utf16(MY_UNICASE_INFO * const*
 }
 
 
+
 static size_t
 my_caseup_utf16(CHARSET_INFO *cs, char *src, size_t srclen,
                 char *dst __attribute__((unused)),
@@ -1204,7 +1205,7 @@ my_caseup_utf16(CHARSET_INFO *cs, char *
   my_charset_conv_wc_mb wc_mb= cs->cset->wc_mb;
   int res;
   char *srcend= src + srclen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(src == dst && srclen == dstlen);
   
   while ((src < srcend) &&
@@ -1227,7 +1228,7 @@ my_hash_sort_utf16(CHARSET_INFO *cs, con
   my_charset_conv_mb_wc mb_wc= cs->cset->mb_wc;
   int res;
   const uchar *e= s + cs->cset->lengthsp(cs, (const char *) s, slen);
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
   while ((s < e) && (res= mb_wc(cs, &wc, (uchar *) s, (uchar *) e)) > 0)
   {
@@ -1251,7 +1252,7 @@ my_casedn_utf16(CHARSET_INFO *cs, char *
   my_charset_conv_wc_mb wc_mb= cs->cset->wc_mb;
   int res;
   char *srcend= src + srclen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(src == dst && srclen == dstlen);
 
   while ((src < srcend) &&
@@ -1277,7 +1278,7 @@ my_strnncoll_utf16(CHARSET_INFO *cs,
   my_charset_conv_mb_wc mb_wc= cs->cset->mb_wc;
   const uchar *se= s + slen;
   const uchar *te= t + tlen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
   while (s < se && t < te)
   {
@@ -1341,7 +1342,7 @@ my_strnncollsp_utf16(CHARSET_INFO *cs,
   my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
   my_charset_conv_mb_wc mb_wc= cs->cset->mb_wc;
   const uchar *se= s + slen, *te= t + tlen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
   DBUG_ASSERT((slen % 2) == 0);
   DBUG_ASSERT((tlen % 2) == 0);
@@ -1483,7 +1484,7 @@ my_wildcmp_utf16_ci(CHARSET_INFO *cs,
                     const char *wildstr,const char *wildend,
                     int escape, int w_one, int w_many)
 {
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   return my_wildcmp_unicode(cs, str, str_end, wildstr, wildend,
                             escape, w_one, w_many, uni_plane); 
 }
@@ -1695,11 +1696,10 @@ struct charset_info_st my_charset_utf16_
   NULL,                /* to_lower     */
   NULL,                /* to_upper     */
   NULL,                /* sort_order   */
-  NULL,                /* contractions */
-  NULL,                /* sort_order_big*/
+  NULL,                /* uca          */
   NULL,                /* tab_to_uni   */
   NULL,                /* tab_from_uni */
-  my_unicase_default,  /* caseinfo     */
+  &my_unicase_default, /* caseinfo     */
   NULL,                /* state_map    */
   NULL,                /* ident_map    */
   1,                   /* strxfrm_multiply */
@@ -1728,11 +1728,10 @@ struct charset_info_st my_charset_utf16_
   NULL,                /* to_lower     */
   NULL,                /* to_upper     */
   NULL,                /* sort_order   */
-  NULL,                /* contractions */
-  NULL,                /* sort_order_big*/
+  NULL,                /* uca          */
   NULL,                /* tab_to_uni   */
   NULL,                /* tab_from_uni */
-  my_unicase_default,  /* caseinfo     */
+  &my_unicase_default, /* caseinfo     */
   NULL,                /* state_map    */
   NULL,                /* ident_map    */
   1,                   /* strxfrm_multiply */
@@ -1864,11 +1863,10 @@ struct charset_info_st my_charset_utf16l
   NULL,                /* to_lower     */
   NULL,                /* to_upper     */
   NULL,                /* sort_order   */
-  NULL,                /* contractions */
-  NULL,                /* sort_order_big*/
+  NULL,                /* uca          */
   NULL,                /* tab_to_uni   */
   NULL,                /* tab_from_uni */
-  my_unicase_default,  /* caseinfo     */
+  &my_unicase_default, /* caseinfo     */
   NULL,                /* state_map    */
   NULL,                /* ident_map    */
   1,                   /* strxfrm_multiply */
@@ -1897,11 +1895,10 @@ struct charset_info_st my_charset_utf16l
   NULL,                /* to_lower     */
   NULL,                /* to_upper     */
   NULL,                /* sort_order   */
-  NULL,                /* contractions */
-  NULL,                /* sort_order_big*/
+  NULL,                /* uca          */
   NULL,                /* tab_to_uni   */
   NULL,                /* tab_from_uni */
-  my_unicase_default,  /* caseinfo     */
+  &my_unicase_default, /* caseinfo     */
   NULL,                /* state_map    */
   NULL,                /* ident_map    */
   1,                   /* strxfrm_multiply */
@@ -1950,31 +1947,31 @@ my_uni_utf32(CHARSET_INFO *cs __attribut
 
 
 static inline void
-my_tolower_utf32(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc)
+my_tolower_utf32(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
 {
-  uint page= *wc >> 8;
-  if (page < 256 && uni_plane[page])
-    *wc= uni_plane[page][*wc & 0xFF].tolower;
+  MY_UNICASE_CHARACTER *page;
+  if ((*wc <= uni_plane->maxchar) && (page= uni_plane->page[*wc >> 8]))
+    *wc= page[*wc & 0xFF].tolower;
 }
 
 
 static inline void
-my_toupper_utf32(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc)
+my_toupper_utf32(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
 {
-  uint page= *wc >> 8;
-  if (page < 256 && uni_plane[page])
-    *wc= uni_plane[page][*wc & 0xFF].toupper;
+  MY_UNICASE_CHARACTER *page;
+  if ((*wc <= uni_plane->maxchar) && (page= uni_plane->page[*wc >> 8]))
+    *wc= page[*wc & 0xFF].toupper;
 }
 
 
 static inline void
-my_tosort_utf32(MY_UNICASE_INFO *const* uni_plane, my_wc_t *wc)
+my_tosort_utf32(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
 {
-  uint page= *wc >> 8;
-  if (page < 256)
+  if (*wc <= uni_plane->maxchar)
   {
-    if (uni_plane[page])
-      *wc= uni_plane[page][*wc & 0xFF].sort;
+    MY_UNICASE_CHARACTER *page;
+    if ((page= uni_plane->page[*wc >> 8]))
+      *wc= page[*wc & 0xFF].sort;
   }
   else
   {
@@ -1991,7 +1988,7 @@ my_caseup_utf32(CHARSET_INFO *cs, char *
   my_wc_t wc;
   int res;
   char *srcend= src + srclen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(src == dst && srclen == dstlen);
   
   while ((src < srcend) &&
@@ -2021,7 +2018,7 @@ my_hash_sort_utf32(CHARSET_INFO *cs, con
   my_wc_t wc;
   int res;
   const uchar *e= s + slen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
   /* Skip trailing spaces */
   while (e > s + 3 && e[-1] == ' ' && !e[-2] && !e[-3] && !e[-4])
@@ -2047,7 +2044,7 @@ my_casedn_utf32(CHARSET_INFO *cs, char *
   my_wc_t wc;
   int res;
   char *srcend= src + srclen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(src == dst && srclen == dstlen);
 
   while ((res= my_utf32_uni(cs, &wc, (uchar*) src, (uchar*) srcend)) > 0)
@@ -2070,7 +2067,7 @@ my_strnncoll_utf32(CHARSET_INFO *cs,
   my_wc_t UNINIT_VAR(s_wc),UNINIT_VAR(t_wc);
   const uchar *se= s + slen;
   const uchar *te= t + tlen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
   while (s < se && t < te)
   {
@@ -2134,7 +2131,7 @@ my_strnncollsp_utf32(CHARSET_INFO *cs,
   int res;
   my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
   const uchar *se= s + slen, *te= t + tlen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
   DBUG_ASSERT((slen % 4) == 0);
   DBUG_ASSERT((tlen % 4) == 0);
@@ -2582,7 +2579,7 @@ my_wildcmp_utf32_ci(CHARSET_INFO *cs,
                     const char *wildstr, const char *wildend,
                     int escape, int w_one, int w_many)
 {
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   return my_wildcmp_unicode(cs, str, str_end, wildstr, wildend,
                             escape, w_one, w_many, uni_plane); 
 }
@@ -2790,11 +2787,10 @@ struct charset_info_st my_charset_utf32_
   NULL,                /* to_lower     */
   NULL,                /* to_upper     */
   NULL,                /* sort_order   */
-  NULL,                /* contractions */
-  NULL,                /* sort_order_big*/
+  NULL,                /* uca          */
   NULL,                /* tab_to_uni   */
   NULL,                /* tab_from_uni */
-  my_unicase_default,  /* caseinfo     */
+  &my_unicase_default, /* caseinfo     */
   NULL,                /* state_map    */
   NULL,                /* ident_map    */
   1,                   /* strxfrm_multiply */
@@ -2823,11 +2819,10 @@ struct charset_info_st my_charset_utf32_
   NULL,                /* to_lower     */
   NULL,                /* to_upper     */
   NULL,                /* sort_order   */
-  NULL,                /* contractions */
-  NULL,                /* sort_order_big*/
+  NULL,                /* uca          */
   NULL,                /* tab_to_uni   */
   NULL,                /* tab_from_uni */
-  my_unicase_default,  /* caseinfo     */
+  &my_unicase_default, /* caseinfo     */
   NULL,                /* state_map    */
   NULL,                /* ident_map    */
   1,                   /* strxfrm_multiply */
@@ -2934,32 +2929,29 @@ static int my_uni_ucs2(CHARSET_INFO *cs
 
 
 static inline void
-my_tolower_ucs2(MY_UNICASE_INFO *const *uni_plane, my_wc_t *wc)
+my_tolower_ucs2(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
 {
-  uint page= *wc >> 8;
-  DBUG_ASSERT(page < 256);
-  if (uni_plane[page])
-    *wc= uni_plane[page][*wc & 0xFF].tolower;
+  MY_UNICASE_CHARACTER *page;
+  if ((page= uni_plane->page[(*wc >> 8) & 0xFF]))
+    *wc= page[*wc & 0xFF].tolower;
 }
 
 
 static inline void
-my_toupper_ucs2(MY_UNICASE_INFO *const *uni_plane, my_wc_t *wc)
+my_toupper_ucs2(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
 {
-  uint page= *wc >> 8;
-  DBUG_ASSERT(page < 256);
-  if (uni_plane[page])
-    *wc= uni_plane[page][*wc & 0xFF].toupper;
+  MY_UNICASE_CHARACTER *page;
+  if ((page= uni_plane->page[(*wc >> 8) & 0xFF]))
+    *wc= page[*wc & 0xFF].toupper;
 }
 
 
 static inline void
-my_tosort_ucs2(MY_UNICASE_INFO *const *uni_plane, my_wc_t *wc)
+my_tosort_ucs2(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
 {
-  uint page= *wc >> 8;
-  DBUG_ASSERT(page < 256);
-  if (uni_plane[page])
-    *wc= uni_plane[page][*wc & 0xFF].sort;
+  MY_UNICASE_CHARACTER *page;
+  if ((page= uni_plane->page[(*wc >> 8) & 0xFF]))
+    *wc= page[*wc & 0xFF].sort;
 }
 
 static size_t my_caseup_ucs2(CHARSET_INFO *cs, char *src, size_t srclen,
@@ -2969,7 +2961,7 @@ static size_t my_caseup_ucs2(CHARSET_INF
   my_wc_t wc;
   int res;
   char *srcend= src + srclen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(src == dst && srclen == dstlen);
   
   while ((src < srcend) &&
@@ -2990,7 +2982,7 @@ static void my_hash_sort_ucs2(CHARSET_IN
   my_wc_t wc;
   int res;
   const uchar *e=s+slen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
   while (e > s+1 && e[-1] == ' ' && e[-2] == '\0')
     e-= 2;
@@ -3014,7 +3006,7 @@ static size_t my_casedn_ucs2(CHARSET_INF
   my_wc_t wc;
   int res;
   char *srcend= src + srclen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(src == dst && srclen == dstlen);
 
   while ((src < srcend) &&
@@ -3062,7 +3054,7 @@ static int my_strnncoll_ucs2(CHARSET_INF
   my_wc_t UNINIT_VAR(s_wc),UNINIT_VAR(t_wc);
   const uchar *se=s+slen;
   const uchar *te=t+tlen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
   while ( s < se && t < te )
   {
@@ -3124,7 +3116,7 @@ static int my_strnncollsp_ucs2(CHARSET_I
 {
   const uchar *se, *te;
   size_t minlen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
   /* extra safety to make sure the lengths are even numbers */
   slen&= ~1;
@@ -3135,11 +3127,11 @@ static int my_strnncollsp_ucs2(CHARSET_I
 
   for (minlen= MY_MIN(slen, tlen); minlen; minlen-= 2)
   {
-    int s_wc = uni_plane[s[0]] ? (int) uni_plane[s[0]][s[1]].sort :
-                                 (((int) s[0]) << 8) + (int) s[1];
+    int s_wc = uni_plane->page[s[0]] ? (int) uni_plane->page[s[0]][s[1]].sort :
+                                       (((int) s[0]) << 8) + (int) s[1];
 
-    int t_wc = uni_plane[t[0]] ? (int) uni_plane[t[0]][t[1]].sort : 
-                                 (((int) t[0]) << 8) + (int) t[1];
+    int t_wc = uni_plane->page[t[0]] ? (int) uni_plane->page[t[0]][t[1]].sort : 
+                                       (((int) t[0]) << 8) + (int) t[1];
     if ( s_wc != t_wc )
       return  s_wc > t_wc ? 1 : -1;
 
@@ -3220,7 +3212,7 @@ int my_wildcmp_ucs2_ci(CHARSET_INFO *cs,
 		    const char *wildstr,const char *wildend,
 		    int escape, int w_one, int w_many)
 {
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   return my_wildcmp_unicode(cs,str,str_end,wildstr,wildend,
                             escape,w_one,w_many,uni_plane); 
 }
@@ -3412,11 +3404,10 @@ struct charset_info_st my_charset_ucs2_g
     to_lower_ucs2,	/* to_lower     */
     to_upper_ucs2,	/* to_upper     */
     to_upper_ucs2,	/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */
@@ -3445,11 +3436,10 @@ struct charset_info_st my_charset_ucs2_g
   to_lower_ucs2,                                   /* to_lower         */
   to_upper_ucs2,                                   /* to_upper         */
   to_upper_ucs2,                                   /* sort_order       */
-  NULL,                                            /* contractions     */
-  NULL,                                            /* sort_order_big   */
+  NULL,                                            /* uca              */
   NULL,                                            /* tab_to_uni       */
   NULL,                                            /* tab_from_uni     */
-  my_unicase_mysql500,                             /* caseinfo         */
+  &my_unicase_mysql500,                            /* caseinfo         */
   NULL,                                            /* state_map        */
   NULL,                                            /* ident_map        */
   1,                                               /* strxfrm_multiply */
@@ -3478,11 +3468,10 @@ struct charset_info_st my_charset_ucs2_b
     to_lower_ucs2,	/* to_lower     */
     to_upper_ucs2,	/* to_upper     */
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */

=== modified file 'strings/ctype-ujis.c'
--- strings/ctype-ujis.c	2013-07-16 17:09:54 +0000
+++ strings/ctype-ujis.c	2013-08-29 09:07:23 +0000
@@ -65988,7 +65988,7 @@ my_wc_mb_euc_jp(CHARSET_INFO *cs __attri
 
 
 /* Case info pages for JIS-X-0208 range */
-static MY_UNICASE_INFO cA2[256]=
+static MY_UNICASE_CHARACTER cA2[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -66109,7 +66109,7 @@ static MY_UNICASE_INFO cA2[256]=
 };
 
 
-static MY_UNICASE_INFO cA3[256]=
+static MY_UNICASE_CHARACTER cA3[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -66230,7 +66230,7 @@ static MY_UNICASE_INFO cA3[256]=
 };
 
 
-static MY_UNICASE_INFO cA6[256]=
+static MY_UNICASE_CHARACTER cA6[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -66351,7 +66351,7 @@ static MY_UNICASE_INFO cA6[256]=
 };
 
 
-static MY_UNICASE_INFO cA7[256]=
+static MY_UNICASE_CHARACTER cA7[256]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -66473,7 +66473,7 @@ static MY_UNICASE_INFO cA7[256]=
 
 
 /* Case info pages for JIS-X-0212 range */
-static MY_UNICASE_INFO c8FA6[]=
+static MY_UNICASE_CHARACTER c8FA6[]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -66594,7 +66594,7 @@ static MY_UNICASE_INFO c8FA6[]=
 };
 
 
-static MY_UNICASE_INFO c8FA7[]=
+static MY_UNICASE_CHARACTER c8FA7[]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -66715,7 +66715,7 @@ static MY_UNICASE_INFO c8FA7[]=
 };
 
 
-static MY_UNICASE_INFO c8FA9[]=
+static MY_UNICASE_CHARACTER c8FA9[]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -66836,7 +66836,7 @@ static MY_UNICASE_INFO c8FA9[]=
 };
 
 
-static MY_UNICASE_INFO c8FAA[]=
+static MY_UNICASE_CHARACTER c8FAA[]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -66957,7 +66957,7 @@ static MY_UNICASE_INFO c8FAA[]=
 };
 
 
-static MY_UNICASE_INFO c8FAB[]=
+static MY_UNICASE_CHARACTER c8FAB[]=
 {
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}, /* xx00 */
   {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
@@ -67078,7 +67078,7 @@ static MY_UNICASE_INFO c8FAB[]=
 };
 
 
-static MY_UNICASE_INFO *my_caseinfo_ujis[512]=
+static MY_UNICASE_CHARACTER *my_caseinfo_pages_ujis[512]=
 {
   /* JIS-X-0208 */
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0 */
@@ -67148,6 +67148,15 @@ static MY_UNICASE_INFO *my_caseinfo_ujis
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* F */
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
+
+static MY_UNICASE_INFO my_caseinfo_ujis=
+{
+  0x0FFFF,
+  my_caseinfo_pages_ujis
+};
+
+
+
 #endif /* HAVE_CHARSET_ujis */
 
 
@@ -67158,11 +67167,11 @@ static MY_UNICASE_INFO *my_caseinfo_ujis
   UJIS and EUCJPMS share the same UPPER/LOWER functions.
 */
 
-static MY_UNICASE_INFO*
+static MY_UNICASE_CHARACTER*
 get_case_info_for_ch(CHARSET_INFO *cs, uint plane, uint page, uint offs)
 {
-  MY_UNICASE_INFO *p;
-  return (p= cs->caseinfo[page + plane * 256]) ? &p[offs & 0xFF] : NULL;
+  MY_UNICASE_CHARACTER *p;
+  return (p= cs->caseinfo->page[page + plane * 256]) ? &p[offs & 0xFF] : NULL;
 }
 
 
@@ -67183,7 +67192,7 @@ my_casefold_ujis(CHARSET_INFO *cs,
     size_t mblen= my_ismbchar(cs, src, srcend);
     if (mblen)
     {
-      MY_UNICASE_INFO *ch;
+      MY_UNICASE_CHARACTER *ch;
       ch= (mblen == 2) ?
         get_case_info_for_ch(cs, 0, (uchar) src[0], (uchar) src[1]) :
         get_case_info_for_ch(cs, 1, (uchar) src[1], (uchar) src[2]);
@@ -67304,11 +67313,10 @@ struct charset_info_st my_charset_ujis_j
     to_lower_ujis,
     to_upper_ujis,
     sort_order_ujis,
-    NULL,		/* sort_order_big*/
-    NULL,		/* contractions */
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_ujis,   /* caseinfo     */
+    &my_caseinfo_ujis,  /* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */
@@ -67337,11 +67345,10 @@ struct charset_info_st my_charset_ujis_b
     to_lower_ujis,
     to_upper_ujis,
     NULL,		/* sort_order   */
-    NULL,		/* contractions */
-    NULL,		/* sort_order_big*/
+    NULL,		/* uca          */
     NULL,		/* tab_to_uni   */
     NULL,		/* tab_from_uni */
-    my_caseinfo_ujis,   /* caseinfo     */
+    &my_caseinfo_ujis,  /* caseinfo     */
     NULL,		/* state_map    */
     NULL,		/* ident_map    */
     1,			/* strxfrm_multiply */

=== modified file 'strings/ctype-utf8.c'
--- strings/ctype-utf8.c	2013-07-21 14:39:19 +0000
+++ strings/ctype-utf8.c	2013-09-12 08:45:23 +0000
@@ -60,7 +60,7 @@
 
 #include "my_uctype.h"
 
-static MY_UNICASE_INFO plane00[]={
+static MY_UNICASE_CHARACTER plane00[]={
   {0x0000,0x0000,0x0000},  {0x0001,0x0001,0x0001},
   {0x0002,0x0002,0x0002},  {0x0003,0x0003,0x0003},
   {0x0004,0x0004,0x0004},  {0x0005,0x0005,0x0005},
@@ -196,7 +196,7 @@ static MY_UNICASE_INFO plane00[]={
   Almost similar to plane00, but maps sorting order
   for U+00DF to 0x00DF instead of 0x0053.
 */
-static MY_UNICASE_INFO plane00_mysql500[]={
+static MY_UNICASE_CHARACTER plane00_mysql500[]={
   {0x0000,0x0000,0x0000},  {0x0001,0x0001,0x0001},
   {0x0002,0x0002,0x0002},  {0x0003,0x0003,0x0003},
   {0x0004,0x0004,0x0004},  {0x0005,0x0005,0x0005},
@@ -328,7 +328,7 @@ static MY_UNICASE_INFO plane00_mysql500[
 };
 
 
-static MY_UNICASE_INFO plane01[]={
+static MY_UNICASE_CHARACTER plane01[]={
   {0x0100,0x0101,0x0041},  {0x0100,0x0101,0x0041},
   {0x0102,0x0103,0x0041},  {0x0102,0x0103,0x0041},
   {0x0104,0x0105,0x0041},  {0x0104,0x0105,0x0041},
@@ -459,7 +459,7 @@ static MY_UNICASE_INFO plane01[]={
   {0x01FE,0x01FF,0x00D8},  {0x01FE,0x01FF,0x00D8}
 };
 
-static MY_UNICASE_INFO plane02[]={
+static MY_UNICASE_CHARACTER plane02[]={
   {0x0200,0x0201,0x0041},  {0x0200,0x0201,0x0041},
   {0x0202,0x0203,0x0041},  {0x0202,0x0203,0x0041},
   {0x0204,0x0205,0x0045},  {0x0204,0x0205,0x0045},
@@ -590,7 +590,7 @@ static MY_UNICASE_INFO plane02[]={
   {0x02FE,0x02FE,0x02FE},  {0x02FF,0x02FF,0x02FF}
 };
 
-static MY_UNICASE_INFO plane03[]={
+static MY_UNICASE_CHARACTER plane03[]={
   {0x0300,0x0300,0x0300},  {0x0301,0x0301,0x0301},
   {0x0302,0x0302,0x0302},  {0x0303,0x0303,0x0303},
   {0x0304,0x0304,0x0304},  {0x0305,0x0305,0x0305},
@@ -721,7 +721,7 @@ static MY_UNICASE_INFO plane03[]={
   {0x03FE,0x03FE,0x03FE},  {0x03FF,0x03FF,0x03FF}
 };
 
-static MY_UNICASE_INFO plane04[]={
+static MY_UNICASE_CHARACTER plane04[]={
   {0x0400,0x0450,0x0415},  {0x0401,0x0451,0x0415},
   {0x0402,0x0452,0x0402},  {0x0403,0x0453,0x0413},
   {0x0404,0x0454,0x0404},  {0x0405,0x0455,0x0405},
@@ -852,7 +852,7 @@ static MY_UNICASE_INFO plane04[]={
   {0x04FE,0x04FE,0x04FE},  {0x04FF,0x04FF,0x04FF}
 };
 
-static MY_UNICASE_INFO plane05[]={
+static MY_UNICASE_CHARACTER plane05[]={
   {0x0500,0x0500,0x0500},  {0x0501,0x0501,0x0501},
   {0x0502,0x0502,0x0502},  {0x0503,0x0503,0x0503},
   {0x0504,0x0504,0x0504},  {0x0505,0x0505,0x0505},
@@ -983,7 +983,7 @@ static MY_UNICASE_INFO plane05[]={
   {0x05FE,0x05FE,0x05FE},  {0x05FF,0x05FF,0x05FF}
 };
 
-static MY_UNICASE_INFO plane1E[]={
+static MY_UNICASE_CHARACTER plane1E[]={
   {0x1E00,0x1E01,0x0041},  {0x1E00,0x1E01,0x0041},
   {0x1E02,0x1E03,0x0042},  {0x1E02,0x1E03,0x0042},
   {0x1E04,0x1E05,0x0042},  {0x1E04,0x1E05,0x0042},
@@ -1114,7 +1114,7 @@ static MY_UNICASE_INFO plane1E[]={
   {0x1EFE,0x1EFE,0x1EFE},  {0x1EFF,0x1EFF,0x1EFF}
 };
 
-static MY_UNICASE_INFO plane1F[]={
+static MY_UNICASE_CHARACTER plane1F[]={
   {0x1F08,0x1F00,0x0391},  {0x1F09,0x1F01,0x0391},
   {0x1F0A,0x1F02,0x0391},  {0x1F0B,0x1F03,0x0391},
   {0x1F0C,0x1F04,0x0391},  {0x1F0D,0x1F05,0x0391},
@@ -1245,7 +1245,7 @@ static MY_UNICASE_INFO plane1F[]={
   {0x1FFE,0x1FFE,0x1FFE},  {0x1FFF,0x1FFF,0x1FFF}
 };
 
-static MY_UNICASE_INFO plane21[]={
+static MY_UNICASE_CHARACTER plane21[]={
   {0x2100,0x2100,0x2100},  {0x2101,0x2101,0x2101},
   {0x2102,0x2102,0x2102},  {0x2103,0x2103,0x2103},
   {0x2104,0x2104,0x2104},  {0x2105,0x2105,0x2105},
@@ -1376,7 +1376,7 @@ static MY_UNICASE_INFO plane21[]={
   {0x21FE,0x21FE,0x21FE},  {0x21FF,0x21FF,0x21FF}
 };
 
-static MY_UNICASE_INFO plane24[]={
+static MY_UNICASE_CHARACTER plane24[]={
   {0x2400,0x2400,0x2400},  {0x2401,0x2401,0x2401},
   {0x2402,0x2402,0x2402},  {0x2403,0x2403,0x2403},
   {0x2404,0x2404,0x2404},  {0x2405,0x2405,0x2405},
@@ -1507,7 +1507,7 @@ static MY_UNICASE_INFO plane24[]={
   {0x24FE,0x24FE,0x24FE},  {0x24FF,0x24FF,0x24FF}
 };
 
-static MY_UNICASE_INFO planeFF[]={
+static MY_UNICASE_CHARACTER planeFF[]={
   {0xFF00,0xFF00,0xFF00},  {0xFF01,0xFF01,0xFF01},
   {0xFF02,0xFF02,0xFF02},  {0xFF03,0xFF03,0xFF03},
   {0xFF04,0xFF04,0xFF04},  {0xFF05,0xFF05,0xFF05},
@@ -1638,7 +1638,9 @@ static MY_UNICASE_INFO planeFF[]={
   {0xFFFE,0xFFFE,0xFFFE},  {0xFFFF,0xFFFF,0xFFFF}
 };
 
-MY_UNICASE_INFO *const my_unicase_default[256]={
+
+static MY_UNICASE_CHARACTER *my_unicase_pages_default[256]=
+{
  plane00, plane01, plane02, plane03, plane04, plane05,    NULL,    NULL,
     NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
     NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
@@ -1671,14 +1673,20 @@ MY_UNICASE_INFO *const my_unicase_defaul
     NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
     NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
     NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL, planeFF
+};
 
+
+MY_UNICASE_INFO my_unicase_default=
+{
+  0xFFFF,
+  my_unicase_pages_default
 };
 
 
 /*
   Reproduce old utf8_general_ci behaviour before we fixed Bug#27877.
 */
-MY_UNICASE_INFO *const my_unicase_mysql500[256]={
+MY_UNICASE_CHARACTER *my_unicase_pages_mysql500[256]={
  plane00_mysql500,
           plane01, plane02, plane03, plane04, plane05,    NULL,    NULL,
     NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
@@ -1716,6 +1724,13 @@ MY_UNICASE_INFO *const my_unicase_mysql5
 };
 
 
+MY_UNICASE_INFO my_unicase_mysql500=
+{
+  0xFFFF,
+  my_unicase_pages_mysql500
+};
+
+
 /*
   Turkish lower/upper mapping:
   1. LOWER(0x0049 LATIN CAPITAL LETTER I) -> 
@@ -1724,7 +1739,7 @@ MY_UNICASE_INFO *const my_unicase_mysql5
            0x0130 LATIN CAPITAL LETTER I WITH DOT ABOVE
 */
 
-static MY_UNICASE_INFO turk00[]=
+static MY_UNICASE_CHARACTER turk00[]=
 {
   {0x0000,0x0000,0x0000},  {0x0001,0x0001,0x0001},
   {0x0002,0x0002,0x0002},  {0x0003,0x0003,0x0003},
@@ -1858,7 +1873,7 @@ static MY_UNICASE_INFO turk00[]=
 
 
 
-MY_UNICASE_INFO *const my_unicase_turkish[256]=
+static MY_UNICASE_CHARACTER *my_unicase_pages_turkish[256]=
 {
   turk00, plane01, plane02, plane03, plane04, plane05,    NULL,    NULL,
     NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,
@@ -1895,14 +1910,23 @@ MY_UNICASE_INFO *const my_unicase_turkis
 };
 
 
+MY_UNICASE_INFO my_unicase_turkish=
+{
+  0xFFFF,
+  my_unicase_pages_turkish
+};
+
+
 static inline void
-my_tosort_unicode(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc)
+my_tosort_unicode(MY_UNICASE_INFO *uni_plane, my_wc_t *wc, uint flags)
 {
-  int page= *wc >> 8;
-  if (page < 256)
+  if (*wc <= uni_plane->maxchar)
   {
-    if (uni_plane[page])
-      *wc= uni_plane[page][*wc & 0xFF].sort;
+    MY_UNICASE_CHARACTER *page;
+    if ((page= uni_plane->page[*wc >> 8]))
+      *wc= (flags & MY_CS_LOWER_SORT) ?
+           page[*wc & 0xFF].tolower :
+           page[*wc & 0xFF].sort;
   }
   else
   {
@@ -1925,7 +1949,7 @@ int my_wildcmp_unicode_impl(CHARSET_INFO
                             const char *str,const char *str_end,
                             const char *wildstr,const char *wildend,
                             int escape, int w_one, int w_many,
-                            MY_UNICASE_INFO *const *weights, int recurse_level)
+                            MY_UNICASE_INFO *weights, int recurse_level)
 {
   int result= -1;                             /* Not found, using wildcards */
   my_wc_t s_wc, w_wc;
@@ -1974,8 +1998,8 @@ int my_wildcmp_unicode_impl(CHARSET_INFO
       {
         if (weights)
         {
-          my_tosort_unicode(weights, &s_wc);
-          my_tosort_unicode(weights, &w_wc);
+          my_tosort_unicode(weights, &s_wc, cs->state);
+          my_tosort_unicode(weights, &w_wc, cs->state);
         }
         if (s_wc != w_wc)
           return 1;                               /* No match */
@@ -2045,8 +2069,8 @@ int my_wildcmp_unicode_impl(CHARSET_INFO
             return 1;
           if (weights)
           {
-            my_tosort_unicode(weights, &s_wc);
-            my_tosort_unicode(weights, &w_wc);
+            my_tosort_unicode(weights, &s_wc, cs->state);
+            my_tosort_unicode(weights, &w_wc, cs->state);
           }
           
           if (s_wc == w_wc)
@@ -2074,7 +2098,7 @@ my_wildcmp_unicode(CHARSET_INFO *cs,
                    const char *str,const char *str_end,
                    const char *wildstr,const char *wildend,
                    int escape, int w_one, int w_many,
-                   MY_UNICASE_INFO *const *weights)
+                   MY_UNICASE_INFO *weights)
 {
   return my_wildcmp_unicode_impl(cs, str, str_end,
                                  wildstr, wildend,
@@ -2099,7 +2123,7 @@ my_strnxfrm_unicode(CHARSET_INFO *cs,
   uchar *de= dst + dstlen;
   uchar *de_beg= de - 1;
   const uchar *se = src + srclen;
-  MY_UNICASE_INFO * const*uni_plane= (cs->state & MY_CS_BINSORT) ?
+  MY_UNICASE_INFO *uni_plane= (cs->state & MY_CS_BINSORT) ?
                                       NULL : cs->caseinfo;
   DBUG_ASSERT(src);
   
@@ -2110,7 +2134,7 @@ my_strnxfrm_unicode(CHARSET_INFO *cs,
     src+=res;
 
     if (uni_plane)
-      my_tosort_unicode(uni_plane, &wc);
+      my_tosort_unicode(uni_plane, &wc, cs->state);
 
     *dst++= (uchar) (wc >> 8);
     if (dst < de)
@@ -2476,20 +2500,45 @@ static int my_uni_utf8_no_range(CHARSET_
 }
 
 
+static inline void
+my_tolower_utf8mb3(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
+{
+  MY_UNICASE_CHARACTER *page;
+  if ((page= uni_plane->page[(*wc >> 8) & 0xFF]))
+    *wc= page[*wc & 0xFF].tolower;
+}
+
+
+static inline void
+my_toupper_utf8mb3(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
+{
+  MY_UNICASE_CHARACTER *page;
+  if ((page= uni_plane->page[(*wc >> 8) & 0xFF]))
+    *wc= page[*wc & 0xFF].toupper;
+}
+
+
+static inline void
+my_tosort_utf8mb3(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
+{
+  MY_UNICASE_CHARACTER *page;
+  if ((page= uni_plane->page[(*wc >> 8) & 0xFF]))
+    *wc= page[*wc & 0xFF].sort;
+}
+
 static size_t my_caseup_utf8(CHARSET_INFO *cs, char *src, size_t srclen,
                              char *dst, size_t dstlen)
 {
   my_wc_t wc;
   int srcres, dstres;
   char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(src != dst || cs->caseup_multiply == 1);
 
   while ((src < srcend) &&
          (srcres= my_utf8_uni(cs, &wc, (uchar *) src, (uchar*) srcend)) > 0)
   {
-    int plane= (wc>>8) & 0xFF;
-    wc= uni_plane[plane] ? uni_plane[plane][wc & 0xFF].toupper : wc;
+    my_toupper_utf8mb3(uni_plane, &wc);
     if ((dstres= my_uni_utf8(cs, wc, (uchar*) dst, (uchar*) dstend)) <= 0)
       break;
     src+= srcres;
@@ -2505,7 +2554,7 @@ static void my_hash_sort_utf8(CHARSET_IN
   my_wc_t wc;
   int res;
   const uchar *e=s+slen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
   /*
     Remove end space. We have to do this to be able to compare
@@ -2516,8 +2565,7 @@ static void my_hash_sort_utf8(CHARSET_IN
 
   while ((s < e) && (res=my_utf8_uni(cs,&wc, (uchar *)s, (uchar*)e))>0 )
   {
-    int plane = (wc>>8) & 0xFF;
-    wc = uni_plane[plane] ? uni_plane[plane][wc & 0xFF].sort : wc;
+    my_tosort_unicode(uni_plane, &wc, cs->state);
     n1[0]^= (((n1[0] & 63)+n2[0])*(wc & 0xFF))+ (n1[0] << 8);
     n2[0]+=3;
     n1[0]^= (((n1[0] & 63)+n2[0])*(wc >> 8))+ (n1[0] << 8);
@@ -2532,14 +2580,13 @@ static size_t my_caseup_str_utf8(CHARSET
   my_wc_t wc;
   int srcres, dstres;
   char *dst= src, *dst0= src;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(cs->caseup_multiply == 1);
 
   while (*src &&
          (srcres= my_utf8_uni_no_range(cs, &wc, (uchar *) src)) > 0)
   {
-    int plane= (wc>>8) & 0xFF;
-    wc= uni_plane[plane] ? uni_plane[plane][wc & 0xFF].toupper : wc;
+    my_toupper_utf8mb3(uni_plane, &wc);
     if ((dstres= my_uni_utf8_no_range(cs, wc, (uchar*) dst)) <= 0)
       break;
     src+= srcres;
@@ -2556,14 +2603,13 @@ static size_t my_casedn_utf8(CHARSET_INF
   my_wc_t wc;
   int srcres, dstres;
   char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(src != dst || cs->casedn_multiply == 1);
 
   while ((src < srcend) &&
          (srcres= my_utf8_uni(cs, &wc, (uchar*) src, (uchar*)srcend)) > 0)
   {
-    int plane= (wc>>8) & 0xFF;
-    wc= uni_plane[plane] ? uni_plane[plane][wc & 0xFF].tolower : wc;
+    my_tolower_utf8mb3(uni_plane, &wc);
     if ((dstres= my_uni_utf8(cs, wc, (uchar*) dst, (uchar*) dstend)) <= 0)
       break;
     src+= srcres;
@@ -2578,14 +2624,13 @@ static size_t my_casedn_str_utf8(CHARSET
   my_wc_t wc;
   int srcres, dstres;
   char *dst= src, *dst0= src;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(cs->casedn_multiply == 1);
 
   while (*src &&
          (srcres= my_utf8_uni_no_range(cs, &wc, (uchar *) src)) > 0)
   {
-    int plane= (wc>>8) & 0xFF;
-    wc= uni_plane[plane] ? uni_plane[plane][wc & 0xFF].tolower : wc;
+    my_tolower_utf8mb3(uni_plane, &wc);
     if ((dstres= my_uni_utf8_no_range(cs, wc, (uchar*) dst)) <= 0)
       break;
     src+= srcres;
@@ -2621,11 +2666,10 @@ static int my_strnncoll_utf8(CHARSET_INF
   my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
   const uchar *se=s+slen;
   const uchar *te=t+tlen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
   while ( s < se && t < te )
   {
-    int plane;
     s_res=my_utf8_uni(cs,&s_wc, s, se);
     t_res=my_utf8_uni(cs,&t_wc, t, te);
 
@@ -2635,10 +2679,9 @@ static int my_strnncoll_utf8(CHARSET_INF
       return bincmp(s, se, t, te);
     }
 
-    plane=(s_wc>>8) & 0xFF;
-    s_wc = uni_plane[plane] ? uni_plane[plane][s_wc & 0xFF].sort : s_wc;
-    plane=(t_wc>>8) & 0xFF;
-    t_wc = uni_plane[plane] ? uni_plane[plane][t_wc & 0xFF].sort : t_wc;
+    my_tosort_unicode(uni_plane, &s_wc, cs->state);
+    my_tosort_unicode(uni_plane, &t_wc, cs->state);
+
     if ( s_wc != t_wc )
     {
       return  s_wc > t_wc ? 1 : -1;
@@ -2690,7 +2733,7 @@ static int my_strnncollsp_utf8(CHARSET_I
   int s_res, t_res, res;
   my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc);
   const uchar *se= s+slen, *te= t+tlen;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
 #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
   diff_if_only_endspace_difference= 0;
@@ -2698,7 +2741,6 @@ static int my_strnncollsp_utf8(CHARSET_I
 
   while ( s < se && t < te )
   {
-    int plane;
     s_res=my_utf8_uni(cs,&s_wc, s, se);
     t_res=my_utf8_uni(cs,&t_wc, t, te);
 
@@ -2708,10 +2750,9 @@ static int my_strnncollsp_utf8(CHARSET_I
       return bincmp(s, se, t, te);
     }
 
-    plane=(s_wc>>8) & 0xFF;
-    s_wc = uni_plane[plane] ? uni_plane[plane][s_wc & 0xFF].sort : s_wc;
-    plane=(t_wc>>8) & 0xFF;
-    t_wc = uni_plane[plane] ? uni_plane[plane][t_wc & 0xFF].sort : t_wc;
+    my_tosort_unicode(uni_plane, &s_wc, cs->state);
+    my_tosort_unicode(uni_plane, &t_wc, cs->state);
+    
     if ( s_wc != t_wc )
     {
       return  s_wc > t_wc ? 1 : -1;
@@ -2778,7 +2819,7 @@ static int my_strnncollsp_utf8(CHARSET_I
 static
 int my_strcasecmp_utf8(CHARSET_INFO *cs, const char *s, const char *t)
 {
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   while (s[0] && t[0])
   {
     my_wc_t s_wc,t_wc;
@@ -2795,7 +2836,7 @@ int my_strcasecmp_utf8(CHARSET_INFO *cs,
     }
     else
     {
-      int plane, res;
+      int res;
       
       /*
         Scan a multibyte character.
@@ -2823,8 +2864,7 @@ int my_strcasecmp_utf8(CHARSET_INFO *cs,
       s+= res;
       
       /* Convert Unicode code into weight according to collation */
-      plane=(s_wc>>8) & 0xFF;
-      s_wc = uni_plane[plane] ? uni_plane[plane][s_wc & 0xFF].tolower : s_wc;
+      my_tolower_utf8mb3(uni_plane, &s_wc);
     }
     
     
@@ -2838,15 +2878,13 @@ int my_strcasecmp_utf8(CHARSET_INFO *cs,
     }
     else
     {
-      int plane;
       int res=my_utf8_uni(cs,&t_wc, (const uchar*)t, (const uchar*) t + 3);
       if (res <= 0)
         return strcmp(s, t);
       t+= res;
       
       /* Convert code into weight */
-      plane=(t_wc>>8) & 0xFF;
-      t_wc = uni_plane[plane] ? uni_plane[plane][t_wc & 0xFF].tolower : t_wc;
+      my_tolower_utf8mb3(uni_plane, &t_wc);
     }
     
     /* Now we have two weights, let's compare them */
@@ -2863,7 +2901,7 @@ int my_wildcmp_utf8(CHARSET_INFO *cs,
 		    const char *wildstr,const char *wildend,
 		    int escape, int w_one, int w_many)
 {
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   return my_wildcmp_unicode(cs,str,str_end,wildstr,wildend,
                             escape,w_one,w_many,uni_plane); 
 }
@@ -2966,11 +3004,10 @@ struct charset_info_st my_charset_utf8_g
     to_lower_utf8,      /* to_lower     */
     to_upper_utf8,      /* to_upper     */
     to_upper_utf8,      /* sort_order   */
-    NULL,               /* contractions */
-    NULL,               /* sort_order_big*/
+    NULL,               /* uca          */
     NULL,               /* tab_to_uni   */
     NULL,               /* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,               /* state_map    */
     NULL,               /* ident_map    */
     1,                  /* strxfrm_multiply */
@@ -2999,11 +3036,10 @@ struct charset_info_st my_charset_utf8_g
   to_lower_utf8,                                /* to_lower         */
   to_upper_utf8,                                /* to_upper         */
   to_upper_utf8,                                /* sort_order       */
-  NULL,                                         /* contractions     */
-  NULL,                                         /* sort_order_big   */
+  NULL,                                         /* uca              */
   NULL,                                         /* tab_to_uni       */
   NULL,                                         /* tab_from_uni     */
-  my_unicase_mysql500,                          /* caseinfo         */
+  &my_unicase_mysql500,                         /* caseinfo         */
   NULL,                                         /* state_map        */
   NULL,                                         /* ident_map        */
   1,                                            /* strxfrm_multiply */
@@ -3032,11 +3068,10 @@ struct charset_info_st my_charset_utf8_b
     to_lower_utf8,      /* to_lower     */
     to_upper_utf8,      /* to_upper     */
     NULL,               /* sort_order   */
-    NULL,               /* contractions */
-    NULL,               /* sort_order_big*/
+    NULL,               /* uca          */
     NULL,               /* tab_to_uni   */
     NULL,               /* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,               /* state_map    */
     NULL,               /* ident_map    */
     1,                  /* strxfrm_multiply */
@@ -3117,7 +3152,7 @@ static int my_strnncollsp_utf8_cs(CHARSE
   const uchar *se= s + slen;
   const uchar *te= t + tlen;
   int save_diff= 0;
-  MY_UNICASE_INFO *const *uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
 #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
   diff_if_only_endspace_difference= 0;
@@ -3125,7 +3160,6 @@ static int my_strnncollsp_utf8_cs(CHARSE
     
   while ( s < se && t < te )
   {
-    int plane;
     s_res=my_utf8_uni(cs,&s_wc, s, se);
     t_res=my_utf8_uni(cs,&t_wc, t, te);
     
@@ -3139,10 +3173,10 @@ static int my_strnncollsp_utf8_cs(CHARSE
     {
       save_diff = ((int)s_wc) - ((int)t_wc);
     }
-    plane=(s_wc>>8) & 0xFF;
-    s_wc = uni_plane[plane] ? uni_plane[plane][s_wc & 0xFF].sort : s_wc;
-    plane=(t_wc>>8) & 0xFF;
-    t_wc = uni_plane[plane] ? uni_plane[plane][t_wc & 0xFF].sort : t_wc;
+
+    my_tosort_unicode(uni_plane, &s_wc, cs->state);
+    my_tosort_unicode(uni_plane, &t_wc, cs->state);
+
     if ( s_wc != t_wc )
     {
       return  ((int) s_wc) - ((int) t_wc);
@@ -4519,11 +4553,10 @@ struct charset_info_st my_charset_filena
     to_lower_utf8,      /* to_lower     */
     to_upper_utf8,      /* to_upper     */
     to_upper_utf8,      /* sort_order   */
-    NULL,               /* contractions */
-    NULL,               /* sort_order_big*/
+    NULL,               /* uca          */
     NULL,               /* tab_to_uni   */
     NULL,               /* tab_from_uni */
-    my_unicase_default, /* caseinfo     */
+    &my_unicase_default,/* caseinfo     */
     NULL,               /* state_map    */
     NULL,               /* ident_map    */
     1,                  /* strxfrm_multiply */
@@ -4885,20 +4918,26 @@ my_wc_mb_utf8mb4_no_range(CHARSET_INFO *
 
 
 static inline void
-my_tolower_utf8mb4(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc)
+my_tolower_utf8mb4(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
 {
-  int page= *wc >> 8;
-  if (page < 256 && uni_plane[page])
-    *wc= uni_plane[page][*wc & 0xFF].tolower;
+  if (*wc <= uni_plane->maxchar)
+  {
+    MY_UNICASE_CHARACTER *page;
+    if ((page= uni_plane->page[(*wc >> 8)]))
+      *wc= page[*wc & 0xFF].tolower;
+  }
 }
 
 
 static inline void
-my_toupper_utf8mb4(MY_UNICASE_INFO * const* uni_plane, my_wc_t *wc)
+my_toupper_utf8mb4(MY_UNICASE_INFO *uni_plane, my_wc_t *wc)
 {
-  int page= *wc >> 8;
-  if (page < 256 && uni_plane[page])
-    *wc= uni_plane[page][*wc & 0xFF].toupper;
+  if (*wc <= uni_plane->maxchar)
+  {
+    MY_UNICASE_CHARACTER *page;
+    if ((page= uni_plane->page[(*wc >> 8)]))
+      *wc= page[*wc & 0xFF].toupper;
+  }
 }
 
 
@@ -4909,7 +4948,7 @@ my_caseup_utf8mb4(CHARSET_INFO *cs, char
   my_wc_t wc;
   int srcres, dstres;
   char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst;
-  MY_UNICASE_INFO * const* uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(src != dst || cs->caseup_multiply == 1);
 
   while ((src < srcend) &&
@@ -4941,7 +4980,7 @@ my_hash_sort_utf8mb4(CHARSET_INFO *cs, c
   my_wc_t wc;
   int res;
   const uchar *e= s + slen;
-  MY_UNICASE_INFO * const* uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
 
   /*
     Remove end space. We do this to be able to compare
@@ -4952,7 +4991,7 @@ my_hash_sort_utf8mb4(CHARSET_INFO *cs, c
 
   while ((res= my_mb_wc_utf8mb4(cs, &wc, (uchar*) s, (uchar*) e)) > 0)
   {
-    my_tosort_unicode(uni_plane, &wc);
+    my_tosort_unicode(uni_plane, &wc, cs->state);
     my_hash_add(n1, n2, (uint) (wc & 0xFF));
     my_hash_add(n1, n2, (uint) (wc >> 8)  & 0xFF);
     if (wc > 0xFFFF)
@@ -4977,7 +5016,7 @@ my_caseup_str_utf8mb4(CHARSET_INFO *cs,
   my_wc_t wc;
   int srcres, dstres;
   char *dst= src, *dst0= src;
-  MY_UNICASE_INFO * const* uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(cs->caseup_multiply == 1);
 
   while (*src &&
@@ -5002,7 +5041,7 @@ my_casedn_utf8mb4(CHARSET_INFO *cs,
   my_wc_t wc;
   int srcres, dstres;
   char *srcend= src + srclen, *dstend= dst + dstlen, *dst0= dst;
-  MY_UNICASE_INFO * const* uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(src != dst || cs->casedn_multiply == 1);
 
   while ((src < srcend) &&
@@ -5025,7 +5064,7 @@ my_casedn_str_utf8mb4(CHARSET_INFO *cs,
   my_wc_t wc;
   int srcres, dstres;
   char *dst= src, *dst0= src;
-  MY_UNICASE_INFO * const* uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   DBUG_ASSERT(cs->casedn_multiply == 1);
 
   while (*src &&
@@ -5067,7 +5106,7 @@ my_strnncoll_utf8mb4(CHARSET_INFO *cs,
   my_wc_t s_wc,t_wc;
   const uchar *se= s + slen;
   const uchar *te= t + tlen;
-  MY_UNICASE_INFO * const* uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   LINT_INIT(s_wc);
   LINT_INIT(t_wc);
 
@@ -5082,9 +5121,9 @@ my_strnncoll_utf8mb4(CHARSET_INFO *cs,
       return bincmp_utf8mb4(s, se, t, te);
     }
 
-    my_tosort_unicode(uni_plane, &s_wc);
-    my_tosort_unicode(uni_plane, &t_wc);
-    
+    my_tosort_unicode(uni_plane, &s_wc, cs->state);
+    my_tosort_unicode(uni_plane, &t_wc, cs->state);
+
     if ( s_wc != t_wc )
     {
       return s_wc > t_wc ? 1 : -1;
@@ -5134,7 +5173,7 @@ my_strnncollsp_utf8mb4(CHARSET_INFO *cs,
   int res;
   my_wc_t s_wc, t_wc;
   const uchar *se= s + slen, *te= t + tlen;
-  MY_UNICASE_INFO * const* uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   LINT_INIT(s_wc);
   LINT_INIT(t_wc);
 
@@ -5153,8 +5192,8 @@ my_strnncollsp_utf8mb4(CHARSET_INFO *cs,
       return bincmp_utf8mb4(s, se, t, te);
     }
 
-    my_tosort_unicode(uni_plane, &s_wc);
-    my_tosort_unicode(uni_plane, &t_wc);
+    my_tosort_unicode(uni_plane, &s_wc, cs->state);
+    my_tosort_unicode(uni_plane, &t_wc, cs->state);
 
     if ( s_wc != t_wc )
     {
@@ -5218,7 +5257,7 @@ my_strnncollsp_utf8mb4(CHARSET_INFO *cs,
 static int
 my_strcasecmp_utf8mb4(CHARSET_INFO *cs, const char *s, const char *t)
 {
-  MY_UNICASE_INFO * const* uni_plane= cs->caseinfo;
+  MY_UNICASE_INFO *uni_plane= cs->caseinfo;
   while (s[0] && t[0])
   {
     my_wc_t s_wc,t_wc;
@@ -5397,11 +5436,10 @@ struct charset_info_st my_charset_utf8mb
   to_lower_utf8mb4,   /* to_lower     */
   to_upper_utf8mb4,   /* to_upper     */
   to_upper_utf8mb4,   /* sort_order   */
-  NULL,               /* contractions */
-  NULL,               /* sort_order_big*/
+  NULL,               /* uca          */
   NULL,               /* tab_to_uni   */
   NULL,               /* tab_from_uni */
-  my_unicase_default, /* caseinfo     */
+  &my_unicase_default,/* caseinfo     */
   NULL,               /* state_map    */
   NULL,               /* ident_map    */
   1,                  /* strxfrm_multiply */
@@ -5430,11 +5468,10 @@ struct charset_info_st my_charset_utf8mb
   to_lower_utf8mb4,   /* to_lower     */
   to_upper_utf8mb4,   /* to_upper     */
   NULL,               /* sort_order   */
-  NULL,               /* contractions */
-  NULL,               /* sort_order_big*/
+  NULL,               /* uca          */
   NULL,               /* tab_to_uni   */
   NULL,               /* tab_from_uni */
-  my_unicase_default, /* caseinfo     */
+  &my_unicase_default,/* caseinfo     */
   NULL,               /* state_map    */
   NULL,               /* ident_map    */
   1,                  /* strxfrm_multiply */

=== modified file 'strings/ctype-win1250ch.c'
--- strings/ctype-win1250ch.c	2012-01-13 14:50:02 +0000
+++ strings/ctype-win1250ch.c	2013-08-29 09:42:41 +0000
@@ -690,11 +690,10 @@ struct charset_info_st my_charset_cp1250
   to_lower_win1250ch,
   to_upper_win1250ch,
   sort_order_win1250ch,
-  NULL,				/* contractions */
-  NULL,				/* sort_order_big*/
+  NULL,				/* uca          */
   tab_cp1250_uni,		/* tab_to_uni   */
   idx_uni_cp1250,		/* tab_from_uni */
-  my_unicase_default,           /* caseinfo     */
+  &my_unicase_default,          /* caseinfo     */
   NULL,				/* state_map    */
   NULL,				/* ident_map    */
   2,				/* strxfrm_multiply */

=== modified file 'strings/ctype.c'
--- strings/ctype.c	2013-08-07 15:40:25 +0000
+++ strings/ctype.c	2013-08-29 09:52:49 +0000
@@ -38,6 +38,18 @@
   
 */
 
+
+/*
+  Avoid using my_snprintf
+  We cannot use my_snprintf() here, because ctype.o is
+  used to build conf_to_src, which must require minimun
+  dependency.
+*/
+
+#undef my_snprinf
+#define my_snprintf "We cannot use my_snprintf in this file"
+
+
 int (*my_string_stack_guard)(int)= NULL;
 
 static char *mstr(char *str,const char *src,size_t l1,size_t l2)
@@ -71,11 +83,75 @@ struct my_cs_file_section_st
 #define _CS_PRIMARY_ID	15
 #define _CS_BINARY_ID	16
 #define _CS_CSDESCRIPT	17
-#define _CS_RESET	18
-#define	_CS_DIFF1	19
-#define	_CS_DIFF2	20
-#define	_CS_DIFF3	21
-#define	_CS_IDENTICAL	22
+
+
+/* Special purpose commands */
+#define _CS_UCA_VERSION                 100
+#define _CS_CL_SUPPRESS_CONTRACTIONS    101
+#define _CS_CL_OPTIMIZE                 102
+#define _CS_CL_SHIFT_AFTER_METHOD       103
+
+
+/* Collation Settings */
+#define _CS_ST_SETTINGS                 200
+#define _CS_ST_STRENGTH                 201
+#define _CS_ST_ALTERNATE                202
+#define _CS_ST_BACKWARDS                203
+#define _CS_ST_NORMALIZATION            204
+#define _CS_ST_CASE_LEVEL               205
+#define _CS_ST_CASE_FIRST               206
+#define _CS_ST_HIRAGANA_QUATERNARY      207
+#define _CS_ST_NUMERIC                  208
+#define _CS_ST_VARIABLE_TOP             209
+#define _CS_ST_MATCH_BOUNDARIES         210
+#define _CS_ST_MATCH_STYLE              211
+
+
+/* Rules */
+#define _CS_RULES                       300
+#define _CS_RESET                       301
+#define _CS_DIFF1                       302
+#define _CS_DIFF2                       303
+#define _CS_DIFF3                       304
+#define _CS_DIFF4                       305
+#define _CS_IDENTICAL                   306
+
+/* Rules: Expansions */
+#define _CS_EXP_X                       320
+#define _CS_EXP_EXTEND                  321
+#define _CS_EXP_DIFF1                   322
+#define _CS_EXP_DIFF2                   323
+#define _CS_EXP_DIFF3                   324
+#define _CS_EXP_DIFF4                   325
+#define _CS_EXP_IDENTICAL               326
+
+/* Rules: Abbreviating Ordering Specifications */
+#define _CS_A_DIFF1                     351
+#define _CS_A_DIFF2                     352
+#define _CS_A_DIFF3                     353
+#define _CS_A_DIFF4                     354
+#define _CS_A_IDENTICAL                 355
+
+/* Rules: previous context */
+#define _CS_CONTEXT                     370
+
+/* Rules: Placing Characters Before Others*/
+#define _CS_RESET_BEFORE 380
+
+/* Rules: Logical Reset Positions */
+#define _CS_RESET_FIRST_PRIMARY_IGNORABLE     401
+#define _CS_RESET_LAST_PRIMARY_IGNORABLE      402
+#define _CS_RESET_FIRST_SECONDARY_IGNORABLE   403
+#define _CS_RESET_LAST_SECONDARY_IGNORABLE    404
+#define _CS_RESET_FIRST_TERTIARY_IGNORABLE    405
+#define _CS_RESET_LAST_TERTIARY_IGNORABLE     406
+#define _CS_RESET_FIRST_TRAILING              407
+#define _CS_RESET_LAST_TRAILING               408
+#define _CS_RESET_FIRST_VARIABLE              409
+#define _CS_RESET_LAST_VARIABLE               410
+#define _CS_RESET_FIRST_NON_IGNORABLE         411
+#define _CS_RESET_LAST_NON_IGNORABLE          412
+
 
 
 static const struct my_cs_file_section_st sec[] =
@@ -85,6 +161,8 @@ static const struct my_cs_file_section_s
   {_CS_MISC,		"xml/encoding"},
   {_CS_MISC,		"charsets"},
   {_CS_MISC,		"charsets/max-id"},
+  {_CS_MISC,		"charsets/copyright"},
+  {_CS_MISC,		"charsets/description"},
   {_CS_CHARSET,		"charsets/charset"},
   {_CS_PRIMARY_ID,	"charsets/charset/primary-id"},
   {_CS_BINARY_ID,	"charsets/charset/binary-id"},
@@ -106,11 +184,72 @@ static const struct my_cs_file_section_s
   {_CS_ORDER,		"charsets/charset/collation/order"},
   {_CS_FLAG,		"charsets/charset/collation/flag"},
   {_CS_COLLMAP,		"charsets/charset/collation/map"},
-  {_CS_RESET,		"charsets/charset/collation/rules/reset"},
-  {_CS_DIFF1,		"charsets/charset/collation/rules/p"},
-  {_CS_DIFF2,		"charsets/charset/collation/rules/s"},
-  {_CS_DIFF3,		"charsets/charset/collation/rules/t"},
-  {_CS_IDENTICAL,	"charsets/charset/collation/rules/i"},
+
+  /* Special purpose commands */
+  {_CS_UCA_VERSION,              "charsets/charset/collation/version"},
+  {_CS_CL_SUPPRESS_CONTRACTIONS, "charsets/charset/collation/suppress_contractions"},
+  {_CS_CL_OPTIMIZE,              "charsets/charset/collation/optimize"},
+  {_CS_CL_SHIFT_AFTER_METHOD,    "charsets/charset/collation/shift-after-method"},
+
+  /* Collation Settings */
+  {_CS_ST_SETTINGS,              "charsets/charset/collation/settings"},
+  {_CS_ST_STRENGTH,              "charsets/charset/collation/settings/strength"},
+  {_CS_ST_ALTERNATE,             "charsets/charset/collation/settings/alternate"},
+  {_CS_ST_BACKWARDS,             "charsets/charset/collation/settings/backwards"},
+  {_CS_ST_NORMALIZATION,         "charsets/charset/collation/settings/normalization"},
+  {_CS_ST_CASE_LEVEL,            "charsets/charset/collation/settings/caseLevel"},
+  {_CS_ST_CASE_FIRST,            "charsets/charset/collation/settings/caseFirst"},
+  {_CS_ST_HIRAGANA_QUATERNARY,   "charsets/charset/collation/settings/hiraganaQuaternary"},
+  {_CS_ST_NUMERIC,               "charsets/charset/collation/settings/numeric"},
+  {_CS_ST_VARIABLE_TOP,          "charsets/charset/collation/settings/variableTop"},
+  {_CS_ST_MATCH_BOUNDARIES,      "charsets/charset/collation/settings/match-boundaries"},
+  {_CS_ST_MATCH_STYLE,           "charsets/charset/collation/settings/match-style"},
+
+  /* Rules */
+  {_CS_RULES,           "charsets/charset/collation/rules"},
+  {_CS_RESET,           "charsets/charset/collation/rules/reset"},
+  {_CS_DIFF1,           "charsets/charset/collation/rules/p"},
+  {_CS_DIFF2,           "charsets/charset/collation/rules/s"},
+  {_CS_DIFF3,           "charsets/charset/collation/rules/t"},
+  {_CS_DIFF4,           "charsets/charset/collation/rules/q"},
+  {_CS_IDENTICAL,       "charsets/charset/collation/rules/i"},
+
+  /* Rules: expansions */
+  {_CS_EXP_X,           "charsets/charset/collation/rules/x"},
+  {_CS_EXP_EXTEND,      "charsets/charset/collation/rules/x/extend"},
+  {_CS_EXP_DIFF1,       "charsets/charset/collation/rules/x/p"},
+  {_CS_EXP_DIFF2,       "charsets/charset/collation/rules/x/s"},
+  {_CS_EXP_DIFF3,       "charsets/charset/collation/rules/x/t"},
+  {_CS_EXP_DIFF4,       "charsets/charset/collation/rules/x/q"},
+  {_CS_EXP_IDENTICAL,   "charsets/charset/collation/rules/x/i"},
+  
+  /* Rules: previous context */
+  {_CS_CONTEXT,         "charsets/charset/collation/rules/x/context"},
+
+  /* Rules: Abbreviating Ordering Specifications */
+  {_CS_A_DIFF1,         "charsets/charset/collation/rules/pc"},
+  {_CS_A_DIFF2,         "charsets/charset/collation/rules/sc"},
+  {_CS_A_DIFF3,         "charsets/charset/collation/rules/tc"},
+  {_CS_A_DIFF4,         "charsets/charset/collation/rules/qc"},
+  {_CS_A_IDENTICAL,     "charsets/charset/collation/rules/ic"},
+
+  /* Rules: Placing Characters Before Others*/
+  {_CS_RESET_BEFORE,    "charsets/charset/collation/rules/reset/before"},
+
+  /* Rules: Logical Reset Positions */
+  {_CS_RESET_FIRST_NON_IGNORABLE,       "charsets/charset/collation/rules/reset/first_non_ignorable"},
+  {_CS_RESET_LAST_NON_IGNORABLE,        "charsets/charset/collation/rules/reset/last_non_ignorable"},
+  {_CS_RESET_FIRST_PRIMARY_IGNORABLE,   "charsets/charset/collation/rules/reset/first_primary_ignorable"},
+  {_CS_RESET_LAST_PRIMARY_IGNORABLE,    "charsets/charset/collation/rules/reset/last_primary_ignorable"},
+  {_CS_RESET_FIRST_SECONDARY_IGNORABLE, "charsets/charset/collation/rules/reset/first_secondary_ignorable"},
+  {_CS_RESET_LAST_SECONDARY_IGNORABLE,  "charsets/charset/collation/rules/reset/last_secondary_ignorable"},
+  {_CS_RESET_FIRST_TERTIARY_IGNORABLE,  "charsets/charset/collation/rules/reset/first_tertiary_ignorable"},
+  {_CS_RESET_LAST_TERTIARY_IGNORABLE,   "charsets/charset/collation/rules/reset/last_tertiary_ignorable"},
+  {_CS_RESET_FIRST_TRAILING,            "charsets/charset/collation/rules/reset/first_trailing"},
+  {_CS_RESET_LAST_TRAILING,             "charsets/charset/collation/rules/reset/last_trailing"},
+  {_CS_RESET_FIRST_VARIABLE,            "charsets/charset/collation/rules/reset/first_variable"},
+  {_CS_RESET_LAST_VARIABLE,             "charsets/charset/collation/rules/reset/last_variable"},
+
   {0,	NULL}
 };
 
@@ -120,14 +259,16 @@ static const struct my_cs_file_section_s
   const struct my_cs_file_section_st *s;
   for (s=sec; s->str; s++)
   {
-    if (!strncmp(attr,s->str,len))
+    if (!strncmp(attr, s->str, len) && s->str[len] == 0)
       return s;
   }
   return NULL;
 }
 
 #define MY_CS_CSDESCR_SIZE	64
-#define MY_CS_TAILORING_SIZE	1024
+#define MY_CS_TAILORING_SIZE	32*1024
+#define MY_CS_UCA_VERSION_SIZE  64
+#define MY_CS_CONTEXT_SIZE      64
 
 typedef struct my_cs_file_info
 {
@@ -139,13 +280,60 @@ typedef struct my_cs_file_info
   uchar  sort_order[MY_CS_SORT_ORDER_TABLE_SIZE];
   uint16 tab_to_uni[MY_CS_TO_UNI_TABLE_SIZE];
   char   comment[MY_CS_CSDESCR_SIZE];
-  char   tailoring[MY_CS_TAILORING_SIZE];
+  char  *tailoring;
   size_t tailoring_length;
+  size_t tailoring_alloced_length;
+  char   context[MY_CS_CONTEXT_SIZE];
   struct charset_info_st cs;
-  int (*add_collation)(struct charset_info_st *cs);
-} MY_CHARSET_LOADER;
+  MY_CHARSET_LOADER *loader;
+} MY_CHARSET_FILE;
+
+
+static void
+my_charset_file_reset_charset(MY_CHARSET_FILE *i)
+{
+  memset(&i->cs, 0, sizeof(i->cs));
+}
+
+
+static void
+my_charset_file_reset_collation(MY_CHARSET_FILE *i)
+{
+  i->tailoring_length= 0;
+  i->context[0]= '\0';
+}
+
+
+static void
+my_charset_file_init(MY_CHARSET_FILE *i)
+{
+  my_charset_file_reset_charset(i);
+  my_charset_file_reset_collation(i);
+  i->tailoring= NULL;
+  i->tailoring_alloced_length= 0;
+}
+
+
+static void
+my_charset_file_free(MY_CHARSET_FILE *i)
+{
+  i->loader->free(i->tailoring);
+}
 
 
+static int
+my_charset_file_tailoring_realloc(MY_CHARSET_FILE *i, size_t newlen)
+{
+  if (i->tailoring_alloced_length > newlen ||
+     (i->tailoring= i->loader->realloc(i->tailoring,
+                                       (i->tailoring_alloced_length=
+                                        (newlen + 32*1024)))))
+  {
+    return MY_XML_OK;
+  }
+  return MY_XML_ERROR;
+}
+
 
 static int fill_uchar(uchar *a,uint size,const char *str, size_t len)
 {
@@ -182,17 +370,119 @@ static int fill_uint16(uint16 *a,uint si
 }
 
 
+
+
+static int
+tailoring_append(MY_XML_PARSER *st,
+                 const char *fmt, size_t len, const char *attr)
+{
+  struct my_cs_file_info *i= (struct my_cs_file_info *) st->user_data;
+  size_t newlen= i->tailoring_length + len + 64; /* 64 for format */ 
+  if (MY_XML_OK == my_charset_file_tailoring_realloc(i, newlen))
+  {
+    char *dst= i->tailoring + i->tailoring_length;
+    sprintf(dst, fmt, (int) len, attr);
+    i->tailoring_length+= strlen(dst);
+    return MY_XML_OK;
+  }
+  return MY_XML_ERROR;
+}
+
+
+static int
+tailoring_append2(MY_XML_PARSER *st,
+                  const char *fmt,
+                  size_t len1, const char *attr1,
+                  size_t len2, const char *attr2)
+{
+  struct my_cs_file_info *i= (struct my_cs_file_info *) st->user_data;
+  size_t newlen= i->tailoring_length + len1 + len2 + 64; /* 64 for format */
+  if (MY_XML_OK == my_charset_file_tailoring_realloc(i, newlen))
+  {
+    char *dst= i->tailoring + i->tailoring_length;
+    sprintf(dst, fmt, (int) len1, attr1, (int) len2, attr2);
+    i->tailoring_length+= strlen(dst);
+    return MY_XML_OK;
+  }
+  return MY_XML_ERROR;
+}
+
+
+static size_t
+scan_one_character(const char *s, const char *e, my_wc_t *wc)
+{
+  CHARSET_INFO *cs= &my_charset_utf8_general_ci;
+  if (s >= e)
+    return 0;
+
+  /* Escape sequence: \uXXXX */
+  if (s[0] == '\\' && s + 2 < e && s[1] == 'u' && my_isxdigit(cs, s[2]))
+  {
+    size_t len= 3; /* We have at least one digit */
+    for (s+= 3; s < e && my_isxdigit(cs, s[0]); s++, len++)
+    {
+    }
+    wc[0]= 0;
+    return len;
+  }
+  else if (s[0] > 0) /* 7-bit character */
+  {
+    wc[0]= 0;
+    return 1;
+  }
+  else /* Non-escaped character */
+  {
+    int rc= cs->cset->mb_wc(cs, wc, (uchar *) s, (uchar *) e);
+    if (rc > 0)
+      return (size_t) rc;
+  }
+  return 0;
+}
+
+
+static int
+tailoring_append_abbreviation(MY_XML_PARSER *st,
+                              const char *fmt, size_t len, const char *attr)
+{
+  size_t clen;
+  const char *attrend= attr + len;
+  my_wc_t wc;
+
+  for ( ; (clen= scan_one_character(attr, attrend, &wc)) > 0; attr+= clen)
+  {
+    DBUG_ASSERT(attr < attrend);
+    if (tailoring_append(st, fmt, clen, attr) != MY_XML_OK)
+      return MY_XML_ERROR;
+  }
+  return MY_XML_OK;
+}
+
+
 static int cs_enter(MY_XML_PARSER *st,const char *attr, size_t len)
 {
   struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
   const struct my_cs_file_section_st *s= cs_file_sec(attr,len);
+  int state= s ? s->state : 0;
   
-  if ( s && (s->state == _CS_CHARSET))
-    bzero(&i->cs,sizeof(i->cs));
-  
-  if (s && (s->state == _CS_COLLATION))
-    i->tailoring_length= 0;
+  switch (state) {
+  case 0:
+    i->loader->reporter(WARNING_LEVEL, "Unknown LDML tag: '%.*s'", len, attr);
+    break;
 
+  case _CS_CHARSET:
+    my_charset_file_reset_charset(i);
+    break;
+
+  case _CS_COLLATION:
+    my_charset_file_reset_collation(i);
+    break;
+
+  case _CS_RESET:
+    return tailoring_append(st, " &", 0, NULL);
+
+  default:
+    break;
+  }
   return MY_XML_OK;
 }
 
@@ -206,8 +496,60 @@ static int cs_leave(MY_XML_PARSER *st,co
   
   switch(state){
   case _CS_COLLATION:
-    rc= i->add_collation ? i->add_collation(&i->cs) : MY_XML_OK;
+    if (i->tailoring_length)
+      i->cs.tailoring= i->tailoring;
+    rc= i->loader->add_collation ? i->loader->add_collation(&i->cs) : MY_XML_OK;
+    break;
+
+  /* Rules: Logical Reset Positions */
+  case _CS_RESET_FIRST_NON_IGNORABLE:
+    rc= tailoring_append(st, "[first non-ignorable]", 0, NULL);
+    break;
+
+  case _CS_RESET_LAST_NON_IGNORABLE:
+    rc= tailoring_append(st, "[last non-ignorable]", 0, NULL);
+    break;
+
+  case _CS_RESET_FIRST_PRIMARY_IGNORABLE:
+    rc= tailoring_append(st, "[first primary ignorable]", 0, NULL);
+    break;
+
+  case _CS_RESET_LAST_PRIMARY_IGNORABLE:
+    rc= tailoring_append(st, "[last primary ignorable]", 0, NULL);
+    break;
+
+  case _CS_RESET_FIRST_SECONDARY_IGNORABLE:
+    rc= tailoring_append(st, "[first secondary ignorable]", 0, NULL);
+    break;
+
+  case _CS_RESET_LAST_SECONDARY_IGNORABLE:
+    rc= tailoring_append(st, "[last secondary ignorable]", 0, NULL);
+    break;
+
+  case _CS_RESET_FIRST_TERTIARY_IGNORABLE:
+    rc= tailoring_append(st, "[first tertiary ignorable]", 0, NULL);
+    break;
+
+  case _CS_RESET_LAST_TERTIARY_IGNORABLE:
+    rc= tailoring_append(st, "[last tertiary ignorable]", 0, NULL);
+    break;
+
+  case _CS_RESET_FIRST_TRAILING:
+    rc= tailoring_append(st, "[first trailing]", 0, NULL);
     break;
+
+  case _CS_RESET_LAST_TRAILING:
+    rc= tailoring_append(st, "[last trailing]", 0, NULL);
+    break;
+
+  case _CS_RESET_FIRST_VARIABLE:
+    rc= tailoring_append(st, "[first variable]", 0, NULL);
+    break;
+
+  case _CS_RESET_LAST_VARIABLE:
+    rc= tailoring_append(st, "[last variable]", 0, NULL);
+    break;
+
   default:
     rc=MY_XML_OK;
   }
@@ -215,14 +557,40 @@ static int cs_leave(MY_XML_PARSER *st,co
 }
 
 
+static const char *diff_fmt[5]=
+{
+  "<%.*s",
+  "<<%.*s",
+  "<<<%.*s",
+  "<<<<%.*s",
+  "=%.*s"
+};
+
+
+static const char *context_diff_fmt[5]=
+{
+  "<%.*s|%.*s",
+  "<<%.*s|%.*s",
+  "<<<%.*s|%.*s",
+  "<<<<%.*s|%.*s",
+  "=%.*s|%.*s"
+};
+
+
 static int cs_value(MY_XML_PARSER *st,const char *attr, size_t len)
 {
   struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
   const struct my_cs_file_section_st *s;
-  int  state= (int)((s= cs_file_sec(st->attr, strlen(st->attr))) ? s->state :
-                    0);
-  
+  int    state= (int)((s= cs_file_sec(st->attr.start,
+                                      st->attr.end - st->attr.start)) ?
+                      s->state : 0);
+  int rc= MY_XML_OK;
+
   switch (state) {
+  case _CS_MISC:
+  case _CS_FAMILY:
+  case _CS_ORDER:
+    break;
   case _CS_ID:
     i->cs.number= strtol(attr,(char**)NULL,10);
     break;
@@ -269,47 +637,185 @@ static int cs_value(MY_XML_PARSER *st,co
     fill_uchar(i->ctype,MY_CS_CTYPE_TABLE_SIZE,attr,len);
     i->cs.ctype=i->ctype;
     break;
+
+  /* Special purpose commands */
+  case _CS_UCA_VERSION:
+    rc= tailoring_append(st, "[version %.*s]", len, attr);
+    break;
+
+  case _CS_CL_SUPPRESS_CONTRACTIONS:
+    rc= tailoring_append(st, "[suppress contractions %.*s]", len, attr);
+    break;
+
+  case _CS_CL_OPTIMIZE:
+    rc= tailoring_append(st, "[optimize %.*s]", len, attr);
+    break;
+
+  case _CS_CL_SHIFT_AFTER_METHOD:
+    rc= tailoring_append(st, "[shift-after-method %.*s]", len, attr);
+    break;
+
+  /* Collation Settings */
+  case _CS_ST_STRENGTH:
+    /* 1, 2, 3, 4, 5, or primary, secondary, tertiary, quaternary, identical */
+    rc= tailoring_append(st, "[strength %.*s]", len, attr);
+    break;
+
+  case _CS_ST_ALTERNATE:
+    /* non-ignorable, shifted */
+    rc= tailoring_append(st, "[alternate %.*s]", len, attr);
+    break;
+
+  case _CS_ST_BACKWARDS:
+    /* on, off, 2 */
+    rc= tailoring_append(st, "[backwards %.*s]", len, attr);
+    break;
+
+  case _CS_ST_NORMALIZATION:
+    /*
+      TODO for WL#896: check collations for normalization: vi.xml
+      We want precomposed characters work well at this point.
+    */
+    /* on, off */
+    rc= tailoring_append(st, "[normalization %.*s]", len, attr);
+    break;
+
+  case _CS_ST_CASE_LEVEL:
+    /* on, off */
+    rc= tailoring_append(st, "[caseLevel %.*s]", len, attr);
+    break;
+
+  case _CS_ST_CASE_FIRST:
+    /* upper, lower, off */
+    rc= tailoring_append(st, "[caseFirst %.*s]", len, attr);
+    break;
+
+  case _CS_ST_HIRAGANA_QUATERNARY:
+    /* on, off */
+    rc= tailoring_append(st, "[hiraganaQ %.*s]", len, attr);
+    break;
+
+  case _CS_ST_NUMERIC:
+    /* on, off */
+    rc= tailoring_append(st, "[numeric %.*s]", len, attr);
+    break;
+
+  case _CS_ST_VARIABLE_TOP:
+    /* TODO for WL#896: check value format */
+    rc= tailoring_append(st, "[variableTop %.*s]", len, attr);
+    break;
+
+  case _CS_ST_MATCH_BOUNDARIES:
+    /* none, whole-character, whole-word */
+    rc= tailoring_append(st, "[match-boundaries %.*s]", len, attr);
+    break;
+
+  case _CS_ST_MATCH_STYLE:
+    /* minimal, medial, maximal */
+    rc= tailoring_append(st, "[match-style %.*s]", len, attr);
+    break;
+
+
+  /* Rules */
   case _CS_RESET:
+    rc= tailoring_append(st, "%.*s", len, attr);
+    break;
+
   case _CS_DIFF1:
   case _CS_DIFF2:
   case _CS_DIFF3:
+  case _CS_DIFF4:
   case _CS_IDENTICAL:
+    rc= tailoring_append(st, diff_fmt[state - _CS_DIFF1], len, attr);
+    break;
+
+
+  /* Rules: Expansion */
+  case _CS_EXP_EXTEND:
+    rc= tailoring_append(st, " / %.*s", len, attr);
+    break;
+
+  case _CS_EXP_DIFF1:
+  case _CS_EXP_DIFF2:
+  case _CS_EXP_DIFF3:
+  case _CS_EXP_DIFF4:
+  case _CS_EXP_IDENTICAL:
+    if (i->context[0])
     {
-      /*
-        Convert collation description from
-        Locale Data Markup Language (LDML)
-        into ICU Collation Customization expression.
-      */
-      char arg[16];
-      const char *cmd[]= {"&","<","<<","<<<","="};
-      i->cs.tailoring= i->tailoring;
-      mstr(arg,attr,len,sizeof(arg)-1);
-      if (i->tailoring_length + 20 < sizeof(i->tailoring))
-      {
-        char *dst= i->tailoring_length + i->tailoring;
-        i->tailoring_length+= sprintf(dst," %s %s",cmd[state-_CS_RESET],arg);
-      }
+      rc= tailoring_append2(st, context_diff_fmt[state - _CS_EXP_DIFF1],
+                            strlen(i->context), i->context, len, attr);
+      i->context[0]= 0;
     }
+    else
+      rc= tailoring_append(st, diff_fmt[state  - _CS_EXP_DIFF1], len, attr);
+    break;
+
+  /* Rules: Context */
+  case _CS_CONTEXT:
+    if (len < sizeof(i->context) + 1)
+    {
+      memcpy(i->context, attr, len);
+      i->context[len]= '\0';
+    }
+    break;
+
+  /* Rules: Abbreviating Ordering Specifications */
+  case _CS_A_DIFF1:
+  case _CS_A_DIFF2:
+  case _CS_A_DIFF3:
+  case _CS_A_DIFF4:
+  case _CS_A_IDENTICAL:
+    rc= tailoring_append_abbreviation(st, diff_fmt[state - _CS_A_DIFF1], len, attr);
+    break;
+
+  /* Rules: Placing Characters Before Others */
+  case _CS_RESET_BEFORE:
+    /*
+      TODO for WL#896: Add this check into text customization parser:
+      It is an error if the strength of the before relation is not identical
+      to the relation after the reset. We'll need this for WL#896.
+    */
+    rc= tailoring_append(st, "[before %.*s]", len, attr);
+    break;
+
+
+  default:
+    break;
   }
-  return MY_XML_OK;
+
+  return rc;
 }
 
 
-my_bool my_parse_charset_xml(const char *buf, size_t len,
-                             int (*add_collation)(struct charset_info_st *cs))
+my_bool
+my_parse_charset_xml(MY_CHARSET_LOADER *loader, const char *buf, size_t len)
 {
   MY_XML_PARSER p;
-  struct my_cs_file_info i;
+  struct my_cs_file_info info;
   my_bool rc;
   
+  my_charset_file_init(&info);
   my_xml_parser_create(&p);
   my_xml_set_enter_handler(&p,cs_enter);
   my_xml_set_value_handler(&p,cs_value);
   my_xml_set_leave_handler(&p,cs_leave);
-  i.add_collation= add_collation;
-  my_xml_set_user_data(&p,(void*)&i);
+  info.loader= loader;
+  my_xml_set_user_data(&p, (void *) &info);
   rc= (my_xml_parse(&p,buf,len) == MY_XML_OK) ? FALSE : TRUE;
   my_xml_parser_free(&p);
+  my_charset_file_free(&info);
+  if (rc != MY_XML_OK)
+  {
+    const char *errstr= my_xml_error_string(&p);
+    if (sizeof(loader->error) > 32 + strlen(errstr))
+    {
+      /* We cannot use my_snprintf() here. See previous comment. */
+      sprintf(loader->error, "at line %d pos %d: %s",
+                my_xml_error_lineno(&p)+1,
+                (int) my_xml_error_pos(&p),
+                my_xml_error_string(&p));
+    }
+  }
   return rc;
 }
 

=== modified file 'strings/str_alloc.c'
--- strings/str_alloc.c	2013-05-07 11:05:09 +0000
+++ strings/str_alloc.c	2013-08-29 10:02:49 +0000
@@ -31,5 +31,11 @@ static void my_str_free_default(void *pt
   free(ptr);
 }
 
+void *my_str_realloc_default(void *ptr, size_t size)
+{
+  return realloc(ptr, size);
+}
+
 void *(*my_str_malloc)(size_t)= &my_str_malloc_default;
 void (*my_str_free)(void *)= &my_str_free_default;
+void *(*my_str_realloc)(void *, size_t)= &my_str_realloc_default;

=== modified file 'strings/xml.c'
--- strings/xml.c	2013-07-16 17:09:54 +0000
+++ strings/xml.c	2013-08-29 10:00:34 +0000
@@ -15,6 +15,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */
 
 #include "strings_def.h"
+#include "m_string.h"
 #include "my_xml.h"
 
 
@@ -207,25 +208,71 @@ static int my_xml_value(MY_XML_PARSER *s
 }
 
 
-static int my_xml_enter(MY_XML_PARSER *st, const char *str, size_t len)
+/**
+  Ensure the attr buffer is wide enough to hold the new value
+
+  Expand and/or allocate dynamic buffer as needed to hold the concatenated
+  path and the terminating zero.
+
+  @attr st   the parser instance
+  @attr len  the length of the attribute to be added
+  @return state
+  @retval 1  failed
+  @retval 0  success
+*/
+static int my_xml_attr_ensure_space(MY_XML_PARSER *st, size_t len)
 {
-  if ((size_t) (st->attrend-st->attr+len+1) > sizeof(st->attr))
+  size_t ofs= st->attr.end - st->attr.start;
+  len++; // Add terminating zero.
+  if (ofs + len > st->attr.buffer_size)
   {
-    sprintf(st->errstr,"To deep XML");
-    return MY_XML_ERROR;
+    st->attr.buffer_size= (SIZE_T_MAX - len) / 2 > st->attr.buffer_size ?
+                            st->attr.buffer_size * 2 + len : SIZE_T_MAX;
+
+    if (!st->attr.buffer)
+    {
+      st->attr.buffer= (char *) my_str_malloc(st->attr.buffer_size);
+      if (st->attr.buffer)
+        memcpy(st->attr.buffer, st->attr.static_buffer, ofs + 1 /*term. zero */);
+    }
+    else
+      st->attr.buffer= (char *) my_str_realloc(st->attr.buffer,
+                                               st->attr.buffer_size);
+    st->attr.start= st->attr.buffer;
+    st->attr.end= st->attr.start + ofs;
+    
+    return st->attr.buffer ? MY_XML_OK : MY_XML_ERROR;
   }
-  if (st->attrend > st->attr)
+  return MY_XML_OK;
+}
+
+
+/** rewind the attr buffer to initial state */
+static void my_xml_attr_rewind(MY_XML_PARSER *p)
+{
+  /* keep the buffer already allocated */
+  p->attr.end= p->attr.start;
+}
+
+
+static int my_xml_enter(MY_XML_PARSER *st, const char *str, size_t len)
+{
+  if (my_xml_attr_ensure_space(st, len + 1 /* the separator char */))
+    return MY_XML_ERROR;
+
+  if (st->attr.end > st->attr.start)
   {
-    st->attrend[0]= '/';
-    st->attrend++;
+    st->attr.end[0]= '/';
+    st->attr.end++;
   }
-  memcpy(st->attrend,str,len);
-  st->attrend+=len;
-  st->attrend[0]='\0';
+  memcpy(st->attr.end, str, len);
+  st->attr.end+= len;
+  st->attr.end[0]= '\0';
   if (st->flags & MY_XML_FLAG_RELATIVE_NAMES)
     return st->enter ? st->enter(st, str, len) : MY_XML_OK;
   else
-    return st->enter ?  st->enter(st,st->attr,st->attrend-st->attr) : MY_XML_OK;
+    return st->enter ?
+      st->enter(st, st->attr.start, st->attr.end - st->attr.start) : MY_XML_OK;
 }
 
 
@@ -246,8 +293,8 @@ static int my_xml_leave(MY_XML_PARSER *p
   int  rc;
 
   /* Find previous '/' or beginning */
-  for (e=p->attrend; (e>p->attr) && (e[0] != '/') ; e--);
-  glen = (size_t) ((e[0] == '/') ? (p->attrend-e-1) : p->attrend-e);
+  for (e= p->attr.end; (e > p->attr.start) && (e[0] != '/') ; e--);
+  glen= (size_t) ((e[0] == '/') ? (p->attr.end - e - 1) : p->attr.end - e);
   
   if (str && (slen != glen))
   {
@@ -265,11 +312,12 @@ static int my_xml_leave(MY_XML_PARSER *p
   if (p->flags & MY_XML_FLAG_RELATIVE_NAMES)
     rc= p->leave_xml ? p->leave_xml(p, str, slen) : MY_XML_OK;
   else
-    rc= (p->leave_xml ?  p->leave_xml(p,p->attr,p->attrend-p->attr) :
+    rc= (p->leave_xml ? 
+         p->leave_xml(p, p->attr.start, p->attr.end - p->attr.start) :
          MY_XML_OK);
   
   *e='\0';
-  p->attrend=e;
+  p->attr.end= e;
   
   return rc;
 }
@@ -277,7 +325,9 @@ static int my_xml_leave(MY_XML_PARSER *p
 
 int my_xml_parse(MY_XML_PARSER *p,const char *str, size_t len)
 {
-  p->attrend=p->attr;
+
+  my_xml_attr_rewind(p);
+
   p->beg=str;
   p->cur=str;
   p->end=str+len;
@@ -432,7 +482,7 @@ int my_xml_parse(MY_XML_PARSER *p,const
     }
   }
 
-  if (p->attr[0])
+  if (p->attr.start[0])
   {
     sprintf(p->errstr,"unexpected END-OF-INPUT");
     return MY_XML_ERROR;
@@ -443,12 +493,22 @@ int my_xml_parse(MY_XML_PARSER *p,const
 
 void my_xml_parser_create(MY_XML_PARSER *p)
 {
-  bzero((void*)p,sizeof(p[0]));
+  memset(p, 0, sizeof(p[0]));
+  /*
+    Use static buffer while it's sufficient.
+  */
+  p->attr.start= p->attr.end= p->attr.static_buffer;
+  p->attr.buffer_size= sizeof(p->attr.static_buffer);
 }
 
 
-void my_xml_parser_free(MY_XML_PARSER *p  __attribute__((unused)))
+void my_xml_parser_free(MY_XML_PARSER *p)
 {
+  if (p->attr.buffer)
+  {
+    my_str_free(p->attr.buffer);
+    p->attr.buffer= NULL;
+  }
 }
 
 


Follow ups

References