[dasher: 13/27] Remove CAlphabet!



commit 65eb69dc5556bab54530de1056d6ab4fd4fb3723
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Sat Aug 7 20:07:40 2010 +0100

    Remove CAlphabet!
    
    Transfer public inspection methods e.g. GetText(symbol) to CAlphInfo;
    transfer GetSymbols and SymbolStream to CAlphabetMap (was alphabet_map).
    CAlphInfo * used directly; CAlphabetMap created for selected alph only.
    Note, GetNumberTextSymbols() returns one less than before.
    
    AlphIO moved inside CAlphInfo (rather than AlphInfo inside CAlphIO!).
    
    Fixed iNumChildNodes - now excludes "root" (actually control!), AlphabetManager
     adds on 1 for control mode when enabled.

 Src/DasherCore/Alphabet/AlphIO.cpp                 |  240 +++++++++++-------
 Src/DasherCore/Alphabet/AlphIO.h                   |  239 +++++++++++-------
 Src/DasherCore/Alphabet/Alphabet.cpp               |  272 --------------------
 Src/DasherCore/Alphabet/Alphabet.h                 |  189 --------------
 Src/DasherCore/Alphabet/AlphabetMap.cpp            |  127 +++++++++-
 Src/DasherCore/Alphabet/AlphabetMap.h              |   33 ++-
 Src/DasherCore/AlphabetManager.cpp                 |   29 +-
 Src/DasherCore/AlphabetManager.h                   |    9 +-
 Src/DasherCore/CannaConversionHelper.cpp           |    2 +-
 Src/DasherCore/CannaConversionHelper.h             |    2 +-
 Src/DasherCore/ConversionHelper.cpp                |    2 +-
 Src/DasherCore/ConversionHelper.h                  |    2 +-
 Src/DasherCore/ConversionManager.cpp               |    8 +-
 Src/DasherCore/ConversionManager.h                 |    6 +-
 Src/DasherCore/ConvertingAlphMgr.cpp               |    6 +-
 Src/DasherCore/ConvertingAlphMgr.h                 |    2 +-
 Src/DasherCore/DasherInterfaceBase.cpp             |    8 +-
 Src/DasherCore/DasherInterfaceBase.h               |    7 +-
 Src/DasherCore/DasherNode.cpp                      |    2 +-
 Src/DasherCore/DasherNode.h                        |    2 +-
 Src/DasherCore/IMEConversionHelper.cpp             |    2 +-
 Src/DasherCore/IMEConversionHelper.h               |    2 +-
 .../LanguageModelling/BigramLanguageModel.cpp      |    2 +-
 .../LanguageModelling/BigramLanguageModel.h        |    2 +-
 .../LanguageModelling/CTWLanguageModel.cpp         |    2 +-
 .../LanguageModelling/CTWLanguageModel.h           |    2 +-
 .../LanguageModelling/DictLanguageModel.cpp        |    8 +-
 .../LanguageModelling/DictLanguageModel.h          |    4 +-
 .../LanguageModelling/JapaneseLanguageModel.cpp    |    2 +-
 .../LanguageModelling/JapaneseLanguageModel.h      |    2 +-
 Src/DasherCore/LanguageModelling/LanguageModel.cpp |    4 +-
 Src/DasherCore/LanguageModelling/LanguageModel.h   |   10 +-
 .../LanguageModelling/MixtureLanguageModel.h       |    4 +-
 .../LanguageModelling/PPMLanguageModel.cpp         |    2 +-
 .../LanguageModelling/PPMLanguageModel.h           |    2 +-
 .../LanguageModelling/PPMPYLanguageModel.cpp       |    6 +-
 .../LanguageModelling/PPMPYLanguageModel.h         |    5 +-
 .../LanguageModelling/WordLanguageModel.cpp        |    8 +-
 .../LanguageModelling/WordLanguageModel.h          |    4 +-
 Src/DasherCore/Makefile.am                         |    2 -
 Src/DasherCore/MandarinAlphMgr.cpp                 |    9 +-
 Src/DasherCore/MandarinAlphMgr.h                   |    5 +-
 Src/DasherCore/NodeCreationManager.cpp             |   56 ++--
 Src/DasherCore/NodeCreationManager.h               |   10 +-
 Src/DasherCore/Trainer.cpp                         |    6 +-
 Src/DasherCore/Trainer.h                           |    9 +-
 Src/DasherCore/TrainingHelper.cpp                  |    6 +-
 Src/DasherCore/TrainingHelper.h                    |   10 +-
 Src/MacOSX/Dasher.xcodeproj/project.pbxproj        |    8 -
 49 files changed, 576 insertions(+), 805 deletions(-)
---
diff --git a/Src/DasherCore/Alphabet/AlphIO.cpp b/Src/DasherCore/Alphabet/AlphIO.cpp
index 1d9fa65..b5a568c 100644
--- a/Src/DasherCore/Alphabet/AlphIO.cpp
+++ b/Src/DasherCore/Alphabet/AlphIO.cpp
@@ -18,7 +18,6 @@
 // along with Dasher; if not, write to the Free Software 
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-#include "../../Common/Common.h"
 #include "AlphIO.h"
 
 #include <iostream>
@@ -37,9 +36,61 @@ static char THIS_FILE[] = __FILE__;
 #endif
 #endif
 
-CAlphIO::CAlphIO(std::string SystemLocation, std::string UserLocation, std::vector<std::string> &Filenames)
+int CAlphInfo::GetTextColour(symbol Symbol) const {
+  const std::string &TextColour(GetForeground(Symbol));
+  if(TextColour != std::string("")) {
+    return atoi(TextColour.c_str());
+  }
+  else {
+    return 4;
+  }
+}
+
+int 
+CAlphInfo::GetColour(symbol i, int iPhase) const {
+  int iColour = m_vCharacters[i-1].Colour;
+  
+  // This is for backwards compatibility with old alphabet files -
+  // ideally make this log a warning (unrelated TODO: automate
+  // validation of alphabet files, plus maintenance of repository
+  // etc.)
+  if(iColour == -1) {
+    if(i == iSpaceCharacter) {
+      iColour = 9;
+    }
+    else {
+      iColour = (i % 3) + 10;
+    }
+  }
+  
+  // Loop on low colours for nodes (TODO: go back to colour namespaces?)
+  if(iPhase == 1 && iColour < 130)
+    iColour += 130;
+  
+  return iColour;
+}
+
+CAlphabetMap *CAlphInfo::MakeMap() const {
+  CAlphabetMap *map = new CAlphabetMap();
+  int i;
+  for(i = 0; i < m_vCharacters.size(); i++) {
+    map->Add(m_vCharacters[i].Text, i+1); //1-indexed
+  }
+  //ACL I'm really not sure where conversion characters should/shouldn't be included.
+  // They seemed to be included in the Alphabet Map, i.e. for reading training text via GetSymbols;
+  // but a TODO comment suggested they should _not_ be included in GetNumberSymbols(),
+  // and I couldn't find any code which would have called e.g. GetText on them....
+  // Hence, not including them in m_vCharacters.
+  if (StartConvertCharacter)
+    map->Add(StartConvertCharacter->Text, ++i);
+  if (EndConvertCharacter)
+    map->Add(EndConvertCharacter->Text, ++i);
+  return map;
+}
+
+CAlphInfo::AlphIO::AlphIO(std::string SystemLocation, std::string UserLocation, std::vector<std::string> &Filenames)
 : SystemLocation(SystemLocation), UserLocation(UserLocation), Filenames(Filenames), LoadMutable(false), CData("") {
-  CreateDefault();
+  Alphabets["Default"]=CreateDefault();
 
   typedef pair < Opts::AlphabetTypes, std::string > AT;
   vector < AT > Types;
@@ -79,26 +130,39 @@ CAlphIO::CAlphIO(std::string SystemLocation, std::string UserLocation, std::vect
   }
 }
 
-CAlphIO::AlphInfo::AlphInfo() {
+CAlphInfo::CAlphInfo() {
   iSpaceCharacter=-1;
   iParagraphCharacter = -1;
   ControlCharacter=NULL;
   StartConvertCharacter=NULL;
   EndConvertCharacter=NULL;
   m_pBaseGroup = 0;
-  iNumChildNodes = 1; // the "root node" symbol (with text "")
+  iNumChildNodes = 0;
   m_iConversionID = 0;
   m_strDefaultContext = ". ";
 }
 
-CAlphIO::AlphInfo::character::character() {
+void DeleteGroups(SGroupInfo *Info) {
+  for(SGroupInfo *next; Info; Info=next) {
+    next = Info->pNext;
+    DeleteGroups(Info->pChild);
+    delete Info;
+    Info = next;
+  }
+}
+
+CAlphInfo::~CAlphInfo() {
+  DeleteGroups(m_pBaseGroup);
+}
+
+CAlphInfo::character::character() {
   Display="";
   Text="";
   Colour=-1;
   Foreground="";
 }
 
-void CAlphIO::ParseFile(std::string Filename) {
+void CAlphInfo::AlphIO::ParseFile(std::string Filename) {
   FILE *Input;
   if((Input = fopen(Filename.c_str(), "r")) == (FILE *) 0) {
     // could not open file
@@ -129,17 +193,17 @@ void CAlphIO::ParseFile(std::string Filename) {
   fclose(Input);
 }
 
-void CAlphIO::GetAlphabets(std::vector <std::string >*AlphabetList) const {
+void CAlphInfo::AlphIO::GetAlphabets(std::vector <std::string >*AlphabetList) const {
   AlphabetList->clear();
 
-  typedef std::map < std::string, AlphInfo >::const_iterator CI;
+  typedef std::map < std::string, const CAlphInfo* >::const_iterator CI;
   CI End = Alphabets.end();
 
   for(CI Cur = Alphabets.begin(); Cur != End; Cur++)
-    AlphabetList->push_back((*Cur).second.AlphID);
+    AlphabetList->push_back(Cur->second->AlphID);
 }
 
-std::string CAlphIO::GetDefault() {
+std::string CAlphInfo::AlphIO::GetDefault() {
   if(Alphabets.count("English with limited punctuation") != 0) {
     return "English with limited punctuation";
   }
@@ -148,10 +212,9 @@ std::string CAlphIO::GetDefault() {
   }
 }
 
-const CAlphIO::AlphInfo & CAlphIO::GetInfo(const std::string &AlphID) {
-  if(Alphabets.count(AlphID) != 0) {
+const CAlphInfo *CAlphInfo::AlphIO::GetInfo(const std::string &AlphID) {
+  if(Alphabets.count(AlphID)!=0) {
     // if we have the alphabet they ask for, return it
-    Alphabets[AlphID].AlphID = AlphID;        // Ensure consistency
     return Alphabets[AlphID];
   }
   else {
@@ -160,35 +223,21 @@ const CAlphIO::AlphInfo & CAlphIO::GetInfo(const std::string &AlphID) {
   }
 }
 
-void CAlphIO::SetInfo(const AlphInfo &NewInfo) {
-  Alphabets[NewInfo.AlphID] = NewInfo;
-  Save(NewInfo.AlphID);
-}
-
-void CAlphIO::DeleteGroups(SGroupInfo *Info) {
-  SGroupInfo *next;
-
-  while (Info) {
-    next = Info->pNext;
-
-    if (Info->pChild)
-      DeleteGroups(Info->pChild);
-
-    delete Info;
-    Info = next;
-  }
+void CAlphInfo::AlphIO::SetInfo(const CAlphInfo *NewInfo) {
+  Alphabets[NewInfo->AlphID] = NewInfo;
+  Save(NewInfo->AlphID);
 }
 
-void CAlphIO::Delete(const std::string &AlphID) {
-  map<std::string, AlphInfo>::iterator it = Alphabets.find(AlphID);
+void CAlphInfo::AlphIO::Delete(const std::string &AlphID) {
+  map<std::string, const CAlphInfo *>::iterator it = Alphabets.find(AlphID);
   if(it != Alphabets.end()) {
-    DeleteGroups(it->second.m_pBaseGroup);
+    delete it->second;
     Alphabets.erase(it);
     Save("");
   }
 }
 
-void CAlphIO::Save(const std::string &AlphID) {
+void CAlphInfo::AlphIO::Save(const std::string &AlphID) {
   // TODO: We cannot reliably output XML at the moment this will have
   // to be re-implemented if we ever decide that we need to do this
   // again
@@ -211,10 +260,10 @@ void CAlphIO::Save(const std::string &AlphID) {
   fwrite("<?xml-stylesheet type=\"text/xsl\" href=\"alphabet.xsl\"?>\n", sizeof(char), 55, Output);
   fwrite("<alphabets>\n", sizeof(char), 12, Output);
 
-  typedef std::map < std::string, AlphInfo >::const_iterator CI;
+  typedef std::map < std::string, const CAlphInfo * >::const_iterator CI;
   CI End = Alphabets.end();
   for(CI Cur = Alphabets.begin(); Cur != End; Cur++) {
-    AlphInfo Info = (*Cur).second;      // Take a copy so that special characters can be escaped
+    CAlphInfo Info = *(Cur->second);      // Take a copy so that special characters can be escaped
 
     if(Info.Mutable == false)   // this is a system alphabet, not one we write
       continue;
@@ -268,7 +317,7 @@ void CAlphIO::Save(const std::string &AlphID) {
     
     // Write out the space character
     if (Info.iSpaceCharacter!=0) {
-      AlphInfo::character &spC(Info.m_vCharacters[Info.iSpaceCharacter]);
+      character &spC(Info.m_vCharacters[Info.iSpaceCharacter]);
       fwrite("<space d=\"", sizeof(char), 10, Output);
       XML_Escape(&spC.Display, true);
       fwrite(spC.Display.c_str(), sizeof(char), spC.Display.size(), Output);
@@ -283,7 +332,7 @@ void CAlphIO::Save(const std::string &AlphID) {
 
     // Write out the paragraph character
     if (Info.iParagraphCharacter!=-1) {
-      AlphInfo::character para(Info.m_vCharacters[Info.iParagraphCharacter]);
+      character para(Info.m_vCharacters[Info.iParagraphCharacter]);
       fwrite("<paragraph d=\"", sizeof(char), 14, Output);
       XML_Escape(&para.Display, true);
       fwrite(para.Display.c_str(), sizeof(char), para.Display.size(), Output);
@@ -348,11 +397,11 @@ void CAlphIO::Save(const std::string &AlphID) {
   fclose(Output);
 }
 
-void CAlphIO::CreateDefault() {
+CAlphInfo *CAlphInfo::AlphIO::CreateDefault() {
   // TODO I appreciate these strings should probably be in a resource file.
   // Not urgent though as this is not intended to be used. It's just a
   // last ditch effort in case file I/O totally fails.
-  AlphInfo & Default = Alphabets["Default"];
+  CAlphInfo &Default(*(new CAlphInfo()));
   Default.AlphID = "Default";
   Default.Type = Opts::Western;
   Default.Mutable = false;
@@ -395,14 +444,15 @@ void CAlphIO::CreateDefault() {
   Default.m_vCharacters[Default.iSpaceCharacter].Text = " ";
   Default.m_vCharacters[Default.iSpaceCharacter].Colour = 9;
   
-  Default.ControlCharacter = new AlphInfo::character();
+  Default.ControlCharacter = new character();
   Default.ControlCharacter->Display = "Control";
   Default.ControlCharacter->Text = "";
   Default.ControlCharacter->Colour = 8;
-  
+
+  return &Default;
 }
 
-void CAlphIO::XML_Escape(std::string *Text, bool Attribute) {
+void CAlphInfo::AlphIO::XML_Escape(std::string *Text, bool Attribute) {
   // The XML "W3C Recommendation" is here: http://www.w3.org/TR/REC-xml
 
   std::string & Input = *Text;       // Makes syntax less fiddly below
@@ -440,15 +490,14 @@ void CAlphIO::XML_Escape(std::string *Text, bool Attribute) {
 // Below here handlers for the Expat XML input library
 ////////////////////////////////////////////////////////////////////////////////////
 
-void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_Char **atts) {
-  CAlphIO *Me = (CAlphIO *) userData;
+void CAlphInfo::AlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_Char **atts) {
+  CAlphInfo::AlphIO *Me = (CAlphInfo::AlphIO *) userData;
 
   Me->CData = "";
 
   if(strcmp(name, "alphabet") == 0) {
-    AlphInfo NewInfo;
-    Me->InputInfo = NewInfo;
-    Me->InputInfo.Mutable = Me->LoadMutable;
+    Me->InputInfo = new CAlphInfo();
+    Me->InputInfo->Mutable = Me->LoadMutable;
     Me->ParagraphCharacter = NULL;
     Me->SpaceCharacter = NULL;
     Me->bFirstGroup = true;
@@ -456,7 +505,7 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
     while(*atts != 0) {
       if(strcmp(*atts, "name") == 0) {
         atts++;
-        Me->InputInfo.AlphID = *atts;
+        Me->InputInfo->AlphID = *atts;
         atts--;
       }
       atts += 2;
@@ -470,16 +519,16 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
       if(!strcmp(*atts, "type")) {
         atts++;
         if(!strcmp(*atts, "RL")) {
-          Me->InputInfo.Orientation = Opts::RightToLeft;
+          Me->InputInfo->Orientation = Opts::RightToLeft;
         }
         else if(!strcmp(*atts, "TB")) {
-          Me->InputInfo.Orientation = Opts::TopToBottom;
+          Me->InputInfo->Orientation = Opts::TopToBottom;
         }
         else if(!strcmp(*atts, "BT")) {
-          Me->InputInfo.Orientation = Opts::BottomToTop;
+          Me->InputInfo->Orientation = Opts::BottomToTop;
         }
         else
-          Me->InputInfo.Orientation = Opts::LeftToRight;
+          Me->InputInfo->Orientation = Opts::LeftToRight;
         atts--;
       }
       atts += 2;
@@ -491,7 +540,7 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
     while(*atts != 0) {
       if(strcmp(*atts, "type") == 0) {
         atts++;
-        Me->InputInfo.Type = Me->StoT[*atts];
+        Me->InputInfo->Type = Me->StoT[*atts];
         atts--;
       }
       atts += 2;
@@ -500,12 +549,12 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
   }
 
   if(strcmp(name, "space") == 0) {
-    if (!Me->SpaceCharacter) Me->SpaceCharacter = new AlphInfo::character();
+    if (!Me->SpaceCharacter) Me->SpaceCharacter = new character();
     Me->ReadCharAtts(atts,*(Me->SpaceCharacter));
     return;
   }
   if(strcmp(name, "paragraph") == 0) {
-    if (!Me->ParagraphCharacter) Me->ParagraphCharacter=new AlphInfo::character();
+    if (!Me->ParagraphCharacter) Me->ParagraphCharacter=new character();
     Me->ReadCharAtts(atts,*(Me->ParagraphCharacter));
     if(Me->ParagraphCharacter->Display != "") {
 #ifdef WIN32
@@ -517,8 +566,8 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
     return;
   }
   if(strcmp(name, "control") == 0) {
-    if (!Me->InputInfo.ControlCharacter) Me->InputInfo.ControlCharacter = new AlphInfo::character();
-    Me->ReadCharAtts(atts, *(Me->InputInfo.ControlCharacter));
+    if (!Me->InputInfo->ControlCharacter) Me->InputInfo->ControlCharacter = new character();
+    Me->ReadCharAtts(atts, *(Me->InputInfo->ControlCharacter));
     return;
   }
 
@@ -527,7 +576,7 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
     pNewGroup->iNumChildNodes=0;
     pNewGroup->iColour = (Me->iGroupIdx % 3) + 110; 
     ++Me->iGroupIdx;
-    if (Me->m_vGroups.empty()) Me->InputInfo.iNumChildNodes++; else Me->m_vGroups.back()->iNumChildNodes++;
+    if (Me->m_vGroups.empty()) Me->InputInfo->iNumChildNodes++; else Me->m_vGroups.back()->iNumChildNodes++;
 
     if(Me->bFirstGroup) {
       pNewGroup->bVisible = false;
@@ -542,7 +591,7 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
 	// TODO: Fix this, or remove if names aren't needed
 
 //         atts++;
-//         Me->InputInfo.Groups.back().Description = *atts;
+//         Me->InputInfo->Groups.back().Description = *atts;
 //         atts--;
       }
       if(strcmp(*atts, "b") == 0) {
@@ -566,7 +615,7 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
       atts += 2;
     }
 
-    pNewGroup->iStart = Me->InputInfo.m_vCharacters.size()+1;
+    pNewGroup->iStart = Me->InputInfo->m_vCharacters.size()+1;
 
     pNewGroup->pChild = NULL;
 
@@ -575,8 +624,8 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
       Me->m_vGroups.back()->pChild = pNewGroup;
     }
     else {
-      pNewGroup->pNext = Me->InputInfo.m_pBaseGroup;
-      Me->InputInfo.m_pBaseGroup = pNewGroup;
+      pNewGroup->pNext = Me->InputInfo->m_pBaseGroup;
+      Me->InputInfo->m_pBaseGroup = pNewGroup;
     }
 
 
@@ -589,7 +638,7 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
     while(*atts != 0) {
       if(strcmp(*atts, "id") == 0) {
         atts++;
-        Me->InputInfo.m_iConversionID = atoi(*atts);
+        Me->InputInfo->m_iConversionID = atoi(*atts);
         atts--;
       }
       atts += 2;
@@ -600,14 +649,14 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
 
   // Special characters for character composition
   if(strcmp(name, "convert") == 0) {
-    if (!Me->InputInfo.StartConvertCharacter) Me->InputInfo.StartConvertCharacter = new AlphInfo::character();
-    Me->ReadCharAtts(atts, *(Me->InputInfo.StartConvertCharacter));
+    if (!Me->InputInfo->StartConvertCharacter) Me->InputInfo->StartConvertCharacter = new character();
+    Me->ReadCharAtts(atts, *(Me->InputInfo->StartConvertCharacter));
     return;
   }
 
   if(strcmp(name, "protect") == 0) {
-    if (!Me->InputInfo.EndConvertCharacter) Me->InputInfo.EndConvertCharacter = new AlphInfo::character();
-    Me->ReadCharAtts(atts, *(Me->InputInfo.EndConvertCharacter));
+    if (!Me->InputInfo->EndConvertCharacter) Me->InputInfo->EndConvertCharacter = new character();
+    Me->ReadCharAtts(atts, *(Me->InputInfo->EndConvertCharacter));
     return;
   }
 
@@ -615,7 +664,7 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
     while(*atts != 0) {
       if(strcmp(*atts, "default") == 0) {
         atts++;
-        Me->InputInfo.m_strDefaultContext = *atts;
+        Me->InputInfo->m_strDefaultContext = *atts;
         atts--;
       }
       atts += 2;
@@ -625,9 +674,9 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
 
   if(strcmp(name, "s") == 0) {
 
-    if (Me->m_vGroups.empty()) Me->InputInfo.iNumChildNodes++; else Me->m_vGroups.back()->iNumChildNodes++;
-    Me->InputInfo.m_vCharacters.resize(Me->InputInfo.m_vCharacters.size()+1);
-    AlphInfo::character &Ch(Me->InputInfo.m_vCharacters.back());
+    if (Me->m_vGroups.empty()) Me->InputInfo->iNumChildNodes++; else Me->m_vGroups.back()->iNumChildNodes++;
+    Me->InputInfo->m_vCharacters.resize(Me->InputInfo->m_vCharacters.size()+1);
+    character &Ch(Me->InputInfo->m_vCharacters.back());
     
     // FIXME - need to do a more sensible job of ensuring that
     // defaults are correct (plus more generally fixing behaviour when
@@ -637,7 +686,7 @@ void CAlphIO::XML_StartElement(void *userData, const XML_Char *name, const XML_C
   }
 }
 
-void CAlphIO::ReadCharAtts(const XML_Char **atts, AlphInfo::character &ch) {
+void CAlphInfo::AlphIO::ReadCharAtts(const XML_Char **atts, character &ch) {
   while(*atts != 0) {
     if(strcmp(*atts, "t") == 0) ch.Text = *(atts+1);
     else if(strcmp(*atts, "d") == 0) ch.Display = *(atts+1);
@@ -659,48 +708,48 @@ void Reverse(SGroupInfo *&pList) {
   pList=pPrev;
 }
 
-void CAlphIO::XML_EndElement(void *userData, const XML_Char *name) {
-  CAlphIO *Me = (CAlphIO *) userData;
+void CAlphInfo::AlphIO::XML_EndElement(void *userData, const XML_Char *name) {
+  CAlphInfo::AlphIO *Me = (CAlphInfo::AlphIO *) userData;
 
   if(strcmp(name, "alphabet") == 0) {
-    Reverse(Me->InputInfo.m_pBaseGroup);
+    Reverse(Me->InputInfo->m_pBaseGroup);
     
     if (Me->ParagraphCharacter) {
-      Me->InputInfo.iParagraphCharacter = Me->InputInfo.m_vCharacters.size();
-      Me->InputInfo.m_vCharacters.push_back(*(Me->ParagraphCharacter));
-      Me->InputInfo.iNumChildNodes++;
+      Me->InputInfo->iParagraphCharacter = Me->InputInfo->m_vCharacters.size();
+      Me->InputInfo->m_vCharacters.push_back(*(Me->ParagraphCharacter));
+      Me->InputInfo->iNumChildNodes++;
       delete Me->ParagraphCharacter;
     }
     if (Me->SpaceCharacter) {
-      Me->InputInfo.iSpaceCharacter = Me->InputInfo.m_vCharacters.size();
-      Me->InputInfo.m_vCharacters.push_back(*(Me->SpaceCharacter));
-      Me->InputInfo.iNumChildNodes++;
+      Me->InputInfo->iSpaceCharacter = Me->InputInfo->m_vCharacters.size();
+      Me->InputInfo->m_vCharacters.push_back(*(Me->SpaceCharacter));
+      Me->InputInfo->iNumChildNodes++;
       delete Me->SpaceCharacter;
     }
     
-    //if (Me->InputInfo.StartConvertCharacter.Text != "") Me->InputInfo.iNumChildNodes++;
-    //if (Me->InputInfo.EndConvertCharacter.Text != "") Me->InputInfo.iNumChildNodes++;
-    Me->Alphabets[Me->InputInfo.AlphID] = Me->InputInfo;
+    //if (Me->InputInfo->StartConvertCharacter.Text != "") Me->InputInfo->iNumChildNodes++;
+    //if (Me->InputInfo->EndConvertCharacter.Text != "") Me->InputInfo->iNumChildNodes++;
+    Me->Alphabets[Me->InputInfo->AlphID] = Me->InputInfo;
     return;
   }
 
   if(strcmp(name, "train") == 0) {
-    Me->InputInfo.TrainingFile = Me->CData;
+    Me->InputInfo->TrainingFile = Me->CData;
     return;
   }
 
   if(strcmp(name, "gamemode") == 0) {
-    Me->InputInfo.GameModeFile = Me->CData;
+    Me->InputInfo->GameModeFile = Me->CData;
     return;
   }
 
   if(strcmp(name, "palette") == 0) {
-    Me->InputInfo.PreferredColours = Me->CData;
+    Me->InputInfo->PreferredColours = Me->CData;
     return;
   }
 
   if(!strcmp(name, "group")) {
-    Me->m_vGroups.back()->iEnd = Me->InputInfo.m_vCharacters.size()+1;
+    Me->m_vGroups.back()->iEnd = Me->InputInfo->m_vCharacters.size()+1;
     //child groups were added (to linked list) in reverse order. Put them in (iStart/iEnd) order...
     Reverse(Me->m_vGroups.back()->pChild);
     Me->m_vGroups.pop_back();
@@ -708,15 +757,16 @@ void CAlphIO::XML_EndElement(void *userData, const XML_Char *name) {
   }
 }
 
-void CAlphIO::XML_CharacterData(void *userData, const XML_Char *s, int len) {
+void CAlphInfo::AlphIO::XML_CharacterData(void *userData, const XML_Char *s, int len) {
   // CAREFUL: s points to a string which is NOT null-terminated.
 
-  CAlphIO *Me = (CAlphIO *) userData;
+  CAlphInfo::AlphIO *Me = (CAlphInfo::AlphIO *) userData;
 
   Me->CData.append(s, len);
 }
 
-CAlphIO::~CAlphIO() {
-  for (std::map<std::string, AlphInfo>::iterator it = Alphabets.begin(); it != Alphabets.end(); ++it)
-    DeleteGroups(it->second.m_pBaseGroup);
+CAlphInfo::AlphIO::~AlphIO() {
+  for (std::map<std::string, const CAlphInfo* >::iterator it = Alphabets.begin(); it != Alphabets.end(); ++it) {
+    delete it->second;
+  }
 }
diff --git a/Src/DasherCore/Alphabet/AlphIO.h b/Src/DasherCore/Alphabet/AlphIO.h
index 6aab1bb..b981ebd 100644
--- a/Src/DasherCore/Alphabet/AlphIO.h
+++ b/Src/DasherCore/Alphabet/AlphIO.h
@@ -21,8 +21,13 @@
 #ifndef __AlphIO_h__
 #define __AlphIO_h__
 
+#include "../../Common/Common.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include "../DasherTypes.h"
-//#include "Alphabet.h"
+#include "AlphabetMap.h"
 #include "GroupInfo.h"
 
 #include <expat.h>
@@ -33,111 +38,155 @@
 #include <stdio.h>              // for C style file IO
 
 namespace Dasher {
-  class CAlphIO;
+  class CAlphInfo;
 } 
 
 
 /// \ingroup Alphabet
 /// @{
 
-class Dasher::CAlphIO {
+/// This structure completely describes the characters used in alphabet
+class Dasher::CAlphInfo {
+private:
+  struct character {
+    character();
+    std::string Display;
+    std::string Text;
+    int Colour;
+    std::string Foreground;
+  };  
 public:
-  // This structure completely describes the characters used in alphabet
-
-  struct AlphInfo {
-    AlphInfo();
-    // Basic information
-    std::string AlphID;
-    bool Mutable;               // If from user we may play. If from system defaults this is immutable. User should take a copy.
-
-    // Complete description of the alphabet:
-    std::string TrainingFile;
-    std::string GameModeFile;
-    std::string PreferredColours;
-    Opts::AlphabetTypes Encoding;
-    Opts::AlphabetTypes Type;
-    Opts::ScreenOrientations Orientation;
-
-    struct character {
-      character();
-      std::string Display;
-      std::string Text;
-      int Colour;
-      std::string Foreground;
-    };
-
-/*     // Obsolete groups stuff */
-/*     struct group { */
-/*       std::string Description; */
-/*       std::vector < character > Characters; */
-/*       int Colour; */
-/*       std::string Label; */
-/*     }; */
-/*     std::vector < group > Groups; */
-/*     // --- */
-
-    SGroupInfo *m_pBaseGroup;
-    int iNumChildNodes;
-
-    std::vector<character> m_vCharacters;
-
-    int iParagraphCharacter;       // index into m_vCharacters of paragraph char (display and edit text), -1 for none.
-    int iSpaceCharacter;   // index into m_vCharacters of space char (display and edit text), -1 for none.
-    character *ControlCharacter; // display and edit text of Control character. Typically ("", "Control"). Use ("", "") if no control character.
-    character *StartConvertCharacter;
-    character *EndConvertCharacter;
-
-    int m_iConversionID;
-    std::string m_strDefaultContext;
+  /// Return number of text symbols - inc space and para, but no control/conversion start/end
+  /// Note symbol numbers are 1-indexed; 0 is reserved (for the root symbol, or for
+  /// element 0 of the probability array to contain a 0)
+  int GetNumberTextSymbols() const {return m_vCharacters.size();}
+  
+  Opts::ScreenOrientations GetOrientation() const {return Orientation;} 
+  
+  Opts::AlphabetTypes GetType() const {return Type;}
+  
+  const std::string & GetTrainingFile() const {return TrainingFile;}
+  
+  const std::string &GetGameModeFile() const {return GameModeFile;}
+  
+  const std::string & GetPalette() const {return PreferredColours;}
+  
+  symbol GetParagraphSymbol() const {return iParagraphCharacter;}
+  
+  symbol GetSpaceSymbol() const {return iSpaceCharacter;}
+  
+  //symbol GetStartConversionSymbol() const;
+  //symbol GetEndConversionSymbol() const;
+  
+  /// return display string for i'th symbol
+  const std::string & GetDisplayText(symbol i) const {return m_vCharacters[i-1].Display;}
+  
+  /// return text for edit box for i'th symbol
+  const std::string & GetText(symbol i) const {return m_vCharacters[i-1].Text;} 
+  
+  // return string for i'th symbol
+  
+  int GetColour(symbol i, int iPhase) const;
+  
+  /// Text foreground colour for i'th symbol; default 4 if unspecified
+  int GetTextColour(symbol i) const;
+  /// Text foreground colour for i'th symbol, as specified in XML
+  const std::string & GetForeground(symbol i) const {return m_vCharacters[i-1].Foreground;}
+    
+  const std::string &GetDefaultContext() const {return m_strDefaultContext;}
+  
+  SGroupInfo *m_pBaseGroup;
+  int iNumChildNodes;
+  int m_iConversionID;
+  
+  CAlphabetMap *MakeMap() const;
+  class AlphIO {
+  public:
+
+    AlphIO(std::string SystemLocation, std::string UserLocation, std::vector < std::string > &Filenames);
+    ~AlphIO();
+    void GetAlphabets(std::vector < std::string > *AlphabetList) const;
+    std::string GetDefault();
+    const CAlphInfo *GetInfo(const std::string & AlphID);
+    void SetInfo(const CAlphInfo *NewInfo);
+    void Delete(const std::string & AlphID);
+  private:
+    character *SpaceCharacter, *ParagraphCharacter;
+    std::vector<SGroupInfo *> m_vGroups;
+    std::string SystemLocation;
+    std::string UserLocation;
+    std::map < std::string, const CAlphInfo* > Alphabets; // map short names (file names) to descriptions. We own all the values but it's easier this way...
+    std::vector < std::string > Filenames;
+
+    void Save(const std::string & AlphID);
+    CAlphInfo *CreateDefault();         // Give the user an English alphabet rather than nothing if anything goes horribly wrong.
+
+    void DeleteAlphabet(CAlphInfo *Alphabet);
+
+    // XML handling:
+    /////////////////////////
+
+    bool LoadMutable;
+    void ParseFile(std::string Filename);
+    void ReadCharAtts(const XML_Char **atts, character &ch);
+    // Alphabet types:
+    std::map < std::string, Opts::AlphabetTypes > StoT;
+    std::map < Opts::AlphabetTypes, std::string > TtoS;
+
+    // & to &amp;  < to &lt; and > to &gt;  and if (Attribute) ' to &apos; and " to &quot;
+    void XML_Escape(std::string * Text, bool Attribute);
+
+    // Data gathered
+    std::string CData;            // Text gathered from when an elemnt starts to when it ends
+    CAlphInfo *InputInfo;
+    bool bFirstGroup;
+    int iGroupIdx;
+
+    // Callback functions. These involve the normal dodgy casting to a pointer
+    // to an instance to get a C++ class to work with a plain C library.
+    static void XML_StartElement(void *userData, const XML_Char * name, const XML_Char ** atts);
+    static void XML_EndElement(void *userData, const XML_Char * name);
+    static void XML_CharacterData(void *userData, const XML_Char * s, int len);
   };
-
-  CAlphIO(std::string SystemLocation, std::string UserLocation, std::vector < std::string > &Filenames);
-  ~CAlphIO();
-  void GetAlphabets(std::vector < std::string > *AlphabetList) const;
-  std::string GetDefault();
-  const AlphInfo & GetInfo(const std::string & AlphID);
-  void SetInfo(const AlphInfo & NewInfo);
-  void Delete(const std::string & AlphID);
+  
+  ~CAlphInfo();
+  
 private:
-  AlphInfo::character *SpaceCharacter, *ParagraphCharacter;
-  std::vector<SGroupInfo *> m_vGroups;
-  std::string SystemLocation;
-  std::string UserLocation;
-  std::map < std::string, AlphInfo > Alphabets; // map short names (file names) to descriptions
-  std::vector < std::string > Filenames;
-
-  void Save(const std::string & AlphID);
-  void CreateDefault();         // Give the user an English alphabet rather than nothing if anything goes horribly wrong.
-
-  void DeleteGroups(SGroupInfo *Info);
-  void DeleteAlphabet(AlphInfo *Alphabet);
-
-  // XML handling:
-  /////////////////////////
-
-  bool LoadMutable;
-  void ParseFile(std::string Filename);
-  void ReadCharAtts(const XML_Char **atts, AlphInfo::character &ch);
-  // Alphabet types:
-  std::map < std::string, Opts::AlphabetTypes > StoT;
-  std::map < Opts::AlphabetTypes, std::string > TtoS;
-
-  // & to &amp;  < to &lt; and > to &gt;  and if (Attribute) ' to &apos; and " to &quot;
-  void XML_Escape(std::string * Text, bool Attribute);
-
-  // Data gathered
-  std::string CData;            // Text gathered from when an elemnt starts to when it ends
-  AlphInfo InputInfo;
-  bool bFirstGroup;
-  int iGroupIdx;
-
-  // Callback functions. These involve the normal dodgy casting to a pointer
-  // to an instance to get a C++ class to work with a plain C library.
-  static void XML_StartElement(void *userData, const XML_Char * name, const XML_Char ** atts);
-  static void XML_EndElement(void *userData, const XML_Char * name);
-  static void XML_CharacterData(void *userData, const XML_Char * s, int len);
+  CAlphInfo();
+  // Basic information
+  std::string AlphID;
+  bool Mutable;               // If from user we may play. If from system defaults this is immutable. User should take a copy.
+  
+  // Complete description of the alphabet:
+  std::string TrainingFile;
+  std::string GameModeFile;
+  std::string PreferredColours;
+  Opts::AlphabetTypes Encoding;
+  Opts::AlphabetTypes Type;
+  Opts::ScreenOrientations Orientation;
+    
+  /*     // Obsolete groups stuff */
+  /*     struct group { */
+  /*       std::string Description; */
+  /*       std::vector < character > Characters; */
+  /*       int Colour; */
+  /*       std::string Label; */
+  /*     }; */
+  /*     std::vector < group > Groups; */
+  /*     // --- */
+    
+  std::vector<character> m_vCharacters;
+  
+  int iParagraphCharacter;       // index into m_vCharacters of paragraph char (display and edit text), -1 for none.
+  int iSpaceCharacter;   // index into m_vCharacters of space char (display and edit text), -1 for none.
+  character *ControlCharacter; // display and edit text of Control character. Typically ("", "Control"). Use ("", "") if no control character.
+  character *StartConvertCharacter;
+  character *EndConvertCharacter;
+  
+  std::string m_strDefaultContext;
 };
 
+
 /// @}
 
 #endif /* #ifndef __AlphIO_h__ */
diff --git a/Src/DasherCore/Alphabet/AlphabetMap.cpp b/Src/DasherCore/Alphabet/AlphabetMap.cpp
index 89b707a..9311de2 100644
--- a/Src/DasherCore/Alphabet/AlphabetMap.cpp
+++ b/Src/DasherCore/Alphabet/AlphabetMap.cpp
@@ -6,10 +6,17 @@
 //
 /////////////////////////////////////////////////////////////////////////////
 
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include "../../Common/Common.h"
 
 #include "AlphabetMap.h"
 #include <limits>
+#include <iostream>
+#include <sstream>
 
 using namespace Dasher;
 using namespace std;
@@ -24,7 +31,117 @@ static char THIS_FILE[] = __FILE__;
 #endif
 #endif
 
-alphabet_map::alphabet_map(unsigned int InitialTableSize)
+class utf8_length
+{
+public:
+  utf8_length();
+  int operator[](const unsigned char) const;
+  int max_length;
+private:
+  int utf8_count_array[0x100];
+};
+static utf8_length m_utf8_count_array;
+
+utf8_length::utf8_length()
+{
+  int i;
+  
+  memset(utf8_count_array, 0, sizeof(utf8_count_array));
+  for (i = 0x00; i <= 0x7f; ++i) utf8_count_array[i] = 1;
+  for (i = 0xc0; i <= 0xdf; ++i) utf8_count_array[i] = 2;
+  for (i = 0xe0; i <= 0xef; ++i) utf8_count_array[i] = 3;
+  for (i = 0xf0; i <= 0xf7; ++i) utf8_count_array[i] = 4;
+  max_length = 4;
+  /* The following would be valid according to RFC 2279 which was rendered
+   * obsolete by RFC 3629
+   * for (i = 0xf8; i <= 0xfb; ++i) utf8_count_array[i] = 5;
+   * for (i = 0xfc; i <= 0xfd; ++i) utf8_count_array[i] = 6;
+   * max_length = 6;
+   *
+   * and from RFC 3629:
+   * o  The octet values C0, C1, F5 to FF never appear.
+   */
+  utf8_count_array[0xc0] = utf8_count_array[0xc1] = 0;
+  for (i = 0xf5; i <= 0xff; ++i) utf8_count_array[i] = 0;
+}
+
+int utf8_length::operator[](const unsigned char i) const
+{
+  return utf8_count_array[i];
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+CAlphabetMap::SymbolStream::SymbolStream(const CAlphabetMap &_map, std::istream &_in)
+: map(_map), in(_in), pos(0), len(0) {
+  readMore();
+}
+
+void CAlphabetMap::SymbolStream::readMore() {
+  //len is first unfilled byte
+  in.read(&buf[len], 1024-len);
+  if (in.good()) {
+    DASHER_ASSERT(in.gcount() == 1024-len);
+    len = 1024;
+  } else {
+    len+=in.gcount();
+    DASHER_ASSERT(len<1024);
+    //next attempt to read more will fail.
+  }
+}
+
+symbol CAlphabetMap::SymbolStream::next()
+{
+  int numChars;
+  
+  for (;;) {
+    if (pos + m_utf8_count_array.max_length > len && len==1024) {
+      //may need more bytes for next char; and input not yet exhausted.
+      
+      if (pos) {
+        //shift remaining bytes to beginning
+        len-=pos; //len of them
+        memcpy(buf, &buf[pos], len);
+        pos=0;
+      }
+      readMore();
+    }
+    //if still don't have any chars after attempting to read more...EOF!
+    if (pos==len) return -1;
+    numChars = m_utf8_count_array[buf[pos]];
+    if (numChars != 0) break;
+#ifdef DEBUG
+    std::cerr << "Read invalid UTF-8 character 0x" << hex << buf[pos]
+    << dec << std::endl;
+#endif
+    ++pos;
+  }
+  if (numChars == 1)
+    return map.GetSingleChar(buf[pos++]);
+  if (pos+numChars > len) {
+    //no more bytes in file (would have tried to read earlier), but not enough for char
+#ifdef DEBUG
+    std::cerr << "Incomplete UTF-8 character beginning 0x" << hex << buf[pos] << dec;
+    std::cerr << "(expecting " << numChars << " bytes but only " << (len-pos) << ")" << std::endl;
+#endif
+    pos=len;
+    return -1;
+  }
+  int sym=map.Get(string(&buf[pos], numChars));
+  pos+=numChars;
+  return sym;
+}
+
+void CAlphabetMap::GetSymbols(std::vector<symbol>& Symbols, const std::string& Input) const
+{
+  std::istringstream in(Input);
+  SymbolStream syms(*this, in);
+  for (symbol sym; (sym=syms.next())!=-1;)
+    Symbols.push_back(sym);
+}
+
+
+CAlphabetMap::CAlphabetMap(unsigned int InitialTableSize)
 :HashTable(InitialTableSize <<1), Undefined(0) {
   Entries.reserve(InitialTableSize);
 
@@ -33,11 +150,11 @@ alphabet_map::alphabet_map(unsigned int InitialTableSize)
   for (int i = 0; i<numChars; i++) m_pSingleChars[i] = Undefined;
 }
 
-alphabet_map::~alphabet_map() {
+CAlphabetMap::~CAlphabetMap() {
   delete m_pSingleChars;
 }
 
-void alphabet_map::Add(const std::string &Key, symbol Value) {
+void CAlphabetMap::Add(const std::string &Key, symbol Value) {
   if (Key.length() == 1) {
     m_pSingleChars[Key[0]] = Value;
     return;
@@ -76,7 +193,7 @@ void alphabet_map::Add(const std::string &Key, symbol Value) {
   HashEntry = &Entries.back();
 }
 
-symbol alphabet_map::Get(const std::string &Key) const {
+symbol CAlphabetMap::Get(const std::string &Key) const {
   if (Key.length() == 1) {
 	return GetSingleChar(Key[0]);
   }
@@ -90,4 +207,4 @@ symbol alphabet_map::Get(const std::string &Key) const {
   return Undefined;
 }
 
-symbol alphabet_map::GetSingleChar(char key) const {return m_pSingleChars[key];}
+symbol CAlphabetMap::GetSingleChar(char key) const {return m_pSingleChars[key];}
diff --git a/Src/DasherCore/Alphabet/AlphabetMap.h b/Src/DasherCore/Alphabet/AlphabetMap.h
index b018e40..c9c46b9 100644
--- a/Src/DasherCore/Alphabet/AlphabetMap.h
+++ b/Src/DasherCore/Alphabet/AlphabetMap.h
@@ -20,7 +20,7 @@
 #include <string>
 
 namespace Dasher {
-  class alphabet_map;
+  class CAlphabetMap;
 } 
 
 /// \ingroup Alphabet
@@ -53,7 +53,7 @@ namespace Dasher {
 /// a standard hash_map would be hard.
 /// 
 /// Usage:
-/// alphabet_map MyMap(NumberOfEntriesWeExpect); // Can omit NumberOfEntriesWeExpect
+/// CAlphabetMap MyMap(NumberOfEntriesWeExpect); // Can omit NumberOfEntriesWeExpect
 /// MyMap.add("asdf", 15);
 /// symbol i = MyMap.get("asdf") // i=15
 /// symbol j = MyMap.get("fdsa") // j=0
@@ -61,18 +61,39 @@ namespace Dasher {
 /// You can't remove items once they are added as Dasher has no need for that.
 /// 
 /// IAM 08/2002
-class Dasher::alphabet_map {
+class Dasher::CAlphabetMap {
 
 public:
-  alphabet_map(unsigned int InitialTableSize = 255);
-  ~alphabet_map();
-  void Add(const std::string & Key, symbol Value);
+  ~CAlphabetMap();
 
   // Return the symbol associated with Key or Undefined.
   symbol Get(const std::string & Key) const;
   symbol GetSingleChar(char key) const;
 
+  class SymbolStream {
+  public:
+    SymbolStream(const CAlphabetMap &_map, std::istream &_in);
+    symbol next();
+  private:
+    void readMore();
+    const CAlphabetMap &map;
+    char buf[1024];
+    int pos, len;
+    std::istream &in;
+  };
+  
+  // Fills Symbols with the symbols corresponding to Input. {{{ Note that this
+  // is not necessarily reversible by repeated use of GetText. Some text
+  // may not be recognised and so discarded. }}}
+  
+  void GetSymbols(std::vector<symbol> &Symbols, const std::string &Input) const;
+  //SymbolStream *GetSymbols(std::istream &in) const;
+  
 private:
+  friend class CAlphInfo;
+  CAlphabetMap(unsigned int InitialTableSize = 255);
+  void Add(const std::string & Key, symbol Value);
+
   class Entry {
   public:
     Entry(std::string Key, symbol Symbol, Entry * Next)
diff --git a/Src/DasherCore/AlphabetManager.cpp b/Src/DasherCore/AlphabetManager.cpp
index 9db092b..a9669fc 100644
--- a/Src/DasherCore/AlphabetManager.cpp
+++ b/Src/DasherCore/AlphabetManager.cpp
@@ -45,14 +45,14 @@ static char THIS_FILE[] = __FILE__;
 #endif
 #endif
 
-CAlphabetManager::CAlphabetManager(CDasherInterfaceBase *pInterface, CNodeCreationManager *pNCManager, CAlphabet *pAlphabet, CLanguageModel *pLanguageModel)
-  : m_pLanguageModel(pLanguageModel), m_pNCManager(pNCManager), m_pAlphabet(pAlphabet) {
+CAlphabetManager::CAlphabetManager(CDasherInterfaceBase *pInterface, CNodeCreationManager *pNCManager, const CAlphInfo *pAlphabet, const CAlphabetMap *pAlphabetMap, CLanguageModel *pLanguageModel)
+  : m_pLanguageModel(pLanguageModel), m_pNCManager(pNCManager), m_pAlphabet(pAlphabet), m_pAlphabetMap(pAlphabetMap) {
   m_pInterface = pInterface;
 
   m_iLearnContext = m_pLanguageModel->CreateEmptyContext();
 }
 
-const CAlphabet *CAlphabetManager::GetAlphabet() const {
+const CAlphInfo *CAlphabetManager::GetAlphabet() const {
   return m_pAlphabet;
 }
 
@@ -77,7 +77,7 @@ CAlphabetManager::CSymbolNode::CSymbolNode(CDasherNode *pParent, int iOffset, un
 CAlphabetManager::CGroupNode::CGroupNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CAlphabetManager *pMgr, const SGroupInfo *pGroup)
 : CAlphNode(pParent, iOffset, iLbnd, iHbnd,
             pGroup ? (pGroup->bVisible ? pGroup->iColour : pParent->getColour())
-                   : pMgr->m_pAlphabet->GetColour(0, iOffset%2),
+            : iOffset%2 == 1 ? 140 : 10, //special case - was AlphInfo::GetColour for symbol _0_
             pGroup ? pGroup->strLabel : "", pMgr), m_pGroup(pGroup) {
 };
 
@@ -98,12 +98,12 @@ CAlphabetManager::CAlphNode *CAlphabetManager::GetRoot(CDasherNode *pParent, uns
   int iStart = max(0, iNewOffset - m_pLanguageModel->GetContextLength());
   
   if(pParent) {
-    pParent->GetContext(m_pInterface, m_pAlphabet, vContextSymbols, iStart, iNewOffset+1 - iStart);
+    pParent->GetContext(m_pInterface, m_pAlphabetMap, vContextSymbols, iStart, iNewOffset+1 - iStart);
   } else {
     std::string strContext = (iNewOffset == -1) 
       ? m_pAlphabet->GetDefaultContext()
       : m_pInterface->GetContext(iStart, iNewOffset+1 - iStart);
-    m_pAlphabet->GetSymbols(vContextSymbols, strContext);
+    m_pAlphabetMap->GetSymbols(vContextSymbols, strContext);
   }
   
   CAlphNode *pNewNode;
@@ -123,7 +123,7 @@ CAlphabetManager::CAlphNode *CAlphabetManager::GetRoot(CDasherNode *pParent, uns
     bEnteredLast=false;
     //instead, Create a node as if we were starting a new sentence...
     vContextSymbols.clear();
-    m_pAlphabet->GetSymbols(vContextSymbols, m_pAlphabet->GetDefaultContext());
+    m_pAlphabetMap->GetSymbols(vContextSymbols, m_pAlphabet->GetDefaultContext());
     it = vContextSymbols.begin();
     //TODO: What it the default context somehow contains symbols not in the alphabet?
   }
@@ -168,12 +168,12 @@ CLanguageModel::Context CAlphabetManager::CAlphNode::CloneAlphContext(CLanguageM
   return CDasherNode::CloneAlphContext(pLanguageModel);
 }
 
-void CAlphabetManager::CSymbolNode::GetContext(CDasherInterfaceBase *pInterface, const CAlphabet *pAlphabet, vector<symbol> &vContextSymbols, int iOffset, int iLength) {
+void CAlphabetManager::CSymbolNode::GetContext(CDasherInterfaceBase *pInterface, const CAlphabetMap *pAlphabetMap, vector<symbol> &vContextSymbols, int iOffset, int iLength) {
   if (!GetFlag(NF_SEEN) && iOffset+iLength-1 == offset()) {
-    if (iLength > 1) Parent()->GetContext(pInterface, pAlphabet, vContextSymbols, iOffset, iLength-1);
+    if (iLength > 1) Parent()->GetContext(pInterface, pAlphabetMap, vContextSymbols, iOffset, iLength-1);
     vContextSymbols.push_back(iSymbol);
   } else {
-    CDasherNode::GetContext(pInterface, pAlphabet, vContextSymbols, iOffset, iLength);
+    CDasherNode::GetContext(pInterface, pAlphabetMap, vContextSymbols, iOffset, iLength);
   }
 }
 
@@ -185,11 +185,12 @@ void CAlphabetManager::CSymbolNode::PopulateChildren() {
   m_pMgr->IterateChildGroups(this, NULL, NULL);
 }
 int CAlphabetManager::CAlphNode::ExpectedNumChildren() {
-  return m_pMgr->m_pAlphabet->iNumChildNodes;
+  int i=m_pMgr->m_pAlphabet->iNumChildNodes;
+  return (m_pMgr->m_pNCManager->GetBoolParameter(BP_CONTROL_MODE)) ? i+1 : i;
 }
 
 void CAlphabetManager::GetProbs(vector<unsigned int> *pProbInfo, CLanguageModel::Context context) {
-  const unsigned int iSymbols = m_pAlphabet->GetNumberTextSymbols() - 1;      // lose the root node
+  const unsigned int iSymbols = m_pAlphabet->GetNumberTextSymbols();
   unsigned long iNorm(m_pNCManager->GetLongParameter(LP_NORMALIZATION));
   
   // TODO - sort out size of control node - for the timebeing I'll fix the control node at 5%
@@ -211,7 +212,7 @@ void CAlphabetManager::GetProbs(vector<unsigned int> *pProbInfo, CLanguageModel:
   // to GetProbs as per ordinary language model, so no need to test....
   m_pLanguageModel->GetProbs(context, *pProbInfo, iNonUniformNorm, 0);
   
-  DASHER_ASSERT(pProbInfo->size() == m_pAlphabet->GetNumberTextSymbols());
+  DASHER_ASSERT(pProbInfo->size() == m_pAlphabet->GetNumberTextSymbols()+1);//initial 0
   
   for(unsigned int k(1); k < pProbInfo->size(); ++k)
     (*pProbInfo)[k] += iUniformAdd;
@@ -334,7 +335,7 @@ void CAlphabetManager::IterateChildGroups(CAlphNode *pParent, const SGroupInfo *
   std::vector<unsigned int> *pCProb(pParent->GetProbInfo());
   DASHER_ASSERT((*pCProb)[0] == 0);
   const int iMin(pParentGroup ? pParentGroup->iStart : 1);
-  const int iMax(pParentGroup ? pParentGroup->iEnd : m_pAlphabet->GetNumberTextSymbols());
+  const int iMax(pParentGroup ? pParentGroup->iEnd : m_pAlphabet->GetNumberTextSymbols()+1);
   unsigned int iRange(pParentGroup ? ((*pCProb)[iMax-1] - (*pCProb)[iMin-1]) : m_pNCManager->GetLongParameter(LP_NORMALIZATION));
   
   // TODO: Think through alphabet file formats etc. to make this class easier.
diff --git a/Src/DasherCore/AlphabetManager.h b/Src/DasherCore/AlphabetManager.h
index 6680b1c..cafa89a 100644
--- a/Src/DasherCore/AlphabetManager.h
+++ b/Src/DasherCore/AlphabetManager.h
@@ -44,7 +44,7 @@ namespace Dasher {
   class CAlphabetManager : public CNodeManager {
   public:
 
-    CAlphabetManager(CDasherInterfaceBase *pInterface, CNodeCreationManager *pNCManager, CAlphabet *pAlphabet, CLanguageModel *pLanguageModel);
+    CAlphabetManager(CDasherInterfaceBase *pInterface, CNodeCreationManager *pNCManager, const CAlphInfo *pAlphabet, const CAlphabetMap *pAlphabetMap, CLanguageModel *pLanguageModel);
     virtual ~CAlphabetManager();
 
   protected:
@@ -87,7 +87,7 @@ namespace Dasher {
       virtual void SetFlag(int iFlag, bool bValue);
 
       virtual bool GameSearchNode(std::string strTargetUtf8Char);
-      virtual void GetContext(CDasherInterfaceBase *pInterface, const CAlphabet *pAlphabet, std::vector<symbol> &vContextSymbols, int iOffset, int iLength);
+      virtual void GetContext(CDasherInterfaceBase *pInterface, const CAlphabetMap *pAlphabetMap, std::vector<symbol> &vContextSymbols, int iOffset, int iLength);
       virtual symbol GetAlphSymbol();
       const symbol iSymbol;
       virtual CDasherNode *RebuildSymbol(CAlphNode *pParent, symbol iSymbol, unsigned int iLbnd, unsigned int iHbnd);
@@ -125,7 +125,7 @@ namespace Dasher {
     /// will enter. (Also used to build context for preceding characters.)
     virtual CAlphNode *GetRoot(CDasherNode *pParent, unsigned int iLower, unsigned int iUpper, bool bEnteredLast, int iOffset);
 
-    const CAlphabet *GetAlphabet() const;
+    const CAlphInfo *GetAlphabet() const;
   protected:
     ///
     /// Factory method for CAlphNode construction, so subclasses can override.
@@ -143,7 +143,8 @@ namespace Dasher {
 
     CLanguageModel *m_pLanguageModel;
     CNodeCreationManager *m_pNCManager;
-    const CAlphabet *m_pAlphabet;
+    const CAlphInfo *m_pAlphabet;
+    const CAlphabetMap *m_pAlphabetMap;
 
   private:
     ///Wraps m_pLanguageModel->GetProbs to implement nonuniformity & leave space for control node.
diff --git a/Src/DasherCore/CannaConversionHelper.cpp b/Src/DasherCore/CannaConversionHelper.cpp
index 4ffcde0..c2867d8 100644
--- a/Src/DasherCore/CannaConversionHelper.cpp
+++ b/Src/DasherCore/CannaConversionHelper.cpp
@@ -14,7 +14,7 @@
 
 using namespace Dasher;
 
-CCannaConversionHelper::CCannaConversionHelper(CNodeCreationManager *pNCManager, CAlphabet *pAlphabet, int Type, int Order)
+CCannaConversionHelper::CCannaConversionHelper(CNodeCreationManager *pNCManager, const CAlphInfo *pAlphabet, int Type, int Order)
 : CConversionHelper(pNCManager, pAlphabet) {
 
   int ret;
diff --git a/Src/DasherCore/CannaConversionHelper.h b/Src/DasherCore/CannaConversionHelper.h
index 3e5b132..7b28f58 100644
--- a/Src/DasherCore/CannaConversionHelper.h
+++ b/Src/DasherCore/CannaConversionHelper.h
@@ -11,7 +11,7 @@
 /// @{
 class CCannaConversionHelper : public Dasher::CConversionHelper {
  public:
-  CCannaConversionHelper(CNodeCreationManager *pNCManager, Dasher::CAlphabet *pAlphabet, int Type, int Order);
+  CCannaConversionHelper(CNodeCreationManager *pNCManager, Dasher::const CAlphInfo *pAlphabet, int Type, int Order);
   ~CCannaConversionHelper();
 
   virtual bool Convert(const std::string &strSource, SCENode ** pRoot);
diff --git a/Src/DasherCore/ConversionHelper.cpp b/Src/DasherCore/ConversionHelper.cpp
index 4fe6d84..257f827 100644
--- a/Src/DasherCore/ConversionHelper.cpp
+++ b/Src/DasherCore/ConversionHelper.cpp
@@ -40,7 +40,7 @@
 using namespace Dasher;
 using namespace std;
 
-CConversionHelper::CConversionHelper(CNodeCreationManager *pNCManager, CAlphabet *pAlphabet, CLanguageModel *pLanguageModel) :
+CConversionHelper::CConversionHelper(CNodeCreationManager *pNCManager, const CAlphInfo *pAlphabet, CLanguageModel *pLanguageModel) :
   CConversionManager(pNCManager, pAlphabet), m_pLanguageModel(pLanguageModel) {
 	  colourStore[0][0]=66;//light blue
 	  colourStore[0][1]=64;//very light green
diff --git a/Src/DasherCore/ConversionHelper.h b/Src/DasherCore/ConversionHelper.h
index 76080b8..f13701d 100644
--- a/Src/DasherCore/ConversionHelper.h
+++ b/Src/DasherCore/ConversionHelper.h
@@ -43,7 +43,7 @@ namespace Dasher{
 ///
   class CConversionHelper : public CConversionManager {
   public:
-	CConversionHelper(CNodeCreationManager *pNCManager, CAlphabet *pAlphabet, CLanguageModel *pLanguageModel);
+	CConversionHelper(CNodeCreationManager *pNCManager, const CAlphInfo *pAlphabet, CLanguageModel *pLanguageModel);
 	
 	/// Convert a given string to a lattice of candidates. Sizes for
 	/// candidates aren't assigned at this point. The input string
diff --git a/Src/DasherCore/ConversionManager.cpp b/Src/DasherCore/ConversionManager.cpp
index 1fbeeaa..65b0755 100644
--- a/Src/DasherCore/ConversionManager.cpp
+++ b/Src/DasherCore/ConversionManager.cpp
@@ -40,7 +40,7 @@
 using namespace Dasher;
 using namespace std;
 
-CConversionManager::CConversionManager(CNodeCreationManager *pNCManager, CAlphabet *pAlphabet) {
+CConversionManager::CConversionManager(CNodeCreationManager *pNCManager, const CAlphInfo *pAlphabet) {
 
   m_pNCManager = pNCManager;
   m_pAlphabet = pAlphabet;
@@ -121,7 +121,7 @@ void CConversionManager::RecursiveDumpTree(SCENode *pCurrent, unsigned int iDept
   }
 }
 
-void CConversionManager::CConvNode::GetContext(CDasherInterfaceBase *pInterface, const CAlphabet *pAlphabet, std::vector<symbol> &vContextSymbols, int iOffset, int iLength) {
+void CConversionManager::CConvNode::GetContext(CDasherInterfaceBase *pInterface, const CAlphabetMap *pAlphabetMap, std::vector<symbol> &vContextSymbols, int iOffset, int iLength) {
   if (!GetFlag(NF_SEEN) && iOffset+iLength-1 == offset()) {
     //ACL I'm extrapolating from PinYinConversionHelper (in which root nodes have their
     // Symbol set by SetConvSymbol, and child nodes are created in PopulateChildren
@@ -131,12 +131,12 @@ void CConversionManager::CConvNode::GetContext(CDasherInterfaceBase *pInterface,
     // everywhere!)
     DASHER_ASSERT(bisRoot || pSCENode);
     if (bisRoot || pSCENode->Symbol!=-1) {
-      if (iLength>1) Parent()->GetContext(pInterface, pAlphabet, vContextSymbols, iOffset, iLength-1);
+      if (iLength>1) Parent()->GetContext(pInterface, pAlphabetMap, vContextSymbols, iOffset, iLength-1);
       vContextSymbols.push_back(bisRoot ? iSymbol : pSCENode->Symbol);
       return;
     } //else, non-root with pSCENode->Symbol==-1 => fallthrough back to superclass code
   }
-  CDasherNode::GetContext(pInterface, pAlphabet, vContextSymbols, iOffset, iLength);
+  CDasherNode::GetContext(pInterface, pAlphabetMap, vContextSymbols, iOffset, iLength);
 }
 
 void CConversionManager::CConvNode::Output(Dasher::VECTOR_SYMBOL_PROB* pAdded, int iNormalization) {
diff --git a/Src/DasherCore/ConversionManager.h b/Src/DasherCore/ConversionManager.h
index a72f54c..72ae66e 100644
--- a/Src/DasherCore/ConversionManager.h
+++ b/Src/DasherCore/ConversionManager.h
@@ -60,7 +60,7 @@ namespace Dasher {
   class CConversionManager : public CNodeManager {
   public:
     // TODO: We shouldn't need to know about this stuff, but the code is somewhat in knots at the moment
-    CConversionManager(CNodeCreationManager *pNCManager, CAlphabet *pAlphabet);
+    CConversionManager(CNodeCreationManager *pNCManager, const CAlphInfo *pAlphabet);
     
     ///
     /// Decrement reference count
@@ -93,7 +93,7 @@ namespace Dasher {
     ~CConvNode();
 
     ///Attempts to fill vContextSymbols with the context that would exist _after_ this node has been entered
-    void GetContext(CDasherInterfaceBase *pInterface, const CAlphabet *pAlphabet, std::vector<symbol> &vContextSymbols, int iOffset, int iLength);
+    void GetContext(CDasherInterfaceBase *pInterface, const CAlphabetMap *pAlphabetMap, std::vector<symbol> &vContextSymbols, int iOffset, int iLength);
 
     ///
     /// Called whenever a node belonging to this manager first 
@@ -134,7 +134,7 @@ namespace Dasher {
 
 	  
 	CNodeCreationManager *m_pNCManager;
-	CAlphabet *m_pAlphabet;
+	const CAlphInfo *m_pAlphabet;
 	
   private:
 
diff --git a/Src/DasherCore/ConvertingAlphMgr.cpp b/Src/DasherCore/ConvertingAlphMgr.cpp
index 6b2158d..8c48e99 100644
--- a/Src/DasherCore/ConvertingAlphMgr.cpp
+++ b/Src/DasherCore/ConvertingAlphMgr.cpp
@@ -12,8 +12,8 @@
 
 using namespace Dasher;
 
-CConvertingAlphMgr::CConvertingAlphMgr(CDasherInterfaceBase *pInterface, CNodeCreationManager *pNCManager, CConversionManager *pConvMgr, CAlphabet *pAlphabet, CLanguageModel *pLanguageModel)
- : CAlphabetManager(pInterface, pNCManager, pAlphabet, pLanguageModel), m_pConvMgr(pConvMgr) {
+CConvertingAlphMgr::CConvertingAlphMgr(CDasherInterfaceBase *pInterface, CNodeCreationManager *pNCManager, CConversionManager *pConvMgr, const CAlphInfo *pAlphabet, const CAlphabetMap *pAlphabetMap, CLanguageModel *pLanguageModel)
+ : CAlphabetManager(pInterface, pNCManager, pAlphabet, pAlphabetMap, pLanguageModel), m_pConvMgr(pConvMgr) {
  }
 
 CConvertingAlphMgr::~CConvertingAlphMgr() {
@@ -22,7 +22,7 @@ CConvertingAlphMgr::~CConvertingAlphMgr() {
 
 void CConvertingAlphMgr::AddExtras(CAlphNode *pParent, std::vector<unsigned int> *pCProb) {
     //should have another probability....
-  const unsigned int i(m_pNCManager->GetAlphabet()->GetNumberTextSymbols());
+  const unsigned int i(m_pNCManager->GetAlphabet()->GetNumberTextSymbols()+1);
   DASHER_ASSERT(pCProb->size() == i+1);
   //ACL setting m_iOffset+1 for consistency with "proper" symbol nodes...
   m_pConvMgr->GetRoot(pParent, (*pCProb)[i-1], (*pCProb)[i], pParent->offset()+1);
diff --git a/Src/DasherCore/ConvertingAlphMgr.h b/Src/DasherCore/ConvertingAlphMgr.h
index a6a3ae0..86495b5 100644
--- a/Src/DasherCore/ConvertingAlphMgr.h
+++ b/Src/DasherCore/ConvertingAlphMgr.h
@@ -16,7 +16,7 @@
 namespace Dasher {
   class CConvertingAlphMgr : public CAlphabetManager {
   public:
-    CConvertingAlphMgr(CDasherInterfaceBase *pInterface, CNodeCreationManager *pNCManager, CConversionManager *pConvMgr, CAlphabet *pAlphabet, CLanguageModel *pLanguageModel);
+    CConvertingAlphMgr(CDasherInterfaceBase *pInterface, CNodeCreationManager *pNCManager, CConversionManager *pConvMgr, const CAlphInfo *pAlphabet, const CAlphabetMap *pAlphabetMap, CLanguageModel *pLanguageModel);
     virtual ~CConvertingAlphMgr();
   protected:
     void AddExtras(CAlphNode *pParent, std::vector<unsigned int> *pCProb);
diff --git a/Src/DasherCore/DasherInterfaceBase.cpp b/Src/DasherCore/DasherInterfaceBase.cpp
index f446a05..9b26865 100644
--- a/Src/DasherCore/DasherInterfaceBase.cpp
+++ b/Src/DasherCore/DasherInterfaceBase.cpp
@@ -138,7 +138,7 @@ void CDasherInterfaceBase::Realize() {
 
   std::vector<std::string> vAlphabetFiles;
   ScanAlphabetFiles(vAlphabetFiles);
-  m_AlphIO = new CAlphIO(GetStringParameter(SP_SYSTEM_LOC), GetStringParameter(SP_USER_LOC), vAlphabetFiles);
+  m_AlphIO = new CAlphInfo::AlphIO(GetStringParameter(SP_SYSTEM_LOC), GetStringParameter(SP_USER_LOC), vAlphabetFiles);
 
   std::vector<std::string> vColourFiles;
   ScanColourFiles(vColourFiles);
@@ -348,7 +348,7 @@ void CDasherInterfaceBase::InterfaceEventHandler(Dasher::CEvent *pEvent) {
       if(GetBoolParameter(BP_LM_ADAPTIVE))
 	 strTrainfileBuffer += pEditEvent->m_sText;
       if (GetBoolParameter(BP_SPEAK_WORDS) && SupportsSpeech()) {
-        const CAlphabet *pAlphabet = m_pNCManager->GetAlphabet();
+        const CAlphInfo *pAlphabet = m_pNCManager->GetAlphabet();
         if (pEditEvent->m_sText == pAlphabet->GetText(pAlphabet->GetSpaceSymbol())) {
           Speak(m_strCurrentWord, false);
           m_strCurrentWord="";
@@ -674,11 +674,11 @@ void CDasherInterfaceBase::ChangeView() {
   }
 }
 
-const CAlphIO::AlphInfo & CDasherInterfaceBase::GetInfo(const std::string &AlphID) {
+const CAlphInfo *CDasherInterfaceBase::GetInfo(const std::string &AlphID) {
   return m_AlphIO->GetInfo(AlphID);
 }
 
-void CDasherInterfaceBase::SetInfo(const CAlphIO::AlphInfo &NewInfo) {
+void CDasherInterfaceBase::SetInfo(const CAlphInfo *NewInfo) {
   m_AlphIO->SetInfo(NewInfo);
 }
 
diff --git a/Src/DasherCore/DasherInterfaceBase.h b/Src/DasherCore/DasherInterfaceBase.h
index 0ed8f40..3c9e63e 100644
--- a/Src/DasherCore/DasherInterfaceBase.h
+++ b/Src/DasherCore/DasherInterfaceBase.h
@@ -34,7 +34,6 @@
 #include "../Common/NoClones.h"
 #include "../Common/ModuleSettings.h"
 #include "ActionButton.h"
-#include "Alphabet/Alphabet.h"
 #include "Alphabet/AlphIO.h"
 #include "AutoSpeedControl.h"
 #include "ColourIO.h"
@@ -94,11 +93,11 @@ public:
   /// \todo Document this
   ///
 
-  const CAlphIO::AlphInfo & GetInfo(const std::string & AlphID);
+  const CAlphInfo *GetInfo(const std::string & AlphID);
 
   /// \todo Document this
 
-  void SetInfo(const CAlphIO::AlphInfo & NewInfo);
+  void SetInfo(const CAlphInfo *NewInfo);
 
   /// \todo Document this
 
@@ -586,7 +585,7 @@ protected:
   CDasherInput *m_pInput;
   CInputFilter* m_pInputFilter;
   CModuleManager m_oModuleManager;
-  CAlphIO *m_AlphIO;
+  CAlphInfo::AlphIO *m_AlphIO;
   CColourIO *m_ColourIO;
   CNodeCreationManager *m_pNCManager;
   CUserLogBase *m_pUserLog; 
diff --git a/Src/DasherCore/DasherNode.cpp b/Src/DasherCore/DasherNode.cpp
index cb0f00c..742862d 100644
--- a/Src/DasherCore/DasherNode.cpp
+++ b/Src/DasherCore/DasherNode.cpp
@@ -96,7 +96,7 @@ void CDasherNode::Trace() const {
    */
 }
 
-void CDasherNode::GetContext(CDasherInterfaceBase *pInterface, const CAlphabet *pAlphabet, vector<symbol> &vContextSymbols, int iOffset, int iLength) {
+void CDasherNode::GetContext(CDasherInterfaceBase *pInterface, const CAlphabetMap *pAlphabet, vector<symbol> &vContextSymbols, int iOffset, int iLength) {
   if (!GetFlag(NF_SEEN)) {
     DASHER_ASSERT(m_pParent);
     if (m_pParent) m_pParent->GetContext(pInterface, pAlphabet, vContextSymbols, iOffset,iLength);
diff --git a/Src/DasherCore/DasherNode.h b/Src/DasherCore/DasherNode.h
index 9523014..51e2d83 100644
--- a/Src/DasherCore/DasherNode.h
+++ b/Src/DasherCore/DasherNode.h
@@ -246,7 +246,7 @@ class Dasher::CDasherNode:private NoClones {
   /// Get as many symbols of context, up to the _end_ of the specified range,
   /// as possible from this node and its uncommitted ancestors
   ///
-  virtual void GetContext(CDasherInterfaceBase *pInterface, const CAlphabet *pAlphabet, std::vector<symbol> &vContextSymbols, int iOffset, int iLength);
+  virtual void GetContext(CDasherInterfaceBase *pInterface, const CAlphabetMap *pAlphabetMap, std::vector<symbol> &vContextSymbols, int iOffset, int iLength);
   
   ///
   /// See if this node represents the specified alphanumeric character; if so, set it's NF_GAME flag and
diff --git a/Src/DasherCore/IMEConversionHelper.cpp b/Src/DasherCore/IMEConversionHelper.cpp
index 3e40373..f386d67 100644
--- a/Src/DasherCore/IMEConversionHelper.cpp
+++ b/Src/DasherCore/IMEConversionHelper.cpp
@@ -7,7 +7,7 @@
 
 #include <iostream>             //For testing 23 June 2005
 
-CIMEConversionHelper::CIMEConversionHelper(Dasher::CNodeCreationManager *pNCManager, Dasher::CAlphabet *pAlphabet)
+CIMEConversionHelper::CIMEConversionHelper(Dasher::CNodeCreationManager *pNCManager, Dasher::const CAlphInfo *pAlphabet)
  : CConversionHelper(pNCManager, pAlphabet) {
   IsInit = 0;
   hIMC = ImmCreateContext();
diff --git a/Src/DasherCore/IMEConversionHelper.h b/Src/DasherCore/IMEConversionHelper.h
index 3f47aea..20ae7c0 100644
--- a/Src/DasherCore/IMEConversionHelper.h
+++ b/Src/DasherCore/IMEConversionHelper.h
@@ -9,7 +9,7 @@
 /// \{
 class CIMEConversionHelper : public CConversionHelper {
  public:
-  CIMEConversionHelper(CNodeCreationManager *pNCManager, CAlphabet *pAlphabet);
+  CIMEConversionHelper(CNodeCreationManager *pNCManager, const CAlphInfo *pAlphabet);
   ~CIMEConversionHelper();
 
   virtual bool Convert(const std::string &strSource, std::vector<std::vector<std::string> > &vResult);
diff --git a/Src/DasherCore/LanguageModelling/BigramLanguageModel.cpp b/Src/DasherCore/LanguageModelling/BigramLanguageModel.cpp
index a46a0c2..cb287d7 100644
--- a/Src/DasherCore/LanguageModelling/BigramLanguageModel.cpp
+++ b/Src/DasherCore/LanguageModelling/BigramLanguageModel.cpp
@@ -23,7 +23,7 @@ static char THIS_FILE[] = __FILE__;
 
 /////////////////////////////////////////////////////////////////////////////
 
-CBigramLanguageModel::CBigramLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphabet *pAlph)
+CBigramLanguageModel::CBigramLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphInfo *pAlph)
 :CLanguageModel(pEventHandler, pSettingsStore, pAlph), m_ContextAlloc(1024) {
 
 }
diff --git a/Src/DasherCore/LanguageModelling/BigramLanguageModel.h b/Src/DasherCore/LanguageModelling/BigramLanguageModel.h
index cd97829..b362ec7 100644
--- a/Src/DasherCore/LanguageModelling/BigramLanguageModel.h
+++ b/Src/DasherCore/LanguageModelling/BigramLanguageModel.h
@@ -25,7 +25,7 @@ namespace Dasher {
   /// \{
   class CBigramLanguageModel:public CLanguageModel, private NoClones {
   public:
-    CBigramLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphabet *pAlph);
+    CBigramLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphInfo *pAlph);
       virtual ~ CBigramLanguageModel();
 
     Context CreateEmptyContext();
diff --git a/Src/DasherCore/LanguageModelling/CTWLanguageModel.cpp b/Src/DasherCore/LanguageModelling/CTWLanguageModel.cpp
index 91503f0..62e1989 100644
--- a/Src/DasherCore/LanguageModelling/CTWLanguageModel.cpp
+++ b/Src/DasherCore/LanguageModelling/CTWLanguageModel.cpp
@@ -40,7 +40,7 @@ static char THIS_FILE[] = __FILE__;
 #endif
 
 
-CCTWLanguageModel::CCTWLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphabet *pAlph)
+CCTWLanguageModel::CCTWLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphInfo *pAlph)
 :CLanguageModel(pEventHandler, pSettingsStore, pAlph){
 
 	Dasher::CHashTable HashTable;  // create hashtable
diff --git a/Src/DasherCore/LanguageModelling/CTWLanguageModel.h b/Src/DasherCore/LanguageModelling/CTWLanguageModel.h
index e557b24..d151430 100644
--- a/Src/DasherCore/LanguageModelling/CTWLanguageModel.h
+++ b/Src/DasherCore/LanguageModelling/CTWLanguageModel.h
@@ -39,7 +39,7 @@ namespace Dasher {
   // CTW language model 
   class CCTWLanguageModel: public CLanguageModel {
   public:    
-	CCTWLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphabet *pAlph);
+	CCTWLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphInfo *pAlph);
 	virtual ~ CCTWLanguageModel(); 
 
     Context CreateEmptyContext();			
diff --git a/Src/DasherCore/LanguageModelling/DictLanguageModel.cpp b/Src/DasherCore/LanguageModelling/DictLanguageModel.cpp
index a4cd9b4..34b99b8 100644
--- a/Src/DasherCore/LanguageModelling/DictLanguageModel.cpp
+++ b/Src/DasherCore/LanguageModelling/DictLanguageModel.cpp
@@ -8,7 +8,7 @@
 
 #include "../../Common/Common.h"
 #include "DictLanguageModel.h"
-#include "../Alphabet/Alphabet.h"
+#include "../Alphabet/AlphabetMap.h"
 
 #include <climits>
 #include <cmath>
@@ -90,8 +90,8 @@ CDictLanguageModel::CDictnode * CDictLanguageModel::AddSymbolToNode(CDictnode *p
 // CDictLanguageModel defs
 /////////////////////////////////////////////////////////////////////
 
-CDictLanguageModel::CDictLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphabet *pAlph)
-:CLanguageModel(pEventHandler, pSettingsStore, pAlph), NodesAllocated(0), max_order(0), m_NodeAlloc(8192), m_ContextAlloc(1024) {
+CDictLanguageModel::CDictLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphInfo *pAlph, const CAlphabetMap *pAlphMap)
+:CLanguageModel(pEventHandler, pSettingsStore, pAlph), m_pAlphMap(pAlphMap), NodesAllocated(0), max_order(0), m_NodeAlloc(8192), m_ContextAlloc(1024) {
   m_pRoot = m_NodeAlloc.Alloc();
   m_pRoot->sbl = -1;
   m_rootcontext = new CDictContext(m_pRoot, 0);
@@ -114,7 +114,7 @@ CDictLanguageModel::CDictLanguageModel(Dasher::CEventHandler *pEventHandler, CSe
     //      std::cout << m_pAlphabet << std::endl;
 
     std::vector < symbol > Symbols;
-    m_pAlphabet->GetSymbols(Symbols, CurrentWord);
+    m_pAlphMap->GetSymbols(Symbols, CurrentWord);
 
     for(std::vector < symbol >::iterator it(Symbols.begin()); it != Symbols.end(); ++it) {
       MyLearnSymbol(TempContext, *it);
diff --git a/Src/DasherCore/LanguageModelling/DictLanguageModel.h b/Src/DasherCore/LanguageModelling/DictLanguageModel.h
index 44fbdcb..d1911c5 100644
--- a/Src/DasherCore/LanguageModelling/DictLanguageModel.h
+++ b/Src/DasherCore/LanguageModelling/DictLanguageModel.h
@@ -28,7 +28,7 @@ namespace Dasher {
   /// \{
   class CDictLanguageModel:public CLanguageModel {
   public:
-    CDictLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphabet *pAlph);
+    CDictLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphInfo *pAlph, const CAlphabetMap *pAlphMap);
     virtual ~CDictLanguageModel();
 
     Context CreateEmptyContext();
@@ -80,6 +80,8 @@ namespace Dasher {
       int word_order;
 
     };
+    
+    const CAlphabetMap *m_pAlphMap;
 
     CDictnode *AddSymbolToNode(CDictnode * pNode, symbol sym, int *update);
 
diff --git a/Src/DasherCore/LanguageModelling/JapaneseLanguageModel.cpp b/Src/DasherCore/LanguageModelling/JapaneseLanguageModel.cpp
index 5aa6a42..cc44e43 100644
--- a/Src/DasherCore/LanguageModelling/JapaneseLanguageModel.cpp
+++ b/Src/DasherCore/LanguageModelling/JapaneseLanguageModel.cpp
@@ -38,7 +38,7 @@ static char THIS_FILE[] = __FILE__;
 
 /////////////////////////////////////////////////////////////////////
 
-CJapaneseLanguageModel::CJapaneseLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphabet *pAlph)
+CJapaneseLanguageModel::CJapaneseLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphInfo *pAlph)
 :CLanguageModel(pEventHandler, pSettingsStore, pAlph), m_iMaxOrder(5), NodesAllocated(0), m_NodeAlloc(8192), m_ContextAlloc(1024) {
   m_pRoot = m_NodeAlloc.Alloc();
   m_pRoot->symbol = -1;
diff --git a/Src/DasherCore/LanguageModelling/JapaneseLanguageModel.h b/Src/DasherCore/LanguageModelling/JapaneseLanguageModel.h
index 034d791..5b1f130 100644
--- a/Src/DasherCore/LanguageModelling/JapaneseLanguageModel.h
+++ b/Src/DasherCore/LanguageModelling/JapaneseLanguageModel.h
@@ -21,7 +21,7 @@ namespace Dasher {
   /// \{
   class CJapaneseLanguageModel:public CLanguageModel, private NoClones {
   public:
-    CJapaneseLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphabet *pAlph);
+    CJapaneseLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphInfo *pAlph);
 
     virtual ~ CJapaneseLanguageModel();
 
diff --git a/Src/DasherCore/LanguageModelling/LanguageModel.cpp b/Src/DasherCore/LanguageModelling/LanguageModel.cpp
index 541bd32..1422d6d 100644
--- a/Src/DasherCore/LanguageModelling/LanguageModel.cpp
+++ b/Src/DasherCore/LanguageModelling/LanguageModel.cpp
@@ -9,7 +9,7 @@
 #include "../../Common/Common.h"
 
 #include "LanguageModel.h"
-#include "../Alphabet/Alphabet.h"
+#include "../Alphabet/AlphabetMap.h"
 
 /////////////////////////////////////////////////////////////////////////////
 
@@ -27,7 +27,7 @@ static char THIS_FILE[] = __FILE__;
 
 ///////////////////////////////////////////////////////////////////
 
-CLanguageModel::CLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphabet *pAlph)
+CLanguageModel::CLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphInfo *pAlph)
   :CDasherComponent(pEventHandler, pSettingsStore), m_pAlphabet(pAlph) {
 }
 
diff --git a/Src/DasherCore/LanguageModelling/LanguageModel.h b/Src/DasherCore/LanguageModelling/LanguageModel.h
index 28365d0..e23c307 100644
--- a/Src/DasherCore/LanguageModelling/LanguageModel.h
+++ b/Src/DasherCore/LanguageModelling/LanguageModel.h
@@ -11,7 +11,7 @@
 
 #include "../DasherTypes.h"
 
-#include "../Alphabet/Alphabet.h"
+#include "../Alphabet/AlphIO.h"
 #include "../DasherComponent.h"
 #include <vector>
 
@@ -36,7 +36,7 @@ public:
 
   /////////////////////////////////////////////////////////////////////////////
 
-  CLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphabet *pAlph);
+  CLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphInfo *pAlph);
 
   virtual ~CLanguageModel() {};
 
@@ -145,11 +145,13 @@ public:
     // UTF-8 encoded alphabet name follows (variable length struct)
   };
 
+  ///Return the number of symbols over which we are making predictions, plus one
+  /// (to leave space for an initial 0).
   int GetSize() const {
-    return m_pAlphabet->GetNumberTextSymbols();
+    return m_pAlphabet->GetNumberTextSymbols()+1;
   }
 
-  const CAlphabet *m_pAlphabet;
+  const CAlphInfo *m_pAlphabet;
 
 };
 
diff --git a/Src/DasherCore/LanguageModelling/MixtureLanguageModel.h b/Src/DasherCore/LanguageModelling/MixtureLanguageModel.h
index 7bcee9a..b4b18cc 100644
--- a/Src/DasherCore/LanguageModelling/MixtureLanguageModel.h
+++ b/Src/DasherCore/LanguageModelling/MixtureLanguageModel.h
@@ -28,14 +28,14 @@ namespace Dasher {
 
     /////////////////////////////////////////////////////////////////////////////
 
-    CMixtureLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphabet *pAlph):CLanguageModel(pEventHandler, pSettingsStore, pAlph) {
+    CMixtureLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphInfo *pAlph, const CAlphabetMap *pAlphMap):CLanguageModel(pEventHandler, pSettingsStore, pAlph) {
 
       //      std::cout << m_pAlphabet << std::endl;
 
       NextContext = 0;
 
       lma = new CPPMLanguageModel(m_pEventHandler, m_pSettingsStore, m_pAlphabet);
-      lmb = new CDictLanguageModel(m_pEventHandler, m_pSettingsStore, m_pAlphabet);
+      lmb = new CDictLanguageModel(m_pEventHandler, m_pSettingsStore, m_pAlphabet, pAlphMap);
 
     };
 
diff --git a/Src/DasherCore/LanguageModelling/PPMLanguageModel.cpp b/Src/DasherCore/LanguageModelling/PPMLanguageModel.cpp
index 3e39120..07c3fc4 100644
--- a/Src/DasherCore/LanguageModelling/PPMLanguageModel.cpp
+++ b/Src/DasherCore/LanguageModelling/PPMLanguageModel.cpp
@@ -30,7 +30,7 @@ static char THIS_FILE[] = __FILE__;
 
 /////////////////////////////////////////////////////////////////////
 
-CPPMLanguageModel::CPPMLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphabet *pAlph)
+CPPMLanguageModel::CPPMLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphInfo *pAlph)
 :CLanguageModel(pEventHandler, pSettingsStore, pAlph), m_iMaxOrder(4), NodesAllocated(0), m_NodeAlloc(8192), m_ContextAlloc(1024) {
   m_pRoot = m_NodeAlloc.Alloc();
   m_pRoot->sym = -1;
diff --git a/Src/DasherCore/LanguageModelling/PPMLanguageModel.h b/Src/DasherCore/LanguageModelling/PPMLanguageModel.h
index 5765658..c151251 100644
--- a/Src/DasherCore/LanguageModelling/PPMLanguageModel.h
+++ b/Src/DasherCore/LanguageModelling/PPMLanguageModel.h
@@ -90,7 +90,7 @@ namespace Dasher {
       int order;
     };
   public:
-    CPPMLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphabet *pAlph);
+    CPPMLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphInfo *pAlph);
     bool eq(CPPMLanguageModel *other);
     virtual ~ CPPMLanguageModel();
 
diff --git a/Src/DasherCore/LanguageModelling/PPMPYLanguageModel.cpp b/Src/DasherCore/LanguageModelling/PPMPYLanguageModel.cpp
index 1b13cf5..1dae797 100644
--- a/Src/DasherCore/LanguageModelling/PPMPYLanguageModel.cpp
+++ b/Src/DasherCore/LanguageModelling/PPMPYLanguageModel.cpp
@@ -33,7 +33,7 @@ static char THIS_FILE[] = __FILE__;
 
 /////////////////////////////////////////////////////////////////////
 
-CPPMPYLanguageModel::CPPMPYLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphabet *pAlph, const CAlphabet *pPyAlphabet)
+CPPMPYLanguageModel::CPPMPYLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, const CAlphInfo *pAlph, const CAlphInfo *pPyAlphabet)
   :CLanguageModel(pEventHandler, pSettingsStore, pAlph), m_iMaxOrder(2), NodesAllocated(0), m_NodeAlloc(8192), m_ContextAlloc(1024), m_pPyAlphabet(pPyAlphabet){
   m_pRoot = m_NodeAlloc.Alloc();
   m_pRoot->symbol = -1;
@@ -48,8 +48,6 @@ CPPMPYLanguageModel::CPPMPYLanguageModel(Dasher::CEventHandler *pEventHandler, C
 
   m_iAlphSize = GetSize();
   //  std::cout<<"Alphaunit: "<<UNITALPH<<std::endl;
-  m_iPYAlphSize = m_pPyAlphabet->GetNumberTextSymbols();
-  //  std::cout<<"PYunit: "<<UNITPY<<std::endl;
   
   // Cache the result of update exclusion - otherwise we have to look up a lot when training, which is slow
 
@@ -327,7 +325,7 @@ void CPPMPYLanguageModel::GetProbs(Context context, std::vector<unsigned int> &p
   */
   //  DASHER_ASSERT(m_setContexts.count(ppmcontext) > 0);
 
-  int iNumSymbols = m_pPyAlphabet->GetNumberTextSymbols();
+  int iNumSymbols = m_pPyAlphabet->GetNumberTextSymbols()+1;
   
   probs.resize(iNumSymbols);
 
diff --git a/Src/DasherCore/LanguageModelling/PPMPYLanguageModel.h b/Src/DasherCore/LanguageModelling/PPMPYLanguageModel.h
index 38258dc..6d71436 100644
--- a/Src/DasherCore/LanguageModelling/PPMPYLanguageModel.h
+++ b/Src/DasherCore/LanguageModelling/PPMPYLanguageModel.h
@@ -75,7 +75,7 @@ namespace Dasher {
     };
 	  
   public:
-    CPPMPYLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphabet *pAlph, const CAlphabet *pPyAlph);
+    CPPMPYLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphInfo *pAlph, const CAlphInfo *pPyAlph);
 
     virtual ~ CPPMPYLanguageModel();
 
@@ -131,9 +131,8 @@ namespace Dasher {
 
   private:
 
-    const CAlphabet *m_pPyAlphabet;
+    const CAlphInfo *m_pPyAlphabet;
     int m_iAlphSize;
-    int m_iPYAlphSize;
 
   };
 
diff --git a/Src/DasherCore/LanguageModelling/WordLanguageModel.cpp b/Src/DasherCore/LanguageModelling/WordLanguageModel.cpp
index ec9ec9c..bb3eb9c 100644
--- a/Src/DasherCore/LanguageModelling/WordLanguageModel.cpp
+++ b/Src/DasherCore/LanguageModelling/WordLanguageModel.cpp
@@ -9,7 +9,7 @@
 #include "../../Common/Common.h"
 #include "WordLanguageModel.h"
 #include "PPMLanguageModel.h"
-#include "../Alphabet/Alphabet.h"
+#include "../Alphabet/AlphabetMap.h"
 
 
 #include <cmath>
@@ -122,8 +122,8 @@ CWordLanguageModel::CWordnode * CWordLanguageModel::AddSymbolToNode(CWordnode *p
 /////////////////////////////////////////////////////////////////////
 
 CWordLanguageModel::CWordLanguageModel(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, 
-				       const CAlphabet *pAlph)
-  :CLanguageModel(pEventHandler, pSettingsStore, pAlph), NodesAllocated(0), 
+				       const CAlphInfo *pAlph, const CAlphabetMap *pAlphMap)
+  :CLanguageModel(pEventHandler, pSettingsStore, pAlph), m_pAlphMap(pAlphMap), NodesAllocated(0), 
    max_order(2), m_NodeAlloc(8192), m_ContextAlloc(1024) {
   
   // Construct a root node for the trie
@@ -166,7 +166,7 @@ CWordLanguageModel::CWordLanguageModel(Dasher::CEventHandler *pEventHandler, CSe
       //      std::cout << m_pAlphabet << std::endl;
 
       std::vector < symbol > Symbols;
-      m_pAlphabet->GetSymbols(Symbols, CurrentWord);
+      m_pAlphMap->GetSymbols(Symbols, CurrentWord);
 
       for(std::vector < symbol >::iterator it(Symbols.begin()); it != Symbols.end(); ++it) {
         pSpellingModel->LearnSymbol(TempContext, *it);
diff --git a/Src/DasherCore/LanguageModelling/WordLanguageModel.h b/Src/DasherCore/LanguageModelling/WordLanguageModel.h
index 2154811..09746ad 100644
--- a/Src/DasherCore/LanguageModelling/WordLanguageModel.h
+++ b/Src/DasherCore/LanguageModelling/WordLanguageModel.h
@@ -35,7 +35,7 @@ namespace Dasher {
   ///
   class CWordLanguageModel:public CLanguageModel {
   public:
-    CWordLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphabet *pAlph);
+    CWordLanguageModel(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, const CAlphInfo *pAlph, const CAlphabetMap *pAlphMap);
       virtual ~ CWordLanguageModel();
 
     Context CreateEmptyContext();
@@ -113,6 +113,8 @@ namespace Dasher {
     int lookup_word(const std::string & w);
     int lookup_word_const(const std::string & w) const;
 
+    const CAlphabetMap *m_pAlphMap;
+    
     CWordContext *m_rootcontext;
     CWordnode *m_pRoot;
 
diff --git a/Src/DasherCore/Makefile.am b/Src/DasherCore/Makefile.am
index 5ca350a..34ca635 100644
--- a/Src/DasherCore/Makefile.am
+++ b/Src/DasherCore/Makefile.am
@@ -10,8 +10,6 @@ libdasherprefs_a_SOURCES = \
 libdashercore_a_SOURCES = \
 		Alphabet/AlphIO.cpp \
 		Alphabet/AlphIO.h \
-		Alphabet/Alphabet.cpp \
-		Alphabet/Alphabet.h \
 		Alphabet/AlphabetMap.cpp \
 		Alphabet/AlphabetMap.h \
 		Alphabet/GroupInfo.h \
diff --git a/Src/DasherCore/MandarinAlphMgr.cpp b/Src/DasherCore/MandarinAlphMgr.cpp
index 87d47d4..5819ff2 100644
--- a/Src/DasherCore/MandarinAlphMgr.cpp
+++ b/Src/DasherCore/MandarinAlphMgr.cpp
@@ -46,10 +46,11 @@ static char THIS_FILE[] = __FILE__;
 #endif
 #endif
 
-CMandarinAlphMgr::CMandarinAlphMgr(CDasherInterfaceBase *pInterface, CNodeCreationManager *pNCManager, CAlphabet *pAlphabet, CLanguageModel *pLanguageModel)
-  : CAlphabetManager(pInterface, pNCManager, pAlphabet, pLanguageModel),
+CMandarinAlphMgr::CMandarinAlphMgr(CDasherInterfaceBase *pInterface, CNodeCreationManager *pNCManager, const CAlphInfo *pAlphabet, const CAlphabetMap *pAlphMap, CLanguageModel *pLanguageModel)
+  : CAlphabetManager(pInterface, pNCManager, pAlphabet, pAlphMap, pLanguageModel),
     m_pParser(new CPinyinParser(pInterface->GetStringParameter(SP_SYSTEM_LOC) +"/alphabet.chineseRuby.xml")),
-    m_pCHAlphabet(new CAlphabet(pInterface->GetInfo("Chinese / ç®?ä½?中æ?? (simplified chinese, in pin yin groups)"))) {
+    m_pCHAlphabet(pInterface->GetInfo("Chinese / ç®?ä½?中æ?? (simplified chinese, in pin yin groups)")),
+    m_pCHAlphabetMap(m_pCHAlphabet->MakeMap()) {
 }
 
 CMandarinAlphMgr::~CMandarinAlphMgr() {
@@ -103,7 +104,7 @@ void CMandarinAlphMgr::CConvRoot::BuildConversions() {
   }
   for(set<string>::const_iterator it = m_pTrie->list()->begin(); it != m_pTrie->list()->end(); ++it) {
     std::vector<symbol> vSyms;
-    m_pMgr->m_pCHAlphabet->GetSymbols(vSyms, *it);
+    m_pMgr->m_pCHAlphabetMap->GetSymbols(vSyms, *it);
     DASHER_ASSERT(vSyms.size()==1); //does it ever happen? if so, Will's code would effectively push -1
     DASHER_ASSERT(m_pMgr->m_pCHAlphabet->GetText(vSyms[0]) == *it);
     m_vChInfo.push_back(std::pair<symbol, unsigned int>(vSyms[0],0));
diff --git a/Src/DasherCore/MandarinAlphMgr.h b/Src/DasherCore/MandarinAlphMgr.h
index 65be35e..1627ac9 100644
--- a/Src/DasherCore/MandarinAlphMgr.h
+++ b/Src/DasherCore/MandarinAlphMgr.h
@@ -36,7 +36,7 @@ namespace Dasher {
   class CMandarinAlphMgr : public CAlphabetManager {
   public:
 
-    CMandarinAlphMgr(CDasherInterfaceBase *pInterface, CNodeCreationManager *pNCManager, CAlphabet *pAlphabet, CLanguageModel *pLanguageModel);
+    CMandarinAlphMgr(CDasherInterfaceBase *pInterface, CNodeCreationManager *pNCManager, const CAlphInfo *pAlphabet, const CAlphabetMap *pAlphMap, CLanguageModel *pLanguageModel);
 
     virtual ~CMandarinAlphMgr();
     
@@ -90,7 +90,8 @@ namespace Dasher {
     
     void AssignSizes(std::vector<std::pair<symbol,unsigned int> > &vChildren, Dasher::CLanguageModel::Context context);
     CPinyinParser *m_pParser;
-    CAlphabet *m_pCHAlphabet;
+    const CAlphInfo *m_pCHAlphabet;
+    const CAlphabetMap *m_pCHAlphabetMap;
   };
   /// @}
 
diff --git a/Src/DasherCore/NodeCreationManager.cpp b/Src/DasherCore/NodeCreationManager.cpp
index 3e6a220..bf5c4b8 100644
--- a/Src/DasherCore/NodeCreationManager.cpp
+++ b/Src/DasherCore/NodeCreationManager.cpp
@@ -15,18 +15,18 @@
 using namespace Dasher;
 
 CNodeCreationManager::CNodeCreationManager(Dasher::CDasherInterfaceBase *pInterface,
-					   Dasher::CEventHandler *pEventHandler, 
-					   CSettingsStore *pSettingsStore,
-					   Dasher::CAlphIO *pAlphIO) : CDasherComponent(pEventHandler, pSettingsStore),
+                                           Dasher::CEventHandler *pEventHandler, 
+                                           CSettingsStore *pSettingsStore,
+                                           Dasher::CAlphInfo::AlphIO *pAlphIO) : CDasherComponent(pEventHandler, pSettingsStore),
   m_pInterface(pInterface), m_pControlManager(NULL) {
 
-  const Dasher::CAlphIO::AlphInfo &oAlphInfo(pAlphIO->GetInfo(pSettingsStore->GetStringParameter(SP_ALPHABET_ID)));
-  CAlphabet *pAlphabet = new CAlphabet(oAlphInfo);
+  const Dasher::CAlphInfo *pAlphInfo(pAlphIO->GetInfo(pSettingsStore->GetStringParameter(SP_ALPHABET_ID)));
+  const CAlphabetMap *pAlphMap = pAlphInfo->MakeMap();
   
-  pSettingsStore->SetStringParameter(SP_TRAIN_FILE, pAlphabet->GetTrainingFile());
-  pSettingsStore->SetStringParameter(SP_GAME_TEXT_FILE, pAlphabet->GetGameModeFile());
+  pSettingsStore->SetStringParameter(SP_TRAIN_FILE, pAlphInfo->GetTrainingFile());
+  pSettingsStore->SetStringParameter(SP_GAME_TEXT_FILE, pAlphInfo->GetGameModeFile());
   
-  pSettingsStore->SetStringParameter(SP_DEFAULT_COLOUR_ID, pAlphabet->GetPalette());
+  pSettingsStore->SetStringParameter(SP_DEFAULT_COLOUR_ID, pAlphInfo->GetPalette());
   
   // --
   
@@ -34,15 +34,15 @@ CNodeCreationManager::CNodeCreationManager(Dasher::CDasherInterfaceBase *pInterf
   CLanguageModel *pLanguageModel;
   //WZ: Mandarin Dasher Change
   //If statement checks for the specific Super PinYin alphabet, and sets language model to PPMPY
-  if((oAlphInfo.m_iConversionID==2)&&(pSettingsStore->GetStringParameter(SP_ALPHABET_ID)=="Chinese Super Pin Yin, grouped by Dictionary")){
+  if((pAlphInfo->m_iConversionID==2)&&(pSettingsStore->GetStringParameter(SP_ALPHABET_ID)=="Chinese Super Pin Yin, grouped by Dictionary")){
     
     std::string CHAlphabet = "Chinese / ç®?ä½?中æ?? (simplified chinese, in pin yin groups)";
-    Dasher::CAlphIO::AlphInfo oCHAlphInfo = pAlphIO->GetInfo(CHAlphabet);
-    CAlphabet *pCHAlphabet = new CAlphabet(oCHAlphInfo);
+    const Dasher::CAlphInfo *pCHAlphInfo(pAlphIO->GetInfo(CHAlphabet));
+    const CAlphabetMap *pCHAlphMap = pCHAlphInfo->MakeMap();
     
     //std::cout<<"CHALphabet size "<< pCHAlphabet->GetNumberTextSymbols(); [7603]
-    pLanguageModel = new CPPMPYLanguageModel(pEventHandler, pSettingsStore, pCHAlphabet, pAlphabet);
-    m_pTrainer = new CMandarinTrainer(pLanguageModel, pAlphabet, pCHAlphabet);
+    pLanguageModel = new CPPMPYLanguageModel(pEventHandler, pSettingsStore, pCHAlphInfo, pAlphInfo);
+    m_pTrainer = new CMandarinTrainer(pLanguageModel, pAlphMap, pCHAlphMap);
     std::cout<<"Setting PPMPY model"<<std::endl;
   }
   else{
@@ -51,33 +51,33 @@ CNodeCreationManager::CNodeCreationManager(Dasher::CDasherInterfaceBase *pInterf
     // FIXME - return to using enum here
     switch (pSettingsStore->GetLongParameter(LP_LANGUAGE_MODEL_ID)) {
       case 0:
-        pLanguageModel = new CPPMLanguageModel(pEventHandler, pSettingsStore, pAlphabet);
+        pLanguageModel = new CPPMLanguageModel(pEventHandler, pSettingsStore, pAlphInfo);
         break;
       case 2:
-        pLanguageModel = new CWordLanguageModel(pEventHandler, pSettingsStore, pAlphabet);
+        pLanguageModel = new CWordLanguageModel(pEventHandler, pSettingsStore, pAlphInfo, pAlphMap);
         break;
       case 3:
-        pLanguageModel = new CMixtureLanguageModel(pEventHandler, pSettingsStore, pAlphabet);
+        pLanguageModel = new CMixtureLanguageModel(pEventHandler, pSettingsStore, pAlphInfo, pAlphMap);
         break;  
       case 4:
-        pLanguageModel = new CCTWLanguageModel(pEventHandler, pSettingsStore, pAlphabet);
+        pLanguageModel = new CCTWLanguageModel(pEventHandler, pSettingsStore, pAlphInfo);
         break;
         
       default:
         // If there is a bogus value for the language model ID, we'll default
         // to our trusty old PPM language model.
-        pLanguageModel = new CPPMLanguageModel(pEventHandler, pSettingsStore, pAlphabet);    
+        pLanguageModel = new CPPMLanguageModel(pEventHandler, pSettingsStore, pAlphInfo);    
         break;
     }
-    m_pTrainer = new CTrainer(pLanguageModel, pAlphabet);
+    m_pTrainer = new CTrainer(pLanguageModel, pAlphMap);
   }
     
-    switch(oAlphInfo.m_iConversionID) {
+    switch(pAlphInfo->m_iConversionID) {
       default:
         //TODO: Error reporting here
         //fall through to
       case 0: // No conversion required
-        m_pAlphabetManager = new CAlphabetManager(pInterface, this, pAlphabet, pLanguageModel);
+        m_pAlphabetManager = new CAlphabetManager(pInterface, this, pAlphInfo, pAlphMap, pLanguageModel);
         break;
 #ifdef JAPANESE
       case 1: // Japanese
@@ -85,25 +85,25 @@ CNodeCreationManager::CNodeCreationManager(Dasher::CDasherInterfaceBase *pInterf
 #ifdef WIN32
         new CIMEConversionHelper;
 #else
-        new CCannaConversionHelper(this, pAlphabet, GetLongParameter(LP_CONVERSION_TYPE), GetLongParameter(LP_CONVERSION_ORDER));
+        new CCannaConversionHelper(this, pAlphInfo, GetLongParameter(LP_CONVERSION_TYPE), GetLongParameter(LP_CONVERSION_ORDER));
 #endif
         //TODO ownership/deletion
-        m_pAlphabetManager = new CConvertingAlphMgr(pInterface, this, pConversionManager, pAlphabet, pLanguageModel);
+        m_pAlphabetManager = new CConvertingAlphMgr(pInterface, this, pConversionManager, pAlphInfo, pLanguageModel);
         break;
 #endif
       case 2:   //(ACL) Modify AlphabetManager for Mandarin Dasher
-        m_pAlphabetManager = new CMandarinAlphMgr(pInterface, this, pAlphabet, pLanguageModel);
+        m_pAlphabetManager = new CMandarinAlphMgr(pInterface, this, pAlphInfo, pAlphMap, pLanguageModel);
     }
 
-  if (!pAlphabet->GetTrainingFile().empty()) {
+  if (!pAlphInfo->GetTrainingFile().empty()) {
     //1. Look for system training text...
     CLockEvent oEvent("Training on System Text", true, 0);
     pEventHandler->InsertEvent(&oEvent);
-    m_pTrainer->LoadFile(GetStringParameter(SP_SYSTEM_LOC) + pAlphabet->GetTrainingFile());
+    m_pTrainer->LoadFile(GetStringParameter(SP_SYSTEM_LOC) + pAlphInfo->GetTrainingFile());
     //Now add in any user-provided individual training text...
     oEvent.m_strMessage = "Training on User Text"; oEvent.m_bLock=true; oEvent.m_iPercent = 0;
     pEventHandler->InsertEvent(&oEvent);
-    m_pTrainer->LoadFile(GetStringParameter(SP_USER_LOC) + pAlphabet->GetTrainingFile());
+    m_pTrainer->LoadFile(GetStringParameter(SP_USER_LOC) + pAlphInfo->GetTrainingFile());
     oEvent.m_bLock = false;
     pEventHandler->InsertEvent(&oEvent);
   }
@@ -117,7 +117,7 @@ CNodeCreationManager::CNodeCreationManager(Dasher::CDasherInterfaceBase *pInterf
     //test...
     pLanguageModel->WriteToFile("test.model");
     CPPMLanguageModel *pLan = (CPPMLanguageModel *)pLanguageModel;
-    CPPMLanguageModel *pLM2 = new CPPMLanguageModel(pEventHandler, pSettingsStore, pAlphabet);
+    CPPMLanguageModel *pLM2 = new CPPMLanguageModel(pEventHandler, pSettingsStore, pAlphInfo);
     pLM2->ReadFromFile("test.model");
     if (!pLan->eq(pLM2)) {
       std::cout << "Not equal!" << std::endl;
diff --git a/Src/DasherCore/NodeCreationManager.h b/Src/DasherCore/NodeCreationManager.h
index 6cca995..ee4ebb2 100644
--- a/Src/DasherCore/NodeCreationManager.h
+++ b/Src/DasherCore/NodeCreationManager.h
@@ -1,7 +1,7 @@
 #ifndef __NodeCreationManager_h__
 #define __NodeCreationManager_h__
 
-#include "Alphabet/Alphabet.h"
+#include "Alphabet/AlphabetMap.h"
 #include "Alphabet/AlphIO.h"
 #include "AlphabetManager.h"
 #include "ConversionManager.h"
@@ -25,9 +25,9 @@ namespace Dasher {
 class CNodeCreationManager : public Dasher::CDasherComponent {
  public:
   CNodeCreationManager(Dasher::CDasherInterfaceBase *pInterface,
-		       Dasher::CEventHandler * pEventHandler,
-		       CSettingsStore * pSettingsStore,
-		       Dasher::CAlphIO *pAlphIO);
+                       Dasher::CEventHandler * pEventHandler,
+                       CSettingsStore * pSettingsStore,
+                       Dasher::CAlphInfo::AlphIO *pAlphIO);
   ~CNodeCreationManager();
   
   //we watch for changes to BP_CONTROL_MODE and create the Control Manager lazily
@@ -44,7 +44,7 @@ class CNodeCreationManager : public Dasher::CDasherComponent {
   /// Get a reference to the current alphabet
   ///
 
-  const Dasher::CAlphabet *GetAlphabet() const {
+  const Dasher::CAlphInfo *GetAlphabet() const {
     return m_pAlphabetManager->GetAlphabet();
   }
 
diff --git a/Src/DasherCore/Trainer.cpp b/Src/DasherCore/Trainer.cpp
index 85123fd..fed75f1 100644
--- a/Src/DasherCore/Trainer.cpp
+++ b/Src/DasherCore/Trainer.cpp
@@ -17,11 +17,11 @@ static char THIS_FILE[] = __FILE__;
 #endif
 #endif
 
-CTrainer::CTrainer(CLanguageModel *pLanguageModel, CAlphabet *pAlphabet)
+CTrainer::CTrainer(CLanguageModel *pLanguageModel, const CAlphabetMap *pAlphabet)
   : CTrainingHelper(pAlphabet), m_pLanguageModel(pLanguageModel) {
 }
 
-void CTrainer::Train(CAlphabet::SymbolStream &syms) {
+void CTrainer::Train(CAlphabetMap::SymbolStream &syms) {
   CLanguageModel::Context sContext = m_pLanguageModel->CreateEmptyContext();
 
   for(symbol sym; (sym=syms.next())!=-1;) {
@@ -30,7 +30,7 @@ void CTrainer::Train(CAlphabet::SymbolStream &syms) {
   m_pLanguageModel->ReleaseContext(sContext);
 }
 
-CMandarinTrainer::CMandarinTrainer(CLanguageModel *pLanguageModel, CAlphabet *pAlphabet, CAlphabet *pCHAlphabet)
+CMandarinTrainer::CMandarinTrainer(CLanguageModel *pLanguageModel, const CAlphabetMap *pAlphabet, const CAlphabetMap *pCHAlphabet)
 : CTrainer(pLanguageModel, pAlphabet), m_pCHAlphabet(pCHAlphabet) {
 }
 
diff --git a/Src/DasherCore/Trainer.h b/Src/DasherCore/Trainer.h
index 4ae11cf..017be35 100644
--- a/Src/DasherCore/Trainer.h
+++ b/Src/DasherCore/Trainer.h
@@ -5,27 +5,26 @@
 #include "TrainingHelper.h"
 
 namespace Dasher {
-  class CAlphIO;
   class CDasherInterfaceBase;
 	
   class CTrainer : public CTrainingHelper {
   public:
-    CTrainer(CLanguageModel *pLanguageModel, CAlphabet *pAlphabet);
+    CTrainer(CLanguageModel *pLanguageModel, const CAlphabetMap *pAlphabet);
 
   protected:
-    virtual void Train(CAlphabet::SymbolStream &syms);
+    virtual void Train(CAlphabetMap::SymbolStream &syms);
     CLanguageModel *m_pLanguageModel;
   };
 	
   class CMandarinTrainer : public CTrainer {
   public:
-    CMandarinTrainer(CLanguageModel *pLanguageModel, CAlphabet *pAlphabet, CAlphabet *pCHAlphabet);
+    CMandarinTrainer(CLanguageModel *pLanguageModel, const CAlphabetMap *pAlphabet, const CAlphabetMap *pCHAlphabet);
 
     //override...
     virtual void LoadFile(const std::string &strPath);
     
   private:
-    CAlphabet * m_pCHAlphabet;
+    const CAlphabetMap *m_pCHAlphabet;
   };
 
 }
diff --git a/Src/DasherCore/TrainingHelper.cpp b/Src/DasherCore/TrainingHelper.cpp
index c8f9936..3b376c3 100644
--- a/Src/DasherCore/TrainingHelper.cpp
+++ b/Src/DasherCore/TrainingHelper.cpp
@@ -35,7 +35,7 @@ static void XML_StartElement(void *pUserData, const XML_Char *szName, const XML_
 static void XML_EndElement(void *pUserData, const XML_Char *szName);
 static void XML_CharacterData(void *pUserData, const XML_Char *szS, int iLen);
 
-Dasher::CTrainingHelper::CTrainingHelper(const Dasher::CAlphabet *pAlphabet) : m_pAlphabet(pAlphabet) {
+Dasher::CTrainingHelper::CTrainingHelper(const Dasher::CAlphabetMap *pAlphabet) : m_pAlphabet(pAlphabet) {
 }
 
 void 
@@ -73,7 +73,7 @@ Dasher::CTrainingHelper::LoadPlain(const std::string &strFileName) {
       return;
     }
 
-  CAlphabet::SymbolStream syms(m_pAlphabet, in);
+  CAlphabetMap::SymbolStream syms(*m_pAlphabet, in);
   Train(syms);
 
   in.close();
@@ -128,7 +128,7 @@ void
 Dasher::CTrainingHelper::HandleEndElement(const XML_Char *szName) {
   if(!strcmp(szName, "segment")) {
     std::istringstream in(m_strCurrentText);
-    CAlphabet::SymbolStream syms(m_pAlphabet,in);
+    CAlphabetMap::SymbolStream syms(*m_pAlphabet,in);
     Train(syms);
     
     m_bInSegment = false;
diff --git a/Src/DasherCore/TrainingHelper.h b/Src/DasherCore/TrainingHelper.h
index 02d0b41..a259603 100644
--- a/Src/DasherCore/TrainingHelper.h
+++ b/Src/DasherCore/TrainingHelper.h
@@ -21,15 +21,15 @@
 #ifndef __TrainingHelper_h__
 #define __TrainingHelper_h__
 
-#include "Alphabet/Alphabet.h"
-
+#include "Alphabet/AlphabetMap.h"
+#include <expat.h>
 #include <string>
 
 namespace Dasher {
 
   class CTrainingHelper {
   public:
-	CTrainingHelper(const CAlphabet *m_pAlphabet);
+	CTrainingHelper(const CAlphabetMap *pAlphabet);
 	  
     void HandleStartElement(const XML_Char *szName, 
 			    const XML_Char **pAtts);
@@ -42,9 +42,9 @@ namespace Dasher {
     void LoadFile(const std::string &strFileName);
 
   protected:
-    const Dasher::CAlphabet *m_pAlphabet;
+    const Dasher::CAlphabetMap *m_pAlphabet;
 
-    virtual void Train(CAlphabet::SymbolStream &syms)=0;
+    virtual void Train(CAlphabetMap::SymbolStream &syms)=0;
 	  
   private:  
 	void LoadPlain(const std::string &strFileName);
diff --git a/Src/MacOSX/Dasher.xcodeproj/project.pbxproj b/Src/MacOSX/Dasher.xcodeproj/project.pbxproj
index 6f8cfa2..fefdb97 100755
--- a/Src/MacOSX/Dasher.xcodeproj/project.pbxproj
+++ b/Src/MacOSX/Dasher.xcodeproj/project.pbxproj
@@ -27,8 +27,6 @@
 		193731A80C8586F20022CBC7 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 193731A70C8586F20022CBC7 /* config.h */; };
 		1948BE9D0C226CFD001DFA32 /* ActionButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1948BDF60C226CFC001DFA32 /* ActionButton.cpp */; };
 		1948BE9E0C226CFD001DFA32 /* ActionButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 1948BDF70C226CFC001DFA32 /* ActionButton.h */; };
-		1948BEA00C226CFD001DFA32 /* Alphabet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1948BDFA0C226CFC001DFA32 /* Alphabet.cpp */; };
-		1948BEA10C226CFD001DFA32 /* Alphabet.h in Headers */ = {isa = PBXBuildFile; fileRef = 1948BDFB0C226CFC001DFA32 /* Alphabet.h */; };
 		1948BEA20C226CFD001DFA32 /* AlphabetMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1948BDFC0C226CFC001DFA32 /* AlphabetMap.cpp */; };
 		1948BEA30C226CFD001DFA32 /* AlphabetMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1948BDFD0C226CFC001DFA32 /* AlphabetMap.h */; };
 		1948BEA40C226CFD001DFA32 /* AlphIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1948BDFE0C226CFC001DFA32 /* AlphIO.cpp */; };
@@ -425,8 +423,6 @@
 		1946CABC0481AD440000000A /* ZippyString.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = ZippyString.m; sourceTree = "<group>"; };
 		1948BDF60C226CFC001DFA32 /* ActionButton.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ActionButton.cpp; sourceTree = "<group>"; };
 		1948BDF70C226CFC001DFA32 /* ActionButton.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ActionButton.h; sourceTree = "<group>"; };
-		1948BDFA0C226CFC001DFA32 /* Alphabet.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Alphabet.cpp; sourceTree = "<group>"; };
-		1948BDFB0C226CFC001DFA32 /* Alphabet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Alphabet.h; sourceTree = "<group>"; };
 		1948BDFC0C226CFC001DFA32 /* AlphabetMap.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AlphabetMap.cpp; sourceTree = "<group>"; };
 		1948BDFD0C226CFC001DFA32 /* AlphabetMap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AlphabetMap.h; sourceTree = "<group>"; };
 		1948BDFE0C226CFC001DFA32 /* AlphIO.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AlphIO.cpp; sourceTree = "<group>"; };
@@ -1064,8 +1060,6 @@
 		1948BDF80C226CFC001DFA32 /* Alphabet */ = {
 			isa = PBXGroup;
 			children = (
-				1948BDFA0C226CFC001DFA32 /* Alphabet.cpp */,
-				1948BDFB0C226CFC001DFA32 /* Alphabet.h */,
 				1948BDFC0C226CFC001DFA32 /* AlphabetMap.cpp */,
 				1948BDFD0C226CFC001DFA32 /* AlphabetMap.h */,
 				1948BDFE0C226CFC001DFA32 /* AlphIO.cpp */,
@@ -1412,7 +1406,6 @@
 				19F36D8E0B18B60E002F41F1 /* ZippyStringImage.h in Headers */,
 				19F36D900B18B60E002F41F1 /* ZippyStringGlyph.h in Headers */,
 				1948BE9E0C226CFD001DFA32 /* ActionButton.h in Headers */,
-				1948BEA10C226CFD001DFA32 /* Alphabet.h in Headers */,
 				1948BEA30C226CFD001DFA32 /* AlphabetMap.h in Headers */,
 				1948BEA50C226CFD001DFA32 /* AlphIO.h in Headers */,
 				1948BEA60C226CFD001DFA32 /* GroupInfo.h in Headers */,
@@ -1776,7 +1769,6 @@
 				19F36D8F0B18B60E002F41F1 /* ZippyStringImage.m in Sources */,
 				19F36D910B18B60E002F41F1 /* ZippyStringGlyph.m in Sources */,
 				1948BE9D0C226CFD001DFA32 /* ActionButton.cpp in Sources */,
-				1948BEA00C226CFD001DFA32 /* Alphabet.cpp in Sources */,
 				1948BEA20C226CFD001DFA32 /* AlphabetMap.cpp in Sources */,
 				1948BEA40C226CFD001DFA32 /* AlphIO.cpp in Sources */,
 				1948BEA80C226CFD001DFA32 /* AlphabetManager.cpp in Sources */,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]