ide/CodeEditor: Customizable color scheme support
[sdk] / ide / src / designer / CodeEditor.ec
index 1cad0f7..e7970ba 100644 (file)
@@ -1,68 +1,5 @@
 import "ide"
 
-// *** Color Schemes ***
-
-// *** The Old Color Scheme that was causing me auras and ophtalmic migraines -- Uncomment at your own risk! ***
-/*
-FontResource panelFont { $"Courier New", 10 };
-FontResource codeFont { $"Courier New", 10 };
-Color selectionColor = Color { 10, 36, 106 };
-Color selectionText = white;
-Color viewsBackground = white;
-Color viewsText = black;
-Color outputBackground = white;
-Color outputText = black;
-Color projectViewBackground = white;
-Color projectViewText = black;
-Color codeEditorBG = white;
-Color codeEditorFG = black;
-Color marginColor = Color {230, 230, 230};
-Color selectedMarginColor = Color {200, 200, 200};
-Color lineNumbersColor = Color {60, 60, 60};
-SyntaxColorScheme colorScheme
-{
-   keywordColors = [ blue, blue ];
-   commentColor = dimGray;
-   charLiteralColor = crimson;
-   stringLiteralColor = crimson;
-   preprocessorColor = green;
-   numberColor = teal;
-};
-*/
-
-// The new nice dark scheme -- so peaceful on my brain
-
-FontResource panelFont { $"Courier New", 10 };
-FontResource codeFont { $"Courier New", 10 };
-/*
-FontResource panelFont { $"Consolas", 12 };
-FontResource codeFont { $"Consolas", 12 };
-*/
-Color selectionColor = lightYellow;
-Color selectionText = Color { 30, 40, 50 };
-Color viewsBackground = Color { 30, 40, 50 };
-Color viewsText = lightGray;
-Color outputBackground = black;
-Color outputText = lime;
-Color projectViewBackground = Color { 30, 40, 50 };
-Color projectViewText = lightGray;
-Color codeEditorBG = black;
-Color codeEditorFG = ivory;
-Color marginColor = Color {24, 24, 24};
-Color selectedMarginColor = Color {64, 64, 64};
-Color lineNumbersColor = Color {160, 160, 160};
-SyntaxColorScheme colorScheme
-{
-   keywordColors = [ skyBlue, skyBlue ];
-   commentColor = Color { 125, 125, 125 };
-   charLiteralColor = Color { 245, 50, 245 };
-   stringLiteralColor = Color { 245, 50, 245 };
-   preprocessorColor = { 120, 220, 140 };
-   numberColor = Color {   0, 192, 192 };
-};
-
-// *********************
-
 import "findCtx"
 import "findExp"
 import "findParams"
@@ -91,7 +28,7 @@ static Array<FileType> fileTypes
    { $"Text Files", "txt", never }
 ] };
 
-static char * iconNames[] = 
+static const char * iconNames[] =
 {
    "<:ecere>constructs/class.png",
    "<:ecere>constructs/data.png",
@@ -117,6 +54,14 @@ extern int __ecereVMethodID_class_OnCopy;
 extern int __ecereVMethodID_class_OnSaveEdit;
 extern int __ecereVMethodID___ecereNameSpace__ecere__com__Module_OnLoad;
 
+class RTCMenuBits
+{
+public:
+   bool ignoreBreakpoints:1;
+   bool atSameLevel:1;
+   bool oldImplementation:1;
+};
+
 class EditFileDialog : FileDialog
 {
    bool OnCreate()
@@ -146,10 +91,10 @@ define CloseBracket = '}';
 
 enum MethodAction
 {
-   actionAddMethod = 1, 
-   actionDeleteMethod = 2, 
-   actionDetachMethod = 3, 
-   actionAttachMethod = 4, 
+   actionAddMethod = 1,
+   actionDeleteMethod = 2,
+   actionDetachMethod = 3,
+   actionAttachMethod = 4,
    actionReattachMethod = 5
 };
 
@@ -160,8 +105,6 @@ File output;
 
 File fileInput;
 
-bool parseError = false;
-
 int returnCode;
 
 Class insideClass;
@@ -170,7 +113,7 @@ Expression paramsInsideExp;
 ClassFunction insideFunction;
 ClassDef insideDef;
 Type instanceType;
-char * instanceName;
+const char * instanceName;
 Type functionType;
 int paramsID;
 bool insideInstance;
@@ -179,7 +122,7 @@ bool insideInstance;
                               GENERATING
 ****************************************************************************/
 
-static void OutputString(File f, char * string)
+static void OutputString(File f, const char * string)
 {
    int c;
    for(c = 0; string[c]; c++)
@@ -188,15 +131,24 @@ static void OutputString(File f, char * string)
          f.Puts("\\\"");
       else if(string[c] == '\\')
          f.Puts("\\\\");
+      else if(string[c] == '\n')
+      {
+         f.Puts("\\n");
+         if(c > 30)
+            f.Puts("\"\n   \"");
+      }
       else
          f.Putc(string[c]);
-   }                              
+   }
 }
 
+// Consider merging with PrintType ?
 void OutputType(File f, Type type, bool outputName)
 {
    if(type)
    {
+      if(type.kind != pointerType && type.constant)
+         f.Printf("const ");
       switch(type.kind)
       {
          case voidType:
@@ -229,9 +181,26 @@ void OutputType(File f, Type type, bool outputName)
             f.Printf("double");
             break;
          case classType:
-            // ADD CODE TO DECIDE WHETHER TO OUTPUT FULLY QUAlIFIED OR NOT:
-            f.Printf(type._class.shortName ? type._class.shortName : type._class.string);
+         {
+            if(type._class && !strcmp(type._class.string, "class"))
+            {
+               switch(type.classObjectType)
+               {
+                  case anyObject:
+                     f.Printf("any_object");
+                     break;
+                  default:
+                     f.Printf("typed_object");
+                     break;
+               }
+               if(type.byReference)
+                  f.Printf(" &");
+            }
+            else
+               // ADD CODE TO DECIDE WHETHER TO OUTPUT FULLY QUAlIFIED OR NOT:
+               f.Printf(type._class.shortName ? type._class.shortName : type._class.string);
             break;
+         }
          case structType:
             break;
          case unionType:
@@ -244,6 +213,8 @@ void OutputType(File f, Type type, bool outputName)
          case pointerType:
             OutputType(f, type.type, false);
             f.Printf(" *");
+            if(type.constant)
+               f.Printf(" const");
             break;
          case ellipsisType:
             f.Printf("...");
@@ -274,10 +245,10 @@ void DeleteJunkBefore(EditBoxStream f, int pos, int * position)
 {
    char ch;
    int before = 0;
-   
+
    if(position)
       f.Seek(pos - *position, current);
-                                                      
+
    // Try to delete spaces and \n before...
    f.Seek(-1, current);
    for(;f.Getc(&ch);)
@@ -329,7 +300,7 @@ void GetLocText(EditBox editBox, File f, int position, Location loc, char ** tex
    editBox.GetSelPos(&l1, &y1, &x1, &l2, &y2, &x2, false);
 
    // Cut & Paste function
-   
+
    {
       EditLine l1, l2;
       int y1,x1,y2,x2;
@@ -348,11 +319,44 @@ void GetLocText(EditBox editBox, File f, int position, Location loc, char ** tex
       *text = new char[*size+1 + (y2-y1+1) * linePad + pad]; // Add pad for tabs and new name
       editBox.GetSel(*text, false);
    }
-   
+
    editBox.SetSelPos(l1, y1, x1, l2, y2, x2);
    f.Printf(""); // Make the stream point to where the editbox is
 }
 
+static int64 GetI64EnumValue(Class dataType, DataValue dataForm)
+{
+   int64 i64Value = 0;
+   switch(dataType.typeSize)
+   {
+      case 1:
+         if(!strcmp(dataType.dataTypeString, "byte"))
+            i64Value = dataForm.uc;
+         else
+            i64Value = dataForm.c;
+         break;
+      case 2:
+         if(!strcmp(dataType.dataTypeString, "uint16"))
+            i64Value = dataForm.us;
+         else
+            i64Value = dataForm.s;
+         break;
+      case 4:
+         if(!strcmp(dataType.dataTypeString, "uint"))
+            i64Value = dataForm.ui;
+         else
+            i64Value = dataForm.i;
+         break;
+      case 8:
+         if(!strcmp(dataType.dataTypeString, "uint64"))
+            i64Value = *(int64 *)&dataForm.ui64;
+         else
+            i64Value = dataForm.i64;
+         break;
+   }
+   return i64Value;
+}
+
 void Code_FixProperty(Property prop, Instance object)
 {
    Designer::FixProperty(prop, object);
@@ -372,7 +376,7 @@ bool Code_IsPropertyModified(Instance test, ObjectInfo selected, Property prop)
       {
          void * dataForm = new0 byte[dataType.structSize];
          void * dataTest = new0 byte[dataType.structSize];
-   
+
          ((void (*)(void *, void *))(void *)prop.Get)(selected.instance, dataForm);
          ((void (*)(void *, void *))(void *)prop.Get)(test, dataTest);
 
@@ -387,23 +391,55 @@ bool Code_IsPropertyModified(Instance test, ObjectInfo selected, Property prop)
       else if(dataType && dataType._vTbl && (dataType.type == normalClass || dataType.type == noHeadClass))
       {
          void * dataForm, * dataTest;
-   
-         dataForm = ((void *(*)(void *))(void *)prop.Get)(selected.instance);
-         dataTest = ((void *(*)(void *))(void *)prop.Get)(test);
-   
+         bool isEditBoxContents = false;
+         bool freeDataForm = false, freeDataTest = false;
+
+         // Because contents property is broken for mutiline EditBox at the moment
+         if(!strcmp(prop.name, "contents") && !strcmp(prop._class.name, "EditBox"))
+            isEditBoxContents = true;
+
+         if(isEditBoxContents && ((EditBox)selected.instance).multiLine)
+         {
+            dataForm = ((EditBox)selected.instance).multiLineContents;
+            freeDataForm = true;
+         }
+         else
+            dataForm = ((void *(*)(void *))(void *)prop.Get)(selected.instance);
+         if(isEditBoxContents && ((EditBox)test).multiLine)
+         {
+            dataTest = ((EditBox)test).multiLineContents;
+            freeDataTest = true;
+         }
+         else
+            dataTest = ((void *(*)(void *))(void *)prop.Get)(test);
+
          if((prop.IsSet && !prop.IsSet(test)) || ((int (*)(void *, void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnCompare])(dataType, dataForm, dataTest))
          {
             ((void (*)(void *, void *))(void *)prop.Set)(test, dataForm);
             result = true;
          }
+
+         // Temporary work around until we standardize how properties should manage memory
+         if(!strcmp(prop.name, "strings") && !strcmp(prop._class.name, "DirectoriesBox"))
+            freeDataForm = freeDataTest = true;
+         if(dataType.type == normalClass && dataType.structSize)
+         {
+            if(freeDataForm) eInstance_Delete(dataForm);
+            if(freeDataTest) eInstance_Delete(dataTest);
+         }
+         else
+         {
+            if(freeDataForm) delete dataForm;
+            if(freeDataTest) delete dataTest;
+         }
       }
       else if(dataType && dataType._vTbl)
       {
          DataValue dataForm, dataTest;
-   
+
          GetProperty(prop, selected.instance, &dataForm);
          GetProperty(prop, test, &dataTest);
-   
+
          if((prop.IsSet && !prop.IsSet(test)) || ((int (*)(void *, void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnCompare])(dataType, &dataForm, &dataTest))
          {
             SetProperty(prop, test, dataForm);
@@ -416,18 +452,18 @@ bool Code_IsPropertyModified(Instance test, ObjectInfo selected, Property prop)
                   SetProperty(prop, selected.instance, dataForm);
             }
             result = true;
-         }                                          
+         }
       }
    }
    return result;
 }
 
-bool Code_IsPropertyDisabled(ObjectInfo selected, char * name)
+bool Code_IsPropertyDisabled(ObjectInfo selected, const char * name)
 {
    bool disabled = false;
    if(selected.oClass == selected)
    {
-      ClassDef def;                  
+      ClassDef def;
       if(selected.classDefinition)
       {
          for(def = selected.classDefinition.definitions->first; def; def = def.next)
@@ -484,7 +520,7 @@ bool Code_IsPropertyDisabled(ObjectInfo selected, char * name)
 
 static bool CheckCompatibleMethod(Method method, Type type, Class regClass, bool isForm, Symbol selectedClass)
 {
-   bool result = false;   
+   bool result = false;
    bool reset = false;
    if(!method.dataType)
       method.dataType = ProcessTypeString(method.dataTypeString, false);
@@ -494,7 +530,7 @@ static bool CheckCompatibleMethod(Method method, Type type, Class regClass, bool
       method.dataType.thisClass = selectedClass;
    }
    //result = MatchTypes(method.dataType, type, null, regClass, regClass, false);
-   result = MatchTypes(type, method.dataType, null, regClass, regClass, false, true, true, false);
+   result = MatchTypes(type, method.dataType, null, regClass, regClass, false, true, true, false, true);
    if(reset)
       method.dataType.thisClass = null;
    return result;
@@ -507,7 +543,7 @@ bool Code_IsFunctionEmpty(ClassFunction function, Method method, ObjectInfo obje
    // Check if it contains any code
    if((!body.compound.declarations || !body.compound.declarations->count) && (!body.compound.statements || body.compound.statements->count <= 1))
    {
-      Class moduleClass = eSystem_FindClass(object.instance._class.module, "Module");
+      // Class moduleClass = eSystem_FindClass(object.instance._class.module, "Module");
       Statement stmt = body.compound.statements ? body.compound.statements->first : null;
       Type dataType = method.dataType;
       Type returnType = dataType.returnType;
@@ -517,9 +553,9 @@ bool Code_IsFunctionEmpty(ClassFunction function, Method method, ObjectInfo obje
          method.dataType = ProcessTypeString(method.dataTypeString, false);
 
       confirmation = false;
-     
+
       // Check if default function should be calling base class:
-      if(object.instance._class._vTbl[method.vid] == moduleClass._vTbl[__ecereVMethodID___ecereNameSpace__ecere__com__Module_OnLoad]) // Temp Check for DefaultFunction
+      if(object.instance._class._vTbl[method.vid] == null /*moduleClass._vTbl[__ecereVMethodID___ecereNameSpace__ecere__com__Module_OnLoad]*/) // Temp Check for DefaultFunction
       {
          if(returnType.kind != voidType)
          {
@@ -544,7 +580,7 @@ bool Code_IsFunctionEmpty(ClassFunction function, Method method, ObjectInfo obje
          else
          {
             if(stmt)
-               confirmation = true;        
+               confirmation = true;
          }
       }
       else
@@ -561,7 +597,7 @@ bool Code_IsFunctionEmpty(ClassFunction function, Method method, ObjectInfo obje
          }
 
          if(!exp || exp.type != callExp || exp.call.exp.type != identifierExp)
-            confirmation = true;        
+            confirmation = true;
          else
          {
             Identifier id = exp.call.exp.identifier;
@@ -587,7 +623,7 @@ bool Code_IsFunctionEmpty(ClassFunction function, Method method, ObjectInfo obje
                      arg = arg ?arg.next : null;
                   }
                }
-            }                  
+            }
          }
       }
    }
@@ -596,7 +632,7 @@ bool Code_IsFunctionEmpty(ClassFunction function, Method method, ObjectInfo obje
 
 class CodeEditor : Window
 {
-   background = marginColor;
+   background = colorScheme.marginColor;
    borderStyle = sizableDeep;
    hasMaximize = true;
    hasMinimize = true;
@@ -605,8 +641,8 @@ class CodeEditor : Window
    isActiveClient = true;
    anchor = Anchor { left = 300, right = 150, top = 0, bottom = 0 };
    menu = Menu { };
-   
-   // eWindow_SetX(A_CASCADE); eWindow_SetY(A_CASCADE); 
+
+   // eWindow_SetX(A_CASCADE); eWindow_SetY(A_CASCADE);
    // eWindow_SetWidth(A_RELATIVE|80); eWindow_SetHeight(A_RELATIVE|80);
 
    SheetType sheetSelected;
@@ -615,7 +651,7 @@ class CodeEditor : Window
 
    OldList * ast;
    Context globalContext { };
-   OldList excludedSymbols { offset = (uint)&((Symbol)0).left };
+   OldList excludedSymbols { offset = (uint)(uintptr)&((Symbol)0).left };
 
    OldList defines;
    OldList imports;
@@ -623,7 +659,7 @@ class CodeEditor : Window
    OldList classes;
    bool codeModified;
    bool formModified;
-   
+
    ObjectInfo selected;
    ObjectInfo oClass;
 
@@ -651,7 +687,7 @@ class CodeEditor : Window
    bool expectingMove;
 
    BitmapResource icons[CodeObjectType];
-   
+
    FontResource boldFont { $"Tahoma", 8.25f, bold = true, window = this };
    FontResource normalFont { $"Tahoma", 8.25f, window = this };
 
@@ -661,11 +697,16 @@ class CodeEditor : Window
    bool inUseDebug;
    OpenedFileInfo openedFileInfo;
 
-   FontResource font { codeFont.faceName, codeFont.size };
+   FontResource font { codeFont.faceName, codeFont.size, codeFont.bold, codeFont.italic };
    saveDialog = codeEditorFileDialog;
 
    Designer designer { codeEditor = this, visible = false, saveDialog = codeEditorFormFileDialog };
 
+   bool noParsing;
+   int maxLineNumberLength;
+
+   property bool parsing { get { return editBox.syntaxHighlighting && !noParsing && !ide.noParsing; } };
+
    void ProcessCaretMove(EditBox editBox, int line, int charPos)
    {
       char temp[512];
@@ -678,7 +719,7 @@ class CodeEditor : Window
          ide.pos.text = temp;
       }
       if(sheet.codeEditor != this) return;
-      
+
       if(!updatingCode)
       {
          for(classItem = classes.first; classItem; classItem = classItem.next)
@@ -725,14 +766,13 @@ class CodeEditor : Window
                   hide = true;
                else
                {
-                  char * buffer = membersLine.text;
                   int c;
 
                   if(charPos - 1 < membersLoc.start.charPos)
                      hide = true;
                   else if(charPos - 1 > membersLoc.end.charPos)
                   {
-                     char * buffer = membersLine.text;
+                     const char * buffer = membersLine.text;
                      //if(membersList.currentRow)
                      //   hide = true;
                      //else
@@ -769,12 +809,16 @@ class CodeEditor : Window
       ProjectView projectView = ide.projectView;
       if(projectView)
       {
-         ProjectNode node = projectView.GetNodeFromWindow(this, null);
-         if(node)
+         char buffer[MAX_LOCATION];
+         char * fullPath = GetSlashPathBuffer(buffer, fileName);
+         Array<ProjectNode> nodes = ide.workspace.GetAllProjectNodes(fullPath, false);
+         if(nodes)
          {
-            node.modified = modifiedDocument;
+            for(node : nodes)
+               node.modified = modifiedDocument;
             projectView.Update(null);
          }
+         delete nodes;
       }
    };
 
@@ -782,11 +826,11 @@ class CodeEditor : Window
    EditBox editBox
    {
       textVertScroll = true, multiLine = true, /*lineNumbers = ideSettings.showLineNumbers,*/
-      freeCaret = ideSettings.useFreeCaret, caretFollowsScrolling = ideSettings.caretFollowsScrolling, 
+      freeCaret = ideSettings.useFreeCaret, caretFollowsScrolling = ideSettings.caretFollowsScrolling,
       tabKey = true, smartHome = true;
-      tabSelection = true, maxLineSize = 65536, parent = this, hasHorzScroll = true, hasVertScroll = true;
-      selectionColor = selectionColor, selectionText = selectionText,
-      background = codeEditorBG, foreground = codeEditorFG, syntaxColorScheme = colorScheme,
+      tabSelection = true, /*maxLineSize = 65536, */parent = this, hasHorzScroll = true, hasVertScroll = true;
+      selectionColor = colorScheme.selectionColor, selectionText = colorScheme.selectionText,
+      background = colorScheme.codeEditorBG, foreground = colorScheme.codeEditorFG, syntaxColorScheme = colorScheme.syntaxColors,
       font = font, borderStyle = none;
       anchor = Anchor { left = 0, right = 0, top = 0, bottom = 0 };
 
@@ -805,11 +849,11 @@ class CodeEditor : Window
          int oldLine = lastLine;
          display.FontExtent(font.font, " ", 1, null, &spaceH);
          {
-            Box box { 0, (Min(oldLine,oldLine)-1) * spaceH - editBox.scroll.y, editBox.anchor.left.distance, (Max(oldLine, oldLine))*spaceH-1 - editBox.scroll.y };
+            Box box { 0, (oldLine-1) * spaceH - editBox.scroll.y, editBox.anchor.left.distance, oldLine*spaceH-1 - editBox.scroll.y };
             Update(box);
          }
          {
-            Box box { 0, (Min(line,line)-1) * spaceH - editBox.scroll.y, editBox.anchor.left.distance, (Max(line, line))*spaceH-1 - editBox.scroll.y };
+            Box box { 0, (line-1) * spaceH - editBox.scroll.y, editBox.anchor.left.distance, line*spaceH-1 - editBox.scroll.y };
             Update(box);
          }
          lastLine = line;
@@ -822,7 +866,7 @@ class CodeEditor : Window
 
       void NotifyOvrToggle(EditBox editBox, bool overwrite)
       {
-         ide.ovr.color = overwrite ? black : Color { 128, 128, 128 };
+         ide.UpdateStateLight(ide.ovr, overwrite);
       }
 
       void NotifyUpdate(EditBox editBox)
@@ -853,8 +897,8 @@ class CodeEditor : Window
             {
                int c;
                // HOW WE MIGHT WANT TO DO IT:
-               char * text = before.line.text;
-               for(c = before.x-1; c>= 0; c--)
+               const char * text = before.line.text;
+               for(c = Min(before.line.count, before.x-1); c>= 0; c--)
                   if(!isspace(text[c]))
                      break;
                ide.debugger.MoveIcons(fileName, before.y + (((!pasteOperation && c > -1) || !after.line.count) ? 1 : 0), after.y - before.y, false);
@@ -869,6 +913,7 @@ class CodeEditor : Window
                */
             }
             Update({ 0, 0, editBox.position.x, clientSize.h });
+            UpdateMarginSize();
          }
 
          if(!updatingCode)
@@ -903,7 +948,7 @@ class CodeEditor : Window
                      hide = true;
                   else
                   {
-                     char * buffer = membersLine.text;
+                     const char * buffer = membersLine.text;
                      int c;
                      bool firstChar = true;
                      bool addedChar = false;
@@ -922,7 +967,7 @@ class CodeEditor : Window
                            hide = true;
                            break;
                         }
-                        if(!isSpace) 
+                        if(!isSpace)
                            firstChar = false;
                         else if(firstChar)
                         {
@@ -969,7 +1014,7 @@ class CodeEditor : Window
                      // Accept current string if hiding typing char
                      if(hide && row && row.selected)
                      {
-                        char * string = row.string;
+                        const char * string = row.string;
                         int len = strlen(string);
                         membersLoc.end.charPos -= after.x - before.x;
                         editBox.GoToPosition(membersLine, membersLoc.start.line, membersLoc.start.charPos);
@@ -991,7 +1036,7 @@ class CodeEditor : Window
                if(/*after.x - before.x == 1 && */after.y == before.y && !membersListShown)
                {
                   EditLine line = editBox.line;
-                  char * text = line.text;
+                  const char * text = line.text;
                   char ch = text[after.x-1];
                   if(ch == '.' || (ch == '>' && after.x-1 > 0 && text[after.x-1-1] == '-') || (ch == ':' && after.x-1 > 0 && text[after.x-1-1] == ':'))
                   {
@@ -1013,14 +1058,14 @@ class CodeEditor : Window
 
                      editBox.GetCaretPosition(&caret);
 
-                     
+
 
                      // Go back in the buffer until no space before
                      //yydebug = true;
                      codeModified = true;
                      EnsureUpToDate();
                      SetYydebug(false);
-                     { 
+                     {
                         EditBoxStream f { editBox = editBox };
                         oldCharPos = x1;
                         x1--;
@@ -1090,7 +1135,7 @@ class CodeEditor : Window
 
                               membersList.position = { x, y };
                            }
-         
+
                            membersLine = l1;
                            membersLoc.start.line = line - 1;
                            membersLoc.start.charPos = oldCharPos;
@@ -1130,13 +1175,13 @@ class CodeEditor : Window
                   }
                   else if(ch == ')' || ch == '}' || ch == ';')
                   {
-                     codeModified = true;               
+                     codeModified = true;
                      skipModified = true;
                      if(paramsShown)
                         InvokeParameters(false, true, false);
                      skipModified = false;
                   }
-                  else 
+                  else
                   {
                      bool back = codeModified;
                      codeModified = false;
@@ -1172,6 +1217,7 @@ class CodeEditor : Window
             if(projectView && fileName)
                ide.debugger.MoveIcons(fileName, before.y + 1, before.y - after.y, before.x == 0);
             Update({ 0, 0, editBox.position.x, clientSize.h });
+            UpdateMarginSize();
          }
 
          if(!updatingCode)
@@ -1188,7 +1234,7 @@ class CodeEditor : Window
                   {
                      loc = &object.instCode.loc;
 
-                     if((before.y+1 < loc->start.line || (before.y+1 == loc->start.line && before.x+1 <= loc->start.charPos)) && 
+                     if((before.y+1 < loc->start.line || (before.y+1 == loc->start.line && before.x+1 <= loc->start.charPos)) &&
                         (after.y+1 > loc->end.line    || (after.y+1 == loc->end.line && after.x+1 >= loc->end.charPos)))
                      {
                         object.instCode = null;
@@ -1203,7 +1249,7 @@ class CodeEditor : Window
                if(oClass.classDefinition)
                {
                   loc = &oClass.classDefinition.loc;
-                  if((before.y+1 < loc->start.line || (before.y+1 == loc->start.line && before.x+1 <= loc->start.charPos)) && 
+                  if((before.y+1 < loc->start.line || (before.y+1 == loc->start.line && before.x+1 <= loc->start.charPos)) &&
                      (after.y+1 > loc->end.line    || (after.y+1 == loc->end.line && after.x+1 >= loc->end.charPos)))
                   {
                      oClass.classDefinition = null;
@@ -1223,7 +1269,7 @@ class CodeEditor : Window
                   hide = true;
                else
                {
-                  char * buffer = membersLine.text;
+                  const char * buffer = membersLine.text;
                   int c;
                   bool firstChar = true;
                   char string[1024];
@@ -1326,9 +1372,11 @@ class CodeEditor : Window
             ObjectInfo object;
             ObjectInfo classObject;
 
-            //editBox.NotifyCaretMove(this, editBox, y, x);
             editBox.GoToLineNum(y);
+            x = Min(x, editBox.line.count);
             editBox.GoToPosition(editBox.line, y, x);
+            // Note: Uncommented this to drag objects after the member instance on which they are dropped
+            editBox.NotifyCaretMove(this, editBox, y+1, x+1);
 
             classObject = selected ? selected.oClass : null;
 
@@ -1346,7 +1394,7 @@ class CodeEditor : Window
                designer.DroppedObject(control, object, false, classObject.instance);
 
                sheet.AddObject(object, object.name, typeData /* className*/, true);
-               
+
                UpdateFormCode();
                //codeModified = true;
                EnsureUpToDate();
@@ -1357,7 +1405,7 @@ class CodeEditor : Window
 
       bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
       {
-         if(key == Key { space, ctrl = true })
+         if(key == ctrlSpace)
          {
             membersList.Destroy(0);
             membersListShown = false;
@@ -1372,13 +1420,13 @@ class CodeEditor : Window
          {
             if(ide.projectView)
             {
-               ProjectNode node = ide.projectView.GetNodeFromWindow(this, null);
+               ProjectNode node = ide.projectView.GetNodeForCompilationFromWindow(this, false, null, null);
                if(!node)
                {
                   char * s;
-                  s = PrintString($"The ", fileName, $" file is not part of any project.\n", 
+                  s = PrintString($"The ", fileName, $" file is not part of any project.\n",
                      $"It can't be compiled.");
-                  MessageBox { type = ok, parent = ide, master = ide, text = $"File not in project error", contents = s }.Modal();
+                  MessageBox { type = ok, /*parent = ide, */master = ide, text = $"File not in project error", contents = s }.Modal();
                   delete s;
                   return false;
                }
@@ -1453,7 +1501,7 @@ class CodeEditor : Window
          DataRow row = listBox.currentRow;
          if(row)
          {
-            char * string = row.string;
+            const char * string = row.string;
 
             editBox.GoToPosition(membersLine, membersLoc.start.line, membersLoc.start.charPos);
             editBox.Delete(
@@ -1470,41 +1518,52 @@ class CodeEditor : Window
       bool OnKeyDown(Key key, unichar ch)
       {
          CodeEditor editor = (CodeEditor) master;
-         if(key == escape || key == leftAlt || key == rightAlt || 
-            (key.ctrl && key.code != left && key.code != right && 
+         if(key == escape || key == leftAlt || key == rightAlt ||
+            (key.ctrl && key.code != left && key.code != right &&
              key.code != leftShift && key.code != rightShift && key.code != space))
          {
+            bool result = true;
             if(editor.paramsShown)
+            {
+               if(key == escape)
+                  result = false;
                editor.paramsList.Destroy(0);
+               editor.paramsShown = false;
+            }
             if(editor.membersListShown)
+            {
+               if(key == escape)
+                  result = false;
                editor.membersList.Destroy(0);
+               editor.membersListShown = false;
+            }
 
-            editor.paramsShown = false;
             FreeType(editor.functionType);
-            FreeType(editor.instanceType);
-
             editor.functionType = null;
+
+            FreeType(editor.instanceType);
             editor.instanceType = null;
+
             editor.paramsID = -1;
 
-            editor.membersListShown = false;
-            return true;
+            return result;
          }
-         else 
+         else
             return editor.editBox.OnKeyDown(key, ch);
          return false;
       }
 
-      bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
+      /*bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
       {
          CodeEditor editor = (CodeEditor)master;
-         if(!active)
+         Window rw = previous ? previous.rootWindow : null;
+         if(!active && rw != editor.paramsList)
          {
             Destroy(0);
             editor.membersListShown = false;
          }
          return ListBox::OnActivate(active, previous, goOnWithActivation, direct);
-      }
+      }*/
 
       bool OnKeyHit(Key key, unichar ch)
       {
@@ -1517,7 +1576,7 @@ class CodeEditor : Window
                DataRow row = currentRow;
                if(row && row.selected)
                {
-                  char * string = row.string;
+                  const char * string = row.string;
 
                   editor.editBox.GoToPosition(editor.membersLine, editor.membersLoc.start.line, editor.membersLoc.start.charPos);
                   editor.editBox.Delete(
@@ -1560,26 +1619,27 @@ class CodeEditor : Window
 
    Window paramsList
    {
-      master = this, 
+      master = this,
       interim = true,
       clickThrough = true,
       autoCreate = false,
       borderStyle = contour,
       cursor = null,
       background = { 255,255,225 },
-      
+
       OnKeyDown = membersList.OnKeyDown;
 
-      bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
+      /*bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
       {
          CodeEditor editor = (CodeEditor)master;
-         if(!active)
+         Window rw = previous ? previous.rootWindow : null;
+         if(!active && previous != editor.editBox && rw != editor.membersList)
          {
             Destroy(0);
-            editor.membersListShown = false;
+            editor.paramsShown = false;
          }
          return Window::OnActivate(active, previous, goOnWithActivation, direct);
-      }
+      }*/
 
       bool OnKeyHit(Key key, unichar ch)
       {
@@ -1629,7 +1689,7 @@ class CodeEditor : Window
          display.FontExtent(font, ")", 1, &parW, null);
 
          string[0] = 0;
-         if(editor.functionType)
+         if(editor.functionType && type.kind == functionType)
          {
             PrintType(type.returnType, string, true, true);
             display.FontExtent(font, string, strlen(string), &functionW, null);
@@ -1645,7 +1705,7 @@ class CodeEditor : Window
                display.FontExtent(boldFont, instanceName, strlen(instanceName), &nameW, null);
             totalW = functionW + nameW;
             surface.TextFont(boldFont);
-         }   
+         }
 
          surface.WriteText(x, y, string, strlen(string));
          x += functionW + spaceW;
@@ -1658,13 +1718,13 @@ class CodeEditor : Window
             surface.WriteText(x, y, "(", 1);
             x += parW;
 
-            if(methodType && !methodType.staticMethod)
+            if(methodType && !methodType.staticMethod && methodType.methodClass)
             {
                int tw = 0, width;
 
                if(id == editor.paramsID)
                   surface.TextFont(boldFont);
-               
+
                if(methodType.methodClass)
                   surface.TextExtent(methodType.methodClass.name, strlen(methodType.methodClass.name), &tw, null);
 
@@ -1693,7 +1753,7 @@ class CodeEditor : Window
                {
                   surface.WriteText(x, y, ",", 1);
                   x += ((id ==  editor.paramsID) ? commaWB : commaW);
-               }      
+               }
 
                lineW += width;
 
@@ -1705,7 +1765,7 @@ class CodeEditor : Window
                id ++;
             }
 
-            if(!methodType || methodType.staticMethod || !type.params.first || ((Type)type.params.first).kind != voidType || type.params.count > 1)
+            if(!methodType || (methodType.staticMethod || !methodType.methodClass) || !type.params.first || ((Type)type.params.first).kind != voidType || type.params.count > 1)
             {
                for(param = type.params.first; param; param = param.next)
                {
@@ -1739,7 +1799,7 @@ class CodeEditor : Window
                   {
                      surface.WriteText(x, y, ",", 1);
                      x += ((id ==  editor.paramsID) ? commaWB : commaW);
-                  }      
+                  }
 
                   lineW += width;
 
@@ -1795,7 +1855,7 @@ class CodeEditor : Window
          display.FontExtent(font, ")", 1, &parW, null);
 
          string[0] = 0;
-         if(editor.functionType && type)
+         if(editor.functionType && type && type.kind == functionType)
          {
             PrintType(type.returnType, string, true, true);
             display.FontExtent(font, string, strlen(string), &functionW, null);
@@ -1811,7 +1871,7 @@ class CodeEditor : Window
                display.FontExtent(boldFont, instanceName, strlen(instanceName), &nameW, null);
             totalW = functionW + nameW + spaceW;
          }
-            
+
          if(editor.functionType)
          {
             if(methodType)
@@ -1849,7 +1909,7 @@ class CodeEditor : Window
                   paramString[0] = 0;
                   PrintType(param, paramString, true, true);
                   display.FontExtent((id == editor.paramsID || param.kind == ellipsisType) ? boldFont : font, paramString, strlen(paramString), &width, null);
-                  if(param.next) 
+                  if(param.next)
                      width += ((id == editor.paramsID) ? commaWB : commaW);
 
                   if(!height)
@@ -1878,48 +1938,65 @@ class CodeEditor : Window
       }
    };
 
-   Menu fileMenu { menu, $"File", f };  // MenuPlacement?
+   Menu fileMenu { menu, $"File", f };
    MenuItem { fileMenu, $"Save", s, Key { s, ctrl = true }, NotifySelect = MenuFileSave };
    MenuItem { fileMenu, $"Save As...", a, NotifySelect = MenuFileSaveAs };
 
-   Menu debugMenu { menu, $"Debug", d };  // MenuPlacement?
-   MenuItem debugRunToCursor
+   Menu editMenu { menu, $"Edit", e };
+   MenuDivider { editMenu };
+   MenuItem clearTrailingSpacesItem
    {
-      debugMenu, $"Run To Cursor", c, Key { f10, ctrl = true };
+      editMenu, $"Clear trailing spaces", t, Key { t, ctrl = true, shift = true };
+
       bool NotifySelect(MenuItem selection, Modifiers mods)
       {
-         ProjectView projectView = ide.projectView;
-         if(!projectView.buildInProgress)
+         // Nuke trailing spaces
+         EditLine line;
+         int y = 0;
+         editBox.recordUndoEvent = true;
+         for(line = editBox.firstLine; line; line = line.next, y++)
          {
-            int line = editBox.lineNumber + 1;
-            if(projectView)
-            {
-               CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
-               ProjectConfig config = projectView.project.config;
-               ide.debugger.RunToCursor(compiler, config, fileName, line, false);
-               delete compiler;
-            }
+            const String buffer = line.text;
+            int count = line.count, i = count-1;
+            while(i >= 0 && isspace(buffer[i])) i--;
+            if(i < count - 1)
+               editBox.Delete(line, y, i + 1, line, y, count);
          }
+         editBox.recordUndoEvent = false;
          return true;
       }
    };
-   MenuItem debugSkipRunToCursor
+
+   Menu debugMenu { menu, $"Debug", d };
+   MenuItem debugRunToCursor                { debugMenu, $"Run To Cursor", c, ctrlF10,                                                                  id = RTCMenuBits { false, false, false }, NotifySelect = RTCMenu_NotifySelect; };
+   MenuItem debugSkipRunToCursor            { debugMenu, $"Run To Cursor Skipping Breakpoints", u, Key { f10, ctrl = true, shift = true },              id = RTCMenuBits { true,  false, false }, NotifySelect = RTCMenu_NotifySelect; };
+   MenuItem debugRunToCursorAtSameLevel     { debugMenu, $"Run To Cursor At Same Level", l, altF10,                                                     id = RTCMenuBits { false, true,  false }, NotifySelect = RTCMenu_NotifySelect; };
+   MenuItem debugSkipRunToCursorAtSameLevel { debugMenu, $"Run To Cursor At Same Level Skipping Breakpoints", g, Key { f10, shift = true, alt = true }, id = RTCMenuBits { true,  true,  false }, NotifySelect = RTCMenu_NotifySelect; };
+#if 0
+   MenuItem debugBpRunToCursor                { debugMenu, $"BP Run To Cursor"/*, c, ctrlF10*/,                                                                  id = RTCMenuBits { false, false, true  }, NotifySelect = RTCMenu_NotifySelect; };
+   MenuItem debugBpSkipRunToCursor            { debugMenu, $"BP Run To Cursor Skipping Breakpoints"/*, u, Key { f10, ctrl = true, shift = true }*/,              id = RTCMenuBits { true,  false, true  }, NotifySelect = RTCMenu_NotifySelect; };
+   MenuItem debugBpRunToCursorAtSameLevel     { debugMenu, $"BP Run To Cursor At Same Level"/*, l, altF10*/,                                                     id = RTCMenuBits { false, true,  true  }, NotifySelect = RTCMenu_NotifySelect; };
+   MenuItem debugBpSkipRunToCursorAtSameLevel { debugMenu, $"BP Run To Cursor At Same Level Skipping Breakpoints"/*, g, Key { f10, shift = true, alt = true }*/, id = RTCMenuBits { true,  true,  true  }, NotifySelect = RTCMenu_NotifySelect; };
+#endif
+   bool RTCMenu_NotifySelect(MenuItem selection, Modifiers mods)
    {
-      debugMenu, $"Run To Cursor Skipping Breakpoints", u, Key { f10, ctrl = true, shift = true };
-      bool NotifySelect(MenuItem selection, Modifiers mods)
+      ProjectView projectView = ide.projectView;
+      if(!projectView.buildInProgress)
       {
-         ProjectView projectView = ide.projectView;
+         RTCMenuBits bits = (RTCMenuBits)selection.id;
          int line = editBox.lineNumber + 1;
          if(projectView)
          {
-            CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+            CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
             ProjectConfig config = projectView.project.config;
-            ide.debugger.RunToCursor(compiler, config, fileName, line, true);
+            int bitDepth = ide.workspace.bitDepth;
+            bool useValgrind = ide.workspace.useValgrind;
+            ide.debugger.RunToCursor(compiler, config, bitDepth, useValgrind, fileName, line, bits.ignoreBreakpoints, bits.atSameLevel, bits.oldImplementation);
             delete compiler;
          }
-         return true;
       }
-   };
+      return true;
+   }
    MenuDivider { debugMenu };
    MenuItem debugToggleBreakpoint
    {
@@ -1930,33 +2007,7 @@ class CodeEditor : Window
          if(projectView && fileName)
          {
             int line = editBox.lineNumber + 1;
-            char name[MAX_LOCATION];
-            Project prj = null;
-            // TOFIX: This only looks at the filename...
-            GetLastDirectory(fileName, name);
-            if(ide && ide.workspace)
-            {
-               for(p : ide.workspace.projects)
-               {
-                  if(p.topNode.Find(name, false))
-                  {
-                     prj = p;
-                     break;
-                  }
-               }
-               if(!prj)
-               {
-                  for(p : ide.workspace.projects)
-                  {
-                     if(IsPathInsideOf(fileName, p.topNode.path))
-                     {
-                        prj = p;
-                        break;
-                     }
-                  }
-               }
-            }
-            ide.debugger.ToggleBreakpoint(fileName, line, prj);
+            ide.debugger.ToggleBreakpoint(fileName, line);
             Update(null);
          }
          return true;
@@ -1987,7 +2038,7 @@ class CodeEditor : Window
       if(!parentClosing)
       {
          if(ide.workspace && fileName)
-            ide.workspace.UpdateOpenedFileInfo(fileName, closed);
+            ide.workspace.UpdateOpenedFileInfo(fileName, closed, false);
          if(inUseDebug && !debugClosing)
          {
             debugClosing = true;
@@ -1995,7 +2046,8 @@ class CodeEditor : Window
             if(CloseConfirmation(false))
             {
                visible = false;
-               OnFileModified({ modified = true }, null);
+               if(modifiedDocument)
+                  OnFileModified({ modified = true }, null);
             }
             debugClosing = false;
             return false;
@@ -2021,7 +2073,7 @@ class CodeEditor : Window
    void OnDestroy(void)
    {
       ObjectInfo oClass, next;
-      Class windowClass = eSystem_FindClass(this.privateModule, "ecere::gui::Window");
+      // Class windowClass = eSystem_FindClass(this.privateModule, "ecere::gui::Window");
 
       FreeType(this.functionType);
       FreeType(this.instanceType);
@@ -2037,7 +2089,7 @@ class CodeEditor : Window
       for(oClass = (classes).first, next = oClass ? oClass.next : null; oClass; oClass = next, next = next ? (next.next) : null)
       {
          ObjectInfo object, next;
-         
+
          for(object = oClass.instances.first; object; object = next)
          {
             next = object.next;
@@ -2046,6 +2098,11 @@ class CodeEditor : Window
                Designer::DestroyObject(object.instance);
                delete object.instance;
             }
+            if(object.i18nStrings)
+            {
+               Map<String, bool> i18nStrings = object.i18nStrings;
+               delete i18nStrings;
+            }
             sheet.DeleteObject(object);
             delete object.name;
             oClass.instances.Delete(object);
@@ -2055,14 +2112,16 @@ class CodeEditor : Window
             Designer::DestroyObject(oClass.instance);
             delete oClass.instance;
          }
+         if(oClass.i18nStrings)
+         {
+            Map<String, bool> i18nStrings = oClass.i18nStrings;
+            delete i18nStrings;
+         }
          sheet.DeleteObject(oClass);
          delete oClass.name;
          classes.Delete(oClass);
       }
 
-      if(windowClass && windowClass.data)
-         UnapplySkin(windowClass);
-
       FreeParser();
 
       if(sheet.codeEditor == this)
@@ -2077,7 +2136,7 @@ class CodeEditor : Window
          ProjectView projectView = ide.projectView;
          if(projectView)
          {
-            ProjectNode node = projectView.GetNodeFromWindow(this, null);
+            ProjectNode node = projectView.GetNodeFromWindow(this, null, true, false, null);
             if(node && node.modified)
             {
                node.modified = false;
@@ -2096,6 +2155,7 @@ class CodeEditor : Window
       */
       if(active && directActivation)
       {
+         AdjustDebugMenus();
          if(openedFileInfo)
             openedFileInfo.Activate();
          if(designer)
@@ -2147,10 +2207,29 @@ class CodeEditor : Window
             ProcessCaretMove(editBox, line, charPos);
          }
       }
+      if(!active)
+      {
+         if(membersListShown)
+         {
+            membersList.Destroy(0);
+            membersListShown = false;
+         }
+         if(paramsShown)
+         {
+            paramsList.Destroy(0);
+            paramsShown = false;
+            FreeType(functionType);
+            FreeType(instanceType);
+
+            functionType = null;
+            instanceType = null;
+            paramsID = -1;
+         }
+      }
       return true;
    }
 
-   bool OnSaveFile(char * fileName)
+   bool OnSaveFile(const char * fileName)
    {
       File f;
       if(designer)
@@ -2169,27 +2248,28 @@ class CodeEditor : Window
             designer.fileName = fileName;
             designer.modifiedDocument = false;
          }
+
          editBox.Save(f, false);
          modifiedDocument = false;
-         
-         delete(f);
+
+         delete f;
          return true;
       }
       return false;
    }
 
-   bool OnFileModified(FileChange fileChange, char * param)
+   bool OnFileModified(FileChange fileChange, const char * param)
    {
       bool reload = false;
       if(visible == false && inUseDebug == true)
-         reload = true;
+         ide.debugger.WatchesReleaseCodeEditor();
       else
       {
          char message[2048];
 
          sprintf(message, $"The document %s was modified by another application.\n"
             "Would you like to reload it and lose your changes?", fileName);
-         if(MessageBox { type = yesNo, master = /*parent = */parent, text = $"Document has been modified",
+         if(MessageBox { creationActivation = flash, type = yesNo, master = /*parent = */parent, text = $"Document has been modified",
             contents = message }.Modal() == yes)
             reload = true;
       }
@@ -2225,7 +2305,7 @@ class CodeEditor : Window
             }
             modifiedDocument = false;
 
-            delete(f);
+            delete f;
          }
       }
       return true;
@@ -2234,12 +2314,13 @@ class CodeEditor : Window
    void OnRedraw(Surface surface)
    {
       // Line Numbers
-      surface.SetBackground(marginColor);
+      surface.SetBackground(colorScheme.marginColor);
       surface.Area(0, 0, editBox.anchor.left.distance, clientSize.h - 1);
       if(ideSettings.showLineNumbers)
       {
          int currentLineNumber;
          int i;
+         char lineFormat[16];
          char lineText[256];
          int spaceH;
 
@@ -2247,28 +2328,28 @@ class CodeEditor : Window
          surface.font = font.font;
          surface.TextExtent(" ", 1, null, &spaceH);
          currentLineNumber = editBox.scroll.y / spaceH + 1;
+         sprintf(lineFormat, " %%%du", maxLineNumberLength);
 
-         surface.SetForeground(lineNumbersColor);
+         surface.SetForeground(colorScheme.lineNumbersColor);
          for(i = 0; i < editBox.clientSize.h - 4; i += spaceH)
          {
             // Highlight current line
             if(editBox.lineNumber == currentLineNumber - 1)
             {
-               surface.SetBackground(selectedMarginColor);
+               surface.SetBackground(colorScheme.selectedMarginColor);
                surface.Area(0, i, editBox.anchor.left.distance, i+spaceH-1);
-               surface.SetBackground(marginColor);
+               surface.SetBackground(colorScheme.marginColor);
             }
-            sprintf(lineText,"%5u ", currentLineNumber % 100000);
+            sprintf(lineText, lineFormat, currentLineNumber);
             if(currentLineNumber <= editBox.numLines)
-               surface.WriteText(editBox.syntaxHighlighting * 20, i+1,lineText,6);
-            
+               surface.WriteText(editBox.syntaxHighlighting * 20, i+1,lineText,maxLineNumberLength+1);
             currentLineNumber++;
          }
       }
 
       if(editBox.syntaxHighlighting && fileName && ide.projectView)
       {
-         bool error, bpOnCursor, bpOnTopFrame, breakpointEnabled[128];
+         bool error, bpOnTopFrame, breakpointEnabled[128];
          int lineCursor, lineTopFrame, breakpointLines[128];
          int count, i, lineH, boxH, scrollY; //, firstLine; firstLine = editBox.firstLine;
          Debugger debugger = ide.debugger;
@@ -2278,7 +2359,7 @@ class CodeEditor : Window
          scrollY = editBox.scroll.y;
          displaySystem.FontExtent(editBox.font.font, " ", 1, null, &lineH);
 
-         bpOnCursor = bpOnTopFrame = false;
+         bpOnTopFrame = false;
          count = debugger.GetMarginIconsLineNumbers(fileName, breakpointLines, breakpointEnabled, 128, &error, &lineCursor, &lineTopFrame);
          if(count)
          {
@@ -2287,14 +2368,12 @@ class CodeEditor : Window
                if(breakpointLines[i] == lineCursor || breakpointLines[i] == lineTopFrame)
                {
                   bmpRes = breakpointEnabled[i] ? ide.bmpBpHalf : ide.bmpBpHalfDisabled;
-                  if(breakpointLines[i] == lineCursor)
-                     bpOnCursor = true;
                   if(breakpointLines[i] == lineTopFrame)
                      bpOnTopFrame = true;
                }
                else
                   bmpRes = breakpointEnabled[i] ? ide.bmpBp : ide.bmpBpDisabled;
-               
+
                DrawLineMarginIcon(surface, bmpRes, breakpointLines[i], lineH, scrollY, boxH);
             }
          }
@@ -2330,7 +2409,7 @@ class CodeEditor : Window
    watch(fileName)
    {
       char ext[MAX_EXTENSION];
-      char * fileName = property::fileName;
+      const char * fileName = property::fileName;
 
       if(SearchString(fileName, 0, "Makefile", false, true))
          editBox.useTab = true;
@@ -2339,46 +2418,63 @@ class CodeEditor : Window
       if(fileName)
       {
          GetExtension(fileName, ext);
-         if(!strcmpi(ext, "ec"))
-         {
-            codeModified = true;
-            EnsureUpToDate();
-         }
 
-         if(!strcmpi(ext, "ec") || !strcmpi(ext, "c") || !strcmpi(ext, "cc") || !strcmpi(ext, "cpp") || !strcmpi(ext, "eh") || !strcmpi(ext, "hh") || !strcmpi(ext, "hpp") || !strcmpi(ext, "h") || !strcmpi(ext, "hxx") || !strcmpi(ext, "cxx"))
+         if(!strcmpi(ext, "ec") || !strcmpi(ext, "eh") || !strcmpi(ext, "c") || !strcmpi(ext, "h") || !strcmpi(ext, "cpp") ||
+               !strcmpi(ext, "hpp") || !strcmpi(ext, "cxx") || !strcmpi(ext, "hxx") || !strcmpi(ext, "cc") || !strcmpi(ext, "hh") ||
+               !strcmpi(ext, "m") || !strcmpi(ext, "mm") || !strcmpi(ext, "cs") || !strcmpi(ext, "java") || !strcmpi(ext, "y") || !strcmpi(ext, "l"))
             editBox.syntaxHighlighting = true;
          else
             editBox.syntaxHighlighting = false;
+
+         if(parsing && !strcmpi(ext, "ec"))
          {
-            int spaceW;
-            display.FontExtent(font.font, " ", 1, &spaceW, null);
-            editBox.anchor = Anchor
-            {
-               left = (editBox.syntaxHighlighting ? 20 : 0) + (ideSettings.showLineNumbers ? (6 * spaceW) : 0),
-               right = 0, top = 0, bottom = 0
-            };
+            codeModified = true;
+            EnsureUpToDate();
          }
+
+         maxLineNumberLength = 0;
+         UpdateMarginSize();
       }
    };
 
-   bool OnPostCreate()
+   bool UpdateMarginSize()
    {
-      int spaceW;
-      display.FontExtent(font.font, " ", 1, &spaceW, null);
-      editBox.anchor = Anchor
+      if(ideSettings.showLineNumbers)
+      {
+         int numLen = Max(4, nofdigits(editBox.numLines));
+         int digitWidth;
+         maxLineNumberLength = numLen;
+         display.FontExtent(font.font, "0", 1, &digitWidth, null);
+         editBox.anchor = Anchor
+         {
+            left = editBox.syntaxHighlighting * 20 + ideSettings.showLineNumbers * (maxLineNumberLength+2) * digitWidth,
+            right = 0, top = 0, bottom = 0
+         };
+      }
+      else
       {
-         left = (editBox.syntaxHighlighting ? 20 : 0) + (ideSettings.showLineNumbers ? (6 * spaceW) : 0),
-         right = 0, top = 0, bottom = 0
-      };
+         maxLineNumberLength = 0;
+         editBox.anchor = Anchor
+         {
+            left = editBox.syntaxHighlighting * 20,
+            right = 0, top = 0, bottom = 0
+         };
+      }
+      return true;
+   }
+
+   bool OnPostCreate()
+   {
+      UpdateMarginSize();
       return true;
    }
 
-   bool LoadFile(char * filePath)
+   bool LoadFile(const char * filePath)
    {
       File f = FileOpen(filePath, read);
       if(f)
       {
-         // Added this here... 
+         // Added this here...
          fileName = filePath;
          loadingFile = true;
          updatingCode = true;
@@ -2387,24 +2483,40 @@ class CodeEditor : Window
          loadingFile = false;
          Create();
 
-         delete(f);
+         delete f;
          return true;
       }
       return false;
    }
 
-   void DebugMenusDisabled()
+   void AdjustDebugMenus()
    {
-      bool debugMenusDisabled = ide.GetDebugMenusDisabled();
-      debugRunToCursor.disabled = debugMenusDisabled;
-      debugSkipRunToCursor.disabled = debugMenusDisabled;
-      debugToggleBreakpoint.disabled = debugMenusDisabled;
+      bool unavailable = ide.areDebugMenusUnavailable;
+      bool isNotNotRunning    = unavailable || ide.isDebuggerRunning;
+      bool isNotStopped       = unavailable || !ide.isDebuggerStopped;
+      bool noBreakpointToggle = ide.isBreakpointTogglingUnavailable;
+
+      debugRunToCursor.disabled                = isNotNotRunning;
+      debugSkipRunToCursor.disabled            = isNotNotRunning;
+      debugRunToCursorAtSameLevel.disabled     = isNotStopped;
+      debugSkipRunToCursorAtSameLevel.disabled = isNotStopped;
+#if 0
+      debugBpRunToCursor.disabled                = isNotNotRunning;
+      debugBpSkipRunToCursor.disabled            = isNotNotRunning;
+      debugBpRunToCursorAtSameLevel.disabled     = isNotStopped;
+      debugBpSkipRunToCursorAtSameLevel.disabled = isNotStopped;
+#endif
+      debugToggleBreakpoint.disabled           = noBreakpointToggle;
    }
 
    CodeEditor()
    {
       CodeObjectType c;
-      ProjectView projectView = ide.projectView;
+
+      globalData.classes.CompareKey = (void *)BinaryTree::CompareString;
+      globalData.defines.CompareKey = (void *)BinaryTree::CompareString;
+      globalData.functions.CompareKey = (void *)BinaryTree::CompareString;
+      globalData.nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
 
       /*if(fileName)
          designer.fileName = fileName;
@@ -2418,7 +2530,7 @@ class CodeEditor : Window
          designer.fileName = title;
       }
 
-      DebugMenusDisabled();
+      AdjustDebugMenus();
 
       for(c = 0; c < CodeObjectType::enumSize; c++)
          icons[c] = BitmapResource { iconNames[c], window = this };
@@ -2435,6 +2547,7 @@ class CodeEditor : Window
 
    void ModifyCode()
    {
+      fixCaret = true;
       selected.modified = true;
       selected.oClass.modified = true;
 
@@ -2448,18 +2561,27 @@ class CodeEditor : Window
    ****************************************************************************/
    void FreeParser()
    {
-      this.defines.Free(FreeModuleDefine);
-      this.imports.Free(FreeModuleImport);
-      
-      if(ast != null)
+      {
+         Class windowClass = eSystem_FindClass(privateModule, "ecere::gui::Window");
+         if(windowClass && windowClass.data)
+            UnapplySkin(windowClass);
+      }
+
+      SetCurrentNameSpace(null);
+      if(ast)
       {
          FreeASTTree(ast);
          ast = null;
       }
-      FreeExcludedSymbols(this.excludedSymbols);
-      FreeContext(this.globalContext);
+      defines.Free(FreeModuleDefine);
+      imports.Free(FreeModuleImport);   // Moved this after FreeAST because Debug printing causes ModuleImports to be created
+
+      FreeExcludedSymbols(excludedSymbols);
+      FreeContext(globalContext);
       FreeIncludeFiles();
-      FreeGlobalData(&this.globalData);
+      FreeGlobalData(&globalData);
+      FindCtx_Terminate();
+      FindParams_Terminate();
 
       if(GetGlobalContext() == globalContext)
       {
@@ -2473,11 +2595,26 @@ class CodeEditor : Window
          SetPrivateModule(null);
       }
 
+      // Note: This code should probably be merged with FreeParser()
+      if(ast)
+      {
+         FreeASTTree(ast);
+         ast = null;
+         //SetAST(null);
+      }
+      defines.Free(FreeModuleDefine);
+      imports.Free(FreeModuleImport);
+
+      FreeContext(this.globalContext);
+      FreeExcludedSymbols(this.excludedSymbols);
+
+      FreeIncludeFiles();
+      FreeGlobalData(&this.globalData);
+
       if(this.privateModule)
       {
          FreeTypeData(this.privateModule);
          delete this.privateModule;
-         this.privateModule = null;
       }
    }
 
@@ -2493,9 +2630,10 @@ class CodeEditor : Window
       Designer backDesigner;
       char oldWorkDir[MAX_LOCATION];
       char mainModuleName[MAX_FILENAME] = "";
-      char * fileName;
+      const char * fileName;
       ImportedModule module;
       char extension[MAX_EXTENSION];
+      PathBackup pathBackup { };
 #ifdef _TIMINGS
       Time parseCodeStart = GetTime();
       Time startTime, startFindClass;
@@ -2509,7 +2647,7 @@ class CodeEditor : Window
 #endif
       Project project;
 
-      // This temporarily fixes issue with 2 overrides in release mode with VC6 (only happens with both ecere.dll and ide.exe compiled in release mode)
+      // This temporarily fixes issue with 2 overrides in release mode with VC6 (only happens with both ecere.dll and ecere-ide.exe compiled in release mode)
       if(reentrant) return;
       reentrant = true;
 
@@ -2533,24 +2671,12 @@ class CodeEditor : Window
                }
             }
          }
-         else 
+         else
             selectedPos = -1;
       }
 
       editBox.GetSelPos(&l1, &y1, &x1, &l2, &y2, &x2, false);
 
-      defines.Free(FreeModuleDefine);
-      imports.Free(FreeModuleImport);
-
-      SetGlobalData(&globalData);
-      SetGlobalContext(globalContext);
-      SetExcludedSymbols(&excludedSymbols);
-      SetTopContext(globalContext);
-      SetCurrentContext(globalContext);
-      SetDefines(&defines);
-      SetImports(&imports);
-      SetCurrentNameSpace(null);
-
       /*
       sprintf(command, "C:\\Program Files\\Microsoft Visual Studio\\VC98\\Bin\\cl "
          "/nologo /D \"MSC\" /D \"WIN32\" /D \"NDEBUG\" /D \"_WINDOWS\" /D \"_MBCS\" "
@@ -2580,6 +2706,8 @@ class CodeEditor : Window
 
       // TOCHECK: COULDN'T WE CALL FreeParser here?
       // Clear everything
+      FreeType(this.functionType);
+      FreeType(this.instanceType);
       this.functionType = null;
       this.instanceType = null;
 
@@ -2597,20 +2725,25 @@ class CodeEditor : Window
       if(this.oClass)
       {
          ObjectInfo _class, next;
-         
+
          for(_class = classes.first; _class; _class = next)
          {
             ObjectInfo object;
 
             next = _class.next;
-            
-            for(;object = _class.instances.first;)
+
+            while((object = _class.instances.first))
             {
                if(object.instance)
                {
                   Designer::DestroyObject(object.instance);
                   delete object.instance;
                }
+               if(object.i18nStrings)
+               {
+                  Map<String, bool> i18nStrings = object.i18nStrings;
+                  delete i18nStrings;
+               }
                sheet.DeleteObject(object);
                delete object.name;
                _class.instances.Delete(object);
@@ -2620,6 +2753,11 @@ class CodeEditor : Window
                Designer::DestroyObject(_class.instance);
                delete _class.instance;
             }
+            if(_class.i18nStrings)
+            {
+               Map<String, bool> i18nStrings = _class.i18nStrings;
+               delete i18nStrings;
+            }
             sheet.DeleteObject(_class);
             delete _class.name;
             classes.Delete(_class);
@@ -2627,36 +2765,21 @@ class CodeEditor : Window
          this.oClass = null;
       }
 
-      {
-         Class windowClass = eSystem_FindClass(this.privateModule, "ecere::gui::Window");
-         if(windowClass && windowClass.data)
-            UnapplySkin(windowClass);
-      }
-
       designer = backDesigner;
 
       SetEchoOn(true);
       fileInput = editFile = EditBoxStream { editBox = editBox };
       SetFileInput(fileInput);
 
-      if(ast)
-      {
-         FreeASTTree(ast);
-         ast = null;
-         //SetAST(null);
-      }
-
-      FreeContext(this.globalContext);
-      FreeExcludedSymbols(this.excludedSymbols);
-
-      FreeIncludeFiles();
-      FreeGlobalData(&this.globalData);
+      FreeParser();
 
-      if(this.privateModule)
-      {
-         FreeTypeData(this.privateModule);
-         delete this.privateModule;
-      }
+      SetGlobalData(&globalData);
+      SetGlobalContext(globalContext);
+      SetExcludedSymbols(&excludedSymbols);
+      SetTopContext(globalContext);
+      SetCurrentContext(globalContext);
+      SetDefines(&defines);
+      SetImports(&imports);
 
 #ifdef _TIMINGS
       startTime = GetTime();
@@ -2667,11 +2790,11 @@ class CodeEditor : Window
 
       if(ide.workspace)
       {
-         CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
-         SetTargetBits(compiler.supportsBitDepth ? 32 : GetHostBits());
+         CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
+         SetTargetBits(ide.workspace.bitDepth ? ide.workspace.bitDepth : GetHostBits());
          delete compiler;
       }
-      this.privateModule = __ecere_COM_Initialize(false | ((GetTargetBits() == sizeof(uintptr) *8) ? 0 : GetTargetBits() == 64 ? 2 : 4), 1, null);
+      this.privateModule = __ecere_COM_Initialize((bool)(false | ((GetTargetBits() == sizeof(uintptr) *8) ? 0 : GetTargetBits() == 64 ? 2 : 4)), 1, null);
 
       SetPrivateModule(privateModule);
 
@@ -2704,7 +2827,7 @@ class CodeEditor : Window
       }
       if(!project)
          project = ide.project;
-         
+
       GetWorkingDir(oldWorkDir, MAX_LOCATION);
       if(project)
          ChangeWorkingDir(project.topNode.path);
@@ -2720,10 +2843,14 @@ class CodeEditor : Window
       // TODO: Get symbolsDir from project settings instead...
       if(ide.projectView)
       {
-         CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+         CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler);
          ProjectConfig config = project.config;
-         DirExpression objDir = project.GetObjDir(compiler, config);
+         int bitDepth = ide.workspace.bitDepth;
+         DirExpression objDir = project.GetObjDir(compiler, config, bitDepth);
          SetSymbolsDir(objDir.dir);
+         SetDefaultNameSpace(project.GetDefaultNameSpace(config));
+         ide.SetPath(true, compiler, config, bitDepth);
+
          delete objDir;
          delete compiler;
          // SetIncludeDirs(ide.projectView.project.config.includeDirs);
@@ -2731,14 +2858,15 @@ class CodeEditor : Window
       }
       else
       {
-         switch(GetRuntimePlatform())
+         switch(__runtimePlatform)
          {
             case win32: SetSymbolsDir("obj/debug.win32"); break;
             case tux:   SetSymbolsDir("obj/debug.linux"); break;
             case apple: SetSymbolsDir("obj/debug.apple"); break;
-         }         
+         }
          SetIncludeDirs(null);
          SetSysIncludeDirs(null);
+         SetDefaultNameSpace(null);
       }
 
       {
@@ -2757,7 +2885,7 @@ class CodeEditor : Window
                }
             }
          }
-         
+
          if(!(strcmpi(mainModuleName, "instance.ec") && strcmpi(mainModuleName, "BinaryTree.ec") &&
             strcmpi(mainModuleName, "dataTypes.ec") && strcmpi(mainModuleName, "OldList.ec") &&
             strcmpi(mainModuleName, "String.ec") && strcmpi(mainModuleName, "BTNode.ec") &&
@@ -2781,7 +2909,7 @@ class CodeEditor : Window
 
             strcpy(symLocation, GetSymbolsDir());
             PathCat(symLocation, symFile);
-            
+
             // if(!GetEcereImported() && !GetBuildingEcereCom())
             if(!strcmp(extension, "ec") || !strcmp(extension, "eh"))
             {
@@ -2847,7 +2975,7 @@ class CodeEditor : Window
 
       SetIncludeDirs(null);
       SetSysIncludeDirs(null);
-      
+
       delete editFile;
       fileInput = null;
       SetFileInput(null);
@@ -2855,7 +2983,7 @@ class CodeEditor : Window
       if(GetAST())
       {
          ast = GetAST();
-         
+
 #ifdef _TIMINGS
          startTime = GetTime();
 #endif
@@ -2915,14 +3043,13 @@ class CodeEditor : Window
                      if(eClass_GetDesigner(regClass) && !GetBuildingEcereComModule())
                      {
                         Instance instance = eInstance_New(regClass);
-                        ObjectInfo classObject 
+                        ObjectInfo classObject
                         {
                            name = CopyString(_class._class.name);
                            instance = instance;
                            classDefinition = _class;
                            oClass = classObject;
                         };
-                        Symbol symbol;
                         classes.Add(classObject);
 
                         incref instance;
@@ -2955,80 +3082,77 @@ class CodeEditor : Window
                                                 propertyClass = prop.dataTypeClass = eSystem_FindClass(this.privateModule, prop.dataTypeString);
                                              if(prop.compiled && prop.Set && prop.Get && propertyClass && propDef.initializer && propDef.initializer.type == expInitializer && propDef.initializer.exp)
                                              {
+                                                Expression computed;
+                                                bool variable = true;
+
                                                 FreeType(propDef.initializer.exp.destType);
                                                 propDef.initializer.exp.destType = MkClassType(propertyClass.name);
                                                 ProcessExpressionType(propDef.initializer.exp);
-                                             
-                                                if(propertyClass.type == structClass || propertyClass.type == noHeadClass || propertyClass.type == normalClass)
-                                                {
-                                                   Expression computed = CopyExpression(propDef.initializer.exp);
-                                                   ComputeExpression(computed);
 
-                                                   if(computed.isConstant && computed.type == instanceExp && !id.next)
+                                                computed = CopyExpression(propDef.initializer.exp);
+                                                ComputeExpression(computed);
+                                                if(computed.isConstant)
+                                                {
+                                                   switch(computed.type)
                                                    {
-                                                      if(prop.Set)
-                                                      {
-                                                         if(computed.instance._class && computed.instance._class.symbol &&
-                                                            computed.instance._class.symbol.registered && 
-                                                            eClass_IsDerived(computed.instance._class.symbol.registered, propertyClass))
+                                                      case stringExp:
+                                                         if(propertyClass.dataTypeString && strstr(propertyClass.dataTypeString, "char *"))
                                                          {
-                                                            ((void (*)(void *, void *))(void *)prop.Set)(instance, computed.instance.data);
+                                                            String temp = new char[strlen(computed.string)+1];
+                                                            ReadString(temp, computed.string);
+                                                            ((void (*)(void *, void *))(void *)prop.Set)(instance, temp);
+                                                            delete temp;
 
-                                                            // This was saved in the control and shouldn't be freed by FreeExpression...
-                                                            if(propertyClass.type == normalClass)
-                                                               computed.instance.data = null;
+                                                            if(!propDef.initializer.exp.intlString)
+                                                            {
+                                                               Map<String, bool> i18nStrings = classObject.i18nStrings;
+                                                               if(!i18nStrings)
+                                                                  classObject.i18nStrings = i18nStrings = { };
+                                                               i18nStrings[prop.name] = false;
+                                                            }
+                                                            variable = false;
                                                          }
-                                                      }
-                                                   }
-                                                   // MOVED THIS UP NOW THAT char * IS A NORMAL CLASS
-                                                   else if(computed.type == stringExp && propertyClass.dataTypeString && strstr(propertyClass.dataTypeString, "char *"))
-                                                   {
-                                                      String temp = new char[strlen(computed.string)+1];
-                                                      ReadString(temp, computed.string);
-                                                      ((void (*)(void *, void *))(void *)prop.Set)(instance, temp);
-                                                      delete temp;
-                                                   }
-                                                   else
-                                                      propDef.variable = true;
-                                                   
-                                                   FreeExpression(computed);
-                                                }
-                                                else
-                                                {
-                                                   Expression computed = CopyExpression(propDef.initializer.exp);
-                                                   ComputeExpression(computed);
-                                                   if(computed.isConstant)
-                                                   {
-                                                      //if(computed.type == memberExp) computed = computed.member.exp;
+                                                         break;
+                                                      case instanceExp:
+                                                         if((propertyClass.type == structClass || propertyClass.type == noHeadClass || propertyClass.type == normalClass) && !id.next)
+                                                         {
+                                                            if(prop.Set)
+                                                            {
+                                                               if(computed.instance._class && computed.instance._class.symbol &&
+                                                                  computed.instance._class.symbol.registered &&
+                                                                  eClass_IsDerived(computed.instance._class.symbol.registered, propertyClass))
+                                                               {
+                                                                  ((void (*)(void *, void *))(void *)prop.Set)(instance, computed.instance.data);
 
-                                                      if(computed.type == constantExp)
+                                                                  // This was saved in the control and shouldn't be freed by FreeExpression...
+                                                                  // (Not doing this anymore, incrementing refCount in pass15 instead)
+                                                                  /*if(propertyClass.type == normalClass)
+                                                                     computed.instance.data = null;*/
+                                                               }
+                                                            }
+                                                            variable = false;
+                                                         }
+                                                         break;
+                                                      case constantExp:
                                                       {
                                                          Operand value = GetOperand(computed);
                                                          DataValue valueData;
                                                          valueData.i64 = value.i64;
                                                          SetProperty(prop, instance, valueData);
-                                                      }
-                                                      else if(computed.type == stringExp && propertyClass.dataTypeString && strstr(propertyClass.dataTypeString, "char *"))
-                                                      {
-                                                         String temp = new char[strlen(computed.string)+1];
-                                                         ReadString(temp, computed.string);
-                                                         ((void (*)(void *, void *))(void *)prop.Set)(instance, temp);
-                                                         delete temp;
+                                                         variable = false;
+                                                         break;
                                                       }
                                                    }
-                                                   else
-                                                      propDef.variable = true;
-
-                                                   FreeExpression(computed);
                                                 }
+                                                if(variable)
+                                                   propDef.variable = true;
+                                                FreeExpression(computed);
                                              }
-                                             else
-                                                propDef.variable = true;
                                           }
                                           else
                                           {
                                              Method method = eClass_FindMethod(regClass, id.string, this.privateModule);
-                                             if(method && method.type == virtualMethod && propDef.initializer && propDef.initializer.type == expInitializer && 
+                                             if(method && method.type == virtualMethod && propDef.initializer && propDef.initializer.type == expInitializer &&
                                                 propDef.initializer.exp && propDef.initializer.exp.type == identifierExp)
                                              {
                                                 ClassDef def;
@@ -3044,7 +3168,7 @@ class CodeEditor : Window
                                                       }
                                                    }
                                                 }
-                                             }                                          
+                                             }
                                           }
                                        }
                                     }
@@ -3108,8 +3232,8 @@ class CodeEditor : Window
                                           {
                                              Instance control;
                                              object = object ? object.next : classObject.instances.first;
-                                             control = object.instance;                                             
-                                             
+                                             control = object.instance;
+
                                              if(inst.members)
                                              {
                                                 MembersInit members;
@@ -3145,7 +3269,7 @@ class CodeEditor : Window
                                                                   {
                                                                      curMember = thisMember;
                                                                      curClass = curMember._class;
-                                                                     memcpy(subMemberStack, _subMemberStack, sizeof(int) * _subMemberStackPos);
+                                                                     memcpy(subMemberStack, _subMemberStack, sizeof(DataMember) * _subMemberStackPos);
                                                                      subMemberStackPos = _subMemberStackPos;
                                                                      found = true;
                                                                   }
@@ -3159,6 +3283,7 @@ class CodeEditor : Window
                                                                {
                                                                   Property prop = (Property) curMember;
                                                                   Class propertyClass = prop.dataTypeClass;
+                                                                  bool variable = true;
                                                                   if(!propertyClass)
                                                                      propertyClass = prop.dataTypeClass = eSystem_FindClass(this.privateModule, prop.dataTypeString);
 
@@ -3168,74 +3293,53 @@ class CodeEditor : Window
                                                                      member.initializer.exp.destType = MkClassType(propertyClass.name);
                                                                      if(propertyClass)
                                                                      {
+                                                                        Expression computed;
+
                                                                         ProcessExpressionType(member.initializer.exp);
-                                       
-                                                                        if(propertyClass.type == structClass || propertyClass.type == normalClass || propertyClass.type == noHeadClass)
+
+                                                                        computed = CopyExpression(member.initializer.exp);
+                                                                        if(computed)
                                                                         {
-                                                                           Expression computed;
+                                                                           bool isClass = propertyClass.type == structClass || propertyClass.type == normalClass || propertyClass.type == noHeadClass;
+                                                                           {
 #ifdef _DEBUG
-                                                                           /*char debugExpString[4096];
-                                                                           debugExpString[0] = '\0';
-                                                                           PrintExpression(member.initializer.exp, debugExpString);*/
+                                                                              /*char debugExpString[4096];
+                                                                              debugExpString[0] = '\0';
+                                                                              PrintExpression(member.initializer.exp, debugExpString);*/
 #endif
-                                                                           computed = CopyExpression(member.initializer.exp);
-                                                                           if(computed)
-                                                                           {
                                                                               ComputeExpression(computed);
-                                                                              
-                                                                              if(computed.type == instanceExp && computed.isConstant && computed.isConstant)
-                                                                              {
-                                                                                 if(computed.instance.data)
-                                                                                 {
-                                                                                    if(computed.instance._class && computed.instance._class.symbol &&
-                                                                                       computed.instance._class.symbol.registered && 
-                                                                                       eClass_IsDerived(computed.instance._class.symbol.registered, propertyClass))
-                                                                                    {
-                                                                                       ((void (*)(void *, void *))(void *)prop.Set)(control, computed.instance.data);
 
-                                                                                       // This was saved in the control and shouldn't be freed by FreeExpression...
-                                                                                       if(propertyClass.type == normalClass)
-                                                                                          computed.instance.data = null;
-                                                                                    }
-                                                                                 }
-                                                                              }
-                                                                              else if(computed.type == identifierExp)
+                                                                              switch(computed.type)
                                                                               {
-                                                                                 member.variable = true;
-
-                                                                                 if(eClass_GetDesigner(propertyClass))
-                                                                                 //if(prop.Set)
-                                                                                 {
-                                                                                    char * name = computed.identifier.string;
-                                                                                    if(!strcmp(name, "this"))
+                                                                                 case instanceExp:
+                                                                                    if(isClass && computed.isConstant && computed.instance.data)
                                                                                     {
-                                                                                       if(prop.Set)
-                                                                                          ((void (*)(void *, void *))(void *)prop.Set)(control, instance);
-                                                                                       member.variable = false;
-                                                                                    }
-                                                                                    else
-                                                                                    {
-                                                                                       ObjectInfo check;
-                                                                                       for(check = classObject.instances.first; check; check = check.next)
-                                                                                          if(check.name && !strcmp(name, check.name))
-                                                                                          {
-                                                                                             if(prop.Set)
-                                                                                                ((void (*)(void *, void *))(void *)prop.Set)(control, check.instance);
-                                                                                             member.variable = false;
-                                                                                             break;
-                                                                                          }
+                                                                                       if(computed.instance._class && computed.instance._class.symbol &&
+                                                                                          computed.instance._class.symbol.registered &&
+                                                                                          eClass_IsDerived(computed.instance._class.symbol.registered, propertyClass))
+                                                                                       {
+                                                                                          ((void (*)(void *, void *))(void *)prop.Set)(control, computed.instance.data);
+
+                                                                                          // This was saved in the control and shouldn't be freed by FreeExpression...
+                                                                                          // (Not doing this anymore, incrementing refCount in pass15 instead)
+                                                                                          /*if(propertyClass.type == normalClass)
+                                                                                             computed.instance.data = null;*/
+                                                                                       }
+                                                                                       variable = false;
                                                                                     }
-                                                                                 }
-                                                                              }
-                                                                              else if(computed.type == memberExp)
-                                                                              {
-                                                                                 member.variable = true;
-                                                                                 if(computed.member.exp.type == identifierExp)
-                                                                                 {
-                                                                                    char * name = computed.member.exp.identifier.string;
-                                                                                    if(!strcmp(name, "this"))
+                                                                                    break;
+                                                                                 case identifierExp:
+                                                                                    if(isClass && eClass_GetDesigner(propertyClass))
+                                                                                    //if(prop.Set)
                                                                                     {
-                                                                                       char * name = computed.member.member.string;
+                                                                                       char * name = computed.identifier.string;
+                                                                                       if(!strcmp(name, "this"))
+                                                                                       {
+                                                                                          if(prop.Set)
+                                                                                             ((void (*)(void *, void *))(void *)prop.Set)(control, instance);
+                                                                                          variable = false;
+                                                                                       }
+                                                                                       else
                                                                                        {
                                                                                           ObjectInfo check;
                                                                                           for(check = classObject.instances.first; check; check = check.next)
@@ -3243,83 +3347,97 @@ class CodeEditor : Window
                                                                                              {
                                                                                                 if(prop.Set)
                                                                                                    ((void (*)(void *, void *))(void *)prop.Set)(control, check.instance);
-                                                                                                member.variable = false;
+                                                                                                variable = false;
                                                                                                 break;
                                                                                              }
                                                                                        }
                                                                                     }
-                                                                                    else
+                                                                                    break;
+                                                                                 case memberExp:
+                                                                                    if(isClass)
                                                                                     {
-                                                                                       ObjectInfo check;
-                                                                                       for(check = classObject.instances.first; check; check = check.next)
+                                                                                       if(computed.member.exp.type == identifierExp)
                                                                                        {
-                                                                                          if(check.name && !strcmp(name, check.name))
+                                                                                          char * name = computed.member.exp.identifier.string;
+                                                                                          ObjectInfo check;
+                                                                                          if(!strcmp(name, "this"))
+                                                                                          {
+                                                                                             if(computed.member.member)
+                                                                                             {
+                                                                                                char * name = computed.member.member.string;
+                                                                                                ObjectInfo check;
+                                                                                                for(check = classObject.instances.first; check; check = check.next)
+                                                                                                   if(check.name && !strcmp(name, check.name))
+                                                                                                   {
+                                                                                                      if(prop.Set)
+                                                                                                         ((void (*)(void *, void *))(void *)prop.Set)(control, check.instance);
+                                                                                                      variable = false;
+                                                                                                      break;
+                                                                                                   }
+                                                                                             }
+                                                                                          }
+                                                                                          else
                                                                                           {
-                                                                                             Property getProperty = eClass_FindProperty(check.instance._class, computed.member.member.string, this.privateModule);
-                                                                                             if(getProperty)
+                                                                                             for(check = classObject.instances.first; check; check = check.next)
                                                                                              {
-                                                                                                DataValue value { };
-                                                                                                GetProperty(getProperty, check.instance, &value);
-                                                                                                SetProperty(prop, control, value);
-                                                                                                member.variable = false;
+                                                                                                if(check.name && !strcmp(name, check.name))
+                                                                                                {
+                                                                                                   Property getProperty = eClass_FindProperty(check.instance._class, computed.member.member.string, this.privateModule);
+                                                                                                   if(getProperty)
+                                                                                                   {
+                                                                                                      DataValue value { };
+                                                                                                      GetProperty(getProperty, check.instance, &value);
+                                                                                                      SetProperty(prop, control, value);
+                                                                                                      variable = false;
+                                                                                                   }
+                                                                                                   break;
+                                                                                                }
                                                                                              }
-                                                                                             break;
                                                                                           }
                                                                                        }
                                                                                     }
-                                                                                 }
-                                                                              }
-                                                                              // MOVED THIS UP NOW THAT char * IS A NORMAL CLASS
-                                                                              else if(computed.isConstant && computed.type == stringExp && propertyClass.dataTypeString && strstr(propertyClass.dataTypeString, "char *"))
-                                                                              {
-                                                                                 String temp = new char[strlen(computed.string)+1];
-                                                                                 ReadString(temp, computed.string);
-                                                                                 ((void (*)(void *, void *))(void *)prop.Set)(control, temp);
-                                                                                 delete temp;
-                                                                              }
-                                                                              else
-                                                                                 member.variable = true;
+                                                                                    break;
+                                                                                 case stringExp:
+                                                                                    if(propertyClass.dataTypeString && strstr(propertyClass.dataTypeString, "char *"))
+                                                                                    {
+                                                                                       String temp = new char[strlen(computed.string)+1];
+                                                                                       ReadString(temp, computed.string);
+                                                                                       ((void (*)(void *, void *))(void *)prop.Set)(control, temp);
+                                                                                       delete temp;
 
-                                                                              FreeExpression(computed);
-                                                                           }
-                                                                        }
-                                                                        else
-                                                                        {
-                                                                           Expression computed = CopyExpression(member.initializer.exp);
-                                                                           if(computed)
-                                                                           {
-                                                                              ComputeExpression(computed);
-                                                                              if(computed.isConstant)
-                                                                              {
-                                                                                 if(computed.type == constantExp && (!propertyClass.dataTypeString || strcmp(propertyClass.dataTypeString, "char *"))) //(strcmp(propertyClass.name, "char *") && (strcmp(propertyClass.name, "String"))))
-                                                                                 {
-                                                                                    if(!strcmp(propertyClass.dataTypeString, "float"))
-                                                                                       ((void (*)(void *, float))(void *)prop.Set)(control, (float)strtod(computed.constant, null));
-                                                                                    else if(!strcmp(propertyClass.dataTypeString, "double"))
-                                                                                       ((void (*)(void *, double))(void *)prop.Set)(control, strtod(computed.constant, null));
-                                                                                    else
-                                                                                       ((void (*)(void *, int))(void *)prop.Set)(control, strtol(computed.constant, null, 0));
-                                                                                 }
-                                                                                 else if(computed.type == stringExp  && propertyClass.dataTypeString && strstr(propertyClass.dataTypeString, "char *"))
-                                                                                 {
-                                                                                    String temp = new char[strlen(computed.string)+1];
-                                                                                    ReadString(temp, computed.string);
-                                                                                    ((void (*)(void *, void *))(void *)prop.Set)(control, temp);
-                                                                                    delete temp;
-                                                                                 }
-                                                                              }
-                                                                              else
-                                                                                 member.variable = true;
+                                                                                       if(!member.initializer.exp.intlString)
+                                                                                       {
+                                                                                          Map<String, bool> i18nStrings = object.i18nStrings;
+                                                                                          if(!i18nStrings)
+                                                                                             object.i18nStrings = i18nStrings = { };
+                                                                                          i18nStrings[prop.name] = false;
+                                                                                       }
 
-                                                                              FreeExpression(computed);
+                                                                                       variable = false;
+                                                                                    }
+                                                                                    break;
+                                                                                 case constantExp:
+                                                                                    if(!isClass && computed.isConstant)
+                                                                                    {
+                                                                                       if(!strcmp(propertyClass.dataTypeString, "float"))
+                                                                                          ((void (*)(void *, float))(void *)prop.Set)(control, (float)strtod(computed.constant, null));
+                                                                                       else if(!strcmp(propertyClass.dataTypeString, "double"))
+                                                                                          ((void (*)(void *, double))(void *)prop.Set)(control, strtod(computed.constant, null));
+                                                                                       else
+                                                                                          ((void (*)(void *, int))(void *)prop.Set)(control, strtol(computed.constant, null, 0));
+                                                                                       variable = false;
+                                                                                    }
+                                                                                    break;
+                                                                              }
                                                                            }
                                                                         }
+                                                                        FreeExpression(computed);
                                                                      }
                                                                   }
-                                                                  else
+                                                                  if(variable)
                                                                      member.variable = true;
                                                                }
-                                                               else if(ident && member.initializer && member.initializer.type == expInitializer && member.initializer.exp && 
+                                                               else if(ident && member.initializer && member.initializer.type == expInitializer && member.initializer.exp &&
                                                                   member.initializer.exp.type == memberExp) // identifierExp
                                                                {
                                                                   Method method = eClass_FindMethod(instClass, ident.string, this.privateModule);
@@ -3348,7 +3466,7 @@ class CodeEditor : Window
                                                          break;
                                                       }
                                                    }
-                                                }                                          
+                                                }
                                              }
 
                                              designer.PostCreateObject(object.instance, object, false, classObject.instance);
@@ -3401,8 +3519,7 @@ class CodeEditor : Window
          if(selectedName)
          {
             ObjectInfo check;
-            int pos = 0;
-         
+
             for(check = this.oClass.instances.first; check; check = check.next)
             {
                if(check.name && !strcmp(check.name, selectedName))
@@ -3471,11 +3588,13 @@ class CodeEditor : Window
       printf("Total MkExternalImport time is %.3f seconds\n\n", externalImportTotalTime);
       printf("Total FindSymbol time is %.3f seconds\n\n", findSymbolTotalTime);
       // printf("Total Class Members Find time is %.3f seconds\n\n", GetClassFindTime());
-      
+
       printf("Whole ParseCode function took %.3f seconds\n\n", GetTime() - parseCodeStart);
 #endif
       if(inUseDebug && ide.projectView)
          ide.debugger.EvaluateWatches();
+
+      delete pathBackup;
    }
 
    void UpdateInstanceCodeClass(Class _class, ObjectInfo object, EditBoxStream f, Instance test, bool * prev, bool * lastIsMethod, DataMember * curMember, Class * curClass)
@@ -3499,29 +3618,29 @@ class CodeEditor : Window
                Class dataType = prop.dataTypeClass;
                if(!dataType)
                   dataType = prop.dataTypeClass = eSystem_FindClass(this.privateModule, prop.dataTypeString);
-         
+
                if(dataType)
                {
                   if(dataType.type == structClass)
                   {
                      void * dataForm = new0 byte[dataType.structSize];
                      void * dataTest = new0 byte[dataType.structSize];
-               
+
                      ((void (*)(void *, void *))(void *)prop.Get)(control, dataForm);
                      ((void (*)(void *, void *))(void *)prop.Get)(test, dataTest);
-               
+
                      if((prop.IsSet && !prop.IsSet(test)) || ((int (*)(void *, void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnCompare])(dataType, dataForm, dataTest))
                      {
                         char tempString[1024] = "";
-                        char * string = "";
+                        const char * string = "";
                         bool needClass = true;
                         if(*prev)
                            f.Printf(", ");
-                  
+
                         ((void (*)(void *, void *))(void *)prop.Set)(test, dataForm);
-                  
+
                         string = ((char * (*)(void *, void *, void *, void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnGetString])(dataType, dataForm, tempString, null, &needClass);
-                        
+
                         eClass_FindNextMember(_class, curClass, curMember, null, null);
                         if(*curMember != (DataMember)prop)
                            f.Printf("%s = ", prop.name);
@@ -3542,19 +3661,37 @@ class CodeEditor : Window
                   else if(dataType.type == normalClass || dataType.type == noHeadClass)
                   {
                      void * dataForm, * dataTest;
-               
-                     dataForm = ((void *(*)(void *))(void *)prop.Get)(control);
-                     dataTest = ((void *(*)(void *))(void *)prop.Get)(test);
-               
+                     bool isEditBoxContents = false;
+                     bool freeDataForm = false, freeDataTest = false;
+
+                     // Because contents property is broken for mutiline EditBox at the moment
+                     if(!strcmp(prop.name, "contents") && !strcmp(prop._class.name, "EditBox"))
+                        isEditBoxContents = true;
+
+                     if(isEditBoxContents && ((EditBox)control).multiLine)
+                     {
+                        dataForm = ((EditBox)control).multiLineContents;
+                        freeDataForm = true;
+                     }
+                     else
+                        dataForm = ((void *(*)(void *))(void *)prop.Get)(control);
+                     if(isEditBoxContents && ((EditBox)test).multiLine)
+                     {
+                        dataTest = ((EditBox)test).multiLineContents;
+                        freeDataTest = true;
+                     }
+                     else
+                        dataTest = ((void *(*)(void *))(void *)prop.Get)(test);
+
                      if((prop.IsSet && !prop.IsSet(test)) || ((int (*)(void *, void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnCompare])(dataType, dataForm, dataTest))
                      {
                         char tempString[1024] = "";
-                        char * string = "";
+                        const char * string = "";
                         if(*prev)
                            f.Printf(", ");
-                  
+
                         ((void (*)(void *, void *))(void *)prop.Set)(test, dataForm);
-                  
+
                         eClass_FindNextMember(_class, curClass, curMember, null, null);
                         if(*curMember != (DataMember)prop)
                            f.Printf("%s = ", prop.name);
@@ -3598,7 +3735,12 @@ class CodeEditor : Window
 
                            if(!strcmp(dataType.dataTypeString, "char *"))
                            {
-                              f.Printf("\"");
+                              Map<String, bool> i18nStrings = object.i18nStrings;
+                              bool i18n = true;
+                              if(i18nStrings && i18nStrings.GetAtPosition(prop.name, false, null))
+                                 i18n = false;
+
+                              f.Printf("%s\"", i18n ? "$" : "");
                               OutputString(f, string);
                               f.Puts("\"");
                            }
@@ -3610,33 +3752,37 @@ class CodeEditor : Window
                         *prev = true;
                         *lastIsMethod = false;
                      }
+
+                     if(freeDataForm) delete dataForm;
+                     if(freeDataTest) delete dataTest;
                   }
                   else
                   {
                      DataValue dataForm, dataTest;
-               
+
                      GetProperty(prop, control, &dataForm);
                      GetProperty(prop, test, &dataTest);
-               
+
                      if((prop.IsSet && !prop.IsSet(test)) || ((int (*)(void *, void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnCompare])(dataType, &dataForm, &dataTest))
                      {
-                        char * string;
+                        char * string = null;
                         char tempString[1024] = "";
                         SetProperty(prop, test, dataForm);
-                  
+
                         if(dataType.type != bitClass)
                         {
                            bool needClass = true;
 
                            if(dataType.type == enumClass)
                            {
-                              NamedLink value;
+                              NamedLink64 value;
                               Class enumClass = eSystem_FindClass(privateModule, "enum");
                               EnumClassData e = ACCESS_CLASSDATA(dataType, enumClass);
+                              int64 i64Value = GetI64EnumValue(dataType, dataForm);
 
                               for(value = e.values.first; value; value = value.next)
                               {
-                                 if((int)value.data == dataForm.i)
+                                 if(value.data == i64Value)
                                  {
                                     string = value.name;
                                     break;
@@ -3645,7 +3791,7 @@ class CodeEditor : Window
                            }
                            else
                               string = ((char * (*)(void *, void *, void *, void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnGetString])(dataType, &dataForm, tempString, null, &needClass);
-                     
+
                            if(string && string[0])
                            {
                               if(*prev)
@@ -3698,10 +3844,8 @@ class CodeEditor : Window
       Window control = (Window)object.instance;
       bool prev = false;
       bool methodPresent = false;
-      Class _class;
       bool lastIsMethod = true;
-      ObjectInfo classObject = object.oClass;
-      
+
       if(inst)
       {
          if(object.deleted)
@@ -3743,7 +3887,7 @@ class CodeEditor : Window
                char ch;
                f.Seek(pos - position, current);
                while(f.Getc(&ch))
-               {  
+               {
                   if(isspace(ch))
                   {
                      f.Seek(-1, current);
@@ -3782,9 +3926,10 @@ class CodeEditor : Window
                {
                   int count = 0;
                   int toDelete = 0;
-                  int toAdd = 0;
+                  //int toAdd = 0;
 
                   f.Seek(-1, current);
+                  DeleteJunkBefore(f, position, &position);
                   f.Puts("\n   ");
                   f.Seek(1, current);
                   //f.Puts("\n");
@@ -3804,12 +3949,12 @@ class CodeEditor : Window
                         position--;
                         if(count > 6)
                         {
-                           toDelete += count - 6; 
+                           toDelete += count - 6;
                            count = 6;
                         }
-                        else 
-                           toAdd = 6 - count;
-                        break;                              
+                        /*else
+                           toAdd = 6 - count;*/
+                        break;
                      }
                   }
                   if(toDelete)
@@ -3818,23 +3963,28 @@ class CodeEditor : Window
                      f.DeleteBytes(toDelete);
                      f.Seek(count, current);
                   }
+
+                  DeleteJunkBefore(f, position, &position);
+
+                  // Removed this here as it was adding trailing spaces when adding a method
+                  /*
                   if(toAdd)
                   {
                      int c;
                      for(c = 0; c<toAdd; c++)
                         f.Putc(' ');
                   }
+                  */
                }
             }
             else
                methodPresent = multiLine;
 
-            if(!prev)
+            //if(!prev) -- always false
                f.Printf(methodPresent ? "\n      " : " ");
-
          }
       }
-      else 
+      else
       {
          // Instance not there, create a brand new one
          DeleteJunkBefore(f, position, &position);
@@ -3886,9 +4036,9 @@ class CodeEditor : Window
          Class instClass = eSystem_FindClass(this.privateModule, inst._class.name);
 
          DeleteJunkBefore(f, position, &position);
-         
+
          // Instance already there, clear out the properties
-         for(members = inst.members->first; members; members = members.next)
+         for(members = inst.members ? inst.members->first : null; members; members = members.next)
          {
             if(members.type == dataMembersInit)
             {
@@ -3920,7 +4070,7 @@ class CodeEditor : Window
                            else
                            {
                               Method method = eClass_FindMethod(instClass, ident.string, this.privateModule);
-                              if(method && method.type == virtualMethod && member.initializer && member.initializer.type == expInitializer && member.initializer.exp && 
+                              if(method && method.type == virtualMethod && member.initializer && member.initializer.type == expInitializer && member.initializer.exp &&
                                  member.initializer.exp.type == memberExp /*ExpIdentifier*/)
                               {
                                  if(((this.methodAction == actionDetachMethod || this.methodAction == actionReattachMethod) && this.method == method && this.selected == object) ||
@@ -3931,7 +4081,7 @@ class CodeEditor : Window
                                     position = member.loc.end.pos;
                                     deleted = true;
                                  }
-                              }                                          
+                              }
                            }
                         }
                      }
@@ -3943,16 +4093,15 @@ class CodeEditor : Window
                         //f.Seek(member.loc.start.pos - position, current);
                         //position = member.loc.start.pos;
                         DeleteJunkBefore(f, member.loc.start.pos, &position);
-                        if(prev) f.Printf(", "); 
+                        if(prev) f.Printf(", ");
                         else if(keptMember) f.Printf(" ");
                         prev = false;
                      }
-                  } 
-               
+                  }
+
                   if(!keptMember || !members.next)
                   {
                      char ch = 0;
-                     int count = 0;
 
                      if(keptMember && lastKept != members.dataMembers->last)
                      {
@@ -3980,7 +4129,7 @@ class CodeEditor : Window
 
                      f.Seek(members.loc.end.pos - position, current);
                      f.Getc(&ch);
-            
+
                      if(ch == ';')
                      {
                         f.Seek(-1, current);
@@ -4038,7 +4187,7 @@ class CodeEditor : Window
                      */
                      prev = true;
                      lastIsMethod = false;
-                     
+
                   }
                }
                else
@@ -4056,7 +4205,7 @@ class CodeEditor : Window
                   methodPresent = true;
 
                // Delete instance method here
-               if((this.methodAction == actionDeleteMethod || (this.methodAction == actionDetachMethod && this.moveAttached)) && 
+               if((this.methodAction == actionDeleteMethod || (this.methodAction == actionDetachMethod && this.moveAttached)) &&
                   members.function == function)
                {
                   if(this.moveAttached && !*text)
@@ -4075,7 +4224,7 @@ class CodeEditor : Window
 
                   DeleteJunkBefore(f, members.loc.start.pos, &position);
                   lastIsMethod = true;
-                  f.Printf("\n\n      ");               
+                  f.Printf("\n\n      ");
                }
 
                f.Seek(members.loc.end.pos - position, current);
@@ -4121,7 +4270,7 @@ class CodeEditor : Window
                   memmove(*text + movedFuncIdPos + newLen, *text + movedFuncIdPos + movedFuncIdLen, *textSize - movedFuncIdPos - movedFuncIdLen + 1);
                   *textSize += newLen - movedFuncIdLen;
                   memcpy(*text + movedFuncIdPos, method.name, newLen);
-                                          
+
                   // Second, tab right
                   {
                      int c;
@@ -4146,12 +4295,12 @@ class CodeEditor : Window
                }
                else
                {
-                  Class moduleClass = eSystem_FindClass(this.privateModule, "Module");
+                  // Class moduleClass = eSystem_FindClass(this.privateModule, "Module");
 
                   // ADDING METHOD HERE
                   f.Printf("\n      ");
                   OutputType(f, returnType, false);
-            
+
                   f.Printf(" ");
                   if(dataType.thisClass)
                   {
@@ -4172,10 +4321,10 @@ class CodeEditor : Window
                      if(param.next)
                         f.Printf(", ");
                   }
-                  f.Printf(")\n");                  
+                  f.Printf(")\n");
                   f.Printf("      %c\n\n", OpenBracket);
 
-                  if(control._class._vTbl[method.vid] == moduleClass._vTbl[__ecereVMethodID___ecereNameSpace__ecere__com__Module_OnLoad]) // Temp Check for DefaultFunction
+                  if(control._class._vTbl[method.vid] == null /*moduleClass._vTbl[__ecereVMethodID___ecereNameSpace__ecere__com__Module_OnLoad]*/) // Temp Check for DefaultFunction
                   {
                      if(returnType.kind == classType && !strcmp(returnType._class.string, "bool"))
                         f.Printf("         return true;\n");
@@ -4203,12 +4352,7 @@ class CodeEditor : Window
       }
 
       if(!object.instCode)
-      {
-         if(methodPresent)
-            f.Printf("   %c;\n", CloseBracket);
-         else
-            f.Printf("%c;\n", CloseBracket);
-      }
+         f.Printf(methodPresent ? "   %c;" : "%c;", CloseBracket);
       else if(!object.deleted)
       {
          // Turn this into a multiline instance when adding a method
@@ -4226,20 +4370,20 @@ class CodeEditor : Window
    {
       Property propIt;
       Class regClass = eSystem_FindClass(privateModule, classObject.name);
-     
+
       if(_class.base && _class.base.type != systemClass) OutputClassProperties(_class.base, classObject, f, test);
-      
+
       for(propIt = _class.membersAndProperties.first; propIt; propIt = propIt.next)
       {
          Property prop = eClass_FindProperty(selected.instance._class, propIt.name, privateModule);
          if(prop && prop.isProperty && !prop.conversion)
          {
-            if(prop.Set && prop.Get && prop.dataTypeString && strcmp(prop.name, "name") && !Code_IsPropertyDisabled(classObject, prop.name) && 
+            if(prop.Set && prop.Get && prop.dataTypeString && strcmp(prop.name, "name") && !Code_IsPropertyDisabled(classObject, prop.name) &&
                (!prop.IsSet || prop.IsSet(classObject.instance)))
             {
                Class dataType = prop.dataTypeClass;
                char tempString[1024] = "";
-               char * string;
+               char * string = null;
                bool specify = false;
                DataMember member;
 
@@ -4249,19 +4393,19 @@ class CodeEditor : Window
 
                if(!dataType)
                   dataType = prop.dataTypeClass = eSystem_FindClass(this.privateModule, prop.dataTypeString);
-            
+
                if(dataType && dataType.type == structClass)
                {
                   void * dataForm = new0 byte[dataType.structSize];
                   void * dataTest = new0 byte[dataType.structSize];
-               
+
                   ((void (*)(void *, void *))(void *)prop.Get)(classObject.instance, dataForm);
                   ((void (*)(void *, void *))(void *)prop.Get)(test, dataTest);
 
                   if(((int (*)(void *, void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnCompare])(dataType, dataForm, dataTest))
                   {
                      bool needClass = true;
-                     
+
                      string = ((char * (*)(void *, void *, void *, void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnGetString])(dataType, dataForm, tempString, null, &needClass);
                      ((void (*)(void *, void *))(void *)prop.Set)(test, dataForm);
                      if(needClass)
@@ -4275,16 +4419,34 @@ class CodeEditor : Window
                else if(dataType && (dataType.type == normalClass || dataType.type == noHeadClass))
                {
                   void * dataForm, * dataTest;
-               
-                  dataForm = ((void *(*)(void *))(void *)prop.Get)(classObject.instance);
-                  dataTest = ((void *(*)(void *))(void *)prop.Get)(test);
-               
+                  bool isEditBoxContents = false;
+                  bool freeDataForm = false, freeDataTest = false;
+
+                  // Because contents property is broken for mutiline EditBox at the moment
+                  if(!strcmp(prop.name, "contents") && !strcmp(prop._class.name, "EditBox"))
+                     isEditBoxContents = true;
+
+                  if(isEditBoxContents && ((EditBox)classObject.instance).multiLine)
+                  {
+                     dataForm = ((EditBox)classObject.instance).multiLineContents;
+                     freeDataForm = true;
+                  }
+                  else
+                     dataForm = ((void *(*)(void *))(void *)prop.Get)(classObject.instance);
+                  if(isEditBoxContents && ((EditBox)test).multiLine)
+                  {
+                     dataTest = ((EditBox)test).multiLineContents;
+                     freeDataTest = true;
+                  }
+                  else
+                     dataTest = ((void *(*)(void *))(void *)prop.Get)(test);
+
                   if(((int (*)(void *, void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnCompare])(dataType, dataForm, dataTest))
                   {
                      char tempString[1024] = "";
-                     char * string;
+                     char * string = null;
                      ((void (*)(void *, void *))(void *)prop.Set)(test, dataForm);
-                  
+
                      if(eClass_IsDerived(classObject.instance._class, dataType) && classObject.instance == dataForm)
                      {
                         // Shouldn't go here ...
@@ -4298,7 +4460,12 @@ class CodeEditor : Window
 
                         if(!strcmp(dataType.dataTypeString, "char *"))
                         {
-                           f.Printf("\n   %s%s = \"", specify ? "property::" : "", prop.name);
+                           Map<String, bool> i18nStrings = classObject.i18nStrings;
+                           bool i18n = true;
+                           if(i18nStrings && i18nStrings.GetAtPosition(prop.name, false, null))
+                              i18n = false;
+
+                           f.Printf("\n   %s%s = %s\"", specify ? "property::" : "", prop.name, i18n ? "$" : "");
                            OutputString(f, string);
                            f.Puts("\";");
                         }
@@ -4308,14 +4475,16 @@ class CodeEditor : Window
                            f.Printf("\n   %s%s = %s;", specify ? "property::" : "", prop.name, string);
                      }
                   }
+                  if(freeDataForm) delete dataForm;
+                  if(freeDataTest) delete dataTest;
                }
                else if(dataType)
                {
                   DataValue dataForm, dataTest;
-               
+
                   GetProperty(prop, classObject.instance, &dataForm);
                   GetProperty(prop, test, &dataTest);
-               
+
                   if(((int (*)(void *, void *, void *))(void *)dataType._vTbl[__ecereVMethodID_class_OnCompare])(dataType, &dataForm, &dataTest))
                   {
                      SetProperty(prop, test, dataForm);
@@ -4333,13 +4502,14 @@ class CodeEditor : Window
                         bool needClass = true;
                         if(dataType.type == enumClass)
                         {
-                           NamedLink value;
+                           NamedLink64 value;
                            Class enumClass = eSystem_FindClass(privateModule, "enum");
                            EnumClassData e = ACCESS_CLASSDATA(dataType, enumClass);
+                           int64 i64Value = GetI64EnumValue(dataType, dataForm);
 
                            for(value = e.values.first; value; value = value.next)
                            {
-                              if((int)value.data == dataForm.i)
+                              if(value.data == i64Value)
                               {
                                  string = value.name;
                                  break;
@@ -4353,7 +4523,7 @@ class CodeEditor : Window
                         else if(string[0])
                            f.Printf("\n   %s%s = %s;", specify ? "property::" : "", prop.name, string);
                      }
-                  }                                          
+                  }
                }
             }
          }
@@ -4363,7 +4533,8 @@ class CodeEditor : Window
    void UpdateFormCode()
    {
       if(!this) return;
-         
+      if(!parsing) return;
+
       updatingCode++;
       if(codeModified)
       {
@@ -4375,12 +4546,14 @@ class CodeEditor : Window
          int position = 0;
          char * text = null;
          int textSize;
-         Identifier movedFuncId; 
+         Identifier movedFuncId;
          int movedFuncIdLen = 0, movedFuncIdPos = 0;
          ObjectInfo classObject;
 
           updatingCode++;
 
+         editBox.recordUndoEvent = true;
+
          if(moveAttached)
          {
             movedFuncId = GetDeclId(function.declarator);
@@ -4390,7 +4563,6 @@ class CodeEditor : Window
 
          for(classObject = classes.first; classObject; classObject = classObject.next)
          {
-            Class _class;
             ClassDefinition classDef = classObject.classDefinition;
             Class regClass = eSystem_FindClass(this.privateModule, ((Specifier)classDef.baseSpecs->first).name);
             Instance test;
@@ -4406,7 +4578,7 @@ class CodeEditor : Window
 
             // Put it in the same desktop window...
             designer.PrepareTestObject(test);
-            
+
             //f.Printf("class %s : %s\n", classObject.name, classObject.oClass.name);
             //f.Printf("%c\n\n", OpenBracket);
 
@@ -4423,7 +4595,7 @@ class CodeEditor : Window
                int back = 0;
                f.Seek(classDef.blockStart.end.pos - position, current);
                position = classDef.blockStart.end.pos;
-               
+
                for(; f.Getc(&ch); count++)
                {
                   if(!isspace(ch))
@@ -4431,15 +4603,15 @@ class CodeEditor : Window
                      f.Seek(-1, current);
                      break;
                   }
-               
+
                   if(ch == '\n')
                      back = 0;
                   else
                      back++;
                }
-            
+
                f.Seek(-count, current);
-            
+
                f.DeleteBytes(count-back);
                //f.Printf("\n");
                position += count-back;
@@ -4457,10 +4629,12 @@ class CodeEditor : Window
                      bool keptMember = false;
                      MemberInit propDef;
                      MemberInit lastKept = null;
-                     
+
                      lastIsDecl = false;
                      DeleteJunkBefore(f, def.loc.start.pos, &position);
-                     f.Printf("\n   ");
+
+                     // This was adding blank spaces between comment and properties -- What was it for?
+                     // f.Printf("\n   ");
 
                      for(propDef = def.defProperties->first; propDef; propDef = propDef.next)
                      {
@@ -4493,7 +4667,7 @@ class CodeEditor : Window
                                        position = propDef.loc.end.pos;
                                        deleted = true;
                                     }
-                                 }                                          
+                                 }
                               }
                            }
                         }
@@ -4503,14 +4677,13 @@ class CodeEditor : Window
                            lastKept = propDef;
                         }
                      }
-                  
+
                      if(!keptMember)
                      {
                         char ch = 0;
-                        int count = 0;
                         f.Seek(def.loc.end.pos - position - 1, current);
                         f.Getc(&ch);
-                        
+
                         if(ch == ';')
                         {
                            f.Seek(-1, current);
@@ -4524,7 +4697,7 @@ class CodeEditor : Window
                         {
                            char ch;
                            int count = 0;
-                           
+
                            f.Seek(-1, current);
                            for(;f.Getc(&ch);)
                            {
@@ -4547,7 +4720,7 @@ class CodeEditor : Window
                         {
                            f.Seek(def.loc.end.pos - position, current);
                            position = def.loc.end.pos;
-                        }                
+                        }
                      }
                      break;
                   }
@@ -4602,7 +4775,7 @@ class CodeEditor : Window
                      f.Printf("\n\n   ");
 
                      // Delete _class methods
-                     if((methodAction == actionDeleteMethod || (moveAttached && selected != classObject)) && 
+                     if((methodAction == actionDeleteMethod || (moveAttached && selected != classObject)) &&
                         def.function == function)
                      {
                         char ch;
@@ -4637,7 +4810,7 @@ class CodeEditor : Window
                         position = function.loc.start.pos + movedFuncIdPos + movedFuncIdLen;
                      }
 
-                     if((methodAction == actionAttachMethod || methodAction == actionReattachMethod) && selected == classObject && moveAttached && 
+                     if((methodAction == actionAttachMethod || methodAction == actionReattachMethod) && selected == classObject && moveAttached &&
                         function == def.function)
                      {
                         // In case of attaching methods in the _class, simply rename the method
@@ -4659,7 +4832,7 @@ class CodeEditor : Window
                         firstObject = false;
                         lastIsDecl = true;
                      }
-                     else           
+                     else
                      {
                         f.Printf("\n   ");
                         lastIsDecl = false;
@@ -4676,7 +4849,7 @@ class CodeEditor : Window
                DeleteJunkBefore(f, position, &position);
                f.Printf("\n   %s = %s;\n", method.name, function.declarator.symbol.string);
             }
-            
+
             // ********** INSTANCES ***************
             for(; object; object = object.next)
             {
@@ -4735,12 +4908,12 @@ class CodeEditor : Window
                   Type dataType = method.dataType;
                   Type returnType = dataType.returnType;
                   Type param;
-                  Class moduleClass = eSystem_FindClass(this.privateModule, "Module");
+                  // Class moduleClass = eSystem_FindClass(this.privateModule, "Module");
 
                   f.Printf("\n\n");
                   f.Printf("   ");
                   OutputType(f, returnType, false);
-               
+
                   f.Printf(" ");
                   if(dataType.thisClass && !dataType.classObjectType)
                   {
@@ -4758,10 +4931,10 @@ class CodeEditor : Window
                      if(param.next)
                         f.Printf(", ");
                   }
-                  f.Printf(")\n");                  
+                  f.Printf(")\n");
                   f.Printf("   %c\n\n", OpenBracket);
 
-                  if(test._class._vTbl[method.vid] == moduleClass._vTbl[__ecereVMethodID___ecereNameSpace__ecere__com__Module_OnLoad]) // Temp Check for DefaultFunction
+                  if(test._class._vTbl[method.vid] == null /*moduleClass._vTbl[__ecereVMethodID___ecereNameSpace__ecere__com__Module_OnLoad]*/) // Temp Check for DefaultFunction
                   {
                      if(returnType && returnType.kind == classType && !strcmp(returnType._class.string, "bool"))
                         f.Printf("      return true;\n");
@@ -4797,6 +4970,8 @@ class CodeEditor : Window
             delete test;
          }
 
+         editBox.recordUndoEvent = false;
+
          updatingCode--;
          delete f;
 
@@ -4816,14 +4991,14 @@ class CodeEditor : Window
       method = null;
    }
 
-   int FindMethod(char * methodName /*Method method*/, ClassFunction*functionPtr, Location propLoc)
+   int FindMethod(const char * methodName /*Method method*/, ClassFunction*functionPtr, Location propLoc)
    {
       int found = 0;
       ClassFunction function = null;
       if(methodName)
       {
          ObjectInfo object = this.selected;
-         
+
          if(object && object == this.oClass)
          {
             ClassDefinition classDef = object.oClass.classDefinition;
@@ -4967,7 +5142,7 @@ class CodeEditor : Window
       return found;
    }
 
-   void GoToMethod(char * methodName /*Method method*/)
+   void GoToMethod(const char * methodName /*Method method*/)
    {
       if(methodName)
       {
@@ -5081,7 +5256,7 @@ class CodeEditor : Window
                   {
                      if(!testMethod.dataType)
                         testMethod.dataType = ProcessTypeString(testMethod.dataTypeString, false);
-                        
+
                      //if(CheckCompatibleMethod(method, testMethod.dataType, &regClass, false, selectedClass)) // this.selected == this.oClass, selectedClass))
                      if(CheckCompatibleMethod(method, testMethod.dataType, this.oClass.instance._class, false, selectedClass)) // this.selected == this.oClass, selectedClass))
                      //if(CheckCompatibleMethod(method, testMethod.dataType, &regClass, this.selected == this.oClass, FindClass(this.oClass.oClass.name)))
@@ -5117,7 +5292,7 @@ class CodeEditor : Window
             this.method = method;
             ModifyCode();
          }
-         UpdateFormCode();         
+         UpdateFormCode();
          GoToMethod(methodName);
       }
    }
@@ -5129,7 +5304,7 @@ class CodeEditor : Window
          methodAction = actionDeleteMethod;
          this.function = function;
          ModifyCode();
-         UpdateFormCode(); 
+         UpdateFormCode();
 
          Update(null);
       }
@@ -5171,7 +5346,7 @@ class CodeEditor : Window
          this.method = method;
          this.function = function;
          ModifyCode();
-         UpdateFormCode(); 
+         UpdateFormCode();
          Update(null);
       }
    }
@@ -5201,7 +5376,7 @@ class CodeEditor : Window
             {
                char title[1024];
                sprintf(title, $"Attach %s", function.declarator.symbol.string);
-               if(MessageBox { type = yesNo, master = parent, text = title, 
+               if(MessageBox { type = yesNo, master = parent, text = title,
                   contents = $"Method is unused. Move method inside instance?" }.Modal() == yes)
                {
                   moveAttached = true;
@@ -5213,7 +5388,7 @@ class CodeEditor : Window
          this.method = method;
          this.function = function;
          ModifyCode();
-         UpdateFormCode(); 
+         UpdateFormCode();
          Update(null);
       }
    }
@@ -5226,7 +5401,7 @@ class CodeEditor : Window
       {
          Window dialog
          {
-            hasClose = true, borderStyle = sizable, minClientSize = { 300, 55 }, 
+            hasClose = true, borderStyle = sizable, minClientSize = { 300, 55 },
             master = sheet, text = $"Name detached method", background = formColor
          };
          Button cancelButton
@@ -5272,7 +5447,7 @@ class CodeEditor : Window
                strcat(name, this.methodName);
                strcpy(this.methodName, name);
             }
-            
+
             this.moveAttached = true;
          }
 
@@ -5280,7 +5455,7 @@ class CodeEditor : Window
          this.method = method;
          this.function = function;
          ModifyCode();
-         UpdateFormCode(); 
+         UpdateFormCode();
          Update(null);
       }
    }
@@ -5300,11 +5475,11 @@ class CodeEditor : Window
          ObjectInfo check;
          sprintf(name, "%c%s%d", tolower(instance._class.name[0]), instance._class.name+1, id);
 
-         // if(strcmp(name, this.oClass.instance.name)) 
-         
+         // if(strcmp(name, this.oClass.instance.name))
+
          {
             for(check = oClass.instances.first; check; check = check.next)
-               if(!check.deleted && check.name && !strcmp(name, check.name)) 
+               if(!check.deleted && check.name && !strcmp(name, check.name))
                   break;
             if(!check)
             {
@@ -5312,7 +5487,7 @@ class CodeEditor : Window
                break;
             }
          }
-      }            
+      }
       toolBox.controlClass = null;
 
       ModifyCode();
@@ -5324,7 +5499,7 @@ class CodeEditor : Window
 
    void EnsureUpToDate()
    {
-      if(sheet && codeModified)
+      if(sheet && codeModified && parsing)
          ParseCode();
    }
 
@@ -5378,9 +5553,9 @@ class CodeEditor : Window
          ObjectInfo select = object;
 
          for(;;)
-         {            
+         {
             select = select.prev;
-            if(!select) 
+            if(!select)
             {
                if(looped) break;
                select = object.oClass.instances.last;
@@ -5403,7 +5578,7 @@ class CodeEditor : Window
          sheet.DeleteObject(object);
    }
 
-   void RenameObject(ObjectInfo object, char * name)
+   void RenameObject(ObjectInfo object, const char * name)
    {
       bool valid = false;
 
@@ -5464,10 +5639,10 @@ class CodeEditor : Window
                BitmapResource bitmap = null;
                if(!subMember.dataType)
                   subMember.dataType = ProcessTypeString(subMember.dataTypeString, false);
-            
+
                if(subMember.dataType && subMember.dataType.kind == classType && subMember.dataType._class)
                {
-                  char * bitmapName = (char *)eClass_GetProperty(subMember.dataType._class.registered, "icon");
+                  char * bitmapName = (char *)(intptr)eClass_GetProperty(subMember.dataType._class.registered, "icon");
                   if(bitmapName)
                   {
                      bitmap = { bitmapName };
@@ -5558,14 +5733,14 @@ class CodeEditor : Window
                   else if(member.name && !membersList.FindString(member.name))
                   {
                      DataRow row = membersList.AddString(member.name);
-               
+
                      BitmapResource bitmap = null;
                      if(!member.dataType)
                         member.dataType = ProcessTypeString(member.dataTypeString, false);
-               
+
                      if(member.dataType && member.dataType.kind == classType && member.dataType._class)
                      {
-                        char * bitmapName = (char *)eClass_GetProperty(member.dataType._class.registered, "icon");
+                        char * bitmapName = (char *)(intptr)eClass_GetProperty(member.dataType._class.registered, "icon");
                         if(bitmapName)
                         {
                            bitmap = { bitmapName };
@@ -5596,8 +5771,6 @@ class CodeEditor : Window
       for(_class = whatClass; _class && _class.type != systemClass; _class = _class.base)
       {
          Method method;
-         Property prop;
-         DataMember member;
 
          for(method = (Method)_class.methods.first; method; method = (Method)((BTNode)method).next)
          {
@@ -5608,7 +5781,7 @@ class CodeEditor : Window
                   if(!method.dataType)
                      method.dataType = ProcessTypeString(method.dataTypeString, false);
 
-                  if(MatchTypes(method.dataType, methodType, null, whatClass, /*null, */whatClass, false, true, false, false))
+                  if(MatchTypes(method.dataType, methodType, null, whatClass, /*null, */whatClass, false, true, false, false, true))
                   {
                      DataRow row = membersList.FindString(method.name);
                      if(!row)
@@ -5628,14 +5801,13 @@ class CodeEditor : Window
       }
    }
 
-   void ListClassPropertiesAndVirtual(Class whatClass)
+   void ListClassPropertiesAndVirtual(Class whatClass, const String curString)
    {
       Class _class;
       bool isPrivate = false;
-      for(_class = whatClass; _class && _class.type != systemClass; _class = _class.base)
+      for(_class = whatClass; _class /*&& _class.type != systemClass*/; _class = _class.base)
       {
          Method method;
-         Property prop;
          DataMember member;
 
          for(method = (Method)_class.methods.first; method; method = (Method)((BTNode)method).next)
@@ -5670,17 +5842,17 @@ class CodeEditor : Window
                      row.icon = icons[(member.memberAccess == publicAccess && !isPrivate) ? typeProperty : typePropertyPrivate];
                   }
                }
-               else if(member.name)
+               else if(member.name && (!curString || strcmp(curString, member.name)))
                {
                   DataRow row = membersList.AddString(member.name);
-               
+
                   BitmapResource bitmap = null;
                   if(!member.dataType)
                      member.dataType = ProcessTypeString(member.dataTypeString, false);
-               
+
                   if(member.dataType && member.dataType.kind == classType && member.dataType._class)
                   {
-                     char * bitmapName = (char *)eClass_GetProperty(member.dataType._class.registered, "icon");
+                     char * bitmapName = (char *)(intptr)eClass_GetProperty(member.dataType._class.registered, "icon");
                      if(bitmapName)
                      {
                         bitmap = { bitmapName };
@@ -5705,8 +5877,6 @@ class CodeEditor : Window
    {
       if(type && (type.kind == classType || type.kind == structType || type.kind == unionType))
       {
-         Class _class;
-         
          if(type.kind == classType)
          {
             if(type._class)
@@ -5752,7 +5922,7 @@ class CodeEditor : Window
          for(link = (BTNamedLink)nameSpace.classes.first; link; link = (BTNamedLink)((BTNode)link).next)
          {
             Class _class = link.data;
-            if(_class.type != systemClass)
+            if(_class.type != systemClass && !_class.templateClass)  // Omit templatized classes
             {
                DataRow row = membersList.AddString(_class.name);
                row.icon = (_class.type == unitClass || _class.type == enumClass) ? icons[typeDataType] : icons[typeClass];
@@ -5762,14 +5932,14 @@ class CodeEditor : Window
 
       for(link = (BTNamedLink)nameSpace.defines.first; link; link = (BTNamedLink)((BTNode)link).next )
       {
-         DefinedExpression definedExp = link.data;
+         //DefinedExpression definedExp = link.data;
          DataRow row = membersList.AddString(link /*definedExp*/.name);
          row.icon = icons[typeData];
       }
 
       for(link = (BTNamedLink)nameSpace.functions.first; link; link = (BTNamedLink)((BTNode)link).next)
       {
-         GlobalFunction function = link.data;
+         //GlobalFunction function = link.data;
          DataRow row = membersList.AddString(link /*function*/.name);
          row.icon = icons[typeMethod];
       }
@@ -5799,7 +5969,7 @@ class CodeEditor : Window
       for(_class : classes)
       {
          EnumClassData enumeration = (EnumClassData)_class.data;
-         NamedLink item;
+         NamedLink64 item;
          for(item = enumeration.values.first; item; item = item.next)
          {
             DataRow row = membersList.AddString(item.name);
@@ -5824,7 +5994,7 @@ class CodeEditor : Window
       return result;
    }
 
-   void ListNameSpaceByString(Module mainModule, char * string)
+   void ListNameSpaceByString(Module mainModule, const char * string)
    {
       NameSpace * nameSpace;
       Module module;
@@ -5852,13 +6022,14 @@ class CodeEditor : Window
       for(link = (BTNamedLink)nameSpace.classes.first; link; link = (BTNamedLink)((BTNode)link).next)
       {
          Class _class = link.data;
-         if(_class.type == enumClass && (dest.kind != classType || !dest._class || dest._class.registered != _class))
+         if(_class.type == enumClass && (dest.kind != classType || ((!dest._class || !dest._class.registered || (dest._class.registered != _class && strcmp(dest._class.registered.dataTypeString, "char *") && strcmp(dest._class.string, "bool"))) && !dest.classObjectType)) &&
+            dest.kind != pointerType && dest.kind != ellipsisType)
          {
             OldList conversions { };
             Type type { };
             type.kind = classType;
             type._class = FindClass(_class.name);
-            if(MatchTypes(type, dest, &conversions, null, null, true, false, false, false))
+            if(MatchTypes(type, dest, &conversions, null, null, true, false, false, false, true))
             {
                ListEnumValues(_class);
                result = true;
@@ -5874,7 +6045,7 @@ class CodeEditor : Window
       return result;
    }
 
-   NameSpace * FindNameSpace(NameSpace nameSpace, char * name)
+   NameSpace * FindNameSpace(NameSpace nameSpace, const char * name)
    {
       int start = 0, c;
       char ch;
@@ -5902,7 +6073,7 @@ class CodeEditor : Window
       return (NameSpace *)nameSpace;
    }
 
-   void ListSymbols(Expression exp, bool enumOnly, char * string, Identifier realIdentifier)
+   void ListSymbols(Expression exp, bool enumOnly, const char * string, Identifier realIdentifier)
    {
       bool listedEnums = false;
       Type destType = (exp && exp.destType && !exp.destType.truth) ? exp.destType : null;
@@ -5944,7 +6115,9 @@ class CodeEditor : Window
          }
       }
 
-      if(this.privateModule && destType && (destType.kind != pointerType || destType.type.kind != voidType) && destType.kind != ellipsisType)
+      if(this.privateModule && destType && (destType.kind == _BoolType || destType.kind == classType || destType.kind == enumType || destType.kind == structType || destType.kind == templateType || destType.kind == thisClassType || destType.kind == unionType ||
+         (destType.kind == pointerType && destType.type.kind != voidType)))
+      //if(this.privateModule && destType && (destType.kind != pointerType || destType.type.kind != voidType) && destType.kind != ellipsisType)
       {
          listedEnums = ListEnumsModule(this.privateModule, destType);
       }
@@ -5954,13 +6127,13 @@ class CodeEditor : Window
          ListEnumValues(destType._class.registered);
 
          if(insideClass)
-            ListClassPropertiesAndVirtual(insideClass);
+            ListClassPropertiesAndVirtual(insideClass, null);
 
          listedEnums = true;
       }
       else if(destType && destType.kind == enumType)
       {
-         NamedLink value;
+         NamedLink64 value;
 
          for(value = destType.members.first; value; value = value.next)
          {
@@ -5969,22 +6142,22 @@ class CodeEditor : Window
          }
 
          if(insideClass)
-            ListClassPropertiesAndVirtual(insideClass);
+            ListClassPropertiesAndVirtual(insideClass, null);
 
          listedEnums = true;
       }
       else if(insideClass && !enumOnly)
       {
-         ListClassPropertiesAndVirtual(insideClass);
+         ListClassPropertiesAndVirtual(insideClass, string);
       }
 
       if(listedEnums && string && string[0])
       {
          DataRow row = membersList.FindSubString(string);
          if(!row)
-            listedEnums = false;      
+            listedEnums = false;
       }
-      
+
       if(!insideClass && exp && exp.destType && exp.destType.kind == functionType && GetThisClass())
       {
          ListClassMembersMatch(GetThisClass(), exp.destType);
@@ -5995,7 +6168,7 @@ class CodeEditor : Window
          Symbol symbol = null;
          {
             if(GetThisClass())
-            { 
+            {
                ListClassMembers(GetThisClass(), false);
             }
 
@@ -6017,12 +6190,12 @@ class CodeEditor : Window
                      {
                         row.icon = icons[typeEnumValue];
                      }
-                     else 
+                     else
                      {
                         BitmapResource bitmap = null;
                         if(symbol.type && symbol.type.kind == classType && symbol.type._class && symbol.type._class)
                         {
-                           char * bitmapName = (char *)eClass_GetProperty(symbol.type._class.registered, "icon");
+                           char * bitmapName = (char *)(intptr)eClass_GetProperty(symbol.type._class.registered, "icon");
                            if(bitmapName)
                            {
                               bitmap = { bitmapName };
@@ -6075,7 +6248,7 @@ class CodeEditor : Window
                      {
                         row.icon = icons[typeEnumValue];
                      }
-                     else 
+                     else
                      {
                         BitmapResource bitmap = null;
                         if(data.dataType && data.dataType.kind == classType && data.dataType._class && data.dataType._class)
@@ -6114,7 +6287,7 @@ class CodeEditor : Window
    void OverrideVirtualFunction(ClassFunction function, Method method, Class _class, bool isInstance, bool extraIndent)
    {
       EditBoxStream f { editBox = editBox };
-      uint position = 0;
+      int position = 0;
       EditLine l1, l2;
       int x1,y1,x2,y2;
 
@@ -6131,7 +6304,7 @@ class CodeEditor : Window
          Type dataType = method.dataType;
          Type returnType = dataType.returnType;
          Type param;
-         Class moduleClass = eSystem_FindClass(this.privateModule, "Module");
+         // Class moduleClass = eSystem_FindClass(this.privateModule, "Module");
 
          if(insideDef.prev)
              f.Printf("\n\n");
@@ -6142,7 +6315,7 @@ class CodeEditor : Window
          OutputType(f, returnType, false);
 
          f.Printf(" ");
-         
+
          if(dataType.thisClass && !dataType.classObjectType && (!isInstance || !insideClass || !eClass_IsDerived(insideClass, dataType.thisClass.registered)))
          {
             if(dataType.thisClass.shortName)
@@ -6163,7 +6336,7 @@ class CodeEditor : Window
                   f.Printf(", ");
             }
          }
-         f.Printf(")\n");                  
+         f.Printf(")\n");
          if(extraIndent) f.Printf("   ");
          f.Printf("   %c\n", OpenBracket);
 
@@ -6171,9 +6344,9 @@ class CodeEditor : Window
 
          f.Printf("\n");
 
-         if(!_class || 
+         if(!_class ||
             (
-               (isInstance ? _class : _class.base)._vTbl[method.vid] == moduleClass._vTbl[__ecereVMethodID___ecereNameSpace__ecere__com__Module_OnLoad] ||
+               (isInstance ? _class : _class.base)._vTbl[method.vid] == null /*moduleClass._vTbl[__ecereVMethodID___ecereNameSpace__ecere__com__Module_OnLoad]*/ ||
                (isInstance ? _class : _class.base)._vTbl[method.vid] == DummyMethod)) // Temp Check for DefaultFunction
          {
             if(returnType && returnType.kind == classType && !strcmp(returnType._class.string, "bool"))
@@ -6222,7 +6395,6 @@ class CodeEditor : Window
    {
       bool didOverride = false;
       EditLine line = editBox.line;
-      char * text = line.text;
       int lineNum, charPos;
       Expression exp = null;
       EditLine l1, l2;
@@ -6231,6 +6403,7 @@ class CodeEditor : Window
       Expression memberExp = null;
       Identifier realIdentifier = null;
 
+      if(!parsing) return true;
       if(!privateModule) return !didOverride;
 
       insideFunction = null;
@@ -6242,7 +6415,7 @@ class CodeEditor : Window
       }
 
       editBox.GetSelPos(&l1, &y1, &x1, &l2, &y2, &x2, false);
-      { 
+      {
          EditBoxStream f { editBox = editBox };
 
          updatingCode = true;
@@ -6273,7 +6446,7 @@ class CodeEditor : Window
          else if(!pointer)
          {
             editBox.GetSelPos(&l1, &y1, &x1, &l2, &y2, &x2, false);
-            { 
+            {
                EditBoxStream f { editBox = editBox };
                char ch = 0;
 
@@ -6323,11 +6496,12 @@ class CodeEditor : Window
          int rowCount;
          char tempString[1024];
          char * string = null;
-         CodePosition idStart, idEnd;
+         CodePosition idStart { };
+         CodePosition idEnd { };
 
          if(membersListShown)
          {
-            char * buffer = membersLine.text;
+            const char * buffer = membersLine.text;
             int c;
             bool firstChar = true;
             int len = 0;
@@ -6359,7 +6533,7 @@ class CodeEditor : Window
             }
             string[len] = 0;
             */
-            int x, y;
+            int x = 0, y;
             int len = 0;
             EditLine editLine = editBox.line;
             bool firstChar = true;
@@ -6368,7 +6542,7 @@ class CodeEditor : Window
             string = tempString;
             for(y = lineNum-1; y >= 0; y--)
             {
-               char * buffer = editLine.text;
+               const char * buffer = editLine.text;
                int lineCount = editLine.count;
                for(x = (y == lineNum-1) ? (Min(charPos, lineCount) - 1 ): lineCount-1; x >= 0; x--)
                {
@@ -6493,7 +6667,7 @@ class CodeEditor : Window
                DataRow row = string ? membersList.FindSubString(string) : null;
                if(row && !membersList.FindSubStringAfter(row, string) && !caretMove)
                {
-                  char * newString = row.string;
+                  const char * newString = row.string;
                   if(!membersListShown)
                   {
                      membersLoc.start.line = idStart.line-1;
@@ -6538,7 +6712,7 @@ class CodeEditor : Window
                         editBox.SetSelPos(l1, y1, idStart.charPos-1, l2, y2, idStart.charPos-1);
                      editBox.GetCaretPosition(caret);
                      editBox.SetSelPos(l1, y1, x1, l2, y2, x2);
-               
+
                      membersList.master = this;
 
                      caret.y += editBox.GetCaretSize();
@@ -6585,7 +6759,7 @@ class CodeEditor : Window
                   }
                   if(row)
                      membersList.SetScrollPosition(0, row.index * membersList.rowHeight);
-               }            
+               }
             }
          }
       }
@@ -6598,18 +6772,17 @@ class CodeEditor : Window
 
    void InvokeParameters(bool exact, bool reposition, bool caretMove)
    {
-      EditLine line = editBox.line;
-      char * text = line.text;
       int lineNum, charPos;
-      Expression exp = null;
       EditLine l1, l2;
       int x1,y1, x2,y2;
 
+      if(!parsing) return;
+
       charPos = editBox.charPos + 1;
       EnsureUpToDate();
 
       editBox.GetSelPos(&l1, &y1, &x1, &l2, &y2, &x2, false);
-      { 
+      {
          EditBoxStream f { editBox = editBox };
          char ch;
 
@@ -6644,7 +6817,7 @@ class CodeEditor : Window
          delete f;
          updatingCode = false;
       }
-      
+
       charPos = Min(charPos, l1.count + 1);
       if(!caretMove)
          FindParamsTree(ast, lineNum, charPos);
@@ -6666,7 +6839,7 @@ class CodeEditor : Window
          if(this.functionType != ::functionType || this.instanceType != ::instanceType)
             reposition = false;
 
-         if(!this.paramsShown || reposition || paramsInsideExp != functionExp || ::instanceType) // Added instanceType here, otherwise instance popups never reposition... 
+         if(!this.paramsShown || reposition || paramsInsideExp != functionExp || ::instanceType) // Added instanceType here, otherwise instance popups never reposition...
                                                                                                           // ( Dummy exp: always ends up with same memory)
          {
             editBox.GetSelPos(&l1, &y1, &x1, &l2, &y2, &x2, false);
@@ -6750,3 +6923,38 @@ CodeEditor NewCodeEditor(Window parent, WindowState state, bool modified)
    document.Create();
    return document;
 }
+
+static int nofdigits(int v)
+{
+   if(v == MININT) return 10 + 1;
+   if(v < 0) return nofdigits(-v) + 1;
+   if(v >= 10000)
+   {
+      if(v >= 10000000)
+      {
+         if(v >= 100000000)
+         {
+            if(v >= 1000000000)
+               return 10;
+            return 9;
+         }
+         return 8;
+      }
+      if(v >= 100000)
+      {
+         if(v >= 1000000)
+            return 7;
+         return 6;
+      }
+      return 5;
+   }
+   if(v >= 100)
+   {
+      if(v >= 1000)
+         return 4;
+      return 3;
+   }
+   if(v >= 10)
+      return 2;
+   return 1;
+}