samples/audio; Installer: Added SineTone sample
[sdk] / compiler / libec / src / pass15.ec
index df55a93..4d4d489 100644 (file)
@@ -1,9 +1,5 @@
 import "ecdefs"
 
-#define uint _uint
-#include <stdlib.h>  // For strtoll
-#undef uint
-
 // UNTIL IMPLEMENTED IN GRAMMAR
 #define ACCESS_CLASSDATA(_class, baseClass) \
    (_class ? ((void *)(((char *)_class.data) + baseClass.offsetClass)) : null)
@@ -88,7 +84,7 @@ bool NeedCast(Type type1, Type type2)
       return false;
    }
 
-   if(type1.kind == type2.kind)
+   if(type1.kind == type2.kind && type1.isLong == type2.isLong)
    {
       switch(type1.kind)
       {
@@ -125,6 +121,7 @@ static void ReplaceClassMembers(Expression exp, Class _class)
          // First, check if the identifier is declared inside the function
          for(ctx = curContext; ctx != topContext.parent && !symbol; ctx = ctx.parent)
          {
+            if(!ctx) break;   // This happened opening old mapTileCache.ec from archives?
             symbol = (Symbol)ctx.symbols.FindString(id.string);
             if(symbol) break;
          }
@@ -670,7 +667,9 @@ void ComputeClassMembers(Class _class, bool isMember)
                if(_class.memberOffset % _class.structAlignment)
                   extra += _class.structAlignment - (_class.memberOffset % _class.structAlignment);
             }
-            _class.structSize = (_class.base ? (_class.base.templateClass ? _class.base.templateClass.structSize : _class.base.structSize) : 0) + _class.memberOffset + extra;
+            _class.structSize = (_class.base ? (_class.base.templateClass ?
+               (_class.base.type == noHeadClass ? _class.base.templateClass.memberOffset : _class.base.templateClass.structSize) :
+                  (_class.base.type == noHeadClass ? _class.base.memberOffset : _class.base.structSize) ) : 0) + _class.memberOffset + extra;
             if(!member)
             {
                Property prop;
@@ -694,7 +693,7 @@ void ComputeClassMembers(Class _class, bool isMember)
                   if(deriv.computeSize)
                   {
                      // TESTING THIS NEW CODE HERE... TRYING TO FIX ScrollBar MEMBERS DEBUGGING
-                     deriv.offset = /*_class.offset + */_class.structSize;
+                     deriv.offset = /*_class.offset + */(_class.type == noHeadClass ? _class.memberOffset : _class.structSize);
                      deriv.memberOffset = 0;
                      // ----------------------
 
@@ -735,8 +734,8 @@ public int ComputeTypeSize(Type type)
          case charType: type.alignment = size = sizeof(char); break;
          case intType: type.alignment = size = sizeof(int); break;
          case int64Type: type.alignment = size = sizeof(int64); break;
-         case intPtrType: type.alignment = size = targetBits / 8; break;
-         case intSizeType: type.alignment = size = targetBits / 8; break;
+         case intPtrType: type.alignment = size = targetBits / 8; type.pointerAlignment = true; break;
+         case intSizeType: type.alignment = size = targetBits / 8; type.pointerAlignment = true; break;
          case longType: type.alignment = size = sizeof(long); break;
          case shortType: type.alignment = size = sizeof(short); break;
          case floatType: type.alignment = size = sizeof(float); break;
@@ -750,6 +749,7 @@ public int ComputeTypeSize(Type type)
                // Ensure all members are properly registered
                ComputeClassMembers(_class, false);
                type.alignment = _class.structAlignment;
+               type.pointerAlignment = (bool)_class.pointerAlignment;
                size = _class.structSize;
                if(type.alignment && size % type.alignment)
                   size += type.alignment - (size % type.alignment);
@@ -764,10 +764,13 @@ public int ComputeTypeSize(Type type)
                size = type.alignment = ComputeTypeSize(_class.dataType);
             }
             else
+            {
                size = type.alignment = targetBits / 8; // sizeof(Instance *);
+               type.pointerAlignment = true;
+            }
             break;
          }
-         case pointerType: case subClassType: size = type.alignment = targetBits / 8; /*sizeof(void *); */break;
+         case pointerType: case subClassType: size = type.alignment = targetBits / 8; /*sizeof(void *); */ type.pointerAlignment = true; break;
          case arrayType:
             if(type.arraySizeExp)
             {
@@ -813,7 +816,10 @@ public int ComputeTypeSize(Type type)
 
             size = ComputeTypeSize(type.type) * type.arraySize;
             if(type.type)
+            {
                type.alignment = type.type.alignment;
+               type.pointerAlignment = type.type.pointerAlignment;
+            }
 
             break;
          case structType:
@@ -839,6 +845,11 @@ public int ComputeTypeSize(Type type)
                      member.offset += member.alignment - (size % member.alignment);
                   size = member.offset;
 
+                  if(member.pointerAlignment && type.size <= 4)
+                     type.pointerAlignment = true;
+                  else if(!member.pointerAlignment && member.alignment >= 8)
+                     type.pointerAlignment = false;
+
                   type.alignment = Max(type.alignment, member.alignment);
                   size += addSize;
                }
@@ -856,6 +867,7 @@ public int ComputeTypeSize(Type type)
                {
                   ComputeTypeSize(symbol.type);
                   size = symbol.type.size;
+                  type.alignment = symbol.type.alignment;
                }
             }
             else
@@ -870,7 +882,13 @@ public int ComputeTypeSize(Type type)
                      member.offset += member.alignment - (size % member.alignment);
                   size = member.offset;
 
+                  if(member.pointerAlignment && type.size <= 4)
+                     type.pointerAlignment = true;
+                  else if(!member.pointerAlignment && member.alignment >= 8)
+                     type.pointerAlignment = false;
+
                   type.alignment = Max(type.alignment, member.alignment);
+
                   size = Max(size, addSize);
                }
                if(type.alignment && size % type.alignment)
@@ -886,6 +904,7 @@ public int ComputeTypeSize(Type type)
             {
                size = ComputeTypeSize(baseType);
                type.alignment = baseType.alignment;
+               type.pointerAlignment = baseType.pointerAlignment;
             }
             else
                type.alignment = size = sizeof(uint64);
@@ -899,6 +918,7 @@ public int ComputeTypeSize(Type type)
          case thisClassType:
          {
             type.alignment = size = targetBits / 8; //sizeof(void *);
+            type.pointerAlignment = true;
             break;
          }
       }
@@ -909,7 +929,7 @@ public int ComputeTypeSize(Type type)
 }
 
 
-/*static */int AddMembers(OldList * declarations, Class _class, bool isMember, uint * retSize, Class topClass, bool *addedPadding)
+/*static */int AddMembers(External neededBy, OldList * declarations, Class _class, bool isMember, uint * retSize, Class topClass, bool *addedPadding)
 {
    // This function is in need of a major review when implementing private members etc.
    DataMember topMember = isMember ? (DataMember) _class : null;
@@ -930,7 +950,7 @@ public int ComputeTypeSize(Type type)
       {
          // DANGER: Testing this noHeadClass here...
          if(_class.type == structClass || _class.type == noHeadClass)
-            /*totalSize = */AddMembers(declarations, _class.base, false, &totalSize, topClass, null);
+            /*totalSize = */AddMembers(neededBy, declarations, _class.base, false, &totalSize, topClass, null);
          else
          {
             uint baseSize = _class.base.templateClass ? _class.base.templateClass.structSize : _class.base.structSize;
@@ -967,7 +987,7 @@ public int ComputeTypeSize(Type type)
 
                   {
                      Type type = ProcessType(specs, decl);
-                     DeclareType(member.dataType, false, false);
+                     DeclareType(neededBy, member.dataType, true, false);
                      FreeType(type);
                   }
                   /*
@@ -997,7 +1017,7 @@ public int ComputeTypeSize(Type type)
                sprintf(id, "__anon%d", anonID++);
 
                size = 0;
-               AddMembers(list, (Class)member, true, &size, topClass, null);
+               AddMembers(neededBy, list, (Class)member, true, &size, topClass, null);
                ListAdd(specs,
                   MkStructOrUnion((member.type == unionMember)?unionSpecifier:structSpecifier, null, list));
                ListAdd(declarations, MkClassDefDeclaration(MkStructDeclaration(specs, MkListOne(MkDeclaratorIdentifier(MkIdentifier(id))),null)));
@@ -1042,14 +1062,14 @@ public int ComputeTypeSize(Type type)
    return topMember ? topMember.memberID : _class.memberID;
 }
 
-static int DeclareMembers(Class _class, bool isMember)
+static int DeclareMembers(External neededBy, Class _class, bool isMember)
 {
    DataMember topMember = isMember ? (DataMember) _class : null;
    DataMember member;
    Context context = isMember ? null : SetupTemplatesContext(_class);
 
    if(!isMember && (_class.type == structClass || _class.type == noHeadClass) && _class.base.type != systemClass)
-      DeclareMembers(_class.base, false);
+      DeclareMembers(neededBy, _class.base, false);
 
    for(member = isMember ? topMember.members.first : _class.membersAndProperties.first; member; member = member.next)
    {
@@ -1059,21 +1079,16 @@ static int DeclareMembers(Class _class, bool isMember)
          {
             case normalMember:
             {
-               /*
-               if(member.dataType && member.dataType.kind == classType && member.dataType._class &&
-                  member.dataType._class.registered && member.dataType._class.registered.type == structClass)
-                  DeclareStruct(member.dataType._class.string, false);
-                  */
                if(!member.dataType && member.dataTypeString)
                   member.dataType = ProcessTypeString(member.dataTypeString, false);
                if(member.dataType)
-                  DeclareType(member.dataType, false, false);
+                  DeclareType(neededBy, member.dataType, true, false);
                break;
             }
             case unionMember:
             case structMember:
             {
-               DeclareMembers((Class)member, true);
+               DeclareMembers(neededBy, (Class)member, true);
                break;
             }
          }
@@ -1133,518 +1148,478 @@ static void IdentifyAnonStructs(OldList/*<ClassDef>*/ *  definitions)
    }
 }
 
-void DeclareStruct(const char * name, bool skipNoHead)
+External DeclareStruct(External neededBy, const char * name, bool skipNoHead, bool needDereference)
+{
+   return _DeclareStruct(neededBy, name, skipNoHead, needDereference, false);
+}
+
+External _DeclareStruct(External neededBy, const char * name, bool skipNoHead, bool needDereference, bool fwdDecl)
 {
    External external = null;
    Symbol classSym = FindClass(name);
+   OldList * curDeclarations = null;
 
-   if(!inCompiler || !classSym) return;
+   if(!inCompiler || !classSym) return null;
 
    // We don't need any declaration for bit classes...
    if(classSym.registered &&
       (classSym.registered.type == bitClass || classSym.registered.type == unitClass || classSym.registered.type == enumClass))
-      return;
+      return null;
 
-   /*if(classSym.registered.templateClass)
-      return DeclareStruct(classSym.registered.templateClass.fullName, skipNoHead);
-   */
+   if(!classSym.registered || (classSym.registered.type == normalClass && classSym.registered.structSize && classSym.registered.base && classSym.registered.base.base))
+      _DeclareStruct(neededBy, "ecere::com::Instance", false, true, fwdDecl);
 
-   if(classSym.registered && classSym.imported && !classSym.declaredStructSym)
+   external = classSym.structExternal;
+
+   if(external && external.declaration)
+   {
+      Specifier spec;
+      for(spec = external.declaration.specifiers ? external.declaration.specifiers->first : null; spec; spec = spec.next)
+         if(spec.type == structSpecifier || spec.type == unionSpecifier)
+         {
+            curDeclarations = spec.definitions;
+            break;
+         }
+   }
+
+   if(classSym.registered && !classSym.declaring && classSym.imported && (!classSym.declaredStructSym || (classSym.registered.type == noHeadClass && !skipNoHead && external && !curDeclarations)))
    {
-      // Add typedef struct
-      Declaration decl;
       OldList * specifiers, * declarators;
       OldList * declarations = null;
       char structName[1024];
-      Specifier spec = null;
-      external = (classSym.registered && classSym.registered.type == structClass) ?
-         classSym.pointerExternal : classSym.structExternal;
-
-      // TEMPORARY HACK: Pass 3 will move up struct declarations without moving members
-      // Moved this one up because DeclareClass done later will need it
+      bool addedPadding = false;
+      Specifier curSpec = null;
 
       classSym.declaring++;
 
       if(strchr(classSym.string, '<'))
       {
          if(classSym.registered.templateClass)
-         {
-            DeclareStruct(classSym.registered.templateClass.fullName, skipNoHead);
-            classSym.declaring--;
-         }
-         return;
+            external = _DeclareStruct(neededBy, classSym.registered.templateClass.fullName, skipNoHead, needDereference, fwdDecl);
+         classSym.declaring--;
+         return external;
       }
 
-      //if(!skipNoHead)
-         DeclareMembers(classSym.registered, false);
-
       structName[0] = 0;
       FullClassNameCat(structName, name, false);
 
-      if(external && external.declaration && external.declaration.specifiers)
+      classSym.declaredStructSym = true;
+      if(!external || (classSym.registered.type == noHeadClass && !skipNoHead && !curDeclarations))
       {
-         for(spec = external.declaration.specifiers->first; spec; spec = spec.next)
+         bool add = false;
+         if(!external)
          {
-            if(spec.type == structSpecifier || spec.type == unionSpecifier)
-               break;
-         }
-      }
-
-      /*if(!external)
-         external = MkExternalDeclaration(null);*/
-
-      if(!skipNoHead && (!spec || !spec.definitions))
-      {
-         bool addedPadding = false;
-         classSym.declaredStructSym = true;
+            external = MkExternalDeclaration(null);
+            classSym.structExternal = external;
+            external.symbol = classSym;
 
-         declarations = MkList();
+            add = true;
+         }
 
-         AddMembers(declarations, classSym.registered, false, null, classSym.registered, &addedPadding);
+         if(!skipNoHead)
+         {
+            declarations = MkList();
+            AddMembers(external, declarations, classSym.registered, false, null, classSym.registered, &addedPadding);
+         }
 
-         //ListAdd(specifiers, MkSpecifier(TYPEDEF));
-         //ListAdd(specifiers, MkStructOrUnion(structSpecifier, null, declarations));
+         if(external.declaration)
+         {
+            Specifier spec;
+            for(spec = external.declaration.specifiers ? external.declaration.specifiers->first : null; spec; spec = spec.next)
+               if(spec.type == structSpecifier || spec.type == unionSpecifier)
+               {
+                  curSpec = spec;
+                  curDeclarations = spec.definitions;
+                  break;
+               }
+         }
 
-         if(!declarations->count || (declarations->count == 1 && addedPadding))
+         if(declarations && (!declarations->count || (declarations->count == 1 && addedPadding)))
          {
             FreeList(declarations, FreeClassDef);
             declarations = null;
          }
-      }
-      if(skipNoHead || declarations)
-      {
-         if(spec)
-         {
-            if(declarations)
-               spec.definitions = declarations;
 
-            if(curExternal && curExternal.symbol && curExternal.symbol.idCode < classSym.id)
-            {
-               // TODO: Fix this
-               //ast->Move(classSym.structExternal ? classSym.structExternal : classSym.pointerExternal, curExternal.prev);
-
-               // DANGER
-               if(classSym.structExternal)
-                  ast->Move(classSym.structExternal, curExternal.prev);
-               ast->Move(classSym.pointerExternal, curExternal.prev);
-
-               classSym.id = curExternal.symbol.idCode;
-               classSym.idCode = curExternal.symbol.idCode;
-               // external = classSym.pointerExternal;
-               //external = classSym.structExternal ? classSym.structExternal : classSym.pointerExternal;
-            }
+         if(classSym.registered.type != noHeadClass && !declarations)
+         {
+            FreeExternal(external);
+            external = null;
+            classSym.structExternal = null;
          }
          else
          {
-            if(!external)
-               external = MkExternalDeclaration(null);
-
-            specifiers = MkList();
-            declarators = MkList();
-            ListAdd(specifiers, MkStructOrUnion(structSpecifier, MkIdentifier(structName), declarations));
-
-            /*
-            d = MkDeclaratorIdentifier(MkIdentifier(structName));
-            ListAdd(declarators, MkInitDeclarator(d, null));
-            */
-            external.declaration = decl = MkDeclaration(specifiers, declarators);
-            if(decl.symbol && !decl.symbol.pointerExternal)
-               decl.symbol.pointerExternal = external;
-
-            // For simple classes, keep the declaration as the external to move around
-            if(classSym.registered && classSym.registered.type == structClass)
-            {
-               char className[1024];
-               strcpy(className, "__ecereClass_");
-               FullClassNameCat(className, classSym.string, true);
-               //MangleClassName(className);
-
-               // Testing This
-               DeclareClass(classSym, className);
-
-               external.symbol = classSym;
-               classSym.pointerExternal = external;
-               classSym.id = (curExternal && curExternal.symbol) ? curExternal.symbol.idCode : 0;
-               classSym.idCode = (curExternal && curExternal.symbol) ? curExternal.symbol.idCode : 0;
-            }
+            if(curSpec)
+               curSpec.definitions = declarations;
             else
             {
-               char className[1024];
-               strcpy(className, "__ecereClass_");
-               FullClassNameCat(className, classSym.string, true);
-               //MangleClassName(className);
-
-               // TOFIX: TESTING THIS...
-               classSym.structExternal = external;
-               DeclareClass(classSym, className);
-               external.symbol = classSym;
+               specifiers = MkList();
+               declarators = MkList();
+               ListAdd(specifiers, MkStructOrUnion(structSpecifier, MkIdentifier(structName), declarations));
+               external.declaration = MkDeclaration(specifiers, declarators);
             }
-
-            //if(curExternal)
-               ast->Insert(curExternal ? curExternal.prev : null, external);
+            if(add)
+               ast->Add(external);
          }
       }
-
       classSym.declaring--;
    }
-   else
+   else if(!classSym.declaredStructSym && classSym.structExternal)
    {
-      if(classSym.structExternal && classSym.structExternal.declaration && classSym.structExternal.declaration.specifiers)
+      classSym.declaredStructSym = true;
+
+      if(classSym.registered)
+         DeclareMembers(classSym.structExternal, classSym.registered, false);
+
+      if(classSym.structExternal.declaration && classSym.structExternal.declaration.specifiers)
       {
          Specifier spec;
          for(spec = classSym.structExternal.declaration.specifiers->first; spec; spec = spec.next)
          {
-            IdentifyAnonStructs(spec.definitions);
+            if(spec.definitions)
+               IdentifyAnonStructs(spec.definitions);
          }
       }
-
-      if(curExternal && curExternal.symbol && curExternal.symbol.idCode < classSym.id)
+   }
+   if(inCompiler && neededBy && (external || !classSym.imported))
+   {
+      if(!external)
       {
-         // TEMPORARY HACK: Pass 3 will move up struct declarations without moving members
-         // Moved this one up because DeclareClass done later will need it
-
-         // TESTING THIS:
-         classSym.declaring++;
-
-         //if(!skipNoHead)
-         {
-            if(classSym.registered)
-               DeclareMembers(classSym.registered, false);
-         }
-
-         if(classSym.registered && (classSym.registered.type == structClass || classSym.registered.type == noHeadClass))
-         {
-            // TODO: Fix this
-            //ast->Move(classSym.structExternal ? classSym.structExternal : classSym.pointerExternal, curExternal.prev);
-
-            // DANGER
-            if(classSym.structExternal)
-               ast->Move(classSym.structExternal, curExternal.prev);
-            ast->Move(classSym.pointerExternal, curExternal.prev);
-
-            classSym.id = curExternal.symbol.idCode;
-            classSym.idCode = curExternal.symbol.idCode;
-            // external = classSym.pointerExternal;
-            // external = classSym.structExternal ? classSym.structExternal : classSym.pointerExternal;
-         }
-
-         classSym.declaring--;
+         classSym.structExternal = external = MkExternalDeclaration(null);
+         external.symbol = classSym;
+         ast->Add(external);
+      }
+      if(reachedPass15 && !external.declaration && classSym.registered && classSym.registered.type == noHeadClass)
+      {
+         // Declare nohead classes without definitions here (e.g. IteratorPointer)
+         char structName[1024];
+         OldList * specifiers, * declarators;
+         structName[0] = 0;
+         FullClassNameCat(structName, name, false);
+         specifiers = MkList();
+         declarators = MkList();
+         ListAdd(specifiers, MkStructOrUnion(structSpecifier, MkIdentifier(structName), null));
+         external.declaration = MkDeclaration(specifiers, declarators);
       }
+      if(fwdDecl)
+      {
+         External e = external.fwdDecl ? external.fwdDecl : external;
+         if(e.incoming.count)
+            neededBy.CreateUniqueEdge(e, !needDereference && !external.fwdDecl);
+      }
+      else
+         neededBy.CreateUniqueEdge(external, !needDereference);
    }
-   //return external;
+   return external;
 }
 
-void DeclareProperty(Property prop, char * setName, char * getName)
+void DeclareProperty(External neededBy, Property prop, char * setName, char * getName)
 {
    Symbol symbol = prop.symbol;
+   bool imported = false;
+   bool dllImport = false;
+   External structExternal = null;
+   External instExternal = null;
 
    strcpy(setName, "__ecereProp_");
    FullClassNameCat(setName, prop._class.fullName, false);
    strcat(setName, "_Set_");
-   // strcat(setName, prop.name);
    FullClassNameCat(setName, prop.name, true);
-   //MangleClassName(setName);
 
    strcpy(getName, "__ecereProp_");
    FullClassNameCat(getName, prop._class.fullName, false);
    strcat(getName, "_Get_");
    FullClassNameCat(getName, prop.name, true);
-   // strcat(getName, prop.name);
-
-   // To support "char *" property
-   //MangleClassName(getName);
-
-   if(prop._class.type == structClass)
-      DeclareStruct(prop._class.fullName, false);
 
-   if(!symbol || curExternal.symbol.idCode < symbol.id)
+   if(!symbol || symbol._import)
    {
-      bool imported = false;
-      bool dllImport = false;
-
-      if(!symbol || symbol._import)
+      if(!symbol)
       {
-         if(!symbol)
+         Symbol classSym;
+
+         if(!prop._class.symbol)
+            prop._class.symbol = FindClass(prop._class.fullName);
+         classSym = prop._class.symbol;
+         if(classSym && !classSym._import)
          {
-            Symbol classSym;
-            if(!prop._class.symbol)
-               prop._class.symbol = FindClass(prop._class.fullName);
-            classSym = prop._class.symbol;
-            if(classSym && !classSym._import)
-            {
-               ModuleImport module;
+            ModuleImport module;
 
-               if(prop._class.module)
-                  module = FindModule(prop._class.module);
-               else
-                  module = mainModule;
+            if(prop._class.module)
+               module = FindModule(prop._class.module);
+            else
+               module = mainModule;
 
-               classSym._import = ClassImport
-               {
-                  name = CopyString(prop._class.fullName);
-                  isRemote = prop._class.isRemote;
-               };
-               module.classes.Add(classSym._import);
-            }
-            symbol = prop.symbol = Symbol { };
-            symbol._import = (ClassImport)PropertyImport
+            classSym._import = ClassImport
             {
-               name = CopyString(prop.name);
-               isVirtual = false; //prop.isVirtual;
-               hasSet = prop.Set ? true : false;
-               hasGet = prop.Get ? true : false;
+               name = CopyString(prop._class.fullName);
+               isRemote = prop._class.isRemote;
             };
-            if(classSym)
-               classSym._import.properties.Add(symbol._import);
+            module.classes.Add(classSym._import);
          }
-         imported = true;
-         // Ugly work around for isNan properties declared within float/double classes which are initialized with ecereCOM
-         if((prop._class.module != privateModule || !strcmp(prop._class.name, "float") || !strcmp(prop._class.name, "double")) &&
-            prop._class.module.importType != staticImport)
-            dllImport = true;
+         symbol = prop.symbol = Symbol { };
+         symbol._import = (ClassImport)PropertyImport
+         {
+            name = CopyString(prop.name);
+            isVirtual = false; //prop.isVirtual;
+            hasSet = prop.Set ? true : false;
+            hasGet = prop.Get ? true : false;
+         };
+         if(classSym)
+            classSym._import.properties.Add(symbol._import);
       }
+      imported = true;
+      // Ugly work around for isNan properties declared within float/double classes which are initialized with ecereCOM
+      if((prop._class.module != privateModule || !strcmp(prop._class.name, "float") || !strcmp(prop._class.name, "double")) &&
+         prop._class.module.importType != staticImport)
+         dllImport = true;
+   }
+
+   if(!symbol.type)
+   {
+      Context context = SetupTemplatesContext(prop._class);
+      symbol.type = ProcessTypeString(prop.dataTypeString, false);
+      FinishTemplatesContext(context);
+   }
+
+   if((prop.Get && !symbol.externalGet) || (prop.Set && !symbol.externalSet))
+   {
+      if(prop._class.type == normalClass && prop._class.structSize)
+         instExternal = DeclareStruct(null, "ecere::com::Instance", false, true);
+      structExternal = DeclareStruct(null, prop._class.fullName, prop._class.type != structClass /*true*/, false);
+   }
+
+   // Get
+   if(prop.Get && !symbol.externalGet)
+   {
+      Declaration decl;
+      OldList * specifiers, * declarators;
+      Declarator d;
+      OldList * params;
+      Specifier spec = null;
+      External external;
+      Declarator typeDecl;
+      bool simple = false;
+      bool needReference;
+
+      specifiers = MkList();
+      declarators = MkList();
+      params = MkList();
+
+      ListAdd(params, MkTypeName(MkListOne(MkSpecifierName(prop._class.fullName)),
+         MkDeclaratorIdentifier(MkIdentifier("this"))));
+
+      d = MkDeclaratorIdentifier(MkIdentifier(getName));
+      //if(imported)
+      if(dllImport)
+         d = MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), d));
 
-      if(!symbol.type)
       {
          Context context = SetupTemplatesContext(prop._class);
-         symbol.type = ProcessTypeString(prop.dataTypeString, false);
+         typeDecl = SpecDeclFromString(prop.dataTypeString, specifiers, null);
          FinishTemplatesContext(context);
       }
 
-      // Get
-      if(prop.Get)
+      // Make sure the simple _class's type is declared
+      needReference = !typeDecl || typeDecl.type == identifierDeclarator;
+      for(spec = specifiers->first; spec; spec = spec.next)
       {
-         if(!symbol.externalGet || symbol.externalGet.type == functionExternal)
+         if(spec.type == nameSpecifier)
          {
-            Declaration decl;
-            OldList * specifiers, * declarators;
-            Declarator d;
-            OldList * params;
-            Specifier spec;
-            External external;
-            Declarator typeDecl;
-            bool simple = false;
+            Symbol classSym = spec.symbol;
+            if(needReference)
+            {
+               symbol._class = classSym.registered;
+               if(classSym.registered && classSym.registered.type == structClass)
+                  simple = true;
+            }
+            break;
+         }
+      }
 
-            specifiers = MkList();
-            declarators = MkList();
-            params = MkList();
+      if(!simple)
+         d = PlugDeclarator(typeDecl, d);
+      else
+      {
+         ListAdd(params, MkTypeName(specifiers,
+            PlugDeclarator(typeDecl, MkDeclaratorIdentifier(MkIdentifier("value")))));
+         specifiers = MkList();
+      }
 
-            ListAdd(params, MkTypeName(MkListOne(MkSpecifierName /*MkClassName*/(prop._class.fullName)),
-               MkDeclaratorIdentifier(MkIdentifier("this"))));
+      d = MkDeclaratorFunction(d, params);
 
-            d = MkDeclaratorIdentifier(MkIdentifier(getName));
-            //if(imported)
-            if(dllImport)
-               d = MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), d));
+      //if(imported)
+      if(dllImport)
+         specifiers->Insert(null, MkSpecifier(EXTERN));
+      else if(prop._class.symbol && ((Symbol)prop._class.symbol).isStatic)
+         specifiers->Insert(null, MkSpecifier(STATIC));
+      if(simple)
+         ListAdd(specifiers, MkSpecifier(VOID));
 
-            {
-               Context context = SetupTemplatesContext(prop._class);
-               typeDecl = SpecDeclFromString(prop.dataTypeString, specifiers, null);
-               FinishTemplatesContext(context);
-            }
+      ListAdd(declarators, MkInitDeclarator(d, null));
 
-            // Make sure the simple _class's type is declared
-            for(spec = specifiers->first; spec; spec = spec.next)
-            {
-               if(spec.type == nameSpecifier /*SpecifierClass*/)
-               {
-                  if((!typeDecl || typeDecl.type == identifierDeclarator))
-                  {
-                     Symbol classSym = spec.symbol; // FindClass(spec.name);
-                     symbol._class = classSym.registered;
-                     if(classSym.registered && classSym.registered.type == structClass)
-                     {
-                        DeclareStruct(spec.name, false);
-                        simple = true;
-                     }
-                  }
-               }
-            }
+      decl = MkDeclaration(specifiers, declarators);
 
-            if(!simple)
-               d = PlugDeclarator(typeDecl, d);
-            else
-            {
-               ListAdd(params, MkTypeName(specifiers,
-                  PlugDeclarator(typeDecl, MkDeclaratorIdentifier(MkIdentifier("value")))));
-               specifiers = MkList();
-            }
+      external = MkExternalDeclaration(decl);
 
-            d = MkDeclaratorFunction(d, params);
+      if(structExternal)
+         external.CreateEdge(structExternal, false);
+      if(instExternal)
+         external.CreateEdge(instExternal, false);
 
-            //if(imported)
-            if(dllImport)
-               specifiers->Insert(null, MkSpecifier(EXTERN));
-            else if(prop._class.symbol && ((Symbol)prop._class.symbol).isStatic)
-               specifiers->Insert(null, MkSpecifier(STATIC));
-            if(simple)
-               ListAdd(specifiers, MkSpecifier(VOID));
+      if(spec)
+         DeclareStruct(external, spec.name, false, needReference);
 
-            ListAdd(declarators, MkInitDeclarator(d, null));
+      ast->Add(external);
+      external.symbol = symbol;
+      symbol.externalGet = external;
 
-            decl = MkDeclaration(specifiers, declarators);
+      ReplaceThisClassSpecifiers(specifiers, prop._class);
 
-            external = MkExternalDeclaration(decl);
-            ast->Insert(curExternal.prev, external);
-            external.symbol = symbol;
-            symbol.externalGet = external;
+      if(typeDecl)
+         FreeDeclarator(typeDecl);
+   }
 
-            ReplaceThisClassSpecifiers(specifiers, prop._class);
+   // Set
+   if(prop.Set && !symbol.externalSet)
+   {
+      Declaration decl;
+      OldList * specifiers, * declarators;
+      Declarator d;
+      OldList * params;
+      Specifier spec = null;
+      External external;
+      Declarator typeDecl;
+      bool needReference;
 
-            if(typeDecl)
-               FreeDeclarator(typeDecl);
-         }
-         else
-         {
-            // Move declaration higher...
-            ast->Move(symbol.externalGet, curExternal.prev);
-         }
+      declarators = MkList();
+      params = MkList();
+
+      if(!prop.conversion || prop._class.type == structClass)
+      {
+         ListAdd(params, MkTypeName(MkListOne(MkSpecifierName(prop._class.fullName)),
+            MkDeclaratorIdentifier(MkIdentifier("this"))));
       }
 
-      // Set
-      if(prop.Set)
+      specifiers = MkList();
+
       {
-         if(!symbol.externalSet || symbol.externalSet.type == functionExternal)
-         {
-            Declaration decl;
-            OldList * specifiers, * declarators;
-            Declarator d;
-            OldList * params;
-            Specifier spec;
-            External external;
-            Declarator typeDecl;
+         Context context = SetupTemplatesContext(prop._class);
+         typeDecl = d = SpecDeclFromString(prop.dataTypeString, specifiers,
+            MkDeclaratorIdentifier(MkIdentifier("value")));
+         FinishTemplatesContext(context);
+      }
+      if(!strcmp(prop._class.base.fullName, "eda::Row") || !strcmp(prop._class.base.fullName, "eda::Id"))
+         specifiers->Insert(null, MkSpecifier(CONST));
 
-            declarators = MkList();
-            params = MkList();
+      ListAdd(params, MkTypeName(specifiers, d));
 
-            // TESTING COMMENTING THIS FIRST LINE OUT, what was the problem? Trying to add noHeadClass here ...
-            if(!prop.conversion || prop._class.type == structClass)
-            {
-               ListAdd(params, MkTypeName(MkListOne(MkSpecifierName/*MkClassName*/(prop._class.fullName)),
-                  MkDeclaratorIdentifier(MkIdentifier("this"))));
-            }
+      d = MkDeclaratorIdentifier(MkIdentifier(setName));
+      if(dllImport)
+         d = MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), d));
+      d = MkDeclaratorFunction(d, params);
 
-            specifiers = MkList();
+      // Make sure the simple _class's type is declared
+      needReference = !typeDecl || typeDecl.type == identifierDeclarator;
+      for(spec = specifiers->first; spec; spec = spec.next)
+      {
+         if(spec.type == nameSpecifier)
+         {
+            Symbol classSym = spec.symbol;
+            if(needReference)
+               symbol._class = classSym.registered;
+            break;
+         }
+      }
 
-            {
-               Context context = SetupTemplatesContext(prop._class);
-               typeDecl = d = SpecDeclFromString(prop.dataTypeString, specifiers,
-                  MkDeclaratorIdentifier(MkIdentifier("value")));
-               FinishTemplatesContext(context);
-            }
-            if(!strcmp(prop._class.base.fullName, "eda::Row") || !strcmp(prop._class.base.fullName, "eda::Id"))
-               specifiers->Insert(null, MkSpecifier(CONST));
+      ListAdd(declarators, MkInitDeclarator(d, null));
 
-            ListAdd(params, MkTypeName(specifiers, d));
+      specifiers = MkList();
+      if(dllImport)
+         specifiers->Insert(null, MkSpecifier(EXTERN));
+      else if(prop._class.symbol && ((Symbol)prop._class.symbol).isStatic)
+         specifiers->Insert(null, MkSpecifier(STATIC));
 
-            d = MkDeclaratorIdentifier(MkIdentifier(setName));
-            //if(imported)
-            if(dllImport)
-               d = MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), d));
-            d = MkDeclaratorFunction(d, params);
+      if(!prop.conversion || prop._class.type == structClass)
+         ListAdd(specifiers, MkSpecifier(VOID));
+      else
+         ListAdd(specifiers, MkSpecifierName(prop._class.fullName));
 
-            // Make sure the simple _class's type is declared
-            for(spec = specifiers->first; spec; spec = spec.next)
-            {
-               if(spec.type == nameSpecifier /*SpecifierClass*/)
-               {
-                  if((!typeDecl || typeDecl.type == identifierDeclarator))
-                  {
-                     Symbol classSym = spec.symbol; // FindClass(spec.name);
-                     symbol._class = classSym.registered;
-                     if(classSym.registered && classSym.registered.type == structClass)
-                        DeclareStruct(spec.name, false);
-                  }
-               }
-            }
+      decl = MkDeclaration(specifiers, declarators);
 
-            ListAdd(declarators, MkInitDeclarator(d, null));
+      external = MkExternalDeclaration(decl);
 
-            specifiers = MkList();
-            //if(imported)
-            if(dllImport)
-               specifiers->Insert(null, MkSpecifier(EXTERN));
-            else if(prop._class.symbol && ((Symbol)prop._class.symbol).isStatic)
-               specifiers->Insert(null, MkSpecifier(STATIC));
+      if(structExternal)
+         external.CreateEdge(structExternal, false);
+      if(instExternal)
+         external.CreateEdge(instExternal, false);
 
-            // TESTING COMMENTING THIS FIRST LINE OUT, what was the problem? Trying to add noHeadClass here ...
-            if(!prop.conversion || prop._class.type == structClass)
-               ListAdd(specifiers, MkSpecifier(VOID));
-            else
-               ListAdd(specifiers, MkSpecifierName/*MkClassName*/(prop._class.fullName));
+      if(spec)
+         DeclareStruct(external, spec.name, false, needReference);
 
-            decl = MkDeclaration(specifiers, declarators);
+      ast->Add(external);
+      external.symbol = symbol;
+      symbol.externalSet = external;
 
-            external = MkExternalDeclaration(decl);
-            ast->Insert(curExternal.prev, external);
-            external.symbol = symbol;
-            symbol.externalSet = external;
+      ReplaceThisClassSpecifiers(specifiers, prop._class);
+   }
 
-            ReplaceThisClassSpecifiers(specifiers, prop._class);
-         }
-         else
-         {
-            // Move declaration higher...
-            ast->Move(symbol.externalSet, curExternal.prev);
-         }
-      }
+   // Property (for Watchers)
+   if(!symbol.externalPtr)
+   {
+      Declaration decl;
+      External external;
+      OldList * specifiers = MkList();
+      char propName[1024];
 
-      // Property (for Watchers)
-      if(!symbol.externalPtr)
+      if(imported)
+         specifiers->Insert(null, MkSpecifier(EXTERN));
+      else
       {
-         Declaration decl;
-         External external;
-         OldList * specifiers = MkList();
-         char propName[1024];
+         specifiers->Insert(null, MkSpecifier(STATIC));
+         specifiers->Add(MkSpecifierExtended(MkExtDeclAttrib(MkAttrib(ATTRIB, MkListOne(MkAttribute(CopyString("unused"), null))))));
+      }
 
-         if(imported)
-            specifiers->Insert(null, MkSpecifier(EXTERN));
-         else
-         {
-            specifiers->Insert(null, MkSpecifier(STATIC));
-            specifiers->Add(MkSpecifierExtended(MkExtDeclAttrib(MkAttrib(ATTRIB, MkListOne(MkAttribute(CopyString("unused"), null))))));
-         }
+      ListAdd(specifiers, MkSpecifierName("Property"));
 
-         ListAdd(specifiers, MkSpecifierName("Property"));
+      strcpy(propName, "__ecereProp_");
+      FullClassNameCat(propName, prop._class.fullName, false);
+      strcat(propName, "_");
+      FullClassNameCat(propName, prop.name, true);
 
-         strcpy(propName, "__ecereProp_");
-         FullClassNameCat(propName, prop._class.fullName, false);
-         strcat(propName, "_");
-         FullClassNameCat(propName, prop.name, true);
-         // strcat(propName, prop.name);
-         //MangleClassName(propName);
+      {
+         OldList * list = MkList();
+         ListAdd(list, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(propName)), null));
 
+         if(!imported)
          {
-            OldList * list = MkList();
+            strcpy(propName, "__ecerePropM_");
+            FullClassNameCat(propName, prop._class.fullName, false);
+            strcat(propName, "_");
+            FullClassNameCat(propName, prop.name, true);
+
             ListAdd(list, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(propName)), null));
+         }
+         decl = MkDeclaration(specifiers, list);
+      }
 
-            if(!imported)
-            {
-               strcpy(propName, "__ecerePropM_");
-               FullClassNameCat(propName, prop._class.fullName, false);
-               strcat(propName, "_");
-               // strcat(propName, prop.name);
-               FullClassNameCat(propName, prop.name, true);
+      external = MkExternalDeclaration(decl);
+      ast->Insert(curExternal.prev, external);
+      external.symbol = symbol;
+      symbol.externalPtr = external;
+   }
 
-               //MangleClassName(propName);
+   if(inCompiler && neededBy)
+   {
+      // Could improve this to create edge on only what is needed...
+      if(symbol.externalPtr)
+         neededBy.CreateUniqueEdge(symbol.externalPtr, false);
 
-               ListAdd(list, MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(propName)), null));
-            }
-            decl = MkDeclaration(specifiers, list);
-         }
+      if(symbol.externalGet)
+         neededBy.CreateUniqueEdge(symbol.externalGet, symbol.externalGet.type == functionExternal);
 
-         external = MkExternalDeclaration(decl);
-         ast->Insert(curExternal.prev, external);
-         external.symbol = symbol;
-         symbol.externalPtr = external;
-      }
-      else
-      {
-         // Move declaration higher...
-         ast->Move(symbol.externalPtr, curExternal.prev);
-      }
+      if(symbol.externalSet)
+         neededBy.CreateUniqueEdge(symbol.externalSet, symbol.externalSet.type == functionExternal);
 
-      symbol.id = curExternal.symbol.idCode;
+      // IsSet ?
    }
 }
 
@@ -2071,17 +2046,14 @@ void ProcessInstantiationType(Instantiation inst)
    if(inst._class)
    {
       MembersInit members;
-      Symbol classSym; // = inst._class.symbol; // FindClass(inst._class.name);
+      Symbol classSym;
       Class _class;
 
-      /*if(!inst._class.symbol)
-         inst._class.symbol = FindClass(inst._class.name);*/
       classSym = inst._class.symbol;
       _class = classSym ? classSym.registered : null;
 
-      // DANGER: Patch for mutex not declaring its struct when not needed
       if(!_class || _class.type != noHeadClass)
-         DeclareStruct(inst._class.name, false); //_class && _class.type == noHeadClass);
+         DeclareStruct(curExternal, inst._class.name, false, true);
 
       afterExternal = afterExternal ? afterExternal : curExternal;
 
@@ -2115,7 +2087,6 @@ void ProcessInstantiationType(Instantiation inst)
                   if(inCompiler)
                   {
                      char number[16];
-                     //members.function.dontMangle = true;
                      strcpy(name, "__ecereInstMeth_");
                      FullClassNameCat(name, _class ? _class.fullName : "_UNKNOWNCLASS", false);
                      strcat(name, "_");
@@ -2153,8 +2124,7 @@ void ProcessInstantiationType(Instantiation inst)
                               symbol.type.thisClass = _class.symbol;
                            }
                         }
-                        // TESTING THIS HERE:
-                        DeclareType(symbol.type, true, true);
+                        DeclareType(curExternal, symbol.type, true, true);
 
                      }
                      else if(classSym)
@@ -2164,7 +2134,6 @@ void ProcessInstantiationType(Instantiation inst)
                      }
                   }
 
-                  //declarator.symbol.id = declarator.symbol.idCode = curExternal.symbol.idCode;
                   createdExternal = ProcessClassFunction(classSym ? classSym.registered : null, members.function, ast, afterExternal, true);
 
                   if(nameID)
@@ -2173,87 +2142,11 @@ void ProcessInstantiationType(Instantiation inst)
                      nameID._class = null;
                   }
 
+                  curExternal = createdExternal;
                   if(inCompiler)
                   {
-                     //Type type = declarator.symbol.type;
-                     External oldExternal = curExternal;
-
-                     // *** Commented this out... Any negative impact? Yes: makes double prototypes declarations... Why was it commented out?
-                     // *** It was commented out for problems such as
-                     /*
-                           class VirtualDesktop : Window
-                           {
-                              clientSize = Size { };
-                              Timer timer
-                              {
-                                 bool DelayExpired()
-                                 {
-                                    clientSize.w;
-                                    return true;
-                                 }
-                              };
-                           }
-                     */
-                     // Commented Out: Good for bet.ec in Poker (Otherwise: obj\bet.c:187: error: `currentBet' undeclared (first use in this function))
-
-                     declarator.symbol.id = declarator.symbol.idCode = curExternal.symbol.idCode;
-
-                     /*
-                     if(strcmp(declarator.symbol.string, name))
-                     {
-                        printf("TOCHECK: Look out for this\n");
-                        delete declarator.symbol.string;
-                        declarator.symbol.string = CopyString(name);
-                     }
-
-                     if(!declarator.symbol.parent && globalContext.symbols.root != (BTNode)declarator.symbol)
-                     {
-                        printf("TOCHECK: Will this ever be in a list? Yes.\n");
-                        excludedSymbols->Remove(declarator.symbol);
-                        globalContext.symbols.Add((BTNode)declarator.symbol);
-                        if(strstr(declarator.symbol.string), "::")
-                           globalContext.hasNameSpace = true;
-
-                     }
-                     */
-
-                     //curExternal = curExternal.prev;
-                     //afterExternal = afterExternal->next;
-
-                     //ProcessFunction(afterExternal->function);
-
-                     //curExternal = afterExternal;
-                     {
-                        External externalDecl;
-                        externalDecl = MkExternalDeclaration(null);
-                        ast->Insert(oldExternal.prev, externalDecl);
-
-                        // Which function does this process?
-                        if(createdExternal.function)
-                        {
-                           ProcessFunction(createdExternal.function);
-
-                           //curExternal = oldExternal;
-
-                           {
-                              //Declaration decl = MkDeclaration(members.function.specifiers, MkListOne(MkInitDeclarator(CopyDeclarator(declarator), null)));
-
-                              Declaration decl = MkDeclaration(CopyList(createdExternal.function.specifiers, CopySpecifier),
-                                 MkListOne(MkInitDeclarator(CopyDeclarator(declarator), null)));
-
-                              //externalDecl = MkExternalDeclaration(decl);
-
-                              //***** ast->Insert(external.prev, externalDecl);
-                              //ast->Insert(curExternal.prev, externalDecl);
-                              externalDecl.declaration = decl;
-                              if(decl.symbol && !decl.symbol.pointerExternal)
-                                 decl.symbol.pointerExternal = externalDecl;
-
-                              // Trying this out...
-                              declarator.symbol.pointerExternal = externalDecl;
-                           }
-                        }
-                     }
+                     if(createdExternal.function)
+                        ProcessFunction(createdExternal.function);
                   }
                   else if(declarator)
                   {
@@ -2298,36 +2191,42 @@ void ProcessInstantiationType(Instantiation inst)
    }
 }
 
-static void DeclareType(Type type, bool declarePointers, bool declareParams)
+void DeclareType(External neededFor, Type type, bool needDereference, bool forFunctionDef)
+{
+   _DeclareType(neededFor, type, needDereference, forFunctionDef, false);
+}
+
+void DeclareTypeForwardDeclare(External neededFor, Type type, bool needDereference, bool forFunctionDef)
+{
+   _DeclareType(neededFor, type, needDereference, forFunctionDef, true);
+}
+
+static void _DeclareType(External neededFor, Type type, bool needDereference, bool forFunctionDef, bool fwdDecl)
 {
-   // OPTIMIZATIONS: TESTING THIS...
    if(inCompiler)
    {
       if(type.kind == functionType)
       {
          Type param;
-         if(declareParams)
-         {
-            for(param = type.params.first; param; param = param.next)
-               DeclareType(param, declarePointers, true);
-         }
-         DeclareType(type.returnType, declarePointers, true);
+         for(param = type.params.first; param; param = param.next)
+            _DeclareType(neededFor, param, forFunctionDef, false, fwdDecl);
+         _DeclareType(neededFor, type.returnType, forFunctionDef, false, fwdDecl);
       }
-      else if(type.kind == pointerType && declarePointers)
-         DeclareType(type.type, declarePointers, false);
+      else if(type.kind == pointerType)
+         _DeclareType(neededFor, type.type, false, false, fwdDecl);
       else if(type.kind == classType)
       {
-         if(type._class.registered && (type._class.registered.type == structClass || type._class.registered.type == noHeadClass) && !type._class.declaring)
-            DeclareStruct(type._class.registered.fullName, type._class.registered.type == noHeadClass);
+         Class c = type._class.registered;
+         _DeclareStruct(neededFor, c ? c.fullName : "ecere::com::Instance", c ? c.type == noHeadClass : false, needDereference && c && c.type == structClass, fwdDecl);
       }
       else if(type.kind == structType || type.kind == unionType)
       {
          Type member;
          for(member = type.members.first; member; member = member.next)
-            DeclareType(member, false, false);
+            _DeclareType(neededFor, member, needDereference, forFunctionDef, fwdDecl);
       }
       else if(type.kind == arrayType)
-         DeclareType(type.arrayType, declarePointers, false);
+         _DeclareType(neededFor, type.arrayType, true, false, fwdDecl);
    }
 }
 
@@ -2505,18 +2404,17 @@ public void ProcessPropertyType(Property prop)
    }
 }
 
-public void DeclareMethod(Method method, const char * name)
+public void DeclareMethod(External neededFor, Method method, const char * name)
 {
    Symbol symbol = method.symbol;
-   if(!symbol || (!symbol.pointerExternal && method.type == virtualMethod) || symbol.id > (curExternal ? curExternal.symbol.idCode : -1))
+   if(!symbol || (!symbol.pointerExternal && (!symbol.methodCodeExternal || method.type == virtualMethod)))
    {
-      //bool imported = false;
       bool dllImport = false;
 
       if(!method.dataType)
          method.dataType = ProcessTypeString(method.dataTypeString, false);
 
-      if(!symbol || symbol._import || method.type == virtualMethod)
+      //if(!symbol || symbol._import || method.type == virtualMethod)
       {
          if(!symbol || method.type == virtualMethod)
          {
@@ -2554,45 +2452,18 @@ public void DeclareMethod(Method method, const char * name)
             }
             if(!symbol)
             {
-               // Set the symbol type
-               /*
-               if(!type.thisClass)
-               {
-                  type.thisClass = method._class.symbol; // FindClass(method._class.fullName);
-               }
-               else if(type.thisClass == (void *)-1)
-               {
-                  type.thisClass = null;
-               }
-               */
-               // symbol.type = ProcessTypeString(method.dataTypeString, false);
                symbol.type = method.dataType;
                if(symbol.type) symbol.type.refCount++;
             }
-            /*
-            if(!method.thisClass || strcmp(method.thisClass, "void"))
-               symbol.type.params.Insert(null,
-                  MkClassType(method.thisClass ? method.thisClass : method._class.fullName));
-            */
          }
          if(!method.dataType.dllExport)
          {
-            //imported = true;
             if((method._class.module != privateModule || !strcmp(method._class.name, "float") || !strcmp(method._class.name, "double")) && method._class.module.importType != staticImport)
                dllImport = true;
          }
       }
 
-      /* MOVING THIS UP
-      if(!method.dataType)
-         method.dataType = ((Symbol)method.symbol).type;
-         //ProcessMethodType(method);
-      */
-
-      if(method.type != virtualMethod && method.dataType)
-         DeclareType(method.dataType, true, true);
-
-      if(!symbol.pointerExternal || symbol.pointerExternal.type == functionExternal)
+      if(inCompiler)
       {
          // We need a declaration here :)
          Declaration decl;
@@ -2604,7 +2475,6 @@ public void DeclareMethod(Method method, const char * name)
          specifiers = MkList();
          declarators = MkList();
 
-         //if(imported)
          if(dllImport)
             ListAdd(specifiers, MkSpecifier(EXTERN));
          else if(method._class.symbol && ((Symbol)method._class.symbol).isStatic)
@@ -2618,7 +2488,6 @@ public void DeclareMethod(Method method, const char * name)
          else
          {
             d = MkDeclaratorIdentifier(MkIdentifier(name));
-            //if(imported)
             if(dllImport)
                d = MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), d));
             {
@@ -2649,7 +2518,7 @@ public void DeclareMethod(Method method, const char * name)
                {
                   Class _class = method.dataType.thisClass ? method.dataType.thisClass.registered : method._class;
                   TypeName thisParam = MkTypeName(MkListOne(
-                     MkSpecifierName/*MkClassName*/(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)),
+                     MkSpecifierName(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)),
                      (_class && _class.type == systemClass) ? MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("this"))) : MkDeclaratorIdentifier(MkIdentifier("this")));
                   TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
                   Specifier firstSpec = firstParam.qualifiers ? firstParam.qualifiers->first : null;
@@ -2666,17 +2535,8 @@ public void DeclareMethod(Method method, const char * name)
                   funcDecl.function.parameters->Insert(null, thisParam);
                }
             }
-            // Make sure we don't have empty parameter declarations for static methods...
-            /*
-            else if(!funcDecl.function.parameters)
-            {
-               funcDecl.function.parameters = MkList();
-               funcDecl.function.parameters->Insert(null,
-                  MkTypeName(MkListOne(MkSpecifier(VOID)),null));
-            }*/
          }
-         // TESTING THIS:
-         ProcessDeclarator(d);
+         ProcessDeclarator(d, true);
 
          ListAdd(declarators, MkInitDeclarator(d, null));
 
@@ -2684,35 +2544,19 @@ public void DeclareMethod(Method method, const char * name)
 
          ReplaceThisClassSpecifiers(specifiers, method._class);
 
-         // Keep a different symbol for the function definition than the declaration...
-         if(symbol.pointerExternal)
-         {
-            Symbol functionSymbol { };
-
-            // Copy symbol
-            {
-               *functionSymbol = *symbol;
-               functionSymbol.string = CopyString(symbol.string);
-               if(functionSymbol.type)
-                  functionSymbol.type.refCount++;
-            }
-
-            excludedSymbols->Add(functionSymbol);
-            symbol.pointerExternal.symbol = functionSymbol;
-         }
          external = MkExternalDeclaration(decl);
-         if(curExternal)
-            ast->Insert(curExternal ? curExternal.prev : null, external);
          external.symbol = symbol;
          symbol.pointerExternal = external;
+         ast->Add(external);
+         DeclareStruct(external, method._class.fullName, true, true);
+         if(method.dataType)
+            DeclareType(external, method.dataType, true, true);
       }
-      else if(ast)
-      {
-         // Move declaration higher...
-         ast->Move(symbol.pointerExternal, curExternal.prev);
-      }
-
-      symbol.id = curExternal ? curExternal.symbol.idCode : MAXINT;
+   }
+   if(inCompiler && neededFor)
+   {
+      External external = symbol.pointerExternal ? symbol.pointerExternal : symbol.methodCodeExternal;
+      neededFor.CreateUniqueEdge(external, external.type == functionExternal);
    }
 }
 
@@ -2823,10 +2667,11 @@ void ReplaceThisClassSpecifiers(OldList specs, Class _class)
 }
 
 // Returns imported or not
-bool DeclareFunction(GlobalFunction function, char * name)
+bool DeclareFunction(External neededFor, GlobalFunction function, char * name)
 {
    Symbol symbol = function.symbol;
-   if(curExternal && (!symbol || symbol.id > curExternal.symbol.idCode))
+   // TOCHECK: Might get rid of the pointerExternal check in favor of marking the edge as breakable
+   if(!symbol || !symbol.pointerExternal)
    {
       bool imported = false;
       bool dllImport = false;
@@ -2866,11 +2711,10 @@ bool DeclareFunction(GlobalFunction function, char * name)
             dllImport = true;
       }
 
-      DeclareType(function.dataType, true, true);
-
       if(inCompiler)
       {
-         if(!symbol.pointerExternal || symbol.pointerExternal.type == functionExternal)
+         // TOCHECK: What's with the functionExternal check here? Is it Edge breaking / forward declaration?
+         //if(!symbol.pointerExternal || symbol.pointerExternal.type == functionExternal)
          {
             // We need a declaration here :)
             Declaration decl;
@@ -2882,15 +2726,9 @@ bool DeclareFunction(GlobalFunction function, char * name)
             specifiers = MkList();
             declarators = MkList();
 
-            //if(imported)
-               ListAdd(specifiers, MkSpecifier(EXTERN));
-            /*
-            else
-               ListAdd(specifiers, MkSpecifier(STATIC));
-            */
+            ListAdd(specifiers, MkSpecifier(EXTERN));
 
             d = MkDeclaratorIdentifier(MkIdentifier(imported ? name : function.name));
-            //if(imported)
             if(dllImport)
                d = MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), d));
 
@@ -2928,7 +2766,8 @@ bool DeclareFunction(GlobalFunction function, char * name)
             }
 
             // Keep a different symbol for the function definition than the declaration...
-            if(symbol.pointerExternal)
+            /* Note: This should be handled by the edge breaking...
+            if(symbol.pointerExternal && symbol.pointerExternal.type == functionExternal)
             {
                Symbol functionSymbol { };
                // Copy symbol
@@ -2943,29 +2782,26 @@ bool DeclareFunction(GlobalFunction function, char * name)
 
                symbol.pointerExternal.symbol = functionSymbol;
             }
+            */
             external = MkExternalDeclaration(decl);
-            if(curExternal)
-               ast->Insert(curExternal.prev, external);
+            ast->Add(external);
             external.symbol = symbol;
             symbol.pointerExternal = external;
-         }
-         else
-         {
-            // Move declaration higher...
-            ast->Move(symbol.pointerExternal, curExternal.prev);
-         }
 
-         if(curExternal)
-            symbol.id = curExternal.symbol.idCode;
+            DeclareType(external, function.dataType, true, true);
+         }
       }
    }
+   if(inCompiler && neededFor && symbol && symbol.pointerExternal)
+      neededFor.CreateUniqueEdge(symbol.pointerExternal, symbol.pointerExternal.type == functionExternal);
    return (symbol && symbol._import && function.module != privateModule && function.module.importType != staticImport) ? true : false;
 }
 
-void DeclareGlobalData(GlobalData data)
+void DeclareGlobalData(External neededFor, GlobalData data)
 {
    Symbol symbol = data.symbol;
-   if(curExternal && (!symbol || symbol.id > curExternal.symbol.idCode))
+   // TOCHECK: Might get rid of the pointerExternal check in favor of marking the edge as breakable
+   if(!symbol || !symbol.pointerExternal)
    {
       if(inCompiler)
       {
@@ -2974,43 +2810,36 @@ void DeclareGlobalData(GlobalData data)
       }
       if(!data.dataType)
          data.dataType = ProcessTypeString(data.dataTypeString, false);
-      DeclareType(data.dataType, true, true);
+
       if(inCompiler)
       {
-         if(!symbol.pointerExternal)
-         {
-            // We need a declaration here :)
-            Declaration decl;
-            OldList * specifiers, * declarators;
-            Declarator d;
-            External external;
-
-            specifiers = MkList();
-            declarators = MkList();
+         // We need a declaration here :)
+         Declaration decl;
+         OldList * specifiers, * declarators;
+         Declarator d;
+         External external;
 
-            ListAdd(specifiers, MkSpecifier(EXTERN));
-            d = MkDeclaratorIdentifier(MkIdentifier(data.fullName));
-            d = SpecDeclFromString(data.dataTypeString, specifiers, d);
+         specifiers = MkList();
+         declarators = MkList();
 
-            ListAdd(declarators, MkInitDeclarator(d, null));
+         ListAdd(specifiers, MkSpecifier(EXTERN));
+         d = MkDeclaratorIdentifier(MkIdentifier(data.fullName));
+         d = SpecDeclFromString(data.dataTypeString, specifiers, d);
 
-            decl = MkDeclaration(specifiers, declarators);
-            external = MkExternalDeclaration(decl);
-            if(curExternal)
-               ast->Insert(curExternal.prev, external);
-            external.symbol = symbol;
-            symbol.pointerExternal = external;
-         }
-         else
-         {
-            // Move declaration higher...
-            ast->Move(symbol.pointerExternal, curExternal.prev);
-         }
+         ListAdd(declarators, MkInitDeclarator(d, null));
 
+         decl = MkDeclaration(specifiers, declarators);
+         external = MkExternalDeclaration(decl);
          if(curExternal)
-            symbol.id = curExternal.symbol.idCode;
+            ast->Insert(curExternal.prev, external);
+         external.symbol = symbol;
+         symbol.pointerExternal = external;
+
+         DeclareType(external, data.dataType, true, true);
       }
    }
+   if(inCompiler && neededFor && symbol && symbol.pointerExternal)
+      neededFor.CreateUniqueEdge(symbol.pointerExternal, false);
 }
 
 class Conversion : struct
@@ -3143,9 +2972,11 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
          else
          {
             // Added this so that DefinedColor = Color doesn't go through ColorRGB property
-            if(enumBaseType &&
-               dest._class && dest._class.registered && dest._class.registered.type == enumClass &&
-               ((source._class && source._class.registered && source._class.registered.type != enumClass) || source.kind == classType)) // Added this here for a base enum to be acceptable for a derived enum (#139)
+            if(dest._class && dest._class.registered && source._class && source._class.registered &&
+               (dest.casted || (enumBaseType && dest._class.registered.type == enumClass &&
+                  (source.kind == classType ||  // Added this here for a base enum to be acceptable for a derived enum (#139)
+                   source._class.registered.type != enumClass)
+                ) ) )
             {
                if(eClass_IsDerived(dest._class.registered, source._class.registered))
                {
@@ -3692,13 +3523,14 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
    Type source;
    Type realDest = dest;
    Type backupSourceExpType = null;
-   Expression computedExp = sourceExp;
+   Expression nbExp = GetNonBracketsExp(sourceExp);
+   Expression computedExp = nbExp;
    dest.refCount++;
 
    if(sourceExp.isConstant && sourceExp.type != constantExp && sourceExp.type != identifierExp && sourceExp.type != castExp &&
       dest.kind == classType && dest._class && dest._class.registered && dest._class.registered.type == enumClass)
    {
-      computedExp = CopyExpression(sourceExp);        // Keep the original expression, but compute for checking enum ranges
+      computedExp = CopyExpression(nbExp);        // Keep the original expression, but compute for checking enum ranges
       ComputeExpression(computedExp /*sourceExp*/);
    }
 
@@ -3706,10 +3538,10 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
 
    if(dest.kind == pointerType && sourceExp.type == constantExp && !strtoul(sourceExp.constant, null, 0))
    {
-      if(computedExp != sourceExp)
+      if(computedExp != nbExp)
       {
          FreeExpression(computedExp);
-         computedExp = sourceExp;
+         computedExp = nbExp;
       }
       FreeType(dest);
       return true;
@@ -3729,10 +3561,10 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
           //if(source._class.registered == dest._class.registered)
           if(sourceBase == destBase)
           {
-            if(computedExp != sourceExp)
+            if(computedExp != nbExp)
             {
                FreeExpression(computedExp);
-               computedExp = sourceExp;
+               computedExp = nbExp;
             }
             FreeType(dest);
             return true;
@@ -3755,21 +3587,21 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
          else
             value = strtoull(computedExp.constant, null, 0);
       }
-      else if(computedExp.type == opExp && sourceExp.op.op == '-' && !computedExp.op.exp1 && computedExp.op.exp2 && computedExp.op.exp2.type == constantExp)
+      else if(computedExp.type == opExp && computedExp.op.op == '-' && !computedExp.op.exp1 && computedExp.op.exp2 && computedExp.op.exp2.type == constantExp)
       {
          if(source.isSigned)
             value = -strtoll(computedExp.op.exp2.constant, null, 0);
          else
             value = -strtoull(computedExp.op.exp2.constant, null, 0);
       }
-      if(computedExp != sourceExp)
+      if(computedExp != nbExp)
       {
          FreeExpression(computedExp);
-         computedExp = sourceExp;
+         computedExp = nbExp;
       }
 
       if(dest.kind != classType && source.kind == classType && source._class && source._class.registered &&
-         !strcmp(source._class.registered.fullName, "ecere::com::unichar"))
+         !strcmp(source._class.registered.fullName, "unichar" /*"ecere::com::unichar"*/))
       {
          FreeType(source);
          source = Type { kind = intType, isSigned = false, refCount = 1 };
@@ -3886,7 +3718,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
       {
          Class _class = source._class ? source._class.registered : null;
 
-         if(_class && (_class.type == unitClass || /*!strcmp(_class.fullName, "bool") || /*_class.type == enumClass || */_class.type == bitClass ))  // TOCHECK: enumClass, bitClass is new here...
+         if(_class && (_class.type == unitClass || /*!strcmp(_class.fullName, "bool") || _class.type == enumClass || */_class.type == bitClass ))  // TOCHECK: enumClass, bitClass is new here...
          {
             /*
             if(dest.kind != classType)
@@ -4109,16 +3941,36 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
       else if(dest.kind == charType && (source.kind == _BoolType || source.kind == charType || source.kind == enumType || source.kind == shortType || source.kind == intType) &&
          (dest.isSigned ? (value >= -128 && value <= 127) : (value >= 0 && value <= 255)))
       {
-         specs = MkList();
-         if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
-         ListAdd(specs, MkSpecifier(CHAR));
+         if(source.kind == intType)
+         {
+            FreeType(dest);
+            FreeType(source);
+            if(backupSourceExpType) FreeType(backupSourceExpType);
+            return true;
+         }
+         else
+         {
+            specs = MkList();
+            if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
+            ListAdd(specs, MkSpecifier(CHAR));
+         }
       }
       else if(dest.kind == shortType && (source.kind == enumType || source.kind == _BoolType || source.kind == charType || source.kind == shortType ||
          (source.kind == intType && (dest.isSigned ? (value >= -32768 && value <= 32767) : (value >= 0 && value <= 65535)))))
       {
-         specs = MkList();
-         if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
-         ListAdd(specs, MkSpecifier(SHORT));
+         if(source.kind == intType)
+         {
+            FreeType(dest);
+            FreeType(source);
+            if(backupSourceExpType) FreeType(backupSourceExpType);
+            return true;
+         }
+         else
+         {
+            specs = MkList();
+            if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
+            ListAdd(specs, MkSpecifier(SHORT));
+         }
       }
       else if(dest.kind == intType && (source.kind == enumType || source.kind == shortType || source.kind == _BoolType || source.kind == charType || source.kind == intType))
       {
@@ -4189,10 +4041,10 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
    }
    else
    {
-      if(computedExp != sourceExp)
+      if(computedExp != nbExp)
       {
          FreeExpression(computedExp);
-         computedExp = sourceExp;
+         computedExp = nbExp;
       }
 
       while((sourceExp.type == bracketsExp || sourceExp.type == extensionExpressionExp) && sourceExp.list) sourceExp = sourceExp.list->last;
@@ -4279,7 +4131,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
    {                                                              \
       t value2 = op2.m;                                           \
       exp.type = constantExp;                                    \
-      exp.string = p(value2 ? (op1.m o value2) : 0);             \
+      exp.string = p(value2 ? ((t)(op1.m o value2)) : 0);             \
       if(!exp.expType) \
          { exp.expType = op1.type; if(op1.type) op1.type.refCount++; } \
       return true;                                                \
@@ -4290,7 +4142,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
    {                                                              \
       t value2 = op2.m;                                           \
       exp.type = constantExp;                                    \
-      exp.string = p(op1.m o value2);             \
+      exp.string = p((t)(op1.m o value2));             \
       if(!exp.expType) \
          { exp.expType = op1.type; if(op1.type) op1.type.refCount++; } \
       return true;                                                \
@@ -4540,7 +4392,7 @@ public Operand GetOperand(Expression exp)
    Type type = exp.expType;
    if(type)
    {
-      while(type.kind == classType &&
+      while(type.kind == classType && type._class &&
          type._class.registered && (type._class.registered.type == bitClass || type._class.registered.type == unitClass || type._class.registered.type == enumClass))
       {
          if(!type._class.registered.dataType)
@@ -4582,7 +4434,12 @@ public Operand GetOperand(Expression exp)
                break;
             }
             case shortType:
-               if(type.isSigned)
+               if(exp.constant[0] == '\'')
+               {
+                  op.s = exp.constant[1];
+                  op.ops = shortOps;
+               }
+               else if(type.isSigned)
                {
                   op.s = (short)strtol(exp.constant, null, 0);
                   op.ops = shortOps;
@@ -4595,7 +4452,12 @@ public Operand GetOperand(Expression exp)
                break;
             case intType:
             case longType:
-               if(type.isSigned)
+               if(exp.constant[0] == '\'')
+               {
+                  op.i = exp.constant[1];
+                  op.ops = intOps;
+               }
+               else if(type.isSigned)
                {
                   op.i = (int)strtol(exp.constant, null, 0);
                   op.ops = intOps;
@@ -4825,7 +4687,7 @@ static void PopulateInstanceProcessMember(Instantiation inst, OldList * memberLi
                {
                   FreeExpContents(exp);
                   // TODO: This should probably use proper type
-                  exp.constant = PrintInt64((int64)*(intptr*)ptr);
+                  exp.constant = PrintInt64((int64)*(intsize*)ptr);
                   exp.type = constantExp;
                   break;
                }
@@ -5863,6 +5725,14 @@ void ComputeExpression(Expression exp)
                OldList * list = exp.list;
                Expression prev = exp.prev;
                Expression next = exp.next;
+
+               // For operations which set the exp type on brackets exp after the inner exp was processed...
+               if(exp.expType && exp.expType.kind == classType && (!e.expType || e.expType.kind != classType))
+               {
+                  FreeType(e.expType);
+                  e.expType = exp.expType;
+                  e.expType.refCount++;
+               }
                ComputeExpression(e);
                //FreeExpContents(exp);
                FreeType(exp.expType);
@@ -6289,9 +6159,8 @@ void ComputeExpression(Expression exp)
                char className[1024];
                strcpy(className, "__ecereClass_");
                FullClassNameCat(className, classSym.string, true);
-               //MangleClassName(className);
 
-               DeclareClass(classSym, className);
+               DeclareClass(curExternal, classSym, className);
 
                FreeExpContents(exp);
                exp.type = pointerExp;
@@ -6824,15 +6693,16 @@ void CheckTemplateTypes(Expression exp)
                   break;
                }
             }
-            if(newExp.type == memberExp && newExp.member.memberType == dataMember)
+            /*if(newExp.type == memberExp && newExp.member.memberType == dataMember)
             {
+               // When was this required?    Removed to address using templated values to pass to printf()
                exp.type = opExp;
                exp.op.op = '*';
                exp.op.exp1 = null;
                exp.op.exp2 = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
                   MkExpBrackets(MkListOne(MkExpOp(null, '&', newExp))));
             }
-            else
+            else*/
             {
                char typeString[1024];
                Declarator decl;
@@ -6846,6 +6716,8 @@ void CheckTemplateTypes(Expression exp)
                exp.cast.typeName = MkTypeName(specs, decl);
                exp.cast.exp = MkExpBrackets(MkListOne(newExp));
                exp.cast.exp.needCast = true;
+               exp.needTemplateCast = 2;
+               newExp.needTemplateCast = 2;
             }
             break;
          }
@@ -6934,8 +6806,6 @@ static Symbol FindWithNameSpace(BinaryTree tree, const char * name)
    return null;
 }
 
-static void ProcessDeclaration(Declaration decl);
-
 /*static */Symbol FindSymbol(const char * name, Context startContext, Context endContext, bool isStruct, bool globalNameSpace)
 {
 #ifdef _DEBUG
@@ -6944,6 +6814,7 @@ static void ProcessDeclaration(Declaration decl);
    // Optimize this later? Do this before/less?
    Context ctx;
    Symbol symbol = null;
+
    // First, check if the identifier is declared inside the function
    //for(ctx = curContext; ctx /*!= topContext.parent */&& !symbol; ctx = ctx.parent)
 
@@ -6969,34 +6840,8 @@ static void ProcessDeclaration(Declaration decl);
 
       if(symbol || ctx == endContext) break;
    }
-   if(inCompiler && curExternal && symbol && ctx == globalContext && curExternal.symbol && symbol.id > curExternal.symbol.idCode && symbol.pointerExternal)
-   {
-      if(symbol.pointerExternal.type == functionExternal)
-      {
-         FunctionDefinition function = symbol.pointerExternal.function;
-
-         // Modified this recently...
-         Context tmpContext = curContext;
-         curContext = null;
-         symbol.pointerExternal = MkExternalDeclaration(MkDeclaration(CopyList(function.specifiers, CopySpecifier), MkListOne(MkInitDeclarator(CopyDeclarator(function.declarator), null))));
-         curContext = tmpContext;
-
-         symbol.pointerExternal.symbol = symbol;
-
-         // TESTING THIS:
-         DeclareType(symbol.type, true, true);
-
-         ast->Insert(curExternal.prev, symbol.pointerExternal);
-
-         symbol.id = curExternal.symbol.idCode;
-
-      }
-      else if(symbol.pointerExternal.type == declarationExternal && curExternal.symbol.idCode < symbol.pointerExternal.symbol.id) // Added id comparison because Global Function prototypes were broken
-      {
-         ast->Move(symbol.pointerExternal, curExternal.prev);
-         symbol.id = curExternal.symbol.idCode;
-      }
-   }
+   if(inCompiler && symbol && ctx == globalContext && symbol.pointerExternal && curExternal && symbol.pointerExternal != curExternal)
+      curExternal.CreateUniqueEdge(symbol.pointerExternal, symbol.pointerExternal.type == functionExternal);
 #ifdef _DEBUG
    //findSymbolTotalTime += GetTime() - startTime;
 #endif
@@ -7589,7 +7434,7 @@ void ApplyAnyObjectLogic(Expression e)
                   {
                      char size[100];
                      ComputeTypeSize(e.expType);
-                     sprintf(size, "%d", e.expType.size);
+                     sprintf(size, "%d", e.expType.size);   // Potential 32/64 Bootstrap issue
                      newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
                         MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
                            MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
@@ -7931,6 +7776,13 @@ void ApplyLocation(Expression exp, Location loc)
    }
 }
 
+bool RelatedUnits(Class c1, Class c2)
+{
+   if(c1.base.type == unitClass) c1 = c1.base;
+   if(c2.base.type == unitClass) c2 = c2.base;
+   return c1 == c2;
+}
+
 void ProcessExpressionType(Expression exp)
 {
    bool unresolved = false;
@@ -7996,7 +7848,13 @@ void ProcessExpressionType(Expression exp)
          }
          else
          {
-            Symbol symbol = FindSymbol(id.string, curContext, topContext /*exp.destType ? topContext : globalContext*/, false, id._class && id._class.name == null);
+            Symbol symbol = null;
+            bool findInGlobal = false;
+            if(!topContext.parent && exp.destType && exp.destType.kind == classType && exp.destType._class && exp.destType._class.registered && exp.destType._class.registered.type == enumClass)
+               findInGlobal = true;  // In global context, look at enum values first
+            else
+               symbol = FindSymbol(id.string, curContext, topContext /*exp.destType ? topContext : globalContext*/, false, id._class && id._class.name == null);
+
             // Enums should be resolved here (Special pass in opExp to fix identifiers not seen as enum on the first pass)
             if(!symbol/* && exp.destType*/)
             {
@@ -8022,6 +7880,8 @@ void ProcessExpressionType(Expression exp)
                   symbol = FindSymbol(id.string, topContext.parent, globalContext, false, id._class && id._class.name == null);
                }
             }
+            if(findInGlobal)
+               symbol = FindSymbol(id.string, curContext, topContext, false, id._class && id._class.name == null);
 
             // If we manage to resolve this symbol
             if(symbol)
@@ -8169,7 +8029,7 @@ void ProcessExpressionType(Expression exp)
                      data = FindGlobalData(id.string);
                   if(data)
                   {
-                     DeclareGlobalData(data);
+                     DeclareGlobalData(curExternal, data);
                      exp.expType = data.dataType;
                      if(data.dataType) data.dataType.refCount++;
 
@@ -8203,7 +8063,7 @@ void ProcessExpressionType(Expression exp)
                         if(function.module.importType != staticImport && (!function.dataType || !function.dataType.dllExport))
                            strcpy(name, "__ecereFunction_");
                         FullClassNameCat(name, id.string, false); // Why is this using FullClassNameCat ?
-                        if(DeclareFunction(function, name))
+                        if(DeclareFunction(curExternal, function, name))
                         {
                            delete id.string;
                            id.string = CopyString(name);
@@ -8330,7 +8190,8 @@ void ProcessExpressionType(Expression exp)
                   char * endP = null;
                   int64 i64 = strtoll(constant, &endP, 0);
                   uint64 ui64 = strtoull(constant, &endP, 0);
-                  bool is64Bit = endP && (!strcmp(endP, "LL") || !strcmp(endP, "ll"));
+                  bool is64Bit = endP && (!strcmp(endP, "LL") || !strcmp(endP, "ll") || !strcmp(endP, "LLU") || !strcmp(endP, "llu") || !strcmp(endP, "ull") || !strcmp(endP, "ULL"));
+                  bool forceUnsigned = endP && (!strcmp(endP, "U") || !strcmp(endP, "u") || !strcmp(endP, "LLU") || !strcmp(endP, "llu") || !strcmp(endP, "ull") || !strcmp(endP, "ULL"));
                   if(isSigned)
                   {
                      if(i64 < MININT)
@@ -8350,6 +8211,8 @@ void ProcessExpressionType(Expression exp)
                      else if(constant[0] != '0' || !constant[1])
                         isSigned = true;
                   }
+                  if(forceUnsigned)
+                     isSigned = false;
                   type.kind = is64Bit ? int64Type : intType;
                   type.isSigned = isSigned;
                }
@@ -8390,7 +8253,7 @@ void ProcessExpressionType(Expression exp)
             kind = pointerType;
             type = ProcessType(exp._new.typeName.qualifiers, exp._new.typeName.declarator);
          };
-         DeclareType(exp.expType.type, false, false);
+         DeclareType(curExternal, exp.expType.type, true, false);
          break;
       case renewExp:
       case renew0Exp:
@@ -8402,7 +8265,7 @@ void ProcessExpressionType(Expression exp)
             kind = pointerType;
             type = ProcessType(exp._renew.typeName.qualifiers, exp._renew.typeName.declarator);
          };
-         DeclareType(exp.expType.type, false, false);
+         DeclareType(curExternal, exp.expType.type, true, false);
          break;
       case opExp:
       {
@@ -8412,6 +8275,8 @@ void ProcessExpressionType(Expression exp)
          Location oldyylloc = yylloc;
          bool useSideUnit = false;
          Class destClass = (exp.destType && exp.destType.kind == classType && exp.destType._class) ? exp.destType._class.registered : null;
+         bool powerOp = false, relationOp = false;
+         Class c1 = null, c2 = null;
 
          // Dummy type to prevent ProcessExpression of operands to say unresolved identifiers yet
          Type dummy
@@ -8458,6 +8323,7 @@ void ProcessExpressionType(Expression exp)
                // Gives boolean result
                boolResult = true;
                useSideType = true;
+               relationOp = true;
                break;
             case '+':
             case '-':
@@ -8468,8 +8334,8 @@ void ProcessExpressionType(Expression exp)
 
             case LEFT_OP:
             case RIGHT_OP:
-               useSideType = true;
-               useDestType = true;
+               // useSideType = true;
+               // useDestType = true;
                break;
 
             case '|':
@@ -8482,6 +8348,7 @@ void ProcessExpressionType(Expression exp)
             case '%':
                useSideType = true;
                useDestType = true;
+               if(exp.op.op == '/') powerOp = true;
                break;
             case '&':
             case '*':
@@ -8490,6 +8357,7 @@ void ProcessExpressionType(Expression exp)
                   // For & operator, useDestType nicely ensures the result will fit in a bool (TODO: Fix for generic enum)
                   useSideType = true;
                   useDestType = true;
+                  if(exp.op.op == '*') powerOp = true;
                }
                break;
 
@@ -8547,6 +8415,17 @@ void ProcessExpressionType(Expression exp)
                if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
                exp.op.exp1.destType = dummy;
                dummy.refCount++;
+               if(powerOp)
+                  exp.op.exp1.opDestType = true;
+               if(relationOp)
+                  exp.op.exp1.usedInComparison = true;
+            }
+            if(exp.op.op == '+' || exp.op.op == '-')
+            {
+               if(exp.opDestType)
+                  exp.op.exp1.parentOpDestType = true;
+               if(exp.usedInComparison)
+                  exp.op.exp1.usedInComparison = true;
             }
 
             // TESTING THIS HERE...
@@ -8555,6 +8434,7 @@ void ProcessExpressionType(Expression exp)
             if(exp.op.exp1.destType && exp.op.op != '=') exp.op.exp1.destType.count--;
 
             exp.op.exp1.opDestType = false;
+            exp.op.exp1.usedInComparison = false;
 
             // Fix for unit and ++ / --
             if(!exp.op.exp2 && (exp.op.op == INC_OP || exp.op.op == DEC_OP) && exp.op.exp1.expType && exp.op.exp1.expType.kind == classType &&
@@ -8570,6 +8450,17 @@ void ProcessExpressionType(Expression exp)
                FreeType(dummy);
                exp.op.exp1.destType = null;
             }
+
+            if(exp.op.exp2)
+            {
+               if(!assign && exp.op.exp1.expType && (exp.op.exp1.expType.kind == charType || exp.op.exp1.expType.kind == shortType))
+               {
+                  Type type { kind = intType, isSigned = true, refCount = 1, signedBeforePromotion = exp.op.exp1.expType.isSigned, bitMemberSize = exp.op.exp1.expType.bitMemberSize, promotedFrom = exp.op.exp1.expType.kind };
+                  FreeType(exp.op.exp1.expType);
+                  exp.op.exp1.expType = type;
+               }
+            }
+
             type1 = exp.op.exp1.expType;
          }
 
@@ -8588,7 +8479,7 @@ void ProcessExpressionType(Expression exp)
                else
                {
                   exp.op.exp2.destType = exp.destType;
-                  if(!exp.op.exp1 || exp.op.op != '&')
+                  if(!exp.op.exp1 || (exp.op.op != '&' && exp.op.op != '^'))
                      exp.op.exp2.opDestType = true;
                   if(exp.destType)
                      exp.destType.refCount++;
@@ -8637,7 +8528,7 @@ void ProcessExpressionType(Expression exp)
             {
                if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
                exp.op.exp2.destType = exp.destType;
-               if(exp.op.op != '&')
+               if(exp.op.op != '&' && exp.op.op != '^')
                   exp.op.exp2.opDestType = true;
                if(exp.destType)
                   exp.destType.refCount++;
@@ -8647,6 +8538,10 @@ void ProcessExpressionType(Expression exp)
                if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
                exp.op.exp2.destType = dummy;
                dummy.refCount++;
+               if(powerOp)
+                  exp.op.exp2.opDestType = true;
+               if(relationOp)
+                  exp.op.exp2.usedInComparison = true;
             }
 
             // TESTING THIS HERE... (DANGEROUS)
@@ -8675,10 +8570,28 @@ void ProcessExpressionType(Expression exp)
                if(e.type == castExp && e.cast.exp)
                   e.cast.exp.needCast = true;
             }
+            if(exp.op.op == '+' || exp.op.op == '-')
+            {
+               if(exp.opDestType)
+                  exp.op.exp2.parentOpDestType = true;
+               if(exp.usedInComparison)
+                  exp.op.exp2.usedInComparison = true;
+            }
             ProcessExpressionType(exp.op.exp2);
             exp.op.exp2.opDestType = false;
+            exp.op.exp2.usedInComparison = false;
             if(exp.op.exp2.destType && exp.op.op != '=') exp.op.exp2.destType.count--;
 
+            if(!assign && (exp.op.exp1 || exp.op.op == '~'))
+            {
+               if(exp.op.exp2.expType && (exp.op.exp2.expType.kind == charType || exp.op.exp2.expType.kind == shortType))
+               {
+                  Type type { kind = intType, isSigned = true, refCount = 1, signedBeforePromotion = exp.op.exp2.expType.isSigned, bitMemberSize = exp.op.exp2.expType.bitMemberSize, promotedFrom = exp.op.exp2.expType.kind };
+                  FreeType(exp.op.exp2.expType);
+                  exp.op.exp2.expType = type;
+               }
+            }
+
             if(assign && type1 && type1.kind == pointerType && exp.op.exp2.expType)
             {
                if(exp.op.exp2.expType.kind == intSizeType || exp.op.exp2.expType.kind == intPtrType || exp.op.exp2.expType.kind == int64Type || exp.op.exp2.expType.kind == intType || exp.op.exp2.expType.kind == shortType || exp.op.exp2.expType.kind == charType)
@@ -8740,6 +8653,24 @@ void ProcessExpressionType(Expression exp)
                if(type2) type2.refCount++;
             }
          }
+         c1 = type1 && type1.kind == classType && type1._class ? type1._class.registered : null;
+         c2 = type2 && type2.kind == classType && type2._class ? type2._class.registered : null;
+
+         if(relationOp &&
+            ( (exp.op.exp1 && exp.op.exp1.ambiguousUnits && (!c2 || c2.type != unitClass)) ||
+               (exp.op.exp2 && exp.op.exp2.ambiguousUnits && (!c1 || c1.type != unitClass))) )
+            Compiler_Warning($"ambiguous units in relational operation\n");
+
+         if(!relationOp &&
+            ((exp.op.exp1 && exp.op.exp1.ambiguousUnits) ||
+             (exp.op.exp2 && exp.op.exp2.ambiguousUnits)) &&
+             (!powerOp || !c1 || c1.type != unitClass || !c2 || c2.type != unitClass || !RelatedUnits(c1, c2)))
+         {
+            if(exp.opDestType || exp.usedInComparison)
+               exp.ambiguousUnits = true;
+            else
+               Compiler_Warning($"ambiguous units\n");
+         }
 
          dummy.kind = voidType;
 
@@ -8761,8 +8692,21 @@ void ProcessExpressionType(Expression exp)
          }
          else if(exp.op.op == '&' && !exp.op.exp1)
             exp.expType = Reference(type2);
+         else if(exp.op.op == LEFT_OP || exp.op.op == RIGHT_OP)
+         {
+            if(exp.op.exp1.expType)
+            {
+               exp.expType = exp.op.exp1.expType;
+               exp.expType.refCount++;
+            }
+         }
          else if(!assign)
          {
+            if(c1 && !c1.dataType)
+               c1.dataType = ProcessTypeString(c1.dataTypeString, false);
+            if(c2 && !c2.dataType)
+               c2.dataType = ProcessTypeString(c2.dataTypeString, false);
+
             if(boolOps)
             {
                if(exp.op.exp1)
@@ -8792,11 +8736,33 @@ void ProcessExpressionType(Expression exp)
                   exp.op.exp2.expType.truth = true;
                }
             }
+            else if(powerOp && exp.op.exp1 && exp.op.exp2 && ((c1 && c1.type == unitClass) || (c2 && c2.type == unitClass)))
+            {
+               // * or / with at least one unit operand
+               if(c1 && c1.type == unitClass && c2 && c2.type == unitClass)
+               {
+                  // This is where we'd handle unit powers e.g. square meters or meters/seconds
+                  // For now using base types
+                  if(c1.dataType.kind == doubleType)        exp.expType = c1.dataType;
+                  else if(c2.dataType.kind == doubleType)   exp.expType = c2.dataType;
+                  else if(c1.dataType.kind == floatType)    exp.expType = c1.dataType;
+                  else if(c2.dataType.kind == floatType)    exp.expType = c2.dataType;
+                  else
+                     exp.expType = c1.dataType;
+               }
+               else if((c1 && c1.type == unitClass) || exp.op.op == '/')   // 1/units should not be typed with unit
+                  exp.expType = type1;
+               else
+                  exp.expType = type2;
+
+               if(exp.expType)
+                  exp.expType.refCount++;
+            }
             else if(exp.op.exp1 && exp.op.exp2 &&
                ((useSideType /*&&
                      (useSideUnit ||
-                        ((!type1 || type1.kind != classType || type1._class.registered.type != unitClass) &&
-                         (!type2 || type2.kind != classType || type2._class.registered.type != unitClass)))*/) ||
+                        ((!c1 || c1.type != unitClass) &&
+                         (!c2 || c2.type != unitClass)))*/) ||
                   ((!type1 || type1.kind != classType || !strcmp(type1._class.string, "String")) &&
                   (!type2 || type2.kind != classType || !strcmp(type2._class.string, "String")))))
             {
@@ -8805,18 +8771,9 @@ void ProcessExpressionType(Expression exp)
                   ((type1.kind == classType && type1._class && strcmp(type1._class.string, "String")) == (type2.kind == classType && type2._class && strcmp(type2._class.string, "String"))))
                {
                   // Added this check for enum subtraction to result in an int type:
-                  if(exp.op.op == '-' &&
-                     ((type1.kind == classType && type1._class.registered && type1._class.registered.type == enumClass) ||
-                      (type2.kind == classType && type2._class.registered && type2._class.registered.type == enumClass)) )
+                  if(exp.op.op == '-' && ((c1 && c1.type == enumClass) || (c2 && c2.type == enumClass)) )
                   {
-                     Type intType;
-                     if(!type1._class.registered.dataType)
-                        type1._class.registered.dataType = ProcessTypeString(type1._class.registered.dataTypeString, false);
-                     if(!type2._class.registered.dataType)
-                        type2._class.registered.dataType = ProcessTypeString(type2._class.registered.dataTypeString, false);
-
-                     intType = ProcessTypeString(
-                        (type1._class.registered.dataType.kind == int64Type || type2._class.registered.dataType.kind == int64Type) ? "int64" : "int", false);
+                     Type intType = ProcessTypeString((c1 && c1.dataType.kind == int64Type) || (c2 && c2.dataType.kind == int64Type) ? "int64" : "int", false);
 
                      if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
                      if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
@@ -8835,12 +8792,17 @@ void ProcessExpressionType(Expression exp)
                   }
 
                   // Warning here for adding Radians + Degrees with no destination type
-                  if(!boolResult && type1.kind == classType && (!exp.destType || exp.destType.kind != classType) &&
-                     type1._class.registered && type1._class.registered.type == unitClass &&
-                     type2._class.registered && type2._class.registered.type == unitClass &&
-                     type1._class.registered != type2._class.registered)
-                     Compiler_Warning($"operating on %s and %s with an untyped result, assuming %s\n",
-                        type1._class.string, type2._class.string, type1._class.string);
+                  if(!boolResult && !exp.opDestType && (!exp.destType || exp.destType.kind != classType) &&
+                     c1 && c1.type == unitClass &&
+                     c2 && c2.type == unitClass &&
+                     c1 != c2)
+                  {
+                     if(exp.usedInComparison || exp.parentOpDestType)
+                        exp.ambiguousUnits = true;
+                     else
+                        Compiler_Warning($"operating on %s and %s with an untyped result, assuming %s\n",
+                           type1._class.string, type2._class.string, type1._class.string);
+                  }
 
                   if(type1.kind == pointerType && type1.type.kind == templateType && type2.kind != pointerType)
                   {
@@ -8865,7 +8827,7 @@ void ProcessExpressionType(Expression exp)
                            {
                               if(type2)
                                  FreeType(type2);
-                              type2 = exp.op.exp2.expType = ProcessTypeString("int", false);
+                              type2 = exp.op.exp2.expType = ProcessTypeString("int", false); c2 = null;
                               type2.refCount++;
                            }
 
@@ -8998,7 +8960,7 @@ void ProcessExpressionType(Expression exp)
                   }
                }
                // ADDED THESE TWO FROM OUTSIDE useSideType CHECK
-               else if(!boolResult && (!useSideUnit /*|| exp.destType*/) && type2 && type1 && type2.kind == classType && type1.kind != classType && type2._class && type2._class.registered && type2._class.registered.type == unitClass)
+               else if(!boolResult && !useSideUnit && c2 && c2.type == unitClass && type1 && type1.kind != classType)
                {
                   if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
                   // Convert e.g. / 4 into / 4.0
@@ -9009,7 +8971,7 @@ void ProcessExpressionType(Expression exp)
                   exp.expType = type2;
                   if(type2) type2.refCount++;
                }
-               else if(!boolResult && (!useSideUnit /*|| exp.destType*/) && type1 && type2 && type1.kind == classType && type2.kind != classType && type1._class && type1._class.registered && type1._class.registered.type == unitClass)
+               else if(!boolResult && !useSideUnit && c1 && c1.type == unitClass && type2 && type2.kind != classType)
                {
                   if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
                   // Convert e.g. / 4 into / 4.0
@@ -9024,36 +8986,34 @@ void ProcessExpressionType(Expression exp)
                {
                   bool valid = false;
 
-                  if(!boolResult && useSideUnit && type1 && type1.kind == classType && type1._class.registered && type1._class.registered.type == unitClass && type2 && type2.kind != classType)
+                  if(!boolResult && useSideUnit && c1 && c1.type == unitClass && type2 && type2.kind != classType)
                   {
                      if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
 
-                     if(!type1._class.registered.dataType)
-                        type1._class.registered.dataType = ProcessTypeString(type1._class.registered.dataTypeString, false);
-                     exp.op.exp2.destType = type1._class.registered.dataType;
+                     exp.op.exp2.destType = c1.dataType;
                      exp.op.exp2.destType.refCount++;
 
                      CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false);
                      if(type2)
                         FreeType(type2);
                      type2 = exp.op.exp2.destType;
+                     c2 = type2 && type2.kind == classType && type2._class ? type2._class.registered : null;
                      if(type2) type2.refCount++;
 
                      exp.expType = type2;
                      type2.refCount++;
                   }
 
-                  if(!boolResult && useSideUnit && type2 && type2.kind == classType && type2._class.registered && type2._class.registered.type == unitClass && type1 && type1.kind != classType)
+                  if(!boolResult && useSideUnit && c2 && c2.type == unitClass && type1 && type1.kind != classType)
                   {
                      if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
 
-                     if(!type2._class.registered.dataType)
-                        type2._class.registered.dataType = ProcessTypeString(type2._class.registered.dataTypeString, false);
-                     exp.op.exp1.destType = type2._class.registered.dataType;
+                     exp.op.exp1.destType = c2.dataType;
                      exp.op.exp1.destType.refCount++;
 
                      CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false);
                      type1 = exp.op.exp1.destType;
+                     c1 = type1 && type1.kind == classType && type1._class ? type1._class.registered : null;
                      exp.expType = type1;
                      type1.refCount++;
                   }
@@ -9061,8 +9021,8 @@ void ProcessExpressionType(Expression exp)
                   // TESTING THIS NEW CODE
                   if(!boolResult || exp.op.op == '>' || exp.op.op == '<' || exp.op.op == GE_OP || exp.op.op == LE_OP)
                   {
-                     bool op1IsEnum = type1 && type1.kind == classType && type1._class && type1._class.registered && type1._class.registered.type == enumClass;
-                     bool op2IsEnum = type2 && type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass;
+                     bool op1IsEnum = c1 && c1.type == enumClass;
+                     bool op2IsEnum = c2 && c2.type == enumClass;
                      if(exp.op.op == '*' || exp.op.op == '/' || exp.op.op == '-' || exp.op.op == '|' || exp.op.op == '^')
                      {
                         // Convert the enum to an int instead for these operators
@@ -9115,8 +9075,7 @@ void ProcessExpressionType(Expression exp)
                   if(!valid)
                   {
                      // Added this first part of the if here to handle  5 + Degrees { 5 } with either a base unit dest or not a unit dest type
-                     if(type2 && type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == unitClass &&
-                        (type1.kind != classType || !type1._class || !type1._class.registered || type1._class.registered.type != unitClass))
+                     if(c2 && c2.type == unitClass && (!c1 || c1.type != unitClass))
                      {
                         if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
                         exp.op.exp1.destType = type2;
@@ -9203,12 +9162,12 @@ void ProcessExpressionType(Expression exp)
 
                            Compiler_Warning($"incompatible expressions %s (%s) and %s (%s)\n", expString1, type1String, expString2, type2String);
 
-                           if(type1.kind == classType && type1._class && type1._class.registered && type1._class.registered.type == enumClass)
+                           if(c1 && c1.type == enumClass)
                            {
                               exp.expType = exp.op.exp1.expType;
                               if(exp.op.exp1.expType) exp.op.exp1.expType.refCount++;
                            }
-                           else if(type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass)
+                           else if(c2 && c2.type == enumClass)
                            {
                               exp.expType = exp.op.exp2.expType;
                               if(exp.op.exp2.expType) exp.op.exp2.expType.refCount++;
@@ -9220,7 +9179,7 @@ void ProcessExpressionType(Expression exp)
                else if(type2)
                {
                   // Maybe this was meant to be an enum...
-                  if(type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass)
+                  if(c2 && c2.type == enumClass)
                   {
                      Type oldType = exp.op.exp1.expType;
                      exp.op.exp1.expType = null;
@@ -9263,7 +9222,7 @@ void ProcessExpressionType(Expression exp)
             }
             else if(type2 && (!type1 || (type2.kind == classType && type1.kind != classType)))
             {
-               if(type1 && type2._class && type2._class.registered && type2._class.registered.type == unitClass)
+               if(type1 && c2 && c2.type == unitClass)
                {
                   if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
                   // Convert e.g. / 4 into / 4.0
@@ -9285,7 +9244,7 @@ void ProcessExpressionType(Expression exp)
             }
             else if(type1 && (!type2 || (type1.kind == classType && type2.kind != classType)))
             {
-               if(type2 && type1._class && type1._class.registered && type1._class.registered.type == unitClass)
+               if(c2 && c2.type == unitClass)
                {
                   if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
                   // Convert e.g. / 4 into / 4.0
@@ -9338,7 +9297,7 @@ void ProcessExpressionType(Expression exp)
 
          if(exp.op.op == SIZEOF && exp.op.exp2.expType)
          {
-            DeclareType(exp.op.exp2.expType, false, false);
+            DeclareType(curExternal, exp.op.exp2.expType, true, false);
          }
 
          if(exp.op.op == DELETE && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.specConst)
@@ -9363,16 +9322,21 @@ void ProcessExpressionType(Expression exp)
             {
                FreeType(e.destType);
                e.opDestType = exp.opDestType;
+               e.usedInComparison = exp.usedInComparison;
+               e.parentOpDestType = exp.parentOpDestType;
                e.destType = exp.destType;
                if(e.destType) { exp.destType.refCount++; /*e.destType.count++; inced = true;*/ }
             }
             ProcessExpressionType(e);
+            if(e.ambiguousUnits)
+               exp.ambiguousUnits = true;
             /*if(inced)
                exp.destType.count--;*/
             if(!exp.expType && !e.next)
             {
                exp.expType = e.expType;
                if(e.expType) e.expType.refCount++;
+               exp.needCast = e.needCast;
             }
             if(!e.isConstant)
                exp.isConstant = false;
@@ -9458,7 +9422,7 @@ void ProcessExpressionType(Expression exp)
          if(!exp.expType)
             exp.expType = Dereference(exp.index.exp.expType);
          if(exp.expType)
-            DeclareType(exp.expType, false, false);
+            DeclareType(curExternal, exp.expType, true, false);
          break;
       }
       case callExp:
@@ -9676,7 +9640,7 @@ void ProcessExpressionType(Expression exp)
                      {
                         Class backupThisClass = thisClass;
                         thisClass = exp.call.exp.expType.usedClass;
-                        ProcessDeclarator(decl);
+                        ProcessDeclarator(decl, true);
                         thisClass = backupThisClass;
                      }
 
@@ -9687,11 +9651,20 @@ void ProcessExpressionType(Expression exp)
                      FinishTemplatesContext(context);
 
                      // Mark parameters that were 'thisclass'
-                     /*{
+                     {
                         Type p, op;
                         for(p = functionType.params.first, op = methodType.method.dataType.params.first; p && op; p = p.next, op = op.next)
-                           p.wasThisClass = op.kind == thisClassType;
-                     }*/
+                        {
+                           //p.wasThisClass = op.kind == thisClassType;
+                           if(op.kind == thisClassType)
+                              p.thisClassFrom = methodType.method._class;
+                        }
+                     }
+                     if(methodType.method.dataType.returnType.kind == thisClassType)
+                     {
+                        // functionType.returnType.wasThisClass = true;
+                        functionType.returnType.thisClassFrom = methodType.method._class;
+                     }
                   }
 
                   FreeList(specs, FreeSpecifier);
@@ -10387,6 +10360,7 @@ void ProcessExpressionType(Expression exp)
                      kind = classType;
                      _class = prop ? prop._class.symbol : method ? method._class.symbol : _class.symbol;
                      // wasThisClass = type ? type.wasThisClass : false;
+                     thisClassFrom = type ? type.thisClassFrom : null;
                   };
                }
 
@@ -10419,13 +10393,18 @@ void ProcessExpressionType(Expression exp)
                   }
 
                   exp.member.memberType = dataMember;
-                  DeclareStruct(_class.fullName, false);
+                  DeclareStruct(curExternal, _class.fullName, false, true);
+                  if(member._class != _class)
+                     DeclareStruct(curExternal, member._class.fullName, false, true);
+
                   if(!member.dataType)
                   {
                      Context context = SetupTemplatesContext(_class);
                      member.dataType = ProcessTypeString(member.dataTypeString, false);
                      FinishTemplatesContext(context);
                   }
+                  if(exp.member.exp.expType.kind == classType && exp.member.exp.expType._class && exp.member.exp.expType._class.registered && exp.member.exp.expType._class.registered.type == bitClass)
+                     member.dataType.bitMemberSize = ((BitMember)member).size;
                   exp.expType = member.dataType;
                   if(member.dataType) member.dataType.refCount++;
                }
@@ -10518,11 +10497,26 @@ void ProcessExpressionType(Expression exp)
                         ClassTemplateArgument arg = tClass.templateArgs[id];
                         Context context = SetupTemplatesContext(tClass);
                         bool constant = exp.expType.constant;
+                        bool passAsTemplate = false;
+                        Class thisClassFrom = null;
+                        Type t = ProcessTypeString(exp.expType.templateParameter.dataTypeString, false);
+                        if(t && t.kind == classType && t._class)
+                           thisClassFrom = t._class.registered;
+                        else
+                           // Mark that 'thisClassFrom' was set to something
+                           thisClassFrom = eSystem_FindClass(GetPrivateModule(), "class");
+
+                        FreeType(t);
+
+                        passAsTemplate = tClass.templateClass && (exp.expType.kind != templateType ||
+                           (!exp.expType.templateParameter || (!exp.expType.templateParameter.dataTypeString && !exp.expType.templateParameter.dataType)));
+
                         /*if(!arg.dataType)
                            arg.dataType = ProcessTypeString(arg.dataTypeString, false);*/
                         FreeType(exp.expType);
 
                         exp.expType = ProcessTypeString(arg.dataTypeString, false);
+                        exp.expType.thisClassFrom = thisClassFrom;
                         if(exp.expType.kind == classType && constant) exp.expType.constant = true;
                         else if(exp.expType.kind == pointerType)
                         {
@@ -10538,7 +10532,7 @@ void ProcessExpressionType(Expression exp)
                               exp.expType = ReplaceThisClassType(_class);
                            }
 
-                           if(tClass.templateClass && (exp.expType.kind != templateType || (!exp.expType.templateParameter || (!exp.expType.templateParameter.dataTypeString && !exp.expType.templateParameter.dataType))))
+                           if(passAsTemplate)
                               exp.expType.passAsTemplate = true;
                            //exp.expType.refCount++;
                            if(!exp.destType)
@@ -10828,19 +10822,54 @@ void ProcessExpressionType(Expression exp)
          Symbol classSym = exp._class.symbol; // FindClass(exp._class.name);
          if(classSym && classSym.registered)
          {
-            if(classSym.registered.type == noHeadClass)
+            if(classSym.registered.type == noHeadClass || (classSym.registered.fixed && classSym.registered.structSize))
             {
                char name[1024];
+               Class b = classSym.registered;
                name[0] = '\0';
-               DeclareStruct(classSym.string, false);
+               DeclareStruct(curExternal, classSym.string, false, true);
                FreeSpecifier(exp._class);
-               exp.type = typeSizeExp;
                FullClassNameCat(name, classSym.string, false);
-               exp.typeName = MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(name), null)), null);
+
+               if(b.offset == 0)
+               {
+                  exp.type = typeSizeExp;
+                  exp.typeName = MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(name), null)), null);
+               }
+               else
+               {
+                  Expression e;
+                  exp.type = opExp;
+                  if(b.structSize == b.offset)
+                     exp.op.exp1 = MkExpConstant("0");
+                  else
+                     exp.op.exp1 = MkExpTypeSize(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(name), null)), null));
+                  exp.op.op = '+';
+                  e = exp;
+                  while(b.offset != 0)
+                  {
+                     Symbol sym;
+                     Expression typeSize;
+
+                     b = b.base;
+                     sym = FindClass(b.fullName);
+
+                     name[0] = '\0';
+                     DeclareStruct(curExternal, sym.string, false, true);
+                     FullClassNameCat(name, sym.string, false);
+
+                     if(b.structSize == b.offset)
+                        typeSize = MkExpConstant("0");
+                     else
+                        typeSize = MkExpTypeSize(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(name), null)), null));
+                     e.op.exp2 = b.offset ? MkExpOp(typeSize, '+', null) : typeSize;
+                     e = e.op.exp2;
+                  }
+               }
             }
             else
             {
-               if(classSym.registered.fixed)
+               if(classSym.registered.fixed && !classSym.registered.structSize)
                {
                   FreeSpecifier(exp._class);
                   exp.constant = PrintUInt(classSym.registered.templateClass ? classSym.registered.templateClass.structSize : classSym.registered.structSize);
@@ -10851,9 +10880,8 @@ void ProcessExpressionType(Expression exp)
                   char className[1024];
                   strcpy(className, "__ecereClass_");
                   FullClassNameCat(className, classSym.string, true);
-                  //MangleClassName(className);
 
-                  DeclareClass(classSym, className);
+                  DeclareClass(curExternal, classSym, className);
 
                   FreeExpContents(exp);
                   exp.type = pointerExp;
@@ -10882,7 +10910,7 @@ void ProcessExpressionType(Expression exp)
          };
          exp.isConstant = true;
 
-         DeclareType(type, false, false);
+         DeclareType(curExternal, type, true, false);
          FreeType(type);
          break;
       }
@@ -11169,7 +11197,7 @@ void ProcessExpressionType(Expression exp)
                delete exp.list;
             }
 
-            DeclareStruct("ecere::com::BuiltInContainer", false);
+            DeclareStruct(curExternal, "ecere::com::BuiltInContainer", false, true);
 
             ListAdd(structInitializers, /*MkIdentifier("_vTbl")*/    MkInitializerAssignment(MkExpMember(MkExpClass(MkListOne(MkSpecifierName("BuiltInContainer")), null), MkIdentifier("_vTbl"))));
                ProcessExpressionType(((Initializer)structInitializers->last).exp);
@@ -11245,6 +11273,16 @@ void ProcessExpressionType(Expression exp)
       }
    }
 
+   // Trying to do this here before conversion properties kick in and this becomes a new expression... (Fixing Class c; const char * a = c;)
+   // Mark nohead classes as by reference, unless we're casting them to an integral type
+   if(!notByReference && exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
+      exp.expType._class.registered.type == noHeadClass && (!exp.destType ||
+         (exp.destType.kind != intType && exp.destType.kind != int64Type && exp.destType.kind != intPtrType && exp.destType.kind != intSizeType &&
+          exp.destType.kind != longType && exp.destType.kind != shortType && exp.destType.kind != charType && exp.destType.kind != _BoolType)))
+   {
+      exp.byReference = true;
+   }
+
    yylloc = exp.loc;
    if(exp.destType && (/*exp.destType.kind == voidType || */exp.destType.kind == dummyType) );
    else if(exp.destType && !exp.destType.keepCast)
@@ -11320,23 +11358,115 @@ void ProcessExpressionType(Expression exp)
                   (exp.expType.kind != classType || exp.expType.classObjectType || (exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type != structClass)));
                else
                {
-                  char expString[10240];
-                  expString[0] = '\0';
-                  if(inCompiler) { PrintExpression(exp, expString); ChangeCh(expString, '\n', ' '); }
+                  Expression nbExp = GetNonBracketsExp(exp);
+                  bool skipWarning = false;
+                  TypeKind kind = exp.destType.kind;
+                  if(nbExp.type == conditionExp && nbExp.destType && !nbExp.destType.casted && nbExp.destType.kind == exp.destType.kind)
+                     // The if/else operands have already been checked / warned about
+                     skipWarning = true;
+                  if((kind == charType || kind == shortType) && exp.destType.isSigned == exp.expType.signedBeforePromotion && nbExp.type == opExp && nbExp.op.exp1 && nbExp.op.exp2)
+                  {
+                     int op = nbExp.op.op;
+                     Expression nbExp1, nbExp2;
+                     TypeKind from;
+
+                     switch(op)
+                     {
+                        case '%': case '/':
+                           nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+                           from = nbExp1.expType.promotedFrom;
+                           // Division and Modulo will not take more room than type before promotion
+                           if(from == charType || (kind == shortType && from == shortType))
+                              skipWarning = true;
+                           break;
+                        // Left shift
+                        case LEFT_OP: case RIGHT_OP:
+                           nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+                           nbExp2 = GetNonBracketsExp(nbExp.op.exp2);
+                           from = nbExp1.expType.promotedFrom;
+                           // Right shift will not take more room than type before promotion
+                           if(op == RIGHT_OP && (from == charType || (kind == shortType && from == shortType)))
+                              skipWarning = true;
+                           else if(nbExp2.isConstant && nbExp2.type == constantExp && (nbExp.op.op == RIGHT_OP || nbExp1.expType.bitMemberSize))
+                           {
+                              int n = (int)strtol(nbExp2.constant, null, 0);
+                              int s = from == charType ? 8 : 16;
+                              // Left shifting a bit member constrained in size may still fit in type before promotion
+                              if(nbExp1.expType.bitMemberSize && nbExp1.expType.bitMemberSize < s)
+                                 s = nbExp1.expType.bitMemberSize;
+
+                              // If right shifted enough things will fit in smaller type
+                              if(nbExp.op.op == RIGHT_OP)
+                                 s -= n;
+                              else
+                                 s += n;
+                              if(s <= (kind == charType ? 8 : 16))
+                                 skipWarning = true;
+                           }
+                           break;
+                        case '-':
+                           if(!exp.destType.isSigned)
+                           {
+                              nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+                              nbExp2 = GetNonBracketsExp(nbExp.op.exp2);
+                              from = nbExp2.expType.promotedFrom;
+                              // Max value of unsigned type before promotion minus the same will always fit
+                              if((from == charType || from == shortType) && nbExp1.isConstant && nbExp1.type == constantExp)
+                              {
+                                 int n = (int)strtol(nbExp1.constant, null, 0);
+                                 if(n == (from == charType ? 255 : 65535))
+                                    skipWarning = true;
+                              }
+                           }
+                           break;
+                        case '|':
+                        {
+                           TypeKind kind1, kind2;
+                           nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+                           nbExp2 = GetNonBracketsExp(nbExp.op.exp2);
+                           kind1 = nbExp1.expType.promotedFrom ? nbExp1.expType.promotedFrom : nbExp1.expType.kind;
+                           kind2 = nbExp2.expType.promotedFrom ? nbExp2.expType.promotedFrom : nbExp2.expType.kind;
+                           if(((kind1 == charType || (kind1 == shortType && kind == shortType)) || MatchTypeExpression(nbExp1, exp.destType, null, false, false)) &&
+                              ((kind2 == charType || (kind2 == shortType && kind == shortType)) || MatchTypeExpression(nbExp2, exp.destType, null, false, false)))
+                              skipWarning = true;
+                           break;
+                        }
+                        case '&':
+                        {
+                           TypeKind kind1, kind2;
+                           nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+                           nbExp2 = GetNonBracketsExp(nbExp.op.exp2);
+                           kind1 = nbExp1.expType.promotedFrom ? nbExp1.expType.promotedFrom : nbExp1.expType.kind;
+                           kind2 = nbExp2.expType.promotedFrom ? nbExp2.expType.promotedFrom : nbExp2.expType.kind;
+                           if(((kind1 == charType || (kind1 == shortType && kind == shortType)) || MatchTypeExpression(nbExp1, exp.destType, null, false, false)) ||
+                              ((kind2 == charType || (kind2 == shortType && kind == shortType)) || MatchTypeExpression(nbExp2, exp.destType, null, false, false)))
+                              skipWarning = true;
+                           break;
+                        }
+                     }
+                  }
+
+                  if(!skipWarning)
+                  {
+                     char expString[10240];
+                     expString[0] = '\0';
+                     if(inCompiler) { PrintExpression(exp, expString); ChangeCh(expString, '\n', ' '); }
 
 #ifdef _DEBUG
-                  CheckExpressionType(exp, exp.destType, false, true);
+                     CheckExpressionType(exp, exp.destType, false, true);
 #endif
-                  // Flex & Bison generate code that triggers this, so we ignore it for a quiet sdk build:
-                  if(!sourceFile || (!strstr(sourceFile, "src\\lexer.ec") && !strstr(sourceFile, "src/lexer.ec") &&
-                                     !strstr(sourceFile, "src\\grammar.ec") && !strstr(sourceFile, "src/grammar.ec") &&
-                                     !strstr(sourceFile, "src\\type.ec") && !strstr(sourceFile, "src/type.ec") &&
-                                     !strstr(sourceFile, "src\\expression.ec") && !strstr(sourceFile, "src/expression.ec")))
-                  {
-                     if(invalidCast)
-                        Compiler_Error($"incompatible expression %s (%s); expected %s\n", expString, type1, type2);
-                     else
-                        Compiler_Warning($"incompatible expression %s (%s); expected %s\n", expString, type1, type2);
+
+                     // Flex & Bison generate code that triggers this, so we ignore it for a quiet sdk build:
+                     if(!sourceFile || (!strstr(sourceFile, "src\\lexer.ec") && !strstr(sourceFile, "src/lexer.ec") &&
+                                        !strstr(sourceFile, "src\\grammar.ec") && !strstr(sourceFile, "src/grammar.ec") &&
+                                        !strstr(sourceFile, "src\\type.ec") && !strstr(sourceFile, "src/type.ec") &&
+                                        !strstr(sourceFile, "src\\expression.ec") && !strstr(sourceFile, "src/expression.ec")))
+                     {
+                        if(invalidCast)
+                           Compiler_Error($"incompatible expression %s (%s); expected %s\n", expString, type1, type2);
+                        else
+                           Compiler_Warning($"incompatible expression %s (%s); expected %s\n", expString, type1, type2);
+                     }
                   }
 
                   // TO CHECK: FORCING HERE TO HELP DEBUGGER
@@ -11557,7 +11687,7 @@ static void ProcessInitializer(Initializer init, Type type)
    }
 }
 
-static void ProcessSpecifier(Specifier spec, bool declareStruct)
+static void ProcessSpecifier(Specifier spec, bool declareStruct, bool warnClasses)
 {
    switch(spec.type)
    {
@@ -11570,7 +11700,7 @@ static void ProcessSpecifier(Specifier spec, bool declareStruct)
                spec.type = nameSpecifier;
                spec.name = ReplaceThisClass(thisClass);
                spec.symbol = FindClass(spec.name);
-               ProcessSpecifier(spec, declareStruct);
+               ProcessSpecifier(spec, declareStruct, false);
             }
          }
          break;
@@ -11579,9 +11709,14 @@ static void ProcessSpecifier(Specifier spec, bool declareStruct)
       {
          Symbol symbol = FindType(curContext, spec.name);
          if(symbol)
-            DeclareType(symbol.type, true, true);
-         else if((symbol = spec.symbol /*FindClass(spec.name)*/) && symbol.registered && symbol.registered.type == structClass && declareStruct)
-            DeclareStruct(spec.name, false);
+            DeclareType(curExternal, symbol.type, true, true);
+         else if(spec.symbol /*&& declareStruct*/)
+         {
+            Class c = spec.symbol.registered;
+            if(warnClasses && !c)
+               Compiler_Warning("Undeclared class %s\n", spec.name);
+            DeclareStruct(curExternal, spec.name, c && c.type == noHeadClass, declareStruct && c && c.type == structClass);
+         }
          break;
       }
       case enumSpecifier:
@@ -11624,7 +11759,7 @@ static void ProcessSpecifier(Specifier spec, bool declareStruct)
       {
          Symbol classSym = FindClass(spec.name);
          if(classSym && classSym.registered && classSym.registered.type == structClass)
-            DeclareStruct(spec.name, false);
+            DeclareStruct(spec.name, false, true);
          break;
       }
       */
@@ -11632,7 +11767,7 @@ static void ProcessSpecifier(Specifier spec, bool declareStruct)
 }
 
 
-static void ProcessDeclarator(Declarator decl)
+static void ProcessDeclarator(Declarator decl, bool isFunction)
 {
    switch(decl.type)
    {
@@ -11652,22 +11787,32 @@ static void ProcessDeclarator(Declarator decl)
       case pointerDeclarator:
       case extendedDeclarator:
       case extendedDeclaratorEnd:
-         if(decl.declarator)
-            ProcessDeclarator(decl.declarator);
+      {
+         Identifier id = null;
+         Specifier classSpec = null;
          if(decl.type == functionDeclarator)
          {
-            Identifier id = GetDeclId(decl);
+            id = GetDeclId(decl);
             if(id && id._class)
             {
+               classSpec = id._class;
+               id._class = null;
+            }
+         }
+         if(decl.declarator)
+            ProcessDeclarator(decl.declarator, isFunction);
+         if(decl.type == functionDeclarator)
+         {
+            if(classSpec)
+            {
                TypeName param
                {
-                  qualifiers = MkListOne(id._class);
+                  qualifiers = MkListOne(classSpec);
                   declarator = null;
                };
                if(!decl.function.parameters)
                   decl.function.parameters = MkList();
                decl.function.parameters->Insert(null, param);
-               id._class = null;
             }
             if(decl.function.parameters)
             {
@@ -11675,61 +11820,83 @@ static void ProcessDeclarator(Declarator decl)
 
                for(param = decl.function.parameters->first; param; param = param.next)
                {
-                  if(param.qualifiers && param.qualifiers->first)
+                  if(param.qualifiers)
                   {
-                     Specifier spec = param.qualifiers->first;
-                     if(spec && spec.specifier == TYPED_OBJECT)
+                     Specifier spec;
+                     for(spec = param.qualifiers->first; spec; spec = spec.next)
                      {
-                        Declarator d = param.declarator;
-                        TypeName newParam
+                        if(spec.type == baseSpecifier)
                         {
-                           qualifiers = MkListOne(MkSpecifier(VOID));
-                           declarator = MkDeclaratorPointer(MkPointer(null,null), d);
-                        };
-                        if(d.type != pointerDeclarator)
-                           newParam.qualifiers->Insert(null, MkSpecifier(CONST));
+                           if(spec.specifier == TYPED_OBJECT)
+                           {
+                              Declarator d = param.declarator;
+                              TypeName newParam
+                              {
+                                 qualifiers = MkListOne(MkSpecifier(VOID));
+                                 declarator = MkDeclaratorPointer(MkPointer(null,null), d);
+                              };
+                              if(!d || d.type != pointerDeclarator)
+                                 newParam.qualifiers->Insert(null, MkSpecifier(CONST));
 
-                        FreeList(param.qualifiers, FreeSpecifier);
+                              FreeList(param.qualifiers, FreeSpecifier);
 
-                        param.qualifiers = MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
-                        param.declarator = MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("class")));
+                              param.qualifiers = MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
+                              param.declarator = MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("class")));
 
-                        decl.function.parameters->Insert(param, newParam);
-                        param = newParam;
-                     }
-                     else if(spec && spec.specifier == ANY_OBJECT)
-                     {
-                        Declarator d = param.declarator;
+                              DeclareStruct(curExternal, "ecere::com::Class", false, true);
+
+                              decl.function.parameters->Insert(param, newParam);
+                              param = newParam;
+                              break;
+                           }
+                           else if(spec.specifier == ANY_OBJECT)
+                           {
+                              Declarator d = param.declarator;
 
-                        FreeList(param.qualifiers, FreeSpecifier);
+                              FreeList(param.qualifiers, FreeSpecifier);
 
-                        param.qualifiers = MkListOne(MkSpecifier(VOID));
-                        if(d.type != pointerDeclarator)
-                           param.qualifiers->Insert(null, MkSpecifier(CONST));
-                        param.declarator = MkDeclaratorPointer(MkPointer(null,null), d);
-                     }
-                     else if(spec.specifier == THISCLASS)
-                     {
-                        if(thisClass)
+                              param.qualifiers = MkListOne(MkSpecifier(VOID));
+                              if(!d || d.type != pointerDeclarator)
+                                 param.qualifiers->Insert(null, MkSpecifier(CONST));
+                              param.declarator = MkDeclaratorPointer(MkPointer(null,null), d);
+                              break;
+                           }
+                           else if(spec.specifier == THISCLASS)
+                           {
+                              if(thisClass)
+                              {
+                                 spec.type = nameSpecifier;
+                                 spec.name = ReplaceThisClass(thisClass);
+                                 spec.symbol = FindClass(spec.name);
+                                 ProcessSpecifier(spec, false, false);
+                              }
+                              break;
+                           }
+                        }
+                        else if(spec.type == nameSpecifier)
+                        {
+                           ProcessSpecifier(spec, isFunction, true);
+                        }
+                        else if((spec.type == structSpecifier || spec.type == unionSpecifier) && !spec.definitions && spec.id && spec.id.string)
                         {
-                           spec.type = nameSpecifier;
-                           spec.name = ReplaceThisClass(thisClass);
-                           spec.symbol = FindClass(spec.name);
-                           ProcessSpecifier(spec, false);
+                           Declarator d = param.declarator;
+                           if(!d || d.type != pointerDeclarator)
+                              DeclareStruct(curExternal, spec.id.string, false, true);
                         }
                      }
                   }
 
                   if(param.declarator)
-                     ProcessDeclarator(param.declarator);
+                     ProcessDeclarator(param.declarator, false);
                }
             }
          }
          break;
+      }
    }
 }
 
-static void ProcessDeclaration(Declaration decl)
+static void ProcessDeclaration(Declaration decl, bool warnClasses)
 {
    yylloc = decl.loc;
    switch(decl.type)
@@ -11749,7 +11916,7 @@ static void ProcessDeclaration(Declaration decl)
             for(d = decl.declarators->first; d; d = d.next)
             {
                Type type, subType;
-               ProcessDeclarator(d.declarator);
+               ProcessDeclarator(d.declarator, false);
 
                type = ProcessType(decl.specifiers, d.declarator);
 
@@ -11805,7 +11972,7 @@ static void ProcessDeclaration(Declaration decl)
             Specifier s;
             for(s = decl.specifiers->first; s; s = s.next)
             {
-               ProcessSpecifier(s, declareStruct);
+               ProcessSpecifier(s, declareStruct, true);
             }
          }
          break;
@@ -11827,7 +11994,7 @@ static void ProcessDeclaration(Declaration decl)
             {
                Type type = ProcessType(decl.specifiers, d.declarator);
                Type subType;
-               ProcessDeclarator(d);
+               ProcessDeclarator(d, false);
                for(subType = type; subType;)
                {
                   if(subType.kind == classType)
@@ -11848,7 +12015,7 @@ static void ProcessDeclaration(Declaration decl)
          if(decl.specifiers)
          {
             for(spec = decl.specifiers->first; spec; spec = spec.next)
-               ProcessSpecifier(spec, declareStruct);
+               ProcessSpecifier(spec, declareStruct, warnClasses);
          }
          break;
       }
@@ -11863,22 +12030,18 @@ static void CreateFireWatcher(Property prop, Expression object, Statement stmt)
    char getName[1024], setName[1024];
    OldList * args;
 
-   DeclareProperty(prop, setName, getName);
+   DeclareProperty(curExternal, prop, setName, getName);
 
    // eInstance_FireWatchers(object, prop);
    strcpy(propName, "__ecereProp_");
    FullClassNameCat(propName, prop._class.fullName, false);
    strcat(propName, "_");
-   // strcat(propName, prop.name);
    FullClassNameCat(propName, prop.name, true);
-   //MangleClassName(propName);
 
    strcpy(propNameM, "__ecerePropM_");
    FullClassNameCat(propNameM, prop._class.fullName, false);
    strcat(propNameM, "_");
-   // strcat(propNameM, prop.name);
    FullClassNameCat(propNameM, prop.name, true);
-   //MangleClassName(propNameM);
 
    if(prop.isWatchable)
    {
@@ -11891,8 +12054,9 @@ static void CreateFireWatcher(Property prop, Expression object, Statement stmt)
       ListAdd(args, object ? CopyExpression(object) : MkExpIdentifier(MkIdentifier("this")));
       ListAdd(args, MkExpIdentifier(MkIdentifier(propNameM)));
       ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eInstance_FireWatchers")), args));
-   }
 
+      DeclareFunctionUtil(curExternal, "eInstance_FireWatchers");
+   }
 
    {
       args = MkList();
@@ -11904,6 +12068,8 @@ static void CreateFireWatcher(Property prop, Expression object, Statement stmt)
       ListAdd(args, object ? CopyExpression(object) : MkExpIdentifier(MkIdentifier("this")));
       ListAdd(args, MkExpIdentifier(MkIdentifier(propNameM)));
       ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eInstance_FireSelfWatchers")), args));
+
+      DeclareFunctionUtil(curExternal, "eInstance_FireSelfWatchers");
    }
 
    if(curFunction.propSet && !strcmp(curFunction.propSet.string, prop.name) &&
@@ -11953,7 +12119,7 @@ static void ProcessStatement(Statement stmt)
             if(stmt.compound.declarations)
             {
                for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
-                  ProcessDeclaration(decl);
+                  ProcessDeclaration(decl, true);
             }
             if(stmt.compound.statements)
             {
@@ -12484,7 +12650,7 @@ static void ProcessStatement(Statement stmt)
                }
                ProcessExpressionType(expIt);
                if(stmt.compound.declarations->first)
-                  ProcessDeclaration(stmt.compound.declarations->first);
+                  ProcessDeclaration(stmt.compound.declarations->first, true);
 
                if(symbol)
                   symbol.isIterator = isMap ? 2 : ((isArray || isBuiltin) ? 3 : (isLinkList ? (isList ? 5 : 4) : (isCustomAVLTree ? 6 : 1)));
@@ -12533,7 +12699,7 @@ static void ProcessStatement(Statement stmt)
       }
       case badDeclarationStmt:
       {
-         ProcessDeclaration(stmt.decl);
+         ProcessDeclaration(stmt.decl, true);
          break;
       }
       case asmStmt:
@@ -12582,8 +12748,6 @@ static void ProcessStatement(Statement stmt)
                stmt.type = expressionStmt;
                stmt.expressions = MkList();
 
-               curExternal = external.prev;
-
                for(propWatch = watches->first; propWatch; propWatch = propWatch.next)
                {
                   ClassFunction func;
@@ -12592,10 +12756,6 @@ static void ProcessStatement(Statement stmt)
                      ((watcher.expType && watcher.expType.kind == classType && watcher.expType._class) ? watcher.expType._class.registered : null) : thisClass;
                   External createdExternal;
 
-                  // Create a declaration above
-                  External externalDecl = MkExternalDeclaration(null);
-                  ast->Insert(curExternal.prev, externalDecl);
-
                   sprintf(watcherName,"__ecerePropertyWatcher_%d", propWatcherID++);
                   if(propWatch.deleteWatch)
                      strcat(watcherName, "_delete");
@@ -12611,33 +12771,18 @@ static void ProcessStatement(Statement stmt)
 
                   if(object && object.expType && object.expType.kind == classType && object.expType._class && object.expType._class.registered)
                   {
-                     // TESTING THIS STUFF... BEWARE OF SYMBOL ID ISSUES
                      func = MkClassFunction(MkListOne(MkSpecifier(VOID)), null, MkDeclaratorFunction(MkDeclaratorIdentifier(MkIdentifier(watcherName)),
-                        //MkListOne(MkTypeName(MkListOne(MkSpecifier(VOID)), null))), null);
                         MkListOne(MkTypeName(MkListOne(MkSpecifierName(object.expType._class.string)), MkDeclaratorIdentifier(MkIdentifier("value"))))), null);
                      ProcessClassFunctionBody(func, propWatch.compound);
                      propWatch.compound = null;
 
-                     //afterExternal = afterExternal ? afterExternal : curExternal;
-
-                     //createdExternal = ProcessClassFunction(watcherClass, func, ast, curExternal.prev);
                      createdExternal = ProcessClassFunction(watcherClass, func, ast, curExternal, true);
-                     // TESTING THIS...
-                     createdExternal.symbol.idCode = external.symbol.idCode;
+
+                     FreeClassFunction(func);
 
                      curExternal = createdExternal;
                      ProcessFunction(createdExternal.function);
 
-
-                     // Create a declaration above
-                     {
-                        Declaration decl = MkDeclaration(CopyList(createdExternal.function.specifiers, CopySpecifier),
-                           MkListOne(MkInitDeclarator(CopyDeclarator(createdExternal.function.declarator), null)));
-                        externalDecl.declaration = decl;
-                        if(decl.symbol && !decl.symbol.pointerExternal)
-                           decl.symbol.pointerExternal = externalDecl;
-                     }
-
                      if(propWatch.deleteWatch)
                      {
                         OldList * args = MkList();
@@ -12660,13 +12805,12 @@ static void ProcessStatement(Statement stmt)
                               char getName[1024], setName[1024];
                               OldList * args = MkList();
 
-                              DeclareProperty(prop, setName, getName);
+                              DeclareProperty(createdExternal, prop, setName, getName);
 
                               // eInstance_Watch(stmt.watch.object, prop, stmt.watch.watcher, callback);
                               strcpy(propName, "__ecereProp_");
                               FullClassNameCat(propName, prop._class.fullName, false);
                               strcat(propName, "_");
-                              // strcat(propName, prop.name);
                               FullClassNameCat(propName, prop.name, true);
 
                               ListAdd(args, CopyExpression(object));
@@ -12675,6 +12819,8 @@ static void ProcessStatement(Statement stmt)
                               ListAdd(args, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpIdentifier(MkIdentifier(watcherName))));
 
                               ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eInstance_Watch")), args));
+
+                              external.CreateUniqueEdge(createdExternal, true);
                            }
                            else
                               Compiler_Error($"Property %s not found in class %s\n", propID.string, _class.fullName);
@@ -12695,7 +12841,7 @@ static void ProcessStatement(Statement stmt)
                FreeList(watches, FreePropertyWatch);
             }
             else
-               Compiler_Error($"No observer specified and not inside a _class\n");
+               Compiler_Error($"No observer specified and not inside a class\n");
          }
          else
          {
@@ -12822,15 +12968,13 @@ static void ProcessStatement(Statement stmt)
                            char getName[1024], setName[1024];
                            OldList * args = MkList();
 
-                           DeclareProperty(prop, setName, getName);
+                           DeclareProperty(curExternal, prop, setName, getName);
 
                            // eInstance_StopWatching(object, prop, watcher);
                            strcpy(propName, "__ecereProp_");
                            FullClassNameCat(propName, prop._class.fullName, false);
                            strcat(propName, "_");
-                           // strcat(propName, prop.name);
                            FullClassNameCat(propName, prop.name, true);
-                           //MangleClassName(propName);
 
                            ListAdd(args, CopyExpression(object));
                            ListAdd(args, MkExpIdentifier(MkIdentifier(propName)));
@@ -12918,14 +13062,10 @@ static void ProcessFunction(FunctionDefinition function)
          strcpy(className, "__ecereClass_");
          FullClassNameCat(className, _class.fullName, true);
 
-         //MangleClassName(className);
-
          structName[0] = 0;
          FullClassNameCat(structName, _class.fullName, false);
 
          // [class] this
-
-
          funcDecl = GetFuncDecl(function.declarator);
          if(funcDecl)
          {
@@ -12939,10 +13079,6 @@ static void ProcessFunction(FunctionDefinition function)
                }
             }
 
-            // DANGER: Watch for this... Check if it's a Conversion?
-            // if((_class.type != bitClass && _class.type != unitClass && _class.type != enumClass) || function != (FunctionDefinition)symbol.externalSet)
-
-            // WAS TRYING THIS FOR CONVERSION PROPERTIES ON NOHEAD CLASSES: if((_class.type == structClass) || function != (FunctionDefinition)symbol.externalSet)
             if(!function.propertyNoThis)
             {
                TypeName thisParam = null;
@@ -12968,6 +13104,7 @@ static void ProcessFunction(FunctionDefinition function)
                      declarator = MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("class")));
                      qualifiers = MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
                   };
+                  DeclareStruct(curExternal, "ecere::com::Class", false, true);
                   funcDecl.function.parameters->Insert(null, thisParam);
                }
             }
@@ -12991,7 +13128,6 @@ static void ProcessFunction(FunctionDefinition function)
 
                if(type.classObjectType != classPointer)
                {
-                  // DANGER: Watch for this... Check if it's a Conversion?
                   if((_class.type != bitClass && _class.type != unitClass && _class.type != enumClass) || function != (FunctionDefinition)symbol.externalSet)
                   {
                      TypeName thisParam = QMkClass(_class.fullName, MkDeclaratorIdentifier(MkIdentifier("this")));
@@ -13013,7 +13149,7 @@ static void ProcessFunction(FunctionDefinition function)
             thisSymbol = Symbol
             {
                string = CopyString("this");
-               type = classSym ? MkClassType(classSym.string) : null; //_class.fullName);
+               type = classSym ? MkClassType(classSym.string) : null;
             };
             function.body.compound.context.symbols.Add((BTNode)thisSymbol);
 
@@ -13022,17 +13158,12 @@ static void ProcessFunction(FunctionDefinition function)
                thisSymbol.type.classObjectType = ClassObjectType::typedObject;
                thisSymbol.type.byReference = type.byReference;
                thisSymbol.type.typedByReference = type.byReference;
-               /*
-               thisSymbol = Symbol { string = CopyString("class") };
-               function.body.compound.context.symbols.Add(thisSymbol);
-               */
             }
          }
       }
 
       // Pointer to class data
-
-      if(inCompiler && _class && (_class.type == normalClass /*|| _class.type == noHeadClass*/) && type.classObjectType != classPointer)
+      if(inCompiler && _class && _class.type == normalClass && type.classObjectType != classPointer)
       {
          DataMember member = null;
          {
@@ -13063,10 +13194,8 @@ static void ProcessFunction(FunctionDefinition function)
                char className[1024];
                strcpy(className, "__ecereClass_");
                FullClassNameCat(className, classSym.string, true);
-               //MangleClassName(className);
 
-               // Testing This
-               DeclareClass(classSym, className);
+               DeclareClass(curExternal, classSym, className);
             }
 
             // ((byte *) this)
@@ -13074,9 +13203,19 @@ static void ProcessFunction(FunctionDefinition function)
 
             if(_class.fixed)
             {
-               char string[256];
-               sprintf(string, "%d", _class.offset);
-               exp = QBrackets(MkExpOp(bytePtr, '+', MkExpConstant(string)));
+               Expression e;
+               if(_class.offset && _class.offset == (_class.base.type == noHeadClass ? _class.base.memberOffset : _class.base.structSize))
+               {
+                  e = MkExpClassSize(MkSpecifierName(_class.base.fullName));
+                  ProcessExpressionType(e);
+               }
+               else
+               {
+                  char string[256];
+                  sprintf(string, "%d", _class.offset);  // Need Bootstrap Fix
+                  e = MkExpConstant(string);
+               }
+               exp = QBrackets(MkExpOp(bytePtr, '+', e));
             }
             else
             {
@@ -13182,7 +13321,7 @@ static void ProcessFunction(FunctionDefinition function)
 
    if(function.declarator)
    {
-      ProcessDeclarator(function.declarator);
+      ProcessDeclarator(function.declarator, true);
    }
 
    topContext = oldTopContext;
@@ -13221,7 +13360,7 @@ static void ProcessClass(OldList definitions, Symbol symbol)
          {
             Class backThisClass = thisClass;
             if(regClass) thisClass = regClass;
-            ProcessDeclaration(def.decl);
+            ProcessDeclaration(def.decl, symbol ? true : false);
             thisClass = backThisClass;
          }
       }
@@ -13252,11 +13391,6 @@ static void ProcessClass(OldList definitions, Symbol symbol)
          PropertyDef prop = def.propertyDef;
 
          // Add this to the context
-         /*
-         Symbol thisSymbol = Symbol { string = CopyString("this"), type = MkClassType(regClass.fullName) };
-         globalContext.symbols.Add(thisSymbol);
-         */
-
          thisClass = regClass;
          if(prop.setStmt)
          {
@@ -13305,11 +13439,6 @@ static void ProcessClass(OldList definitions, Symbol symbol)
          }
 
          thisClass = null;
-
-         /*
-         globalContext.symbols.Remove(thisSymbol);
-         FreeSymbol(thisSymbol);
-         */
       }
       else if(def.type == propertyWatchClassDef && def.propertyWatch)
       {
@@ -13334,7 +13463,7 @@ static void ProcessClass(OldList definitions, Symbol symbol)
    }
 }
 
-void DeclareFunctionUtil(const String s)
+void DeclareFunctionUtil(External neededBy, const String s)
 {
    GlobalFunction function = eSystem_FindFunction(privateModule, s);
    if(function)
@@ -13344,111 +13473,81 @@ void DeclareFunctionUtil(const String s)
       if(function.module.importType != staticImport && (!function.dataType || !function.dataType.dllExport))
          strcpy(name, "__ecereFunction_");
       FullClassNameCat(name, s, false); // Why is this using FullClassNameCat ?
-      DeclareFunction(function, name);
+      DeclareFunction(neededBy, function, name);
    }
+   else if(neededBy)
+      FindSymbol(s, globalContext, globalContext, false, false);
 }
 
+bool reachedPass15;
+
 void ComputeDataTypes()
 {
    External external;
-   External temp { };
-   External after = null;
 
    currentClass = null;
 
    containerClass = eSystem_FindClass(GetPrivateModule(), "Container");
 
-   for(external = ast->first; external; external = external.next)
-   {
-      if(external.type == declarationExternal)
-      {
-         Declaration decl = external.declaration;
-         if(decl)
-         {
-            OldList * decls = decl.declarators;
-            if(decls)
-            {
-               InitDeclarator initDecl = decls->first;
-               if(initDecl)
-               {
-                  Declarator declarator = initDecl.declarator;
-                  if(declarator && declarator.type == identifierDeclarator)
-                  {
-                     Identifier id = declarator.identifier;
-                     if(id && id.string)
-                     {
-                        if(!strcmp(id.string, "uintptr_t") || !strcmp(id.string, "intptr_t") || !strcmp(id.string, "size_t") || !strcmp(id.string, "ssize_t"))
-                        {
-                           external.symbol.id = -1001, external.symbol.idCode = -1001;
-                           after = external;
-                        }
-                     }
-                  }
-               }
-            }
-         }
-       }
-   }
-
-   {
-      // Workaround until we have proper toposort for declarations reordering
-      External e = MkExternalDeclaration(MkDeclaration(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Instance"), null)), null));
-      ast->Insert(after, e);
-      after = e;
-   }
-
-   temp.symbol = Symbol { id = -1000, idCode = -1000 };
-   ast->Insert(after, temp);
-   curExternal = temp;
-
-   DeclareFunctionUtil("eSystem_New");
-   DeclareFunctionUtil("eSystem_New0");
-   DeclareFunctionUtil("eSystem_Renew");
-   DeclareFunctionUtil("eSystem_Renew0");
-   DeclareFunctionUtil("eSystem_Delete");
-   DeclareFunctionUtil("eClass_GetProperty");
-   DeclareFunctionUtil("eClass_SetProperty");
-   DeclareFunctionUtil("eInstance_FireSelfWatchers");
-   DeclareFunctionUtil("eInstance_SetMethod");
-   DeclareFunctionUtil("eInstance_IncRef");
-   DeclareFunctionUtil("eInstance_StopWatching");
-   DeclareFunctionUtil("eInstance_Watch");
-   DeclareFunctionUtil("eInstance_FireWatchers");
-   if(memoryGuard)
-   {
-      DeclareFunctionUtil("MemoryGuard_PushLoc");
-      DeclareFunctionUtil("MemoryGuard_PopLoc");
-   }
-
-   DeclareStruct("ecere::com::Class", false);
-   DeclareStruct("ecere::com::Instance", false);
-   DeclareStruct("ecere::com::Property", false);
-   DeclareStruct("ecere::com::DataMember", false);
-   DeclareStruct("ecere::com::Method", false);
-   DeclareStruct("ecere::com::SerialBuffer", false);
-   DeclareStruct("ecere::com::ClassTemplateArgument", false);
-
-   ast->Remove(temp);
+   DeclareStruct(null, "ecere::com::Class", false, true);
+   DeclareStruct(null, "ecere::com::Instance", false, true);
+   DeclareStruct(null, "ecere::com::Property", false, true);
+   DeclareStruct(null, "ecere::com::DataMember", false, true);
+   DeclareStruct(null, "ecere::com::Method", false, true);
+   DeclareStruct(null, "ecere::com::SerialBuffer", false, true);
+   DeclareStruct(null, "ecere::com::ClassTemplateArgument", false, true);
+
+   DeclareFunctionUtil(null, "eSystem_New");
+   DeclareFunctionUtil(null, "eSystem_New0");
+   DeclareFunctionUtil(null, "eSystem_Renew");
+   DeclareFunctionUtil(null, "eSystem_Renew0");
+   DeclareFunctionUtil(null, "eSystem_Delete");
+   DeclareFunctionUtil(null, "eClass_GetProperty");
+   DeclareFunctionUtil(null, "eClass_SetProperty");
+   DeclareFunctionUtil(null, "eInstance_FireSelfWatchers");
+   DeclareFunctionUtil(null, "eInstance_SetMethod");
+   DeclareFunctionUtil(null, "eInstance_IncRef");
+   DeclareFunctionUtil(null, "eInstance_StopWatching");
+   DeclareFunctionUtil(null, "eInstance_Watch");
+   DeclareFunctionUtil(null, "eInstance_FireWatchers");
+   reachedPass15 = true;
 
    for(external = ast->first; external; external = external.next)
    {
       afterExternal = curExternal = external;
       if(external.type == functionExternal)
       {
+         if(memoryGuard)
+         {
+            DeclareFunctionUtil(external, "MemoryGuard_PushLoc");
+            DeclareFunctionUtil(external, "MemoryGuard_PopLoc");
+         }
+
          currentClass = external.function._class;
          ProcessFunction(external.function);
       }
       // There shouldn't be any _class member access here anyways...
       else if(external.type == declarationExternal)
       {
+         if(memoryGuard && external.declaration && external.declaration.type == instDeclaration)
+         {
+            DeclareFunctionUtil(external, "MemoryGuard_PushLoc");
+            DeclareFunctionUtil(external, "MemoryGuard_PopLoc");
+         }
+
          currentClass = null;
          if(external.declaration)
-            ProcessDeclaration(external.declaration);
+            ProcessDeclaration(external.declaration, true);
       }
       else if(external.type == classExternal)
       {
          ClassDefinition _class = external._class;
          currentClass = external.symbol.registered;
+         if(memoryGuard)
+         {
+            DeclareFunctionUtil(external, "MemoryGuard_PushLoc");
+            DeclareFunctionUtil(external, "MemoryGuard_PopLoc");
+         }
          if(_class.definitions)
          {
             ProcessClass(_class.definitions, _class.symbol);
@@ -13468,7 +13567,4 @@ void ComputeDataTypes()
    currentClass = null;
    thisNameSpace = null;
    curExternal = null;
-
-   delete temp.symbol;
-   delete temp;
 }