[anjuta-extras] Update scintilla plugin to scintilla 2.0



commit 64a689bb15c8b16f70ee78f7bfd27909292dbc09
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Mon Aug 17 16:27:45 2009 +0200

    Update scintilla plugin to scintilla 2.0

 plugins/scintilla/FilePath.cxx                     |  662 +++++
 plugins/scintilla/FilePath.h                       |   96 +
 plugins/scintilla/Makefile.am                      |    6 +-
 plugins/scintilla/PropSetFile.cxx                  |  780 ++++++
 plugins/scintilla/PropSetFile.h                    |   58 +
 plugins/scintilla/SString.h                        |  303 ++
 plugins/scintilla/aneditor-priv.h                  |    3 +-
 plugins/scintilla/aneditor.cxx                     |   19 +-
 plugins/scintilla/properties.cxx                   |  287 +--
 plugins/scintilla/properties/styles.properties     |  488 +++-
 plugins/scintilla/properties_cxx.h                 |   47 -
 plugins/scintilla/scintilla/AutoComplete.cxx       |    2 +-
 plugins/scintilla/scintilla/CallTip.cxx            |    3 +-
 plugins/scintilla/scintilla/CellBuffer.cxx         |  367 +---
 plugins/scintilla/scintilla/CellBuffer.h           |   80 +-
 plugins/scintilla/scintilla/CharClassify.cxx       |   35 +
 plugins/scintilla/scintilla/CharClassify.h         |   14 +-
 plugins/scintilla/scintilla/Document.cxx           |  237 ++-
 plugins/scintilla/scintilla/Document.h             |  102 +-
 plugins/scintilla/scintilla/DocumentAccessor.h     |    5 +-
 plugins/scintilla/scintilla/Editor.cxx             | 2875 ++++++++++++--------
 plugins/scintilla/scintilla/Editor.h               |  103 +-
 plugins/scintilla/scintilla/ExternalLexer.cxx      |    4 +-
 plugins/scintilla/scintilla/ExternalLexer.h        |    2 +-
 plugins/scintilla/scintilla/Indicator.cxx          |    2 +-
 plugins/scintilla/scintilla/Indicator.h            |    3 +-
 plugins/scintilla/scintilla/KeyWords.cxx           |  195 ++-
 plugins/scintilla/scintilla/LexAU3.cxx             |    3 +-
 plugins/scintilla/scintilla/LexAda.cxx             |   21 +-
 plugins/scintilla/scintilla/LexBash.cxx            |    4 +
 plugins/scintilla/scintilla/LexCOBOL.cxx           |  368 +++
 plugins/scintilla/scintilla/LexCPP.cxx             |   36 +
 plugins/scintilla/scintilla/LexCaml.cxx            |  156 +-
 plugins/scintilla/scintilla/LexCmake.cxx           |    1 +
 plugins/scintilla/scintilla/LexD.cxx               |  607 +++--
 plugins/scintilla/scintilla/LexForth.cxx           |  440 +---
 plugins/scintilla/scintilla/LexFortran.cxx         |    4 +-
 plugins/scintilla/scintilla/LexHTML.cxx            |  350 +--
 plugins/scintilla/scintilla/LexHaskell.cxx         |    3 +-
 plugins/scintilla/scintilla/LexInno.cxx            |   51 +-
 plugins/scintilla/scintilla/LexLisp.cxx            |    9 +-
 plugins/scintilla/scintilla/LexMPT.cxx             |   16 +-
 plugins/scintilla/scintilla/LexMagik.cxx           |    2 +-
 plugins/scintilla/scintilla/LexMySQL.cxx           |  671 +++--
 plugins/scintilla/scintilla/LexNimrod.cxx          |  430 +++
 plugins/scintilla/scintilla/LexNsis.cxx            |    1 +
 plugins/scintilla/scintilla/LexOthers.cxx          |   69 +-
 plugins/scintilla/scintilla/LexPascal.cxx          |  699 ++++--
 plugins/scintilla/scintilla/LexPerl.cxx            |   16 +-
 plugins/scintilla/scintilla/LexPowerPro.cxx        |  600 ++++
 plugins/scintilla/scintilla/LexProgress.cxx        |   47 +-
 plugins/scintilla/scintilla/LexPython.cxx          |  160 +-
 plugins/scintilla/scintilla/LexRuby.cxx            |    4 +-
 plugins/scintilla/scintilla/LexSML.cxx             |  223 ++
 plugins/scintilla/scintilla/LexSQL.cxx             |    3 +
 plugins/scintilla/scintilla/LexSorcus.cxx          |  205 ++
 plugins/scintilla/scintilla/LexSpice.cxx           |    7 +-
 plugins/scintilla/scintilla/LexTACL.cxx            |  397 +++
 plugins/scintilla/scintilla/LexTADS3.cxx           |    2 +-
 plugins/scintilla/scintilla/LexTAL.cxx             |  396 +++
 plugins/scintilla/scintilla/LexTeX.cxx             |    7 +-
 plugins/scintilla/scintilla/LexVerilog.cxx         |    6 +-
 plugins/scintilla/scintilla/LexYAML.cxx            |    2 +-
 plugins/scintilla/scintilla/LineMarker.cxx         |    3 +-
 plugins/scintilla/scintilla/Makefile.am            |   85 +-
 plugins/scintilla/scintilla/Partitioning.h         |    2 +-
 plugins/scintilla/scintilla/PerLine.cxx            |  485 ++++
 plugins/scintilla/scintilla/PerLine.h              |  120 +
 plugins/scintilla/scintilla/PlatGTK.cxx            |  200 +-
 plugins/scintilla/scintilla/PositionCache.cxx      |   52 +-
 plugins/scintilla/scintilla/PositionCache.h        |    8 +-
 plugins/scintilla/scintilla/PropSet.cxx            |  713 +-----
 plugins/scintilla/scintilla/PropSetSimple.h        |   33 +
 plugins/scintilla/scintilla/RESearch.cxx           |    7 +-
 plugins/scintilla/scintilla/SVector.h              |   24 +-
 plugins/scintilla/scintilla/ScintillaBase.cxx      |   77 +-
 plugins/scintilla/scintilla/ScintillaBase.h        |    3 +-
 plugins/scintilla/scintilla/ScintillaGTK.cxx       | 1531 ++++++-----
 plugins/scintilla/scintilla/Selection.cxx          |  345 +++
 plugins/scintilla/scintilla/Selection.h            |  170 ++
 plugins/scintilla/scintilla/SplitVector.h          |    2 +-
 plugins/scintilla/scintilla/UniConversion.cxx      |    2 +-
 plugins/scintilla/scintilla/ViewStyle.cxx          |   30 +-
 plugins/scintilla/scintilla/ViewStyle.h            |   10 +
 plugins/scintilla/scintilla/WindowAccessor.cxx     |    2 +-
 plugins/scintilla/scintilla/XPM.h                  |    6 +-
 plugins/scintilla/scintilla/include/Face.py        |   43 +-
 plugins/scintilla/scintilla/include/HFacer.py      |   19 +-
 plugins/scintilla/scintilla/include/KeyWords.h     |   23 +
 plugins/scintilla/scintilla/include/Platform.h     |   31 +-
 plugins/scintilla/scintilla/include/PropSet.h      |   90 +-
 plugins/scintilla/scintilla/include/SciLexer.h     |   90 +-
 plugins/scintilla/scintilla/include/Scintilla.h    |  229 ++-
 .../scintilla/scintilla/include/Scintilla.iface    |  348 +++-
 .../scintilla/scintilla/include/ScintillaWidget.h  |    6 +-
 .../scintilla/scintilla/include/WindowAccessor.h   |    5 +-
 plugins/scintilla/scintilla/lexers.make            |  156 +-
 .../scintilla/patches/scintilla-64-bit.diff        |   22 +
 .../scintilla/patches/scintilla-pango-always.diff  |   28 +
 .../patches/scintilla-remove-deprecated.diff       |   90 +
 100 files changed, 12515 insertions(+), 5369 deletions(-)
---
diff --git a/plugins/scintilla/FilePath.cxx b/plugins/scintilla/FilePath.cxx
new file mode 100644
index 0000000..cbbb907
--- /dev/null
+++ b/plugins/scintilla/FilePath.cxx
@@ -0,0 +1,662 @@
+// SciTE - Scintilla based Text Editor
+/** @file FilePath.cxx
+ ** Encapsulate a file path.
+ **/
+// Copyright 1998-2005 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#include <unistd.h>
+#include <gtk/gtk.h>
+
+#include <dirent.h>
+#include <errno.h>
+
+#include "SString.h"
+#include "PropSet.h"
+#include "FilePath.h"
+
+#ifdef unix
+const char pathSepString[] = "/";
+const char pathSepChar = '/';
+const char listSepString[] = ":";
+const char configFileVisibilityString[] = ".";
+const char fileRead[] = "rb";
+const char fileWrite[] = "wb";
+#endif
+#ifdef __vms
+const char pathSepString[] = "/";
+const char pathSepChar = '/';
+const char listSepString[] = ":";
+const char configFileVisibilityString[] = "";
+const char fileRead[] = "r";
+const char fileWrite[] = "w";
+#endif
+#ifdef WIN32
+// Windows
+const char pathSepString[] = "\\";
+const char pathSepChar = '\\';
+const char listSepString[] = ";";
+const char configFileVisibilityString[] = "";
+const char fileRead[] = "rb";
+const char fileWrite[] = "wb";
+#endif
+
+FilePath::FilePath(const char *fileName_) : fileName(fileName_) {}
+
+FilePath::FilePath(FilePath const &directory, FilePath const &name) {
+	Set(directory, name);
+}
+
+void FilePath::Set(const char *fileName_) {
+	fileName = fileName_;
+}
+
+const char *FilePath::AsFileSystem() const {
+	return AsInternal();
+}
+
+void FilePath::Set(FilePath const &other) {
+	fileName = other.fileName;
+}
+
+void FilePath::Set(FilePath const &directory, FilePath const &name) {
+	if (name.IsAbsolute()) {
+		fileName = name.fileName;
+	} else {
+		fileName = directory.fileName;
+		fileName.appendwithseparator(name.fileName.c_str(),
+			fileName.endswith(pathSepString) ? '\0' : pathSepChar);
+	}
+}
+
+void FilePath::SetDirectory(FilePath directory) {
+	FilePath curName(*this);
+	Set(directory, curName);
+}
+
+void FilePath::Init() {
+	fileName = "";
+}
+
+bool FilePath::SameNameAs(const char *other) const {
+#ifdef WIN32
+	return EqualCaseInsensitive(fileName.c_str(), other);
+#else
+	return fileName == other;
+#endif
+}
+
+bool FilePath::SameNameAs(const FilePath &other) const {
+	return SameNameAs(other.fileName.c_str());
+}
+
+bool FilePath::IsSet() const {
+	return fileName.length() > 0;
+}
+
+bool FilePath::IsUntitled() const {
+	const char *dirEnd = strrchr(AsInternal(), pathSepChar);
+	return !dirEnd || !dirEnd[1];
+}
+
+bool FilePath::IsAbsolute() const {
+	if (fileName.length() == 0)
+		return false;
+#ifdef unix
+	if (fileName[0] == '/')
+		return true;
+#endif
+#ifdef __vms
+	if (fileName[0] == '/')
+		return true;
+#endif
+#ifdef WIN32
+	if (fileName[0] == pathSepChar || fileName[1] == ':')	// UNC path or drive separator
+		return true;
+#endif
+
+	return false;
+}
+
+bool FilePath::IsRoot() const {
+#ifdef WIN32
+    if ((fileName[0] == pathSepChar) && (fileName[1] == pathSepChar) && (fileName.search(pathSepString, 2) < 0))
+        return true; // UNC path like \\server
+	return (fileName.length() == 3) && (fileName[1] == ':') && (fileName[2] == pathSepChar);
+#else
+	return fileName == "/";
+#endif
+}
+
+int FilePath::RootLength() {
+#ifdef WIN32
+	return 3;
+#else
+	return 1;
+#endif
+}
+
+const char *FilePath::AsInternal() const {
+	return fileName.c_str();
+}
+
+FilePath FilePath::Name() const {
+	const char *dirEnd = strrchr(fileName.c_str(), pathSepChar);
+	if (dirEnd)
+		return dirEnd + 1;
+	else
+		return fileName.c_str();
+}
+
+FilePath FilePath::BaseName() const {
+	const char *dirEnd = strrchr(fileName.c_str(), pathSepChar);
+	const char *extStart = strrchr(fileName.c_str(), '.');
+	if (dirEnd) {
+		if (extStart > dirEnd) {
+			return FilePath(SString(dirEnd + 1, 0, extStart - dirEnd - 1).c_str());
+		} else {
+			return FilePath(dirEnd + 1);
+		}
+	} else if (extStart) {
+		return FilePath(SString(fileName.c_str(), 0, extStart - fileName.c_str()).c_str());
+	} else {
+		return fileName.c_str();
+	}
+}
+
+FilePath FilePath::Extension() const {
+	const char *dirEnd = strrchr(fileName.c_str(), pathSepChar);
+	const char *extStart = strrchr(fileName.c_str(), '.');
+	if (extStart > dirEnd)
+		return extStart + 1;
+	else
+		return "";
+}
+
+FilePath FilePath::Directory() const {
+	if (IsRoot()) {
+		return FilePath(fileName.c_str());
+	} else {
+		const char *dirEnd = strrchr(fileName.c_str(), pathSepChar);
+		if (dirEnd) {
+			int lenDirectory = dirEnd - fileName.c_str();
+			if (lenDirectory < RootLength()) {
+				lenDirectory = RootLength();
+			}
+			return FilePath(fileName.substr(0, lenDirectory).c_str());
+		} else {
+			return FilePath();
+		}
+	}
+}
+
+static char *split(char*& s, char c) {
+	char *t = s;
+	if (s && (s = strchr(s, c)) != NULL)
+		* s++ = '\0';
+	return t;
+}
+
+FilePath FilePath::NormalizePath() const {
+	char *path = new char[fileName.length() + 1];
+	strcpy(path, AsInternal());
+#ifdef WIN32
+	// Convert unix path separators to Windows
+	for (char *cp = path; *cp; cp++) {
+		if (*cp == '/')
+			*cp = pathSepChar;
+	}
+#endif
+	char *absPath = new char[fileName.length() + 1];
+	char *cur = absPath;
+	*cur = '\0';
+	char *tmp = path;
+	if (*tmp == pathSepChar) {
+		*cur++ = pathSepChar;
+		*cur = '\0';
+		tmp++;
+	}
+	char *part;
+	while ((part = split(tmp, pathSepChar)) != NULL) {
+		char *last;
+		if (strcmp(part, ".") == 0)
+			;
+		else if (strcmp(part, "..") == 0 && (last = strrchr(absPath, pathSepChar)) != NULL) {
+			if (last > absPath)
+				cur = last;
+			else
+				cur = last + 1;
+			*cur = '\0';
+		} else {
+			if (cur > absPath && *(cur - 1) != pathSepChar)
+				*cur++ = pathSepChar;
+			strcpy(cur, part);
+			cur += strlen(part);
+		}
+	}
+	FilePath ret(absPath);
+	delete []path;
+	delete []absPath;
+	return ret;
+}
+
+#ifdef __vms
+
+FilePath FilePath::VMSToUnixStyle() {
+	// possible formats:
+	// o disk:[dir.dir]file.type
+	// o logical:file.type
+	// o [dir.dir]file.type
+	// o file.type
+	// o /disk//dir/dir/file.type
+	// o /disk/dir/dir/file.type
+
+	char unixStyleFileName[MAX_PATH + 20];
+	const char *vmsName = FullPath();
+
+	if (strchr(vmsName, ':') == NULL && strchr(vmsName, '[') == NULL) {
+		// o file.type
+		// o /disk//dir/dir/file.type
+		// o /disk/dir/dir/file.type
+		if (strstr (vmsName, "//") == NULL) {
+			return FilePath(vmsName);
+		}
+		strcpy(unixStyleFileName, vmsName);
+		char *p;
+		while ((p = strstr (unixStyleFileName, "//")) != NULL) {
+			strcpy (p, p + 1);
+		}
+		return FilePath(unixStyleFileName);
+	}
+
+	// o disk:[dir.dir]file.type
+	// o logical:file.type
+	// o [dir.dir]file.type
+
+	if (vmsName [0] == '/') {
+		strcpy(unixStyleFileName, vmsName);
+	} else {
+		unixStyleFileName [0] = '/';
+		strcpy(unixStyleFileName + 1, vmsName);
+		char *p = strstr(unixStyleFileName, ":[");
+		if (p == NULL) {
+			// o logical:file.type
+			p = strchr(unixStyleFileName, ':');
+			*p = '/';
+		} else {
+			*p = '/';
+			strcpy(p + 1, p + 2);
+			char *end = strchr(unixStyleFileName, ']');
+			if (*end != NULL) {
+				*end = '/';
+			}
+			while (p = strchr(unixStyleFileName, '.'), p != NULL && p < end) {
+				*p = '/';
+			}
+		}
+	}
+	return FilePath(unixStyleFileName);
+} // VMSToUnixStyle
+
+#endif
+
+/**
+ * Take a filename or relative path and put it at the end of the current path.
+ * If the path is absolute, return the same path.
+ */
+FilePath FilePath::AbsolutePath() const {
+#ifdef WIN32
+	// The runtime libraries for GCC and Visual C++ give different results for _fullpath
+	// so use the OS.
+	char absPath[2000];
+	absPath[0] = '\0';
+	LPTSTR fileBit = 0;
+	::GetFullPathNameA(AsFileSystem(), sizeof(absPath), absPath, &fileBit);
+	return FilePath(absPath);
+#else
+	if (IsAbsolute()) {
+		return NormalizePath();
+	} else {
+		return FilePath(GetWorkingDirectory(), *this).NormalizePath();
+	}
+#endif
+}
+
+// Only used on Windows to fix the case of file names
+
+FilePath FilePath::GetWorkingDirectory() {
+	char dir[MAX_PATH + 1];
+	dir[0] = '\0';
+	if (getcwd(dir, MAX_PATH)) {
+		dir[MAX_PATH] = '\0';
+		// In Windows, getcwd returns a trailing backslash
+		// when the CWD is at the root of a disk, so remove it
+		size_t endOfPath = strlen(dir) - 1;
+		if (dir[endOfPath] == pathSepChar) {
+			dir[endOfPath] = '\0';
+		}
+	}
+	return FilePath(dir);
+}
+
+bool FilePath::SetWorkingDirectory() const {
+	return chdir(AsFileSystem()) == 0;
+}
+
+void FilePath::FixCase() {}
+
+void FilePath::List(FilePathSet &directories, FilePathSet &files) {
+#ifdef WIN32
+	FilePath wildCard(*this, "*.*");
+	bool complete = false;
+	WIN32_FIND_DATA findFileData;
+	HANDLE hFind = ::FindFirstFile(wildCard.AsFileSystem(), &findFileData);
+	if (hFind != INVALID_HANDLE_VALUE) {
+		while (!complete) {
+			if ((strcmp(findFileData.cFileName, ".") != 0) && (strcmp(findFileData.cFileName, "..") != 0)) {
+				if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+					directories.Append(FilePath(AsInternal(), findFileData.cFileName));
+				} else {
+					files.Append(FilePath(AsInternal(), findFileData.cFileName));
+				}
+			}
+			if (!::FindNextFile(hFind, &findFileData)) {
+				complete = true;
+			}
+		}
+		::FindClose(hFind);
+	}
+#else
+	errno = 0;
+	DIR *dp = opendir(AsInternal());
+	if (dp == NULL) {
+		//~ fprintf(stderr, "%s: cannot open for reading: %s\n", AsInternal(), strerror(errno));
+		return;
+	}
+	struct dirent *ent;
+	while ((ent = readdir(dp)) != NULL) {
+		if ((strcmp(ent->d_name, ".") != 0) && (strcmp(ent->d_name, "..") != 0)) {
+			FilePath pathFull(AsInternal(), ent->d_name);
+			if (pathFull.IsDirectory()) {
+				directories.Append(pathFull);
+			} else {
+				files.Append(pathFull);
+			}
+		}
+	}
+
+	if (errno == 0) {
+		closedir(dp);
+	}
+#endif
+}
+
+FILE *FilePath::Open(const char *mode) const {
+	if (IsSet()) {
+		return fopen(fileName.c_str(), mode);
+	} else {
+		return NULL;
+	}
+}
+
+void FilePath::Remove() const {
+	unlink(AsFileSystem());
+}
+
+#ifndef R_OK
+// Neither Borland nor Microsoft define the constants used to call access
+#define R_OK 4
+#endif
+
+time_t FilePath::ModifiedTime() const {
+	if (IsUntitled())
+		return 0;
+	if (access(AsFileSystem(), R_OK) == -1)
+		return 0;
+	struct stat statusFile;
+	if (stat(AsFileSystem(), &statusFile) != -1)
+		return statusFile.st_mtime;
+	else
+		return 0;
+}
+
+int FilePath::GetFileLength() const {
+	int size = -1;
+	if (IsSet()) {
+		FILE *fp = Open(fileRead);
+		if (fp) {
+			fseek(fp, 0, SEEK_END);
+			size = ftell(fp);
+			fseek(fp, 0, SEEK_SET);
+			fclose(fp);
+		}
+	}
+	return size;
+}
+
+bool FilePath::Exists() const {
+	bool ret = false;
+	if (IsSet()) {
+		FILE *fp = Open(fileRead);
+		if (fp) {
+			ret = true;
+			fclose(fp);
+		}
+	}
+	return ret;
+}
+
+bool FilePath::IsDirectory() const {
+	struct stat statusFile;
+	if (stat(AsFileSystem(), &statusFile) != -1)
+#ifdef WIN32
+		return statusFile.st_mode & _S_IFDIR;
+#else
+		return statusFile.st_mode & S_IFDIR;
+#endif
+	else
+		return false;
+}
+
+bool FilePath::Matches(const char *pattern) const {
+	SString pat(pattern);
+	pat.substitute(' ', '\0');
+	SString nameCopy(Name().fileName);
+	nameCopy.lowercase();
+	size_t start = 0;
+	while (start < pat.length()) {
+		const char *patElement = pat.c_str() + start;
+		if (patElement[0] == '*') {
+			if (nameCopy.endswith(patElement + 1)) {
+				return true;
+			}
+		} else {
+			if (nameCopy == SString(patElement).lowercase()) {
+				return true;
+			}
+		}
+		start += strlen(patElement) + 1;
+	}
+	return false;
+}
+
+#ifdef WIN32
+/**
+ * Makes a long path from a given, possibly short path/file.
+ *
+ * The short path/file must exist, and if it is a file it must be fully specified
+ * otherwise the function fails.
+ *
+ * sizeof @a longPath buffer must be a least _MAX_PATH
+ * @returns true on success, and the long path in @a longPath buffer,
+ * false on failure, and copies the @a shortPath arg to the @a longPath buffer.
+ */
+bool MakeLongPath(const char* shortPath, char* longPath) {
+	// when we have pfnGetLong, we assume it never changes as kernel32 is always loaded
+	static DWORD (STDAPICALLTYPE* pfnGetLong)(const char* lpszShortPath, char* lpszLongPath, DWORD cchBuffer) = NULL;
+	static bool kernelTried = FALSE;
+	bool ok = FALSE;
+
+	if (!kernelTried) {
+		HMODULE hModule;
+		kernelTried = true;
+		hModule = ::GetModuleHandleA("KERNEL32");
+		//assert(hModule != NULL); // must not call FreeLibrary on such handle
+
+		// attempt to get GetLongPathName (implemented in Win98/2000 only!)
+		(FARPROC&)pfnGetLong = ::GetProcAddress(hModule, "GetLongPathNameA");
+	}
+
+	// the kernel GetLongPathName proc is faster and (hopefully) more reliable
+	if (pfnGetLong != NULL) {
+		// call kernel proc
+		ok = (pfnGetLong)(shortPath, longPath, _MAX_PATH) != 0;
+	} else {
+		char short_path[_MAX_PATH];  // copy, so we can modify it
+		char* tok;
+
+		*longPath = '\0';
+
+		lstrcpyn(short_path, shortPath, _MAX_PATH);
+
+		for (;;) {
+			tok = strtok(short_path, "\\");
+			if (tok == NULL)
+				break;
+
+			if ((strlen(shortPath) > 3) &&
+			        (shortPath[0] == '\\') && (shortPath[1] == '\\')) {
+				// UNC, skip first seps
+				strcat(longPath, "\\\\");
+				strcat(longPath, tok);
+				strcat(longPath, "\\");
+
+				tok = strtok(NULL, "\\");
+				if (tok == NULL)
+					break;
+			}
+			strcat(longPath, tok);
+
+			bool isDir = false;
+
+			for (;;) {
+				WIN32_FIND_DATA fd;
+				HANDLE hfind;
+				char* tokend;
+
+				tok = strtok(NULL, "\\");
+				if (tok == NULL)
+					break;
+
+				strcat(longPath, "\\");
+				tokend = longPath + strlen(longPath);
+
+				// temporary add short component
+				strcpy(tokend, tok);
+
+				hfind = ::FindFirstFile(longPath, &fd);
+				if (hfind == INVALID_HANDLE_VALUE)
+					break;
+
+				isDir = (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
+
+				// finally add long component we got
+				strcpy(tokend, fd.cFileName);
+
+				::FindClose(hfind);
+			}
+			ok = tok == NULL;
+
+			if (ok && isDir)
+				strcat(longPath, "\\");
+
+			break;
+		}
+	}
+
+	if (!ok) {
+		lstrcpyn(longPath, shortPath, _MAX_PATH);
+	}
+	return ok;
+}
+#endif
+
+void FilePath::FixName() {
+#ifdef WIN32
+	// Only used on Windows to use long file names and fix the case of file names
+	char longPath[_MAX_PATH];
+	// first try MakeLongPath which corrects the path and the case of filename too
+	if (MakeLongPath(AsFileSystem(), longPath)) {
+		Set(longPath);
+	} else {
+		// On Windows file comparison is done case insensitively so the user can
+		// enter scite.cxx and still open this file, SciTE.cxx. To ensure that the file
+		// is saved with correct capitalisation FindFirstFile is used to find out the
+		// real name of the file.
+		WIN32_FIND_DATA FindFileData;
+		HANDLE hFind = ::FindFirstFile(AsFileSystem(), &FindFileData);
+		FilePath dir = Directory();
+		if (hFind != INVALID_HANDLE_VALUE) {	// FindFirstFile found the file
+			Set(dir, FindFileData.cFileName);
+			::FindClose(hFind);
+		}
+	}
+#endif
+}
+
+FilePathSet &FilePathSet::operator=(const FilePathSet &) {
+	// Private so won't be called.
+	return *this;
+}
+
+FilePathSet::FilePathSet(int size_) {
+	size = size_;
+	body = new FilePath[size];
+	lengthBody = 0;
+}
+
+FilePathSet::FilePathSet(const FilePathSet &other) {
+	size = other.size;
+	lengthBody = other.lengthBody;
+	body = new FilePath[size];
+	for (size_t i = 0; i < lengthBody; i++) {
+		body[i] = other.body[i];
+	}
+}
+
+FilePathSet::~FilePathSet() {
+	delete []body;
+	body = NULL;
+	size = 0;
+	lengthBody = 0;
+}
+
+FilePath FilePathSet::At(size_t pos) const {
+	return body[pos];
+}
+
+void FilePathSet::Append(FilePath fp) {
+	if (lengthBody >= size) {
+		size *= 2;
+		FilePath *bodyNew = new FilePath[size];
+		for (size_t i = 0; i < lengthBody; i++) {
+			bodyNew[i] = body[i];
+		}
+		delete []body;
+		body = bodyNew;
+	}
+	body[lengthBody++] = fp;
+}
+
+size_t FilePathSet::Length() const {
+	return lengthBody;
+}
+
diff --git a/plugins/scintilla/FilePath.h b/plugins/scintilla/FilePath.h
new file mode 100644
index 0000000..119cbe2
--- /dev/null
+++ b/plugins/scintilla/FilePath.h
@@ -0,0 +1,96 @@
+// SciTE - Scintilla based Text Editor
+/** @file FilePath.h
+ ** Definition of platform independent base class of editor.
+ **/
+// Copyright 1998-2005 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+extern const char pathSepString[];
+extern const char pathSepChar;
+extern const char listSepString[];
+extern const char configFileVisibilityString[];
+extern const char fileRead[];
+extern const char fileWrite[];
+
+#ifdef unix
+#include <limits.h>
+#ifdef PATH_MAX
+#define MAX_PATH PATH_MAX
+#else
+#define MAX_PATH 260
+#endif
+#endif
+
+#ifdef WIN32
+#ifdef _MSC_VER
+// Shut up level 4 warning:
+// warning C4710: function 'void whatever(...)' not inlined
+// warning C4800: forcing value to bool 'true' or 'false' (performance warning)
+#pragma warning(disable: 4710 4800)
+#endif
+#ifdef __DMC__
+#include <time.h>
+#endif
+#endif
+
+class FilePath;
+
+class FilePathSet;
+
+class FilePath {
+	SString fileName;
+public:
+	FilePath(const char *fileName_ = "");
+	FilePath(FilePath const &directory, FilePath const &name);
+	void Set(const char *fileName_);
+	const char *AsFileSystem() const;
+#ifdef __vms
+	FilePath VMSToUnixStyle();
+#endif
+	void Set(FilePath const &other);
+	void Set(FilePath const &directory, FilePath const &name);
+	void SetDirectory(FilePath directory);
+	void Init();
+	bool SameNameAs(const char *other) const;
+	bool SameNameAs(const FilePath &other) const;
+	bool IsSet() const;
+	bool IsUntitled() const;
+	bool IsAbsolute() const;
+	bool IsRoot() const;
+	static int RootLength();
+	const char *AsInternal() const;
+	FilePath Name() const;
+	FilePath BaseName() const;
+	FilePath Extension() const;
+	FilePath Directory() const;
+	void FixName();
+	FilePath AbsolutePath() const;
+	FilePath NormalizePath() const;
+	static FilePath GetWorkingDirectory();
+	bool SetWorkingDirectory() const;
+	void FixCase();
+	void List(FilePathSet &directories, FilePathSet &files);
+	FILE *Open(const char *mode) const;
+	void Remove() const;
+	time_t ModifiedTime() const;
+	int GetFileLength() const;
+	bool Exists() const;
+	bool IsDirectory() const;
+	bool Matches(const char *pattern) const;
+};
+
+class FilePathSet {
+	size_t size;
+	size_t lengthBody;
+	FilePath *body;
+	// Private so won't be called.
+	FilePathSet &operator=(const FilePathSet &);
+public:
+	FilePathSet(int size_ = 10);
+	FilePathSet(const FilePathSet &other);
+	~FilePathSet();
+	FilePath At(size_t pos) const;
+	void Append(FilePath fp);
+	size_t Length() const;
+};
+
diff --git a/plugins/scintilla/Makefile.am b/plugins/scintilla/Makefile.am
index 8ffea52..6f5873c 100644
--- a/plugins/scintilla/Makefile.am
+++ b/plugins/scintilla/Makefile.am
@@ -36,7 +36,6 @@ libanjuta_editor_la_LIBADD = \
 libanjuta_editor_la_SOURCES= \
 	properties.cxx \
 	properties.h \
-	properties_cxx.h \
 	aneditor.h \
 	aneditor-priv.h \
 	aneditor.cxx \
@@ -58,6 +57,11 @@ libanjuta_editor_la_SOURCES= \
 	style-editor.h \
 	print.c \
 	print.h \
+	PropSetFile.h \
+	PropSetFile.cxx \
+	SString.h \
+	FilePath.cxx \
+	FilePath.h \
 	anjuta-bookmark-16.xpm \
 	anjuta-breakpoint-disabled-16.xpm \
 	anjuta-breakpoint-enabled-16.xpm \
diff --git a/plugins/scintilla/PropSetFile.cxx b/plugins/scintilla/PropSetFile.cxx
new file mode 100644
index 0000000..83fe8f9
--- /dev/null
+++ b/plugins/scintilla/PropSetFile.cxx
@@ -0,0 +1,780 @@
+// SciTE - Scintilla based Text Editor
+/** @file PropSetFile.cxx
+ ** Property set implementation.
+ **/
+// Copyright 1998-2007 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <time.h>
+#include <locale.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
+
+#include <unistd.h>
+
+#include "PropSetFile.h"
+
+// The comparison and case changing functions here assume ASCII
+// or extended ASCII such as the normal Windows code page.
+
+static inline char MakeUpperCase(char ch) {
+	if (ch < 'a' || ch > 'z')
+		return ch;
+	else
+		return static_cast<char>(ch - 'a' + 'A');
+}
+
+inline bool IsASpace(unsigned int ch) {
+    return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
+bool PropSetFile::caseSensitiveFilenames = false;
+
+PropSetFile::PropSetFile(bool lowerKeys_) : lowerKeys(lowerKeys_), superPS(0) {
+}
+
+PropSetFile::~PropSetFile() {
+	superPS = 0;
+	Clear();
+}
+
+void PropSetFile::Set(const char *key, const char *val, int lenKey, int lenVal) {
+	if (!*key)	// Empty keys are not supported
+		return;
+	if (lenKey == -1)
+		lenKey = static_cast<int>(strlen(key));
+	if (lenVal == -1)
+		lenVal = static_cast<int>(strlen(val));
+	props[std::string(key, lenKey)] = std::string(val, lenVal);
+}
+
+void PropSetFile::Set(const char *keyVal) {
+	while (IsASpace(*keyVal))
+		keyVal++;
+	const char *endVal = keyVal;
+	while (*endVal && (*endVal != '\n'))
+		endVal++;
+	const char *eqAt = strchr(keyVal, '=');
+	if (eqAt) {
+		Set(keyVal, eqAt + 1, eqAt-keyVal, endVal - eqAt - 1);
+	} else if (*keyVal) {	// No '=' so assume '=1'
+		Set(keyVal, "1", endVal-keyVal, 1);
+	}
+}
+
+void PropSetFile::Unset(const char *key, int lenKey) {
+	if (!*key)	// Empty keys are not supported
+		return;
+	if (lenKey == -1)
+		lenKey = static_cast<int>(strlen(key));
+	mapss::iterator keyPos = props.find(std::string(key, lenKey));
+	props.erase(keyPos);
+}
+
+void PropSetFile::SetMultiple(const char *s) {
+	const char *eol = strchr(s, '\n');
+	while (eol) {
+		Set(s);
+		s = eol + 1;
+		eol = strchr(s, '\n');
+	}
+	Set(s);
+}
+
+SString PropSetFile::Get(const char *key) const {
+	mapss::const_iterator keyPos = props.find(std::string(key));
+	if (keyPos != props.end()) {
+		return SString(keyPos->second.c_str());
+	} else {
+		if (superPS) {
+			// Failed here, so try in base property set
+			return superPS->Get(key);
+		} else {
+			return "";
+		}
+	}
+}
+
+// There is some inconsistency between GetExpanded("foo") and Expand("$(foo)").
+// A solution is to keep a stack of variables that have been expanded, so that
+// recursive expansions can be skipped.  For now I'll just use the C++ stack
+// for that, through a recursive function and a simple chain of pointers.
+
+struct VarChain {
+	VarChain(const char*var_=NULL, const VarChain *link_=NULL): var(var_), link(link_) {}
+
+	bool contains(const char *testVar) const {
+		return (var && (0 == strcmp(var, testVar)))
+			|| (link && link->contains(testVar));
+	}
+
+	const char *var;
+	const VarChain *link;
+};
+
+static int ExpandAllInPlace(const PropSetFile &props, SString &withVars, int maxExpands, const VarChain &blankVars = VarChain()) {
+	int varStart = withVars.search("$(");
+	while ((varStart >= 0) && (maxExpands > 0)) {
+		int varEnd = withVars.search(")", varStart+2);
+		if (varEnd < 0) {
+			break;
+		}
+
+		// For consistency, when we see '$(ab$(cde))', expand the inner variable first,
+		// regardless whether there is actually a degenerate variable named 'ab$(cde'.
+		int innerVarStart = withVars.search("$(", varStart+2);
+		while ((innerVarStart > varStart) && (innerVarStart < varEnd)) {
+			varStart = innerVarStart;
+			innerVarStart = withVars.search("$(", varStart+2);
+		}
+
+		SString var(withVars.c_str(), varStart + 2, varEnd);
+		SString val = props.Get(var.c_str());
+
+		if (blankVars.contains(var.c_str())) {
+			val.clear(); // treat blankVar as an empty string (e.g. to block self-reference)
+		}
+
+		if (--maxExpands >= 0) {
+			maxExpands = ExpandAllInPlace(props, val, maxExpands, VarChain(var.c_str(), &blankVars));
+		}
+
+		withVars.remove(varStart, varEnd-varStart+1);
+		withVars.insert(varStart, val.c_str(), val.length());
+
+		varStart = withVars.search("$(");
+	}
+
+	return maxExpands;
+}
+
+SString PropSetFile::GetExpanded(const char *key) const {
+	SString val = Get(key);
+	ExpandAllInPlace(*this, val, 100, VarChain(key));
+	return val;
+}
+
+SString PropSetFile::Expand(const char *withVars, int maxExpands) const {
+	SString val = withVars;
+	ExpandAllInPlace(*this, val, maxExpands);
+	return val;
+}
+
+int PropSetFile::GetInt(const char *key, int defaultValue) const {
+	SString val = GetExpanded(key);
+	if (val.length())
+		return val.value();
+	return defaultValue;
+}
+
+static bool isPrefix(const char *target, const char *prefix) {
+	while (*target && *prefix) {
+		if (*target != *prefix)
+			return false;
+		target++;
+		prefix++;
+	}
+	if (*prefix)
+		return false;
+	else
+		return true;
+}
+
+void PropSetFile::Clear() {
+	props.clear();
+}
+
+char *PropSetFile::ToString() const {
+	std::string sval;
+	for (mapss::const_iterator it=props.begin(); it != props.end(); it++) {
+		sval += it->first;
+		sval += "=";
+		sval += it->second;
+		sval += "\n";
+	}
+	char *ret = new char [sval.size() + 1];
+	strcpy(ret, sval.c_str());
+	return ret;
+}
+
+/**
+ * Get a line of input. If end of line escaped with '\\' then continue reading.
+ */
+static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) {
+	bool continuation = true;
+	s[0] = '\0';
+	while ((len > 1) && lenData > 0) {
+		char ch = *fpc;
+		fpc++;
+		lenData--;
+		if ((ch == '\r') || (ch == '\n')) {
+			if (!continuation) {
+				if ((lenData > 0) && (ch == '\r') && ((*fpc) == '\n')) {
+					// munch the second half of a crlf
+					fpc++;
+					lenData--;
+				}
+				*s = '\0';
+				return true;
+			}
+		} else if ((ch == '\\') && (lenData > 0) && ((*fpc == '\r') || (*fpc == '\n'))) {
+			continuation = true;
+			if ((lenData > 1) && (((*fpc == '\r') && (*(fpc+1) == '\r')) || ((*fpc == '\n') && (*(fpc+1) == '\n'))))
+				continuation = false;
+			else if ((lenData > 2) && ((*fpc == '\r') && (*(fpc+1) == '\n') && (*(fpc+2) == '\n' || *(fpc+2) == '\r')))
+				continuation = false;
+		} else {
+			continuation = false;
+			*s++ = ch;
+			*s = '\0';
+			len--;
+		}
+	}
+	return false;
+}
+
+static bool IsSpaceOrTab(char ch) {
+	return (ch == ' ') || (ch == '\t');
+}
+
+static bool IsCommentLine(const char *line) {
+	while (IsSpaceOrTab(*line)) ++line;
+	return (*line == '#');
+}
+
+bool PropSetFile::ReadLine(const char *lineBuffer, bool ifIsTrue, FilePath directoryForImports,
+                           FilePath imports[], int sizeImports) {
+	//UnSlash(lineBuffer);
+	if (!IsSpaceOrTab(lineBuffer[0]))    // If clause ends with first non-indented line
+		ifIsTrue = true;
+	if (isPrefix(lineBuffer, "if ")) {
+		const char *expr = lineBuffer + strlen("if") + 1;
+		ifIsTrue = GetInt(expr) != 0;
+	} else if (isPrefix(lineBuffer, "import ") && directoryForImports.IsSet()) {
+		SString importName(lineBuffer + strlen("import") + 1);
+		importName += ".properties";
+		FilePath importPath(directoryForImports, FilePath(importName.c_str()));
+		if (Read(importPath, directoryForImports, imports, sizeImports)) {
+			if (imports) {
+				for (int i = 0; i < sizeImports; i++) {
+					if (!imports[i].IsSet()) {
+						imports[i] = importPath;
+						break;
+					}
+				}
+			}
+		}
+	} else if (ifIsTrue && !IsCommentLine(lineBuffer)) {
+		Set(lineBuffer);
+	}
+	return ifIsTrue;
+}
+
+void PropSetFile::ReadFromMemory(const char *data, int len, FilePath directoryForImports,
+                                 FilePath imports[], int sizeImports) {
+	const char *pd = data;
+	char lineBuffer[60000];
+	bool ifIsTrue = true;
+	while (len > 0) {
+		GetFullLine(pd, len, lineBuffer, sizeof(lineBuffer));
+		if (lowerKeys) {
+			for (int i=0; lineBuffer[i] && (lineBuffer[i] != '='); i++) {
+				if ((lineBuffer[i] >= 'A') && (lineBuffer[i] <= 'Z')) {
+					lineBuffer[i] = static_cast<char>(lineBuffer[i] - 'A' + 'a');
+				}
+			}
+		}
+		ifIsTrue = ReadLine(lineBuffer, ifIsTrue, directoryForImports, imports, sizeImports);
+	}
+}
+
+bool PropSetFile::Read(FilePath filename, FilePath directoryForImports,
+                       FilePath imports[], int sizeImports) {
+	FILE *rcfile = filename.Open(fileRead);
+	if (rcfile) {
+		unsigned int lenFile;
+		char *propsData;
+
+		fseek (rcfile, 0, SEEK_END);
+		lenFile = ftell (rcfile);
+		fseek (rcfile, 0, SEEK_SET);
+		propsData = new char[lenFile];
+		lenFile = fread(propsData, 1, lenFile, rcfile);
+		fclose(rcfile);
+		const char *data = propsData;
+		if (memcmp(data, "\xef\xbb\xbf", 3) == 0) {
+			data += 3;
+			lenFile -= 3;
+		}
+		ReadFromMemory(data, lenFile, directoryForImports, imports, sizeImports);
+		return true;
+	}
+	return false;
+}
+
+void PropSetFile::SetInteger(const char *key, int i) {
+	char tmp[32];
+	sprintf(tmp, "%d", static_cast<int>(i));
+	Set(key, tmp);
+}
+
+static bool StringEqual(const char *a, const char *b, size_t len, bool caseSensitive) {
+	if (caseSensitive) {
+		for (size_t i = 0; i < len; i++) {
+			if (a[i] != b[i])
+				return false;
+		}
+	} else {
+		for (size_t i = 0; i < len; i++) {
+			if (MakeUpperCase(a[i]) != MakeUpperCase(b[i]))
+				return false;
+		}
+	}
+	return true;
+}
+
+// Match file names to patterns allowing for a '*' suffix or prefix.
+static bool MatchWild(const char *pattern, size_t lenPattern, const char *fileName, bool caseSensitive) {
+	size_t lenFileName = strlen(fileName);
+	if (lenFileName == lenPattern) {
+		if (StringEqual(pattern, fileName, lenFileName, caseSensitive)) {
+			return true;
+		}
+	}
+	if (lenFileName >= lenPattern-1) {
+		if (pattern[0] == '*') {
+			// Matching suffixes
+			return StringEqual(pattern+1, fileName + lenFileName - (lenPattern-1), lenPattern-1, caseSensitive);
+		} else if (pattern[lenPattern-1] == '*') {
+			// Matching prefixes
+			return StringEqual(pattern, fileName, lenPattern-1, caseSensitive);
+		}
+	}
+	return false;
+}
+
+static bool startswith(const std::string &s, const char *keybase) {
+	return isPrefix(s.c_str(), keybase);
+}
+
+SString PropSetFile::GetWildUsingStart(const PropSetFile &psStart, const char *keybase, const char *filename) {
+	mapss::iterator it = props.lower_bound(std::string(keybase));
+	while ((it != props.end()) && startswith(it->first, keybase)) {
+		const char *orgkeyfile = it->first.c_str() + strlen(keybase);
+		char *keyptr = NULL;
+
+		if (strncmp(orgkeyfile, "$(", 2) == 0) {
+			const char *cpendvar = strchr(orgkeyfile, ')');
+			if (cpendvar) {
+				SString var(orgkeyfile, 2, cpendvar-orgkeyfile);
+				SString s = psStart.GetExpanded(var.c_str());
+				keyptr = StringDup(s.c_str());
+			}
+		}
+		const char *keyfile = keyptr;
+
+		if (keyfile == NULL)
+			keyfile = orgkeyfile;
+
+		for (;;) {
+			const char *del = strchr(keyfile, ';');
+			if (del == NULL)
+				del = keyfile + strlen(keyfile);
+			if (MatchWild(keyfile, del - keyfile, filename, caseSensitiveFilenames)) {
+				delete []keyptr;
+				return SString(it->second.c_str());
+			}
+			if (*del == '\0')
+				break;
+			keyfile = del + 1;
+		}
+		delete []keyptr;
+
+		if (0 == strcmp(it->first.c_str(), keybase)) {
+			return SString(it->second.c_str());
+		}
+		it++;
+	}
+	if (superPS) {
+		// Failed here, so try in super property set
+		return static_cast<PropSetFile *>(superPS)->GetWildUsingStart(psStart, keybase, filename);
+	} else {
+		return "";
+	}
+}
+
+SString PropSetFile::GetWild(const char *keybase, const char *filename) {
+	return GetWildUsingStart(*this, keybase, filename);
+}
+
+// GetNewExpand does not use Expand as it has to use GetWild with the filename for each
+// variable reference found.
+SString PropSetFile::GetNewExpand(const char *keybase, const char *filename) {
+	char *base = StringDup(GetWild(keybase, filename).c_str());
+	char *cpvar = strstr(base, "$(");
+	int maxExpands = 1000;	// Avoid infinite expansion of recursive definitions
+	while (cpvar && (maxExpands > 0)) {
+		const char *cpendvar = strchr(cpvar, ')');
+		if (cpendvar) {
+			int lenvar = cpendvar - cpvar - 2;  	// Subtract the $()
+			char *var = StringDup(cpvar + 2, lenvar);
+			SString val = GetWild(var, filename);
+			if (0 == strcmp(var, keybase))
+				val.clear(); // Self-references evaluate to empty string
+			size_t newlenbase = strlen(base) + val.length() - lenvar;
+			char *newbase = new char[newlenbase];
+			strncpy(newbase, base, cpvar - base);
+			strcpy(newbase + (cpvar - base), val.c_str());
+			strcpy(newbase + (cpvar - base) + val.length(), cpendvar + 1);
+			delete []var;
+			delete []base;
+			base = newbase;
+		}
+		cpvar = strstr(base, "$(");
+		maxExpands--;
+	}
+	SString sret = base;
+	delete []base;
+	return sret;
+}
+
+/**
+ * Initiate enumeration.
+ */
+bool PropSetFile::GetFirst(const char *&key, const char *&val) {
+	mapss::iterator it = props.begin();
+	if (it != props.end()) {
+		key = it->first.c_str();
+		val = it->second.c_str();
+		it++;
+		if (it != props.end()) {
+			enumnext = it->first; // GetNext will begin here ...
+		} else {
+			enumnext = "";
+		}
+		return true;
+	} else {
+		return false;
+	}
+}
+
+/**
+ * Continue enumeration.
+ */
+bool PropSetFile::GetNext(const char *&key, const char *&val) {
+	mapss::iterator it = props.find(enumnext);
+	if (it != props.end()) {
+		key = it->first.c_str();
+		val = it->second.c_str();
+		it++;
+		if (it != props.end()) {
+			enumnext = it->first; // GetNext will begin here ...
+		} else {
+			enumnext = "";
+		}
+		return true;
+	} else {
+		return false;
+	}
+}
+
+static inline bool IsLetter(char ch) {
+	return ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'));
+}
+
+int CompareNoCase(const char *a, const char *b) {
+	while (*a && *b) {
+		if (*a != *b) {
+			char upperA = MakeUpperCase(*a);
+			char upperB = MakeUpperCase(*b);
+			if (upperA != upperB)
+				return upperA - upperB;
+		}
+		a++;
+		b++;
+	}
+	// Either *a or *b is nul
+	return *a - *b;
+}
+
+bool EqualCaseInsensitive(const char *a, const char *b) {
+	return 0 == CompareNoCase(a, b);
+}
+
+// Since the CaseInsensitive functions declared in SString
+// are implemented here, I will for now put the non-inline
+// implementations of the SString members here as well, so
+// that I can quickly see what effect this has.
+
+SString::SString(int i) : sizeGrowth(sizeGrowthDefault) {
+	char number[32];
+	sprintf(number, "%0d", i);
+	s = StringAllocate(number);
+	sSize = sLen = (s) ? strlen(s) : 0;
+}
+
+SString::SString(double d, int precision) : sizeGrowth(sizeGrowthDefault) {
+	char number[32];
+	sprintf(number, "%.*f", precision, d);
+	s = StringAllocate(number);
+	sSize = sLen = (s) ? strlen(s) : 0;
+}
+
+bool SString::grow(lenpos_t lenNew) {
+	while (sizeGrowth * 6 < lenNew) {
+		sizeGrowth *= 2;
+	}
+	char *sNew = new char[lenNew + sizeGrowth + 1];
+	if (sNew) {
+		if (s) {
+			memcpy(sNew, s, sLen);
+			delete []s;
+		}
+		s = sNew;
+		s[sLen] = '\0';
+		sSize = lenNew + sizeGrowth;
+	}
+	return sNew != 0;
+}
+
+SString &SString::assign(const char *sOther, lenpos_t sSize_) {
+	if (!sOther) {
+		sSize_ = 0;
+	} else if (sSize_ == measure_length) {
+		sSize_ = strlen(sOther);
+	}
+	if (sSize > 0 && sSize_ <= sSize) {	// Does not allocate new buffer if the current is big enough
+		if (s && sSize_) {
+			memcpy(s, sOther, sSize_);
+		}
+		s[sSize_] = '\0';
+		sLen = sSize_;
+	} else {
+		delete []s;
+		s = StringAllocate(sOther, sSize_);
+		if (s) {
+			sSize = sSize_;	// Allow buffer bigger than real string, thus providing space to grow
+			sLen = sSize_;
+		} else {
+			sSize = sLen = 0;
+		}
+	}
+	return *this;
+}
+
+bool SString::operator==(const SString &sOther) const {
+	if ((s == 0) && (sOther.s == 0))
+		return true;
+	if ((s == 0) || (sOther.s == 0))
+		return false;
+	return strcmp(s, sOther.s) == 0;
+}
+
+bool SString::operator==(const char *sOther) const {
+	if ((s == 0) && (sOther == 0))
+		return true;
+	if ((s == 0) || (sOther == 0))
+		return false;
+	return strcmp(s, sOther) == 0;
+}
+
+SString SString::substr(lenpos_t subPos, lenpos_t subLen) const {
+	if (subPos >= sLen) {
+		return SString();					// return a null string if start index is out of bounds
+	}
+	if ((subLen == measure_length) || (subPos + subLen > sLen)) {
+		subLen = sLen - subPos;		// can't substr past end of source string
+	}
+	return SString(s, subPos, subPos + subLen);
+}
+
+SString &SString::lowercase(lenpos_t subPos, lenpos_t subLen) {
+	if ((subLen == measure_length) || (subPos + subLen > sLen)) {
+		subLen = sLen - subPos;		// don't apply past end of string
+	}
+	for (lenpos_t i = subPos; i < subPos + subLen; i++) {
+		if (s[i] < 'A' || s[i] > 'Z')
+			continue;
+		else
+			s[i] = static_cast<char>(s[i] - 'A' + 'a');
+	}
+	return *this;
+}
+
+SString &SString::uppercase(lenpos_t subPos, lenpos_t subLen) {
+	if ((subLen == measure_length) || (subPos + subLen > sLen)) {
+		subLen = sLen - subPos;		// don't apply past end of string
+	}
+	for (lenpos_t i = subPos; i < subPos + subLen; i++) {
+		if (s[i] < 'a' || s[i] > 'z')
+			continue;
+		else
+			s[i] = static_cast<char>(s[i] - 'a' + 'A');
+	}
+	return *this;
+}
+
+SString &SString::append(const char *sOther, lenpos_t sLenOther, char sep) {
+	if (!sOther) {
+		return *this;
+	}
+	if (sLenOther == measure_length) {
+		sLenOther = strlen(sOther);
+	}
+	int lenSep = 0;
+	if (sLen && sep) {	// Only add a separator if not empty
+		lenSep = 1;
+	}
+	lenpos_t lenNew = sLen + sLenOther + lenSep;
+	// Conservative about growing the buffer: don't do it, unless really needed
+	if ((lenNew < sSize) || (grow(lenNew))) {
+		if (lenSep) {
+			s[sLen] = sep;
+			sLen++;
+		}
+		memcpy(&s[sLen], sOther, sLenOther);
+		sLen += sLenOther;
+		s[sLen] = '\0';
+	}
+	return *this;
+}
+
+SString &SString::insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther) {
+	if (!sOther || pos > sLen) {
+		return *this;
+	}
+	if (sLenOther == measure_length) {
+		sLenOther = strlen(sOther);
+	}
+	lenpos_t lenNew = sLen + sLenOther;
+	// Conservative about growing the buffer: don't do it, unless really needed
+	if ((lenNew < sSize) || grow(lenNew)) {
+		lenpos_t moveChars = sLen - pos + 1;
+		for (lenpos_t i = moveChars; i > 0; i--) {
+			s[pos + sLenOther + i - 1] = s[pos + i - 1];
+		}
+		memcpy(s + pos, sOther, sLenOther);
+		sLen = lenNew;
+	}
+	return *this;
+}
+
+/**
+ * Remove @a len characters from the @a pos position, included.
+ * Characters at pos + len and beyond replace characters at pos.
+ * If @a len is 0, or greater than the length of the string
+ * starting at @a pos, the string is just truncated at @a pos.
+ */
+void SString::remove(lenpos_t pos, lenpos_t len) {
+	if (pos >= sLen) {
+		return;
+	}
+	if (len < 1 || pos + len >= sLen) {
+		s[pos] = '\0';
+		sLen = pos;
+	} else {
+		for (lenpos_t i = pos; i < sLen - len + 1; i++) {
+			s[i] = s[i+len];
+		}
+		sLen -= len;
+	}
+}
+
+bool SString::startswith(const char *prefix) {
+	lenpos_t lenPrefix = strlen(prefix);
+	if (lenPrefix > sLen) {
+		return false;
+	}
+	return strncmp(s, prefix, lenPrefix) == 0;
+}
+
+bool SString::endswith(const char *suffix) {
+	lenpos_t lenSuffix = strlen(suffix);
+	if (lenSuffix > sLen) {
+		return false;
+	}
+	return strncmp(s + sLen - lenSuffix, suffix, lenSuffix) == 0;
+}
+
+int SString::search(const char *sFind, lenpos_t start) const {
+	if (start < sLen) {
+		const char *sFound = strstr(s + start, sFind);
+		if (sFound) {
+			return sFound - s;
+		}
+	}
+	return -1;
+}
+
+int SString::substitute(char chFind, char chReplace) {
+	int c = 0;
+	char *t = s;
+	while (t) {
+		t = strchr(t, chFind);
+		if (t) {
+			*t = chReplace;
+			t++;
+			c++;
+		}
+	}
+	return c;
+}
+
+int SString::substitute(const char *sFind, const char *sReplace) {
+	int c = 0;
+	lenpos_t lenFind = strlen(sFind);
+	lenpos_t lenReplace = strlen(sReplace);
+	int posFound = search(sFind);
+	while (posFound >= 0) {
+		remove(posFound, lenFind);
+		insert(posFound, sReplace, lenReplace);
+		posFound = search(sFind, posFound + lenReplace);
+		c++;
+	}
+	return c;
+}
+
+char *SContainer::StringAllocate(lenpos_t len) {
+	if (len != measure_length) {
+		return new char[len + 1];
+	} else {
+		return 0;
+	}
+}
+
+char *SContainer::StringAllocate(const char *s, lenpos_t len) {
+	if (s == 0) {
+		return 0;
+	}
+	if (len == measure_length) {
+		len = strlen(s);
+	}
+	char *sNew = new char[len + 1];
+	if (sNew) {
+		memcpy(sNew, s, len);
+		sNew[len] = '\0';
+	}
+	return sNew;
+}
+
+// End SString functions
+
+bool isprefix(const char *target, const char *prefix) {
+	while (*target && *prefix) {
+		if (*target != *prefix)
+			return false;
+		target++;
+		prefix++;
+	}
+	if (*prefix)
+		return false;
+	else
+		return true;
+}
diff --git a/plugins/scintilla/PropSetFile.h b/plugins/scintilla/PropSetFile.h
new file mode 100644
index 0000000..c0cdb05
--- /dev/null
+++ b/plugins/scintilla/PropSetFile.h
@@ -0,0 +1,58 @@
+// SciTE - Scintilla based Text Editor
+/** @file PropSetFile.h
+ ** Definition of platform independent base class of editor.
+ **/
+// Copyright 1998-2009 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+/**
+ */
+
+#include <string>
+#include <map>
+
+#include "PropSet.h"
+
+#include "SString.h"
+#include "FilePath.h"
+
+typedef std::map<std::string, std::string> mapss;
+
+class PropSetFile : public PropertyGet {
+	bool lowerKeys;
+	SString GetWildUsingStart(const PropSetFile &psStart, const char *keybase, const char *filename);
+	static bool caseSensitiveFilenames;
+	mapss props;
+	std::string enumnext;
+public:
+	PropSetFile *superPS;
+	PropSetFile(bool lowerKeys_=false);
+	virtual ~PropSetFile();
+	void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1);
+	void Set(const char *keyVal);
+	void Unset(const char *key, int lenKey=-1);
+	void SetMultiple(const char *s);
+	SString Get(const char *key) const;
+	SString GetExpanded(const char *key) const;
+	SString Expand(const char *withVars, int maxExpands=100) const;
+	int GetInt(const char *key, int defaultValue=0) const;
+	void Clear();
+	char *ToString() const;	// Caller must delete[] the return value
+
+	bool ReadLine(const char *data, bool ifIsTrue, FilePath directoryForImports, FilePath imports[] = 0, int sizeImports = 0);
+	void ReadFromMemory(const char *data, int len, FilePath directoryForImports, FilePath imports[] = 0, int sizeImports = 0);
+	bool Read(FilePath filename, FilePath directoryForImports, FilePath imports[] = 0, int sizeImports = 0);
+	void SetInteger(const char *key, int i);
+	SString GetWild(const char *keybase, const char *filename);
+	SString GetNewExpand(const char *keybase, const char *filename="");
+	bool GetFirst(const char *&key, const char *&val);
+	bool GetNext(const char *&key, const char *&val);
+	static void SetCaseSensitiveFilenames(bool caseSensitiveFilenames_) {
+		caseSensitiveFilenames = caseSensitiveFilenames_;
+	}
+
+private:
+	// copy-value semantics not implemented
+	PropSetFile(const PropSetFile &copy);
+	void operator=(const PropSetFile &assign);
+};
diff --git a/plugins/scintilla/SString.h b/plugins/scintilla/SString.h
new file mode 100644
index 0000000..4748cd0
--- /dev/null
+++ b/plugins/scintilla/SString.h
@@ -0,0 +1,303 @@
+// SciTE - Scintilla based Text Editor
+/** @file SString.h
+ ** A simple string class.
+ **/
+// Copyright 1998-2004 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef SSTRING_H
+#define SSTRING_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// Define another string class.
+// While it would be 'better' to use std::string, that doubles the executable size.
+// An SString may contain embedded nul characters.
+
+/**
+ * Base class from which the two other classes (SBuffer & SString)
+ * are derived.
+ */
+class SContainer {
+public:
+	/** Type of string lengths (sizes) and positions (indexes). */
+	typedef size_t lenpos_t;
+	/** Out of bounds value indicating that the string argument should be measured. */
+	enum { measure_length=0xffffffffU};
+
+protected:
+	char *s;				///< The C string
+	lenpos_t sSize;			///< The size of the buffer, less 1: ie. the maximum size of the string
+
+	SContainer() : s(0), sSize(0) {}
+	~SContainer() {
+		delete []s;	// Suppose it was allocated using StringAllocate
+		s = 0;
+		sSize = 0;
+	}
+	/** Size of buffer. */
+	lenpos_t size() const {
+		if (s) {
+			return sSize;
+		} else {
+			return 0;
+		}
+	}
+public:
+	/**
+	 * Allocate uninitialized memory big enough to fit a string of the given length.
+	 * @return the pointer to the new string
+	 */
+	static char *StringAllocate(lenpos_t len);
+	/**
+	 * Duplicate a buffer/C string.
+	 * Allocate memory of the given size, or big enough to fit the string if length isn't given;
+	 * then copy the given string in the allocated memory.
+	 * @return the pointer to the new string
+	 */
+	static char *StringAllocate(
+		const char *s,			///< The string to duplicate
+		lenpos_t len=measure_length);	///< The length of memory to allocate. Optional.
+};
+
+
+/**
+ * @brief A string buffer class.
+ *
+ * Main use is to ask an API the length of a string it can provide,
+ * then to allocate a buffer of the given size, and to provide this buffer
+ * to the API to put the string.
+ * This class is intended to be shortlived, to be transformed as SString
+ * as soon as it holds the string, so it has little members.
+ * Note: we assume the buffer is filled by the API. If the length can be shorter,
+ * we should set sLen to strlen(sb.ptr()) in related SString constructor and assignment.
+ */
+class SBuffer : protected SContainer {
+public:
+	SBuffer(lenpos_t len) {
+		s = StringAllocate(len);
+		if (s) {
+			*s = '\0';
+		sSize = len;
+		} else {
+			sSize = 0;
+		}
+	}
+private:
+	/// Copy constructor
+	// Here only to be on the safe size, user should avoid returning SBuffer values.
+	SBuffer(const SBuffer &source) : SContainer() {
+		s = StringAllocate(source.s, source.sSize);
+		sSize = (s) ? source.sSize : 0;
+	}
+	/// Default assignment operator
+	// Same here, shouldn't be used
+	SBuffer &operator=(const SBuffer &source) {
+		if (this != &source) {
+			delete []s;
+			s = StringAllocate(source.s, source.sSize);
+			sSize = (s) ? source.sSize : 0;
+		}
+		return *this;
+	}
+public:
+	/** Provide direct read/write access to buffer. */
+	char *ptr() {
+	    return s;
+	}
+	/** Ownership of the buffer have been taken, so release it. */
+	void reset() {
+		s = 0;
+		sSize = 0;
+	}
+	/** Size of buffer. */
+	lenpos_t size() const {
+		return SContainer::size();
+	}
+};
+
+
+/**
+ * @brief A simple string class.
+ *
+ * Hold the length of the string for quick operations,
+ * can have a buffer bigger than the string to avoid too many memory allocations and copies.
+ * May have embedded zeroes as a result of @a substitute, but relies too heavily on C string
+ * functions to allow reliable manipulations of these strings, other than simple appends, etc.
+ */
+class SString : public SContainer {
+	lenpos_t sLen;			///< The size of the string in s
+	lenpos_t sizeGrowth;	///< Minimum growth size when appending strings
+	enum { sizeGrowthDefault = 64 };
+
+	bool grow(lenpos_t lenNew);
+	SString &assign(const char *sOther, lenpos_t sSize_=measure_length);
+
+public:
+	SString() : sLen(0), sizeGrowth(sizeGrowthDefault) {}
+	SString(const SString &source) : SContainer(), sizeGrowth(sizeGrowthDefault) {
+		s = StringAllocate(source.s, source.sLen);
+		sSize = sLen = (s) ? source.sLen : 0;
+	}
+	SString(const char *s_) : sizeGrowth(sizeGrowthDefault) {
+		s = StringAllocate(s_);
+		sSize = sLen = (s) ? strlen(s) : 0;
+	}
+	SString(SBuffer &buf) : sizeGrowth(sizeGrowthDefault) {
+		s = buf.ptr();
+		sSize = sLen = buf.size();
+		// Consumes the given buffer!
+		buf.reset();
+	}
+	SString(const char *s_, lenpos_t first, lenpos_t last) : sizeGrowth(sizeGrowthDefault) {
+		// note: expects the "last" argument to point one beyond the range end (a la STL iterators)
+		s = StringAllocate(s_ + first, last - first);
+		sSize = sLen = (s) ? last - first : 0;
+	}
+	SString(int i);
+	SString(double d, int precision);
+	~SString() {
+		sLen = 0;
+	}
+	void clear() {
+		if (s) {
+			*s = '\0';
+		}
+		sLen = 0;
+	}
+	/** Size of buffer. */
+	lenpos_t size() const {
+		return SContainer::size();
+	}
+	/** Size of string in buffer. */
+	lenpos_t length() const {
+		return sLen;
+	}
+	/** Read access to a character of the string. */
+	char operator[](lenpos_t i) const {
+		return (s && i < sSize) ? s[i] : '\0';
+	}
+	SString &operator=(const char *source) {
+		return assign(source);
+	}
+	SString &operator=(const SString &source) {
+		if (this != &source) {
+			assign(source.s, source.sLen);
+		}
+		return *this;
+	}
+	bool operator==(const SString &sOther) const;
+	bool operator!=(const SString &sOther) const {
+		return !operator==(sOther);
+	}
+	bool operator==(const char *sOther) const;
+	bool operator!=(const char *sOther) const {
+		return !operator==(sOther);
+	}
+	bool contains(char ch) const {
+		return (s && *s) ? strchr(s, ch) != 0 : false;
+	}
+	void setsizegrowth(lenpos_t sizeGrowth_) {
+		sizeGrowth = sizeGrowth_;
+	}
+	const char *c_str() const {
+		return s ? s : "";
+	}
+
+	/** Attach to a string allocated by means of StringAlloc(len). */
+	SString &attach(char *s_, lenpos_t sLen_ = measure_length, lenpos_t sSize_ = measure_length) {
+		delete []s;
+		s = s_;
+		if (!s) {
+			sLen = sSize = 0;
+		}
+		else
+		{
+			sLen = (sLen_ == measure_length ? strlen(s) : sLen_);
+			sSize = (sSize_ == measure_length ? sLen + 1 : sSize_);
+		}
+		return *this;
+	}
+
+	/** Give ownership of buffer to caller which must use delete[] to free buffer. */
+	char *detach() {
+		char *sRet = s;
+		s = 0;
+		sSize = 0;
+		sLen = 0;
+		return sRet;
+	}
+	SString substr(lenpos_t subPos, lenpos_t subLen=measure_length) const;
+	SString &lowercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
+	SString &uppercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
+	SString &append(const char *sOther, lenpos_t sLenOther=measure_length, char sep = '\0');
+	SString &operator+=(const char *sOther) {
+		return append(sOther, static_cast<lenpos_t>(measure_length));
+	}
+	SString &operator+=(const SString &sOther) {
+		return append(sOther.s, sOther.sLen);
+	}
+	SString &operator+=(char ch) {
+		return append(&ch, 1);
+	}
+	SString &appendwithseparator(const char *sOther, char sep) {
+		return append(sOther, strlen(sOther), sep);
+	}
+	SString &insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther=measure_length);
+
+	/**
+	 * Remove @a len characters from the @a pos position, included.
+	 * Characters at pos + len and beyond replace characters at pos.
+	 * If @a len is 0, or greater than the length of the string
+	 * starting at @a pos, the string is just truncated at @a pos.
+	 */
+	void remove(lenpos_t pos, lenpos_t len);
+
+	SString &change(lenpos_t pos, char ch) {
+		if (pos < sLen) {					// character changed must be in string bounds
+			*(s + pos) = ch;
+		}
+		return *this;
+	}
+	/** Read an integral numeric value from the string. */
+	int value() const {
+		return s ? atoi(s) : 0;
+	}
+	bool startswith(const char *prefix);
+	bool endswith(const char *suffix);
+	int search(const char *sFind, lenpos_t start=0) const;
+	bool contains(const char *sFind) const {
+		return search(sFind) >= 0;
+	}
+	int substitute(char chFind, char chReplace);
+	int substitute(const char *sFind, const char *sReplace);
+	int remove(const char *sFind) {
+		return substitute(sFind, "");
+	}
+};
+
+
+/**
+ * Duplicate a C string.
+ * Allocate memory of the given size, or big enough to fit the string if length isn't given;
+ * then copy the given string in the allocated memory.
+ * @return the pointer to the new string
+ */
+inline char *StringDup(
+	const char *s,			///< The string to duplicate
+	SContainer::lenpos_t len=SContainer::measure_length)	///< The length of memory to allocate. Optional.
+{
+	return SContainer::StringAllocate(s, len);
+}
+
+bool isprefix(const char *target, const char *prefix);
+int CompareNoCase(const char *a, const char *b);
+bool EqualCaseInsensitive(const char *a, const char *b);
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/aneditor-priv.h b/plugins/scintilla/aneditor-priv.h
index 7cf6408..6867b0a 100644
--- a/plugins/scintilla/aneditor-priv.h
+++ b/plugins/scintilla/aneditor-priv.h
@@ -46,8 +46,8 @@
 #include "Scintilla.h"
 #include "ScintillaWidget.h"
 #include "SciLexer.h"
+#include "PropSetFile.h"
 #include "lexer.h"
-#include "properties_cxx.h"
 #include "properties.h"
 #include "aneditor.h"
 
@@ -80,7 +80,6 @@ using namespace std;
 // #define DEBUG
 
 #define ANE_MARKER_BOOKMARK 0
-#define MAX_PATH 260
 #define MAXIMUM(x, y)	((x>y)?x:y)
 #define MINIMUM(x,y)	((x<y)?x:y)
 
diff --git a/plugins/scintilla/aneditor.cxx b/plugins/scintilla/aneditor.cxx
index 10ce61c..cb6c84a 100644
--- a/plugins/scintilla/aneditor.cxx
+++ b/plugins/scintilla/aneditor.cxx
@@ -1399,8 +1399,7 @@ bool AnEditor::HandleXml(char ch) {
 	}
 
 	// This may make sense only in certain languages
-	if (lexLanguage != SCLEX_HTML && lexLanguage != SCLEX_XML &&
-	        lexLanguage != SCLEX_ASP && lexLanguage != SCLEX_PHP) {
+	if (lexLanguage != SCLEX_HTML && lexLanguage != SCLEX_XML) {
 		return false;
 	}
 
@@ -2366,7 +2365,7 @@ static Colour ColourFromString(const char *val) {
 	return Colour(r, g, b);
 }
 
-static long ColourOfProperty(PropSet *props, const char *key, ColourDesired colourDefault) {
+static long ColourOfProperty(PropSetFile *props, const char *key, ColourDesired colourDefault) {
 	SString colour = props->Get(key);
 	if (colour.length()) {
 		return ColourFromString(colour.c_str()).AsLong();
@@ -2519,13 +2518,23 @@ void AnEditor::ReadProperties(const char *fileForExt, char **typedef_hl) {
 	/* For C/C++ projects, get list of typedefs for colorizing */
 	if (SCLEX_CPP == lexLanguage)
 	{
+		SString kw1 = props->GetNewExpand("keywords2.", fileNameForExtension.c_str());
+		SString kw3 = props->GetNewExpand("keywords4.", fileNameForExtension.c_str());
 		if (typedef_hl != NULL)
 		{
 			if (typedef_hl[0] != NULL)
-				SendEditorString(SCI_SETKEYWORDS, 3, typedef_hl[0]);
+			{
+				kw3 += ' ';
+				kw3 += typedef_hl[0];
+			}
 			if (typedef_hl[1] != NULL)
-				SendEditorString(SCI_SETKEYWORDS, 1, typedef_hl[1]);
+			{
+				kw1 +=  ' ';
+				kw1 += typedef_hl[1];
+			}
 		}
+		SendEditorString(SCI_SETKEYWORDS, 3, kw3.c_str());
+		SendEditorString(SCI_SETKEYWORDS, 1, kw1.c_str());
 	}
 	else
 	{
diff --git a/plugins/scintilla/properties.cxx b/plugins/scintilla/properties.cxx
index 74097f0..f9456f0 100644
--- a/plugins/scintilla/properties.cxx
+++ b/plugins/scintilla/properties.cxx
@@ -11,294 +11,9 @@
 #undef PLAT_GTK
 #define PLAT_GTK 1
 
-#include "PropSet.h"
-#include "properties_cxx.h"
+#include "PropSetFile.h"
 #include "properties.h"
 
-bool PropSetFile::caseSensitiveFilenames = false;
-
-PropSetFile::PropSetFile(bool lowerKeys_) : lowerKeys(lowerKeys_) {}
-
-PropSetFile::~PropSetFile() {}
-
-/**
- * Get a line of input. If end of line escaped with '\\' then continue reading.
- */
-static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) {
-	bool continuation = true;
-	s[0] = '\0';
-	while ((len > 1) && lenData > 0) {
-		char ch = *fpc;
-		fpc++;
-		lenData--;
-		if ((ch == '\r') || (ch == '\n')) {
-			if (!continuation) {
-				if ((lenData > 0) && (ch == '\r') && ((*fpc) == '\n')) {
-					// munch the second half of a crlf
-					fpc++;
-					lenData--;
-				}
-				*s = '\0';
-				return true;
-			}
-		} else if ((ch == '\\') && (lenData > 0) && ((*fpc == '\r') || (*fpc == '\n'))) {
-			continuation = true;
-			if ((lenData > 1) && ((*fpc == '\r') && (*(fpc+1) == '\r') || (*fpc == '\n') && (*(fpc+1) == '\n')))
-				continuation = false;
-			else if ((lenData > 2) && ((*fpc == '\r') && (*(fpc+1) == '\n') && (*(fpc+2) == '\n' || *(fpc+2) == '\r')))
-				continuation = false;
-		} else {
-			continuation = false;
-			*s++ = ch;
-			*s = '\0';
-			len--;
-		}
-	}
-	return false;
-}
-
-static bool IsSpaceOrTab(char ch) {
-	return (ch == ' ') || (ch == '\t');
-}
-
-static bool IsCommentLine(const char *line) {
-	while (IsSpaceOrTab(*line)) ++line;
-	return (*line == '#');
-}
-
-bool PropSetFile::ReadLine(const char *lineBuffer, bool ifIsTrue, const char *directoryForImports) {
-	if (!IsSpaceOrTab(lineBuffer[0]))    // If clause ends with first non-indented line
-		ifIsTrue = true;
-	if (isprefix(lineBuffer, "if ")) {
-		const char *expr = lineBuffer + strlen("if") + 1;
-		ifIsTrue = GetInt(expr) != 0;
-	} else if (isprefix(lineBuffer, "import ") && directoryForImports) {
-		char importPath[1024];
-		strcpy(importPath, directoryForImports);
-		strcat(importPath, lineBuffer + strlen("import") + 1);
-		strcat(importPath, ".properties");
-		Read(importPath, directoryForImports);
-	} else if (ifIsTrue && !IsCommentLine(lineBuffer)) {
-		Set(lineBuffer);
-	}
-	return ifIsTrue;
-}
-
-void PropSetFile::ReadFromMemory(const char *data, int len, const char *directoryForImports) {
-	const char *pd = data;
-	char lineBuffer[60000];
-	bool ifIsTrue = true;
-	while (len > 0) {
-		GetFullLine(pd, len, lineBuffer, sizeof(lineBuffer));
-		if (lowerKeys) {
-			for (int i=0; lineBuffer[i] && (lineBuffer[i] != '='); i++) {
-				if ((lineBuffer[i] >= 'A') && (lineBuffer[i] <= 'Z')) {
-					lineBuffer[i] = static_cast<char>(lineBuffer[i] - 'A' + 'a');
-				}
-			}
-		}
-		ifIsTrue = ReadLine(lineBuffer, ifIsTrue, directoryForImports);
-	}
-}
-
-bool PropSetFile::Read(const char *filename, const char *directoryForImports) {
-#ifdef __vms
-	FILE *rcfile = fopen(filename, "r");
-#else
-	FILE *rcfile = fopen(filename, "rb");
-#endif
-	if (rcfile) {
-		unsigned int lenFile;
-		char *propsData;
-
-		fseek (rcfile, 0, SEEK_END);
-		lenFile = ftell (rcfile);
-		fseek (rcfile, 0, SEEK_SET);
-		propsData = new char[lenFile];
-		lenFile = fread(propsData, 1, lenFile, rcfile);
-		fclose(rcfile);
-		ReadFromMemory(propsData, lenFile, directoryForImports);
-		delete[] propsData;
-		return true;
-
-	} else {
-		//printf("Could not open <%s>\n", filename);
-		return false;
-	}
-}
-
-static inline char MakeUpperCase(char ch) {
-	if (ch < 'a' || ch > 'z')
-		return ch;
-	else
-		return static_cast<char>(ch - 'a' + 'A');
-}
-
-static bool StringEqual(const char *a, const char *b, size_t len, bool caseSensitive) {
-	if (caseSensitive) {
-		for (size_t i = 0; i < len; i++) {
-			if (a[i] != b[i])
-				return false;
-		}
-	} else {
-		for (size_t i = 0; i < len; i++) {
-			if (MakeUpperCase(a[i]) != MakeUpperCase(b[i]))
-				return false;
-		}
-	}
-	return true;
-}
-
-// Match file names to patterns allowing for a '*' suffix or prefix.
-static bool MatchWild(const char *pattern, size_t lenPattern, const char *fileName, bool caseSensitive) {
-	size_t lenFileName = strlen(fileName);
-	if (lenFileName == lenPattern) {
-		if (StringEqual(pattern, fileName, lenFileName, caseSensitive)) {
-			return true;
-		}
-	}
-	if (lenFileName >= lenPattern-1) {
-		if (pattern[0] == '*') {
-			// Matching suffixes
-			return StringEqual(pattern+1, fileName + lenFileName - (lenPattern-1), lenPattern-1, caseSensitive);
-		} else if (pattern[lenPattern-1] == '*') {
-			// Matching prefixes
-			return StringEqual(pattern, fileName, lenPattern-1, caseSensitive);
-		}
-	}
-	return false;
-}
-
-SString PropSetFile::GetWildUsingStart(const PropSet &psStart, const char *keybase, const char *filename) {
-
-	for (int root = 0; root < hashRoots; root++) {
-		for (Property *p = props[root]; p; p = p->next) {
-			if (isprefix(p->key, keybase)) {
-				char *orgkeyfile = p->key + strlen(keybase);
-				char *keyfile = NULL;
-
-				if (strncmp(orgkeyfile, "$(", 2) == 0) {
-					const char *cpendvar = strchr(orgkeyfile, ')');
-					if (cpendvar) {
-						SString var(orgkeyfile, 2, cpendvar-orgkeyfile);
-						SString s = psStart.GetExpanded(var.c_str());
-						keyfile = StringDup(s.c_str());
-					}
-				}
-				char *keyptr = keyfile;
-
-				if (keyfile == NULL)
-					keyfile = orgkeyfile;
-
-				for (;;) {
-					char *del = strchr(keyfile, ';');
-					if (del == NULL)
-						del = keyfile + strlen(keyfile);
-					if (MatchWild(keyfile, del - keyfile, filename, caseSensitiveFilenames)) {
-						delete []keyptr;
-						return p->val;
-					}
-					if (*del == '\0')
-						break;
-					keyfile = del + 1;
-				}
-				delete []keyptr;
-
-				if (0 == strcmp(p->key, keybase)) {
-					return p->val;
-				}
-			}
-		}
-	}
-	if (superPS) {
-		// Failed here, so try in super property set
-		return static_cast<PropSetFile *>(superPS)->GetWildUsingStart(psStart, keybase, filename);
-	} else {
-		return "";
-	}
-}
-
-SString PropSetFile::GetWild(const char *keybase, const char *filename) {
-	return GetWildUsingStart(*this, keybase, filename);
-}
-
-// GetNewExpand does not use Expand as it has to use GetWild with the filename for each
-// variable reference found.
-SString PropSetFile::GetNewExpand(const char *keybase, const char *filename) {
-	char *base = StringDup(GetWild(keybase, filename).c_str());
-	char *cpvar = strstr(base, "$(");
-	int maxExpands = 1000;	// Avoid infinite expansion of recursive definitions
-	while (cpvar && (maxExpands > 0)) {
-		const char *cpendvar = strchr(cpvar, ')');
-		if (cpendvar) {
-			int lenvar = cpendvar - cpvar - 2;  	// Subtract the $()
-			char *var = StringDup(cpvar + 2, lenvar);
-			SString val = GetWild(var, filename);
-			if (0 == strcmp(var, keybase))
-				val.clear(); // Self-references evaluate to empty string
-			size_t newlenbase = strlen(base) + val.length() - lenvar;
-			char *newbase = new char[newlenbase];
-			strncpy(newbase, base, cpvar - base);
-			strcpy(newbase + (cpvar - base), val.c_str());
-			strcpy(newbase + (cpvar - base) + val.length(), cpendvar + 1);
-			delete []var;
-			delete []base;
-			base = newbase;
-		}
-		cpvar = strstr(base, "$(");
-		maxExpands--;
-	}
-	SString sret = base;
-	delete []base;
-	return sret;
-}
-
-/**
- * Initiate enumeration.
- */
-bool PropSetFile::GetFirst(char **key, char **val) {
-	for (int i = 0; i < hashRoots; i++) {
-		for (Property *p = props[i]; p; p = p->next) {
-			if (p) {
-				*key = p->key;
-				*val = p->val;
-				enumnext = p->next; // GetNext will begin here ...
-				enumhash = i;		  // ... in this block
-				return true;
-			}
-		}
-	}
-	return false;
-}
-
-/**
- * Continue enumeration.
- */
-bool PropSetFile::GetNext(char ** key, char ** val) {
-	bool firstloop = true;
-
-	// search begins where we left it : in enumhash block
-	for (int i = enumhash; i < hashRoots; i++) {
-		if (!firstloop)
-			enumnext = props[i]; // Begin with first property in block
-		// else : begin where we left
-		firstloop = false;
-
-		for (Property *p = enumnext; p; p = p->next) {
-			if (p) {
-				*key = p->key;
-				*val = p->val;
-				enumnext = p->next; // for GetNext
-				enumhash = i;
-				return true;
-			}
-		}
-	}
-	return false;
-}
-
-
-
 // Global property bank for anjuta.
 static GList *anjuta_propset;
 
diff --git a/plugins/scintilla/properties/styles.properties b/plugins/scintilla/properties/styles.properties
index c7cff00..45a31ea 100644
--- a/plugins/scintilla/properties/styles.properties
+++ b/plugins/scintilla/properties/styles.properties
@@ -789,20 +789,38 @@ command.build.subsystem.*.ant=
 
 ###############################################################################
 # From caml.properties
-# Define SciTE settings for Objective Caml
+#	Define SciTE settings for Objective Caml, Standard ML 97 files
+#
+#	To use with Standard ML source in .ml files, select Standard ML
+#	from the SciTE Language menu (or adjust the properties below).
+#
+# To fully enable this Scintilla lexer, make sure the following entries
+#	are present and uncommented in your SciTE properties:
+#
+#		$(filter.caml)\
+#		$(filter.sml)\
+#
+#		Objective Caml|ml||\
+#		Standard ML|sml||\
+#
+#		import caml
 
-# OCaml implementation and interface files
+# OCaml/SML implementation and interface files
 file.patterns.caml=*.ml;*.mli
+file.patterns.sml=*.sml
 
 filter.caml=Objective Caml (ml mli)|$(file.patterns.caml)|
+filter.sml=Standard ML 97 (sml ml)|$(file.patterns.sml)|
 
 lexer.*.caml=caml
 lexer.$(file.patterns.caml)=caml
+lexer.$(file.patterns.sml)=caml
 
 # the line below is ONLY used as part of "external" lexer support
 #lexerpath.$(file.patterns.caml)=LexCaml.dll
+#lexerpath.$(file.patterns.sml)=LexCaml.dll
 
-# the standard Objective Caml 3.09/3.10 language "textual" keywords
+# the standard Objective Caml 3.09/3.10/3.11 language "textual" keywords
 keywordstandard.caml= \
 and as assert asr begin class \
 constraint do done downto else end \
@@ -816,19 +834,43 @@ try type val virtual when while \
 with
 keywords.$(file.patterns.caml)=$(keywordstandard.caml)
 
+# the standard Standard ML '97 language "textual" keywords
+keywordstandard.sml= \
+abstype andalso and as case datatype div do \
+else end eqtype exception \
+false fn fun functor handle if infixr infix include in let local \
+mod nonfix not of open op orelse raise rec \
+sharing signature sig structure struct then true type use \
+val while withtype with
+keywords.$(file.patterns.sml)=$(keywordstandard.sml)
+
 # "optional" Objective Caml / library keywords; some suggested entries are here,
 # more could come from, say, Pervasives ('parser' is from Camlp4)
 keywordoptional1.caml= \
 option Some None ignore ref lnot succ pred parser
 keywords2.$(file.patterns.caml)=$(keywordoptional1.caml)
 
+# "optional" Standard ML '97 / library keywords; some suggested entries are here,
+# more could come from, say, Standard Basis Library
+keywordoptional1.sml= \
+option SOME NONE ignore ref \
+chr explode implode ord size
+keywords2.$(file.patterns.sml)=$(keywordoptional1.sml)
+
 # "optional" Objective Caml / library keywords; some suggested entries are here,
 # more could come from, say, user-defined types
 keywordoptional2.caml= \
 array bool char float int list string unit
 keywords3.$(file.patterns.caml)=$(keywordoptional2.caml)
 
+# "optional" Standard ML '97 / library keywords; some suggested entries are here,
+# more could come from, say, user-defined types
+keywordoptional2.sml= \
+array bool char int list nil real string unit vector word
+keywords3.$(file.patterns.sml)=$(keywordoptional2.sml)
+
 word.characters.$(file.patterns.caml)=$(chars.alpha)$(chars.numeric)_'`
+word.characters.$(file.patterns.sml)=$(chars.alpha)$(chars.numeric)_'
 
 comment.stream.start.caml=(*
 comment.stream.end.caml=*)
@@ -844,6 +886,7 @@ comment.box.end.caml= *)
 # Tag-names
 # Keywords2 (season to taste - use for option, Some, None, etc)
 # Keywords3 (season to taste - use for bool, char, float, etc)
+# Embedded whitespace (SML character/string constant)
 
 # Braces are only matched in operator style
 braces.caml.style=7
@@ -1239,36 +1282,44 @@ command.build.$(file.patterns.conf)=httpd -t -f $(FilePath)
 # sma files are Small script (C-like)
 file.patterns.cpp=*.c;*.cc;*.cpp;*.cxx;*.h;*.hh;*.hpp;*.hxx;*.ipp;*.sma
 file.patterns.cplusplus=*.cc;*.cpp;*.cxx
+# jad = decompiled class files; pde = Processing.org sketch files
+file.patterns.java=*.java;*.jad;*.pde
+file.patterns.javafx=*.fx
 # pln, inc and t are SilkTest (4Test) files.
 file.patterns.test=*.pln;*.inc;*.t
+# es = JS dialect of Abobe for SVG
+file.patterns.js=*.js;*.es
 file.patterns.cs=*.cs
 file.patterns.rc=*.rc;*.rc2;*.dlg
 file.patterns.idl=*.idl;*.odl
 file.patterns.flash=*.as;*.asc;*.jsfl
 file.patterns.ch=*.ch;*.chf;*.chs
-file.patterns.c.like=$(file.patterns.cpp);$(file.patterns.cs);$(file.patterns.idl);*.java;$(file.patterns.flash);$(file.patterns.ch)
+file.patterns.vala=*.vala
+file.patterns.c.like=$(file.patterns.cpp);$(file.patterns.cs);$(file.patterns.idl);$(file.patterns.java);$(file.patterns.js);$(file.patterns.flash);$(file.patterns.ch);$(file.patterns.vala)
 
 shbang.tcc=cpp
 shbang.tinycc=cpp
 
-filter.cpp=C/C++ (c cc cpp cxx cs h hh hxx hpp ipp dlg rc rc2 mak)|\
-$(file.patterns.cpp);$(file.patterns.cs);$(file.patterns.rc);*.mak;make*|
+filter.cpp=C/C++ (c cc cpp cxx cs vala h hh hxx hpp ipp dlg rc rc2 mak)|\
+$(file.patterns.cpp);$(file.patterns.cs);$(file.patterns.rc);$(file.patterns.vala);*.mak;make*|
 filter.java=Java (java)|*.java|
-filter.js=JavaScript (js)|*.js|
+filter.js=JavaScript (js es)|$(file.patterns.js)|
 filter.idl=IDL (idl odl)|$(file.patterns.idl)|
 filter.test=SilkTest (pln inc t)|$(file.patterns.test)|
 filter.flash=Flash (as asc jsfl)|$(file.patterns.flash)|
 filter.ch=Ch (ch chf chs)|$(file.patterns.ch)|
 
-lexer.*.java=cpp
+lexer.$(file.patterns.java)=cpp
+lexer.$(file.patterns.javafx)=cpp
 lexer.$(file.patterns.cpp)=cpp
 lexer.$(file.patterns.rc)=cpp
 lexer.$(file.patterns.idl)=cpp
 lexer.$(file.patterns.cs)=cpp
-lexer.*.js=cpp
+lexer.$(file.patterns.js)=cpp
 lexer.$(file.patterns.test)=cpp
 lexer.$(file.patterns.flash)=cpp
 lexer.$(file.patterns.ch)=cpp
+lexer.$(file.patterns.vala)=cpp
 
 keywordclass.cpp=and and_eq asm auto bitand bitor bool break \
 case catch char class compl const const_cast continue \
@@ -1279,11 +1330,14 @@ register reinterpret_cast return short signed sizeof static static_cast struct s
 template this throw true try typedef typeid typename union unsigned using \
 virtual void volatile wchar_t while xor xor_eq
 keywords.$(file.patterns.cpp)=$(keywordclass.cpp)
+
 # keywords2 is for highlighting user defined keywords or function calls or similar
 #keywords2.$(file.patterns.cpp)=file
+
 # keywords3 is for doc comment keywords, highlighted in style 17
 #CPP doxygen
-keywords3.$(file.patterns.cpp)=a addindex addtogroup anchor arg attention \
+file.patterns.doxygen.langs=$(file.patterns.cpp);$(file.patterns.java)
+keywordclass.doxygen=a addindex addtogroup anchor arg attention \
 author b brief bug c class code date def defgroup deprecated dontinclude \
 e em endcode endhtmlonly endif endlatexonly endlink endverbatim enum example exception \
 f$ f[ f] file fn hideinitializer htmlinclude htmlonly \
@@ -1292,12 +1346,12 @@ mainpage name namespace nosubgrouping note overload \
 p page par param param[in] param[out] \
 post pre ref relates remarks return retval \
 sa section see showinitializer since skip skipline struct subsection \
-test throw todo typedef union until \
+test throw throws todo typedef union until \
 var verbatim verbinclude version warning weakgroup $ @ \ & < > # { }
+keywords3.$(file.patterns.doxygen.langs)=$(keywordclass.doxygen)
 
 word.chars.cxx=$(chars.alpha)$(chars.numeric)_#
 word.characters.$(file.patterns.cpp)=$(word.chars.cxx)
-word.characters.$(file.patterns.cs)=$(word.chars.cxx)
 calltip.cpp.word.characters=$(chars.alpha)$(chars.numeric)_
 comment.block.cpp=//~
 #comment.block.at.line.start.cpp=1
@@ -1308,6 +1362,8 @@ comment.box.middle.cpp= *
 comment.box.end.cpp= */
 #fold.at.else=1
 
+word.characters.$(file.patterns.javafx)=$(word.chars.cxx)$-
+
 file.patterns.c.except.cpp=$(file.patterns.cs);$(file.patterns.idl);*.java;$(file.patterns.flash);$(file.patterns.ch)
 statement.indent.$(file.patterns.c.except.cpp)=5 case default do else for if while
 statement.indent.$(file.patterns.cpp)=5 case default do else for if private protected public while
@@ -1410,13 +1466,29 @@ keywordclass.msidl=handle
 keywordclass.xpidl=attribute native noscript scriptable shared wstring inout
 keywords.$(file.patterns.idl)=$(keywordclass.idl) $(keywordclass.xpidl)
 
+# http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
 keywordclass.java=abstract assert boolean break byte case catch char class \
-const continue default do double else extends final finally float for future \
-generic goto if implements import inner instanceof int interface long \
-native new null outer package private protected public rest \
-return short static super switch synchronized this throw throws \
+const continue default do double else enum extends final finally float for \
+goto if implements import instanceof int interface long \
+native new package private protected public \
+return short static strictfp super switch synchronized this throw throws \
 transient try var void volatile while
-keywords.*.java=$(keywordclass.java)
+keywords.$(file.patterns.java)=$(keywordclass.java)
+
+keywordclass.javafx=abstract after and as assert at attribute before bind bound break \
+catch class continue def delete else exclusive extends false finally for from function \
+if import indexof insert instanceof lazy mod new not null \
+or override package private protected public-init public public-read \
+return reverse sizeof static super then this throw true try typeof \
+var while
+keywords.$(file.patterns.javafx)=$(keywordclass.javafx)
+# Base types and global functions (defined in javafx.lang.Builtins and javafx.lang.FX)
+# And now language words deprecated from their keyword status...
+keywords2.$(file.patterns.javafx)=Boolean Duration Integer Number Object String Void \
+Character Byte Short Long Float Double \
+isInitialized isSameObject print println \
+first in init into inverse last on postinit replace step trigger tween where with
+# I don't know what first and last nor trigger do. Neither lazy or typeof...
 
 keywordclass.javascript=abstract boolean break byte case catch char class \
 const continue debugger default delete do double else enum export extends \
@@ -1424,7 +1496,7 @@ final finally float for function goto if implements import in instanceof \
 int interface long native new package private protected public \
 return short static super switch synchronized this throw throws \
 transient try typeof var void volatile while with
-keywords.*.js=$(keywordclass.javascript)
+keywords.$(file.patterns.js)=$(keywordclass.javascript)
 
 keywordclass.flash=add and break case catch class continue default delete do \
 dynamic else eq extends false finally for function ge get gt if implements import in \
@@ -1449,6 +1521,17 @@ targetPath tellTarget toggleHighQuality trace unescape unloadMovie unLoadMovieNu
 keywords.$(file.patterns.flash)=$(keywordclass.flash)
 keywords2.$(file.patterns.flash)=$(keywordclass2.flash)
 
+keywordclass.vala=if else switch case default break continue return yield for foreach in \
+do while try catch finally throw
+
+keywordclass2.vala=namespace interface class struct enum delegate signal errordomain \
+construct get set value base const static var dynamic weak unowned virtual abstract \
+override public protected private extern throws requires ensures yields out ref lock \
+using true false null delete generic new this typeof sizeof as owned int string char bool
+
+keywords.$(file.patterns.vala))=$(keywordclass.vala)
+keywords2.$(file.patterns.vala)=$(keywordclass2.vala)
+
 # C++ styles
 
 # Braces are only matched in operator style
@@ -1461,6 +1544,7 @@ ccc=gcc $(ccopts) -c $(FileNameExt) -o $(FileName).o
 make.command=make
 command.compile.*.c=$(ccc) -std=c99
 command.build.*.c=$(make.command)
+command.build.*.h=$(make.command)
 command.go.*.c=./$(FileName)
 # To make the Go command both compile (if needed) and execute, use this setting:
 #command.go.needs.*.c=gcc $(ccopts) -std=c99 $(FileNameExt) -o $(FileName)
@@ -1470,8 +1554,6 @@ command.build.$(file.patterns.cplusplus)=$(make.command)
 command.go.$(file.patterns.cplusplus)=./$(FileName)
 command.go.needs.$(file.patterns.cplusplus)=g++ $(ccopts) $(FileNameExt) -o $(FileName)
 
-command.build.*.h=$(make.command)
-
 command.name.0.$(file.patterns.cpp)=Indent
 command.0.$(file.patterns.cpp)=astyle -tapOK -M8 $(FileNameExt)
 command.is.filter.0.$(file.patterns.cpp)=1
@@ -1504,7 +1586,15 @@ if PLAT_GTK
 
 command.compile.*.java=javac $(FileNameExt)
 command.build.*.java=javac *.java
-command.go.*.java=java $(FileName)
+command.go.*.java=java -cp . $(FileName)
+
+command.compile.*.fx=javafxc -d bin $(FileNameExt)
+command.build.*.fx=javafxc -d bin *.fx
+command.go.*.fx=javafx -cp bin $(FileName)
+
+if PLAT_WIN
+	command.help.*.java=http://java.sun.com/javase/6/docs/api/java/util/$(CurrentWord).html
+	command.help.subsystem.*.java=2
 
 command.compile.*.ch=ch -n $(FileNameExt)
 command.build.*.ch=ch -n  $(FileNameExt)
@@ -1513,6 +1603,13 @@ command.go.*.ch=ch -u $(FileNameExt)
 command.compile.*.as=mtasc -strict $(FileNameExt)
 command.build.*.as=mtasc -strict *.as
 
+command.compile.*.fx=javafxc -d . $(FileNameExt)
+command.build.*.fx=javafxc -d . *.fx
+command.go.*.fx=javafx -cp . $(FileName)
+
+command.build.$(file.patterns.vala)=valac $(FileNameExt)
+command.go.*.vala=./$(FileName)
+
 
 
 ###############################################################################
@@ -2915,7 +3012,7 @@ if PLAT_WIN
 	command.go.$(file.patterns.web)="file://$(FilePath)"
 	command.go.subsystem.$(file.patterns.web)=2
 if PLAT_GTK
-	command.go.$(file.patterns.web)=netscape "file://$(FilePath)"
+	command.go.$(file.patterns.web)=firefox "file://$(FilePath)"
 
 command.go.$(file.patterns.php)=php -f "$(FileNameExt)"
 command.compile.$(file.patterns.php)=php -l "$(FileNameExt)"
@@ -3686,6 +3783,79 @@ command.2.$(file.patterns.mmixal)=mmotype $(FileName).mmo $(FileName).out
 
 
 ###############################################################################
+# From nimrod.properties
+# Define SciTE settings for Nimrod files.
+
+file.patterns.nimrod=*.nim
+
+shbang.nimrod=nim
+
+filter.nimrod=Nimrod (nim)|$(file.patterns.nimrod)|
+
+lexer.$(file.patterns.nimrod)=nimrod
+
+keywordclass.nimrod=addr and as asm \
+block break \
+case cast const continue converter \
+discard div \
+elif else end enum except exception \
+finally for from generic \
+if implies import in include is isnot iterator \
+lambda \
+macro method mod \
+nil not notin \
+object of or out \
+proc ptr \
+raise ref return \
+shl shr \
+template try tuple type \
+var \
+when where while with without \
+xor \
+yield
+
+keywords.$(file.patterns.nimrod)=$(keywordclass.nimrod)
+
+#~ statement.indent.$(file.patterns.nimrod)=10 :
+statement.indent.$(file.patterns.nimrod)=5 elif else except finally of \
+for if try while
+
+statement.lookback.$(file.patterns.nimrod)=0
+block.start.$(file.patterns.nimrod)=
+block.end.$(file.patterns.nimrod)=
+
+view.indentation.examine.*.nim=2
+
+#fold.quotes.nimrod=1
+
+comment.block.nimrod=#~
+
+# nimrod styles
+# Braces are only matched in operator style
+braces.nimrod.style=10
+
+if PLAT_WIN
+	command.go.*.nim=nimrod c -r "$(FileNameExt)"
+	command.go.subsystem.*.nim=1
+
+if PLAT_GTK
+	command.go.*.nim=nimrod c -r "$(FileNameExt)"
+
+command.name.1.*.nim=Syntax Check
+command.1.*.nim=nimrod check $(FilePath)
+
+# compile
+command.compile.*.nim=nimrod c "$(FilePath)"
+
+# build
+command.build.*.nim=nimrod --forcebuild "$(FilePath)"
+command.build.subsystem.*.nim=1
+
+
+
+
+
+###############################################################################
 # From nncrontab.properties
 # Define SciTE settings for extended crontab files used by a powerful
 # Windows scheduler/event monitor/automation manager nnCron.
@@ -3987,43 +4157,58 @@ if PLAT_WIN
 # Define SciTE settings for Pascal files.
 # Changed by Fernando Lozano <fsl centroin com br> for Free Pascal
 # Changed by Mathias Rauen <scite madshi net> for Delphi
+# Changed by Marko Njezic <sf maxempire com> to match new LexPascal lexer and updated for Delphi 2009
+
+filter.pascal=Pascal (dpr dpk pas dfm inc pp)|*.dpr;*.dpk;*.pas;*.dfm;*.inc;*.pp|
+
+file.patterns.pascal=*.dpr;*.pas;*.dfm;*.inc;*.pp
+file.patterns.pascal.package=*.dpk
+file.patterns.pascal.all=$(file.patterns.pascal);$(file.patterns.pascal.package)
+lexer.$(file.patterns.pascal.all)=pascal
 
-filter.pascal=Pascal (dpr dpk pas dfm inc)|*.dpr;*.dpk;*.pas;*.dfm;*.inc;*.pp|
+keywordclass.pascal=absolute abstract and array as asm assembler automated begin case \
+cdecl class const constructor deprecated destructor dispid dispinterface div do downto \
+dynamic else end except export exports external far file final finalization finally for \
+forward function goto if implementation in inherited initialization inline interface is \
+label library message mod near nil not object of on or out overload override packed \
+pascal platform private procedure program property protected public published raise \
+record register reintroduce repeat resourcestring safecall sealed set shl shr static \
+stdcall strict string then threadvar to try type unit unsafe until uses var varargs \
+virtual while with xor
 
-file.patterns.pascal=*.dpr;*.dpk;*.pas;*.dfm;*.inc;*.pp
-lexer.$(file.patterns.pascal)=pascal
+keywordclass.pascal.smart=add default implements index name nodefault read readonly \
+remove stored write writeonly
 
-keywordclass.pascal=and array asm begin case cdecl class const constructor contains \
-default destructor div do downto else end end. except exit exports external \
-far file finalization finally for function goto if implementation in index inherited \
-initialization inline interface label library message mod near nil not \
-object of on or out overload override package packed pascal private procedure program \
-property protected public published raise read record register repeat requires resourcestring \
-safecall set shl shr stdcall stored string then threadvar to try type unit \
-until uses var virtual while with write xor
+keywordclass.pascal.package=package contains requires
 
-keywordclass.pascalclasses=write read default public protected private property published stored
+keywords.$(file.patterns.pascal)=$(keywordclass.pascal) $(keywordclass.pascal.smart)
+keywords.$(file.patterns.pascal.package)=$(keywordclass.pascal) $(keywordclass.pascal.smart) $(keywordclass.pascal.package)
 
-keywords.$(file.patterns.pascal)=$(keywordclass.pascal)
-keywords2.$(file.patterns.pascal)=$(keywordclass.pascalclasses)
+# If enabled some keywords will only be highlightend in appropriate context.
+# As implemented those are keywords related to property and DLL exports declarations
+lexer.pascal.smart.highlighting=1
 
 # Pascal styles
 
+
 # Braces are only matched in operator style
-braces.pascal.style=10
+braces.pascal.style=13
+
+
 
 comment.block.pascal=//~
-comment.stream.start.pascal=(*
-comment.stream.end.pascal=*)
-comment.box.start.pascal={
-comment.box.middle.pascal=
-comment.box.end.pascal=}
-
-statement.indent.$(file.patterns.pascal)=5 case catch class default do else for then \
-private protected public struct try union while type
+comment.stream.start.pascal={
+comment.stream.end.pascal=}
+comment.box.start.pascal=(*
+comment.box.middle.pascal= *
+comment.box.end.pascal= *)
+
+statement.indent.$(file.patterns.pascal)=9 case class do else for then \
+private protected public published repeat try while type
+statement.end.$(file.patterns.pascal)=13 ;
 statement.lookback.$(file.patterns.pascal)=20
-block.start.$(file.patterns.pascal)=10 begin
-block.end.$(file.patterns.pascal)=10 end
+block.start.$(file.patterns.pascal)=9 begin
+block.end.$(file.patterns.pascal)=9 end
 
 #using virtual pascal
 #pc=C:\Vp21\Bin.w32\Vpc.exe -VC:\Vp21\Bin.w32\Vp.vpo "$(FilePath)"
@@ -4370,6 +4555,58 @@ if PLAT_WIN
 
 
 ###############################################################################
+# From powerpro.properties
+# Define SciTE settings for powerpro files.
+file.patterns.powerpro=*.powerpro
+
+filter.powerpro=PowerPro (powerpro)|$(file.patterns.powerpro)|
+lexer.$(file.patterns.powerpro)=powerpro
+
+keywordclass.control=\
+break do else elseif endfor endif for function global gt if ifelse \
+ifx jump local lt quit static
+
+keywords.$(file.patterns.powerpro)=$(keywordclass.control)
+
+keywordclass.plugins=\
+win.debug win.debugshow win.exists win.getdisplayrect win.getfocus win.gethandle win.getrect \
+win.getsystemmetrics win.gettext win.maximize win.minimize win.move win.sendkeys win.setdebug \
+win.setfocus win.setrect win.settext win.show
+
+keywordclass.functions=\
+bar case clip env exec fill flag floattostring format formattime ftos \
+index input inputcancel inputdefault inputdialog join length messagebox mouse \
+not note readline remove replace replacechars replaceg revindex select \
+stof validpath visiblewindow wait wait.activity wait.for wait.forinterval wait.message \
+wait.quit wait.ready wait.sleep wait.until wallpaper window window word 
+
+keywords2.$(file.patterns.powerpro)=$(keywordclass.plugins)|$(keywordclass.functions)
+
+calltip.powerpro.word.characters=$(chars.alpha)$(chars.numeric)_
+comment.block.powerpro=//~
+comment.stream.start.powerpro=/*
+comment.stream.end.powerpro=*/
+comment.box.start.powerpro=/*
+comment.box.middle.powerpro= *
+comment.box.end.powerpro= */
+
+# Autocomplete and call tip settings
+#api.*.powerpro=$(SciteDefaultHome)\api\powerpro.api
+word.characters.*.powerpro=$(chars.alpha)$(chars.numeric)@$_
+
+# Braces are only matched in operator style
+braces.powerpro.style=11
+
+
+command.go.$(file.patterns.powerpro)="$(FilePath)"
+command.go.subsystem.$(file.patterns.powerpro)=2
+
+command.help.$(file.patterns.powerpro)=$(CurrentWord)!C:\Program Files\PowerPro\powerpro.chm
+command.help.subsystem.$(file.patterns.powerpro)=4
+
+
+
+###############################################################################
 # From powershell.properties
 # Define SciTE settings for PowerShell files
 
@@ -4938,6 +5175,39 @@ keywords.$(file.patterns.smalltalk)=\
 
 
 ###############################################################################
+# From sorcins.properties
+# Define SciTE settings for SORCUS Installation Files
+# Originally by Christoph Baumann cb sorcus com
+
+# SORCUS Installation files end with .ins
+file.patterns.sorcins=*.ins
+filter.sorcins=SORCUS Installation File|$(file.patterns.sorcins)|
+
+lexer.$(file.patterns.sorcins)=sorcins
+
+commands=ARGUSCONNECTCHANNELS \
+    M2DEVICE M2INST M2PAR M2PROC M2FUNC M2CMD M2LOADMODUL \
+    M6DEVICE M6INST M6PAR M6PROC M6FUNC M6CMD M6LOADMODUL \
+    M7DEVICE M7INST M7PAR M7PROC M7FUNC M7CMD M7LOADMODUL \
+    M8DEVICE M8INST M8PAR M8PROC M8FUNC M8CMD M8LOADMODUL \
+    MAXRESET MAXCONNECTCPU MAXLOADOSX MAXINST MAXPROC \
+    MAXFUNC MAXPAR MAXLOADMDD MAXFLASHFILE
+
+parameter=board slot layer osx file no usage task tasktype level irq flags \
+    datasize func para start progno name count index TIMEOUT RESET
+
+constants=MAX_NI_TASK MAX_TI_TASK MAX_II_TASK MAX_DI_TASK
+
+keywords.$(file.patterns.sorcins)=$(commands) 
+keywords2.$(file.patterns.sorcins)=$(parameter)
+keywords3.$(file.patterns.sorcins)=$(constants)
+
+comment.block.sorcins=;
+
+
+
+
+###############################################################################
 # From specman.properties
 # Define SciTE settings for Specman E language files.
 
@@ -6437,6 +6707,8 @@ keywords.$(file.patterns.yaml)=true false yes no
 	style.caml.8=$(style.anjuta.number)
 # Single quoted string (character constant)
 	style.caml.9=$(style.anjuta.char)
+#style.caml.10=
+	style.caml.10=$(style.anjuta.regex)
 # Double quoted string (string constant)
 	style.caml.11=$(style.anjuta.string)
 # Comment (NOT nested)
@@ -7501,7 +7773,7 @@ keywords.$(file.patterns.yaml)=true false yes no
 ###############################################################################
 # Style for metapost from file metapost.properties
 
-#
+# Default
 	style.metapost.0=$(style.anjuta.whitespace)
 # Special
 	style.metapost.1=$(style.anjuta.extrakeyword)
@@ -7551,6 +7823,42 @@ keywords.$(file.patterns.yaml)=true false yes no
 
 
 ###############################################################################
+# Style for nimrod from file nimrod.properties
+
+# White space
+	style.nimrod.0=$(style.anjuta.whitespace)
+# Comment
+	style.nimrod.1=$(style.anjuta.comment)
+# Number
+	style.nimrod.2=$(style.anjuta.number)
+# String
+	style.nimrod.3=$(style.anjuta.string)
+# Single quoted string
+	style.nimrod.4=$(style.anjuta.char)
+# Keyword
+	style.nimrod.5=$(style.anjuta.keyword)
+# Triple quotes
+	style.nimrod.6=$(style.anjuta.regex)
+# Triple double quotes
+	style.nimrod.7=$(style.anjuta.string)
+# Class name definition
+	style.nimrod.8=$(style.anjuta.definition)
+# Function or method name definition
+	style.nimrod.9=$(style.anjuta.function)
+# Operators
+	style.nimrod.10=$(style.anjuta.operator)
+# Comment-blocks
+	style.nimrod.12=$(style.anjuta.comment)
+# End of line where string is not closed
+	style.nimrod.13=$(style.anjuta.error)
+# Highlighted identifiers
+	style.nimrod.14=$(style.anjuta.identifier)
+# Decorators
+	style.nimrod.15=$(style.anjuta.attribute)
+
+
+
+###############################################################################
 # Style for nncrontab from file nncrontab.properties
 
 # Comment (SCE_NNCRONTAB_COMMENT)
@@ -7669,26 +7977,30 @@ keywords.$(file.patterns.yaml)=true false yes no
 
 # White space
 	style.pascal.0=$(style.anjuta.whitespace)
-# Comment
-	style.pascal.1=$(style.anjuta.comment)
-# Line Comment
+# Comment: { ... }
 	style.pascal.2=$(style.anjuta.comment)
-# Doc comment
+# Comment: (* ... *)
 	style.pascal.3=$(style.anjuta.comment)
-# Number
+# Line Comment: // ...
 	style.pascal.4=$(style.anjuta.number)
-# Keyword
+# Preprocessor: {$ ... }
 	style.pascal.5=$(style.anjuta.keyword)
-# Double quoted string
+# Preprocessor: (*$ ... *)
 	style.pascal.6=$(style.anjuta.string)
-# Single quoted string
+# Number
 	style.pascal.7=$(style.anjuta.char)
-# Symbols
+# Hex Number
 	style.pascal.8=$(style.anjuta.operator)
-# Preprocessor
+# Keyword
 	style.pascal.9=$(style.anjuta.preprocessor)
-# Operators
+# String
 	style.pascal.10=$(style.anjuta.operator)
+# End of line where string is not closed
+	style.pascal.11=$(style.anjuta.error)
+# Character
+	style.pascal.12=$(style.anjuta.char)
+# Operators
+	style.pascal.13=$(style.anjuta.operator)
 # Inline Asm
 	style.pascal.14=$(style.anjuta.localkeyword)
 
@@ -7807,6 +8119,46 @@ keywords.$(file.patterns.yaml)=true false yes no
 
 
 ###############################################################################
+# Style for powerpro from file powerpro.properties
+
+# Default text color
+	style.powerpro.0=$(style.anjuta.normal)
+# Comment: /* */
+	style.powerpro.1=$(style.anjuta.comment)
+# Line Comment: // ;; ;
+	style.powerpro.2=$(style.anjuta.comment)
+# Number
+	style.powerpro.3=$(style.anjuta.number)
+# Keywords1
+	style.powerpro.4=$(style.anjuta.keyword)
+# Keywords2
+	style.powerpro.5=$(style.anjuta.localkeyword)
+# Keywords3
+	style.powerpro.6=$(style.anjuta.syskeyword)
+# Keywords4
+	style.powerpro.7=$(style.anjuta.extrakeyword)
+# Double quoted string
+	style.powerpro.8=$(style.anjuta.string)
+# Single quoted string
+	style.powerpro.9=$(style.anjuta.char)
+# Line continuation
+	style.powerpro.10=$(style.anjuta.preprocessor)
+# Operators
+	style.powerpro.11=$(style.anjuta.operator)
+# Identifiers
+	style.powerpro.12=$(style.anjuta.identifier)
+# End of line where string is not closed
+	style.powerpro.13=$(style.anjuta.error)
+# Verbatim strings
+	style.powerpro.14=$(style.anjuta.regex)
+#alternate quote style (#)
+	style.powerpro.15=$(style.anjuta.string)
+#function style
+	style.powerpro.16=$(style.anjuta.function)
+
+
+
+###############################################################################
 # Style for powershell from file powershell.properties
 
 # White space
@@ -8183,6 +8535,22 @@ keywords.$(file.patterns.yaml)=true false yes no
 
 
 ###############################################################################
+# Style for sorcins from file sorcins.properties
+
+# Command
+	style.sorcins.1=$(style.anjuta.keyword)
+# Parameter
+	style.sorcins.2=$(style.anjuta.attribute)
+# Comment line
+	style.sorcins.3=$(style.anjuta.comment)
+# String
+	style.sorcins.4=$(style.anjuta.string)
+# Constant
+	style.sorcins.9=$(style.anjuta.number)
+
+
+
+###############################################################################
 # Style for specman from file specman.properties
 
 # White space
@@ -8341,7 +8709,7 @@ keywords.$(file.patterns.yaml)=true false yes no
 ###############################################################################
 # Style for tex from file tex.properties
 
-#
+# Default
 	style.tex.0=$(style.anjuta.whitespace)
 # Special
 	style.tex.1=$(style.anjuta.keyword)
diff --git a/plugins/scintilla/scintilla/AutoComplete.cxx b/plugins/scintilla/scintilla/AutoComplete.cxx
index af6154e..86c64df 100644
--- a/plugins/scintilla/scintilla/AutoComplete.cxx
+++ b/plugins/scintilla/scintilla/AutoComplete.cxx
@@ -11,7 +11,7 @@
 
 #include "Platform.h"
 
-#include "PropSet.h"
+#include "CharClassify.h"
 #include "AutoComplete.h"
 
 #ifdef SCI_NAMESPACE
diff --git a/plugins/scintilla/scintilla/CallTip.cxx b/plugins/scintilla/scintilla/CallTip.cxx
index 9f5f884..511282e 100644
--- a/plugins/scintilla/scintilla/CallTip.cxx
+++ b/plugins/scintilla/scintilla/CallTip.cxx
@@ -256,9 +256,8 @@ PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
 	clickPlace = 0;
 	if (val)
 		delete []val;
+	val = 0;
 	val = new char[strlen(defn) + 1];
-	if (!val)
-		return PRectangle();
 	strcpy(val, defn);
 	codePage = codePage_;
 	Surface *surfaceMeasure = Surface::Allocate();
diff --git a/plugins/scintilla/scintilla/CellBuffer.cxx b/plugins/scintilla/scintilla/CellBuffer.cxx
index 0e9ae69..0868cf2 100644
--- a/plugins/scintilla/scintilla/CellBuffer.cxx
+++ b/plugins/scintilla/scintilla/CellBuffer.cxx
@@ -21,165 +21,23 @@
 using namespace Scintilla;
 #endif
 
-MarkerHandleSet::MarkerHandleSet() {
-	root = 0;
-}
-
-MarkerHandleSet::~MarkerHandleSet() {
-	MarkerHandleNumber *mhn = root;
-	while (mhn) {
-		MarkerHandleNumber *mhnToFree = mhn;
-		mhn = mhn->next;
-		delete mhnToFree;
-	}
-	root = 0;
-}
-
-int MarkerHandleSet::Length() const {
-	int c = 0;
-	MarkerHandleNumber *mhn = root;
-	while (mhn) {
-		c++;
-		mhn = mhn->next;
-	}
-	return c;
-}
-
-int MarkerHandleSet::NumberFromHandle(int handle) const {
-	MarkerHandleNumber *mhn = root;
-	while (mhn) {
-		if (mhn->handle == handle) {
-			return mhn->number;
-		}
-		mhn = mhn->next;
-	}
-	return - 1;
-}
-
-int MarkerHandleSet::MarkValue() const {
-	unsigned int m = 0;
-	MarkerHandleNumber *mhn = root;
-	while (mhn) {
-		m |= (1 << mhn->number);
-		mhn = mhn->next;
-	}
-	return m;
-}
-
-bool MarkerHandleSet::Contains(int handle) const {
-	MarkerHandleNumber *mhn = root;
-	while (mhn) {
-		if (mhn->handle == handle) {
-			return true;
-		}
-		mhn = mhn->next;
-	}
-	return false;
-}
-
-bool MarkerHandleSet::InsertHandle(int handle, int markerNum) {
-	MarkerHandleNumber *mhn = new MarkerHandleNumber;
-	if (!mhn)
-		return false;
-	mhn->handle = handle;
-	mhn->number = markerNum;
-	mhn->next = root;
-	root = mhn;
-	return true;
-}
-
-void MarkerHandleSet::RemoveHandle(int handle) {
-	MarkerHandleNumber **pmhn = &root;
-	while (*pmhn) {
-		MarkerHandleNumber *mhn = *pmhn;
-		if (mhn->handle == handle) {
-			*pmhn = mhn->next;
-			delete mhn;
-			return;
-		}
-		pmhn = &((*pmhn)->next);
-	}
-}
-
-bool MarkerHandleSet::RemoveNumber(int markerNum) {
-	bool performedDeletion = false;
-	MarkerHandleNumber **pmhn = &root;
-	while (*pmhn) {
-		MarkerHandleNumber *mhn = *pmhn;
-		if (mhn->number == markerNum) {
-			*pmhn = mhn->next;
-			delete mhn;
-			performedDeletion = true;
-		} else {
-			pmhn = &((*pmhn)->next);
-		}
-	}
-	return performedDeletion;
-}
-
-void MarkerHandleSet::CombineWith(MarkerHandleSet *other) {
-	MarkerHandleNumber **pmhn = &root;
-	while (*pmhn) {
-		pmhn = &((*pmhn)->next);
-	}
-	*pmhn = other->root;
-	other->root = 0;
-}
-
-LineVector::LineVector() : starts(256) {
-	handleCurrent = 1;
-
+LineVector::LineVector() : starts(256), perLine(0) {
 	Init();
 }
 
 LineVector::~LineVector() {
 	starts.DeleteAll();
-	for (int line = 0; line < markers.Length(); line++) {
-		delete markers[line];
-		markers[line] = 0;
-	}
-	markers.DeleteAll();
-	levels.DeleteAll();
 }
 
 void LineVector::Init() {
 	starts.DeleteAll();
-	for (int line = 0; line < markers.Length(); line++) {
-		delete markers[line];
-		markers[line] = 0;
+	if (perLine) {
+		perLine->Init();
 	}
-	markers.DeleteAll();
-	levels.DeleteAll();
-}
-
-void LineVector::ExpandLevels(int sizeNew) {
-	levels.InsertValue(levels.Length(), sizeNew - levels.Length(), SC_FOLDLEVELBASE);
-}
-
-void LineVector::ClearLevels() {
-	levels.DeleteAll();
 }
 
-int LineVector::SetLevel(int line, int level) {
-	int prev = 0;
-	if ((line >= 0) && (line < Lines())) {
-		if (!levels.Length()) {
-			ExpandLevels(Lines() + 1);
-		}
-		prev = levels[line];
-		if (prev != level) {
-			levels[line] = level;
-		}
-	}
-	return prev;
-}
-
-int LineVector::GetLevel(int line) {
-	if (levels.Length() && (line >= 0) && (line < Lines())) {
-		return levels[line];
-	} else {
-		return SC_FOLDLEVELBASE;
-	}
+void LineVector::SetPerLine(PerLine *pl) {
+	perLine = pl;
 }
 
 void LineVector::InsertText(int line, int delta) {
@@ -188,15 +46,8 @@ void LineVector::InsertText(int line, int delta) {
 
 void LineVector::InsertLine(int line, int position) {
 	starts.InsertPartition(line, position);
-	if (markers.Length()) {
-		markers.Insert(line, 0);
-	}
-	if (levels.Length()) {
-		int level = SC_FOLDLEVELBASE;
-		if ((line > 0) && (line < Lines())) {
-			level = levels[line-1] & ~SC_FOLDLEVELWHITEFLAG;
-		}
-		levels.InsertValue(line, 1, level);
+	if (perLine) {
+		perLine->InsertLine(line);
 	}
 }
 
@@ -206,103 +57,15 @@ void LineVector::SetLineStart(int line, int position) {
 
 void LineVector::RemoveLine(int line) {
 	starts.RemovePartition(line);
-	// Retain the markers from the deleted line by oring them into the previous line
-	if (markers.Length()) {
-		if (line > 0) {
-			MergeMarkers(line - 1);
-		}
-		markers.Delete(line);
-	}
-	if (levels.Length()) {
-		// Move up following lines but merge header flag from this line
-		// to line before to avoid a temporary disappearence causing expansion.
-		int firstHeader = levels[line] & SC_FOLDLEVELHEADERFLAG;
-		levels.Delete(line);
-		if (line > 0)
-			levels[line-1] |= firstHeader;
+	if (perLine) {
+		perLine->RemoveLine(line);
 	}
 }
 
-int LineVector::LineFromPosition(int pos) {
+int LineVector::LineFromPosition(int pos) const {
 	return starts.PartitionFromPosition(pos);
 }
 
-int LineVector::MarkValue(int line) {
-	if (markers.Length() && markers[line])
-		return markers[line]->MarkValue();
-	else
-		return 0;
-}
-
-int LineVector::AddMark(int line, int markerNum) {
-	handleCurrent++;
-	if (!markers.Length()) {
-		// No existing markers so allocate one element per line
-		markers.InsertValue(0, Lines(), 0);
-	}
-	if (!markers[line]) {
-		// Need new structure to hold marker handle
-		markers[line] = new MarkerHandleSet();
-		if (!markers[line])
-			return - 1;
-	}
-	markers[line]->InsertHandle(handleCurrent, markerNum);
-
-	return handleCurrent;
-}
-
-void LineVector::MergeMarkers(int pos) {
-	if (markers[pos + 1] != NULL) {
-		if (markers[pos] == NULL)
-			markers[pos] = new MarkerHandleSet;
-		markers[pos]->CombineWith(markers[pos + 1]);
-		delete markers[pos + 1];
-		markers[pos + 1] = NULL;
-	}
-}
-
-void LineVector::DeleteMark(int line, int markerNum, bool all) {
-	if (markers.Length() && markers[line]) {
-		if (markerNum == -1) {
-			delete markers[line];
-			markers[line] = NULL;
-		} else {
-			bool performedDeletion = markers[line]->RemoveNumber(markerNum);
-			while (all && performedDeletion) {
-				performedDeletion = markers[line]->RemoveNumber(markerNum);
-			}
-			if (markers[line]->Length() == 0) {
-				delete markers[line];
-				markers[line] = NULL;
-			}
-		}
-	}
-}
-
-void LineVector::DeleteMarkFromHandle(int markerHandle) {
-	int line = LineFromHandle(markerHandle);
-	if (line >= 0) {
-		markers[line]->RemoveHandle(markerHandle);
-		if (markers[line]->Length() == 0) {
-			delete markers[line];
-			markers[line] = NULL;
-		}
-	}
-}
-
-int LineVector::LineFromHandle(int markerHandle) {
-	if (markers.Length()) {
-		for (int line = 0; line < Lines(); line++) {
-			if (markers[line]) {
-				if (markers[line]->Contains(markerHandle)) {
-					return line;
-				}
-			}
-		}
-	}
-	return -1;
-}
-
 Action::Action() {
 	at = startAction;
 	position = 0;
@@ -387,8 +150,6 @@ void UndoHistory::EnsureUndoRoom() {
 		// Run out of undo nodes so extend the array
 		int lenActionsNew = lenActions * 2;
 		Action *actionsNew = new Action[lenActionsNew];
-		if (!actionsNew)
-			return;
 		for (int act = 0; act <= currentAction; act++)
 			actionsNew[act].Grab(&actions[act]);
 		delete []actions;
@@ -398,7 +159,7 @@ void UndoHistory::EnsureUndoRoom() {
 }
 
 void UndoHistory::AppendAction(actionType at, int position, char *data, int lengthData,
-	bool &startSequence) {
+	bool &startSequence, bool mayCoalesce) {
 	EnsureUndoRoom();
 	//Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction);
 	//Platform::DebugPrintf("^ %d action %d %d\n", actions[currentAction - 1].at,
@@ -410,25 +171,35 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng
 	if (currentAction >= 1) {
 		if (0 == undoSequenceDepth) {
 			// Top level actions may not always be coalesced
-			Action &actPrevious = actions[currentAction - 1];
+			int targetAct = -1;
+			const Action *actPrevious = &(actions[currentAction + targetAct]);
+			// Container actions may forward the coalesce state of Scintilla Actions.
+			while ((actPrevious->at == containerAction) && actPrevious->mayCoalesce) {
+				targetAct--;
+				actPrevious = &(actions[currentAction + targetAct]);
+			}
 			// See if current action can be coalesced into previous action
 			// Will work if both are inserts or deletes and position is same
-			if (at != actPrevious.at) {
+			if (currentAction == savePoint) {
+				currentAction++;
+			} else if (!actions[currentAction].mayCoalesce) {
+				// Not allowed to coalesce if this set
 				currentAction++;
-			} else if (currentAction == savePoint) {
+			} else if (!mayCoalesce || !actPrevious->mayCoalesce) {
+				currentAction++;
+			} else if (at == containerAction || actions[currentAction].at == containerAction) {
+				;	// A coalescible containerAction
+			} else if ((at != actPrevious->at) && (actPrevious->at != startAction)) {
 				currentAction++;
 			} else if ((at == insertAction) &&
-			           (position != (actPrevious.position + actPrevious.lenData))) {
+			           (position != (actPrevious->position + actPrevious->lenData))) {
 				// Insertions must be immediately after to coalesce
 				currentAction++;
-			} else if (!actions[currentAction].mayCoalesce) {
-				// Not allowed to coalesce if this set
-				currentAction++;
 			} else if (at == removeAction) {
 				if ((lengthData == 1) || (lengthData == 2)){
-					if ((position + lengthData) == actPrevious.position) {
+					if ((position + lengthData) == actPrevious->position) {
 						; // Backspace -> OK
-					} else if (position == actPrevious.position) {
+					} else if (position == actPrevious->position) {
 						; // Delete -> OK
 					} else {
 						// Removals must be at same position to coalesce
@@ -451,7 +222,7 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng
 		currentAction++;
 	}
 	startSequence = oldCurrentAction != currentAction;
-	actions[currentAction].Create(at, position, data, lengthData);
+	actions[currentAction].Create(at, position, data, lengthData, mayCoalesce);
 	currentAction++;
 	actions[currentAction].Create(startAction);
 	maxAction = currentAction;
@@ -666,6 +437,10 @@ void CellBuffer::Allocate(int newSize) {
 	style.ReAllocate(newSize);
 }
 
+void CellBuffer::SetPerLine(PerLine *pl) {
+	lv.SetPerLine(pl);
+}
+
 int CellBuffer::Lines() const {
 	return lv.Lines();
 }
@@ -695,54 +470,14 @@ bool CellBuffer::IsSavePoint() {
 	return uh.IsSavePoint();
 }
 
-int CellBuffer::AddMark(int line, int markerNum) {
-	if ((line >= 0) && (line < Lines())) {
-		return lv.AddMark(line, markerNum);
-	}
-	return - 1;
-}
-
-void CellBuffer::DeleteMark(int line, int markerNum) {
-	if ((line >= 0) && (line < Lines())) {
-		lv.DeleteMark(line, markerNum, false);
-	}
-}
-
-void CellBuffer::DeleteMarkFromHandle(int markerHandle) {
-	lv.DeleteMarkFromHandle(markerHandle);
-}
-
-int CellBuffer::GetMark(int line) {
-	if ((line >= 0) && (line < Lines()))
-		return lv.MarkValue(line);
-	return 0;
-}
-
-void CellBuffer::DeleteAllMarks(int markerNum) {
-	for (int line = 0; line < Lines(); line++) {
-		lv.DeleteMark(line, markerNum, true);
-	}
-}
-
-int CellBuffer::LineFromHandle(int markerHandle) {
-	return lv.LineFromHandle(markerHandle);
-}
-
 // Without undo
 
 void CellBuffer::InsertLine(int line, int position) {
 	lv.InsertLine(line, position);
-	if (lineStates.Length()) {
-		lineStates.EnsureLength(line);
-		lineStates.Insert(line, 0);
-	}
 }
 
 void CellBuffer::RemoveLine(int line) {
 	lv.RemoveLine(line);
-	if (lineStates.Length() > line) {
-		lineStates.Delete(line);
-	}
 }
 
 void CellBuffer::BasicInsertString(int position, const char *s, int insertLength) {
@@ -862,6 +597,11 @@ void CellBuffer::EndUndoAction() {
 	uh.EndUndoAction();
 }
 
+void CellBuffer::AddUndoAction(int token, bool mayCoalesce) {
+	bool startSequence;
+	uh.AppendAction(containerAction, token, 0, 0, startSequence, mayCoalesce);
+}
+
 void CellBuffer::DeleteUndoHistory() {
 	uh.DeleteUndoHistory();
 }
@@ -910,30 +650,3 @@ void CellBuffer::PerformRedoStep() {
 	uh.CompletedRedoStep();
 }
 
-int CellBuffer::SetLineState(int line, int state) {
-	lineStates.EnsureLength(line + 1);
-	int stateOld = lineStates[line];
-	lineStates[line] = state;
-	return stateOld;
-}
-
-int CellBuffer::GetLineState(int line) {
-	lineStates.EnsureLength(line + 1);
-	return lineStates[line];
-}
-
-int CellBuffer::GetMaxLineState() {
-	return lineStates.Length();
-}
-
-int CellBuffer::SetLevel(int line, int level) {
-	return lv.SetLevel(line, level);
-}
-
-int CellBuffer::GetLevel(int line) {
-	return lv.GetLevel(line);
-}
-
-void CellBuffer::ClearLevels() {
-	lv.ClearLevels();
-}
diff --git a/plugins/scintilla/scintilla/CellBuffer.h b/plugins/scintilla/scintilla/CellBuffer.h
index 4b83f48..3381c19 100644
--- a/plugins/scintilla/scintilla/CellBuffer.h
+++ b/plugins/scintilla/scintilla/CellBuffer.h
@@ -12,33 +12,13 @@
 namespace Scintilla {
 #endif
 
-/**
- * This holds the marker identifier and the marker type to display.
- * MarkerHandleNumbers are members of lists.
- */
-struct MarkerHandleNumber {
-	int handle;
-	int number;
-	MarkerHandleNumber *next;
-};
-
-/**
- * A marker handle set contains any number of MarkerHandleNumbers.
- */
-class MarkerHandleSet {
-	MarkerHandleNumber *root;
-
+// Interface to per-line data that wants to see each line insertion and deletion
+class PerLine {
 public:
-	MarkerHandleSet();
-	~MarkerHandleSet();
-	int Length() const;
-	int NumberFromHandle(int handle) const;
-	int MarkValue() const;	///< Bit set of marker numbers.
-	bool Contains(int handle) const;
-	bool InsertHandle(int handle, int markerNum);
-	void RemoveHandle(int handle);
-	bool RemoveNumber(int markerNum);
-	void CombineWith(MarkerHandleSet *other);
+	virtual ~PerLine() {}
+	virtual void Init()=0;
+	virtual void InsertLine(int)=0;
+	virtual void RemoveLine(int)=0;
 };
 
 /**
@@ -47,21 +27,14 @@ public:
 class LineVector {
 
 	Partitioning starts;
-	SplitVector<MarkerHandleSet *> markers;
-	SplitVector<int> levels;
-	/// Handles are allocated sequentially and should never have to be reused as 32 bit ints are very big.
-	int handleCurrent;
+	PerLine *perLine;
 
 public:
 
 	LineVector();
 	~LineVector();
 	void Init();
-
-	void ExpandLevels(int sizeNew=-1);
-	void ClearLevels();
-	int SetLevel(int line, int level);
-	int GetLevel(int line);
+	void SetPerLine(PerLine *pl);
 
 	void InsertText(int line, int delta);
 	void InsertLine(int line, int position);
@@ -70,7 +43,7 @@ public:
 	int Lines() const {
 		return starts.Partitions();
 	}
-	int LineFromPosition(int pos);
+	int LineFromPosition(int pos) const;
 	int LineStart(int line) const {
 		return starts.PositionFromPartition(line);
 	}
@@ -81,9 +54,18 @@ public:
 	void DeleteMark(int line, int markerNum, bool all);
 	void DeleteMarkFromHandle(int markerHandle);
 	int LineFromHandle(int markerHandle);
+
+	void ClearLevels();
+	int SetLevel(int line, int level);
+	int GetLevel(int line);
+
+	int SetLineState(int line, int state);
+	int GetLineState(int line);
+	int GetMaxLineState();
+
 };
 
-enum actionType { insertAction, removeAction, startAction };
+enum actionType { insertAction, removeAction, startAction, containerAction };
 
 /**
  * Actions are used to store all the information required to perform one undo/redo step.
@@ -120,7 +102,7 @@ public:
 	UndoHistory();
 	~UndoHistory();
 
-	void AppendAction(actionType at, int position, char *data, int length, bool &startSequence);
+	void AppendAction(actionType at, int position, char *data, int length, bool &startSequence, bool mayCoalesce=true);
 
 	void BeginUndoAction();
 	void EndUndoAction();
@@ -160,8 +142,6 @@ private:
 
 	LineVector lv;
 
-	SplitVector<int> lineStates;
-
 public:
 
 	CellBuffer();
@@ -175,9 +155,10 @@ public:
 
 	int Length() const;
 	void Allocate(int newSize);
+	void SetPerLine(PerLine *pl);
 	int Lines() const;
 	int LineStart(int line) const;
-	int LineFromPosition(int pos) { return lv.LineFromPosition(pos); }
+	int LineFromPosition(int pos) const { return lv.LineFromPosition(pos); }
 	void InsertLine(int line, int position);
 	void RemoveLine(int line);
 	const char *InsertString(int position, const char *s, int insertLength, bool &startSequence);
@@ -197,14 +178,6 @@ public:
 	void SetSavePoint();
 	bool IsSavePoint();
 
-	/// Line marker functions
-	int AddMark(int line, int markerNum);
-	void DeleteMark(int line, int markerNum);
-	void DeleteMarkFromHandle(int markerHandle);
-	int GetMark(int line);
-	void DeleteAllMarks(int markerNum);
-	int LineFromHandle(int markerHandle);
-
 	/// Actions without undo
 	void BasicInsertString(int position, const char *s, int insertLength);
 	void BasicDeleteChars(int position, int deleteLength);
@@ -213,6 +186,7 @@ public:
 	bool IsCollectingUndo();
 	void BeginUndoAction();
 	void EndUndoAction();
+	void AddUndoAction(int token, bool mayCoalesce);
 	void DeleteUndoHistory();
 
 	/// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is
@@ -225,14 +199,6 @@ public:
 	int StartRedo();
 	const Action &GetRedoStep() const;
 	void PerformRedoStep();
-
-	int SetLineState(int line, int state);
-	int GetLineState(int line);
-	int GetMaxLineState();
-
-	int SetLevel(int line, int level);
-	int GetLevel(int line);
-	void ClearLevels();
 };
 
 #ifdef SCI_NAMESPACE
diff --git a/plugins/scintilla/scintilla/CharClassify.cxx b/plugins/scintilla/scintilla/CharClassify.cxx
index acab4b2..bbd25a0 100644
--- a/plugins/scintilla/scintilla/CharClassify.cxx
+++ b/plugins/scintilla/scintilla/CharClassify.cxx
@@ -5,6 +5,7 @@
 // Copyright 2006 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
+#include <stdlib.h>
 #include <ctype.h>
 
 #include "CharClassify.h"
@@ -41,3 +42,37 @@ void CharClassify::SetCharClasses(const unsigned char *chars, cc newCharClass) {
 		}
 	}
 }
+
+int CompareCaseInsensitive(const char *a, const char *b) {
+	while (*a && *b) {
+		if (*a != *b) {
+			char upperA = MakeUpperCase(*a);
+			char upperB = MakeUpperCase(*b);
+			if (upperA != upperB)
+				return upperA - upperB;
+		}
+		a++;
+		b++;
+	}
+	// Either *a or *b is nul
+	return *a - *b;
+}
+
+int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
+	while (*a && *b && len) {
+		if (*a != *b) {
+			char upperA = MakeUpperCase(*a);
+			char upperB = MakeUpperCase(*b);
+			if (upperA != upperB)
+				return upperA - upperB;
+		}
+		a++;
+		b++;
+		len--;
+	}
+	if (len == 0)
+		return 0;
+	else
+		// Either *a or *b is nul
+		return *a - *b;
+}
diff --git a/plugins/scintilla/scintilla/CharClassify.h b/plugins/scintilla/scintilla/CharClassify.h
index 881d3a1..d746fe0 100644
--- a/plugins/scintilla/scintilla/CharClassify.h
+++ b/plugins/scintilla/scintilla/CharClassify.h
@@ -2,7 +2,7 @@
 /** @file CharClassify.h
  ** Character classifications used by Document and RESearch.
  **/
-// Copyright 2006 by Neil Hodgson <neilh scintilla org>
+// Copyright 2006-2009 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef CHARCLASSIFY_H
@@ -22,4 +22,16 @@ private:
 	enum { maxChar=256 };
 	unsigned char charClass[maxChar];    // not type cc to save space
 };
+
+// These functions are implemented because each platform calls them something different.
+int CompareCaseInsensitive(const char *a, const char *b);
+int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
+
+inline char MakeUpperCase(char ch) {
+	if (ch < 'a' || ch > 'z')
+		return ch;
+	else
+		return static_cast<char>(ch - 'a' + 'A');
+}
+
 #endif
diff --git a/plugins/scintilla/scintilla/Document.cxx b/plugins/scintilla/scintilla/Document.cxx
index bded3a3..ab29c79 100644
--- a/plugins/scintilla/scintilla/Document.cxx
+++ b/plugins/scintilla/scintilla/Document.cxx
@@ -17,6 +17,7 @@
 #include "Partitioning.h"
 #include "RunStyles.h"
 #include "CellBuffer.h"
+#include "PerLine.h"
 #include "CharClassify.h"
 #include "Decoration.h"
 #include "Document.h"
@@ -74,6 +75,14 @@ Document::Document() {
 
 	matchesValid = false;
 	regex = 0;
+
+	perLineData[ldMarkers] = new LineMarkers();
+	perLineData[ldLevels] = new LineLevels();
+	perLineData[ldState] = new LineState();
+	perLineData[ldMargin] = new LineAnnotation();
+	perLineData[ldAnnotation] = new LineAnnotation();
+
+	cb.SetPerLine(this);
 }
 
 Document::~Document() {
@@ -81,12 +90,37 @@ Document::~Document() {
 		watchers[i].watcher->NotifyDeleted(this, watchers[i].userData);
 	}
 	delete []watchers;
+	for (int j=0; j<ldSize; j++) {
+		delete perLineData[j];
+		perLineData[j] = 0;
+	}
 	watchers = 0;
 	lenWatchers = 0;
 	delete regex;
 	regex = 0;
 }
 
+void Document::Init() {
+	for (int j=0; j<ldSize; j++) {
+		if (perLineData[j])
+			perLineData[j]->Init();
+	}
+}
+
+void Document::InsertLine(int line) {
+	for (int j=0; j<ldSize; j++) {
+		if (perLineData[j])
+			perLineData[j]->InsertLine(line);
+	}
+}
+
+void Document::RemoveLine(int line) {
+	for (int j=0; j<ldSize; j++) {
+		if (perLineData[j])
+			perLineData[j]->RemoveLine(line);
+	}
+}
+
 // Increase reference count and return its previous value.
 int Document::AddRef() {
 	return refCount++;
@@ -106,42 +140,58 @@ void Document::SetSavePoint() {
 	NotifySavePoint(true);
 }
 
+int Document::GetMark(int line) { 
+	return static_cast<LineMarkers*>(perLineData[ldMarkers])->MarkValue(line); 
+}
+
 int Document::AddMark(int line, int markerNum) {
-	int prev = cb.AddMark(line, markerNum);
-	DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
-	NotifyModified(mh);
-	return prev;
+	if (line <= LinesTotal()) {
+		int prev = static_cast<LineMarkers*>(perLineData[ldMarkers])->
+			AddMark(line, markerNum, LinesTotal());
+		DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
+		NotifyModified(mh);
+		return prev;
+	} else {
+		return 0;
+	}
 }
 
 void Document::AddMarkSet(int line, int valueSet) {
 	unsigned int m = valueSet;
 	for (int i = 0; m; i++, m >>= 1)
 		if (m & 1)
-			cb.AddMark(line, i);
+			static_cast<LineMarkers*>(perLineData[ldMarkers])->
+				AddMark(line, i, LinesTotal());
 	DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
 	NotifyModified(mh);
 }
 
 void Document::DeleteMark(int line, int markerNum) {
-	cb.DeleteMark(line, markerNum);
+	static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMark(line, markerNum, false);
 	DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
 	NotifyModified(mh);
 }
 
 void Document::DeleteMarkFromHandle(int markerHandle) {
-	cb.DeleteMarkFromHandle(markerHandle);
+	static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMarkFromHandle(markerHandle);
 	DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
 	mh.line = -1;
 	NotifyModified(mh);
 }
 
 void Document::DeleteAllMarks(int markerNum) {
-	cb.DeleteAllMarks(markerNum);
+	for (int line = 0; line < LinesTotal(); line++) {
+		static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMark(line, markerNum, true);
+	}
 	DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
 	mh.line = -1;
 	NotifyModified(mh);
 }
 
+int Document::LineFromHandle(int markerHandle) { 
+	return static_cast<LineMarkers*>(perLineData[ldMarkers])->LineFromHandle(markerHandle); 
+}
+
 int Document::LineStart(int line) const {
 	return cb.LineStart(line);
 }
@@ -159,15 +209,19 @@ int Document::LineEnd(int line) const {
 	}
 }
 
-int Document::LineFromPosition(int pos) {
+int Document::LineFromPosition(int pos) const {
 	return cb.LineFromPosition(pos);
 }
 
-int Document::LineEndPosition(int position) {
+int Document::LineEndPosition(int position) const {
 	return LineEnd(LineFromPosition(position));
 }
 
-int Document::VCHomePosition(int position) {
+bool Document::IsLineEndPosition(int position) const {
+	return LineEnd(LineFromPosition(position)) == position;
+}
+
+int Document::VCHomePosition(int position) const {
 	int line = LineFromPosition(position);
 	int startPosition = LineStart(line);
 	int endLine = LineEnd(line);
@@ -181,7 +235,7 @@ int Document::VCHomePosition(int position) {
 }
 
 int Document::SetLevel(int line, int level) {
-	int prev = cb.SetLevel(line, level);
+	int prev = static_cast<LineLevels*>(perLineData[ldLevels])->SetLevel(line, level, LinesTotal());
 	if (prev != level) {
 		DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER,
 		                   LineStart(line), 0, 0, 0, line);
@@ -192,6 +246,14 @@ int Document::SetLevel(int line, int level) {
 	return prev;
 }
 
+int Document::GetLevel(int line) { 
+	return static_cast<LineLevels*>(perLineData[ldLevels])->GetLevel(line); 
+}
+
+void Document::ClearLevels() { 
+	static_cast<LineLevels*>(perLineData[ldLevels])->ClearLevels(); 
+}
+
 static bool IsSubordinate(int levelStart, int levelTry) {
 	if (levelTry & SC_FOLDLEVELWHITEFLAG)
 		return true;
@@ -503,21 +565,27 @@ int Document::Undo() {
 				if (action.at == removeAction) {
 					NotifyModified(DocModification(
 									SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action));
+				} else if (action.at == containerAction) {
+					DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_UNDO);
+					dm.token = action.position;
+					NotifyModified(dm);
 				} else {
 					NotifyModified(DocModification(
 									SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action));
 				}
 				cb.PerformUndoStep();
 				int cellPosition = action.position;
-				ModifiedAt(cellPosition);
-				newPos = cellPosition;
+				if (action.at != containerAction) {
+					ModifiedAt(cellPosition);
+					newPos = cellPosition;
+				}
 
 				int modFlags = SC_PERFORMED_UNDO;
 				// With undo, an insertion action becomes a deletion notification
 				if (action.at == removeAction) {
 					newPos += action.lenData;
 					modFlags |= SC_MOD_INSERTTEXT;
-				} else {
+				} else if (action.at == insertAction) {
 					modFlags |= SC_MOD_DELETETEXT;
 				}
 				if (steps > 1)
@@ -558,19 +626,25 @@ int Document::Redo() {
 				if (action.at == insertAction) {
 					NotifyModified(DocModification(
 									SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action));
+				} else if (action.at == containerAction) {
+					DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_REDO);
+					dm.token = action.position;
+					NotifyModified(dm);
 				} else {
 					NotifyModified(DocModification(
 									SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action));
 				}
 				cb.PerformRedoStep();
-				ModifiedAt(action.position);
-				newPos = action.position;
+				if (action.at != containerAction) {
+					ModifiedAt(action.position);
+					newPos = action.position;
+				}
 
 				int modFlags = SC_PERFORMED_REDO;
 				if (action.at == insertAction) {
 					newPos += action.lenData;
 					modFlags |= SC_MOD_INSERTTEXT;
-				} else {
+				} else if (action.at == removeAction) {
 					modFlags |= SC_MOD_DELETETEXT;
 				}
 				if (steps > 1)
@@ -687,10 +761,9 @@ void Document::SetLineIndentation(int line, int indent) {
 		CreateIndentation(linebuf, sizeof(linebuf), indent, tabInChars, !useTabs);
 		int thisLineStart = LineStart(line);
 		int indentPos = GetLineIndentPosition(line);
-		BeginUndoAction();
+		UndoGroup ug(this);
 		DeleteChars(thisLineStart, indentPos - thisLineStart);
 		InsertCString(thisLineStart, linebuf);
-		EndUndoAction();
 	}
 }
 
@@ -797,7 +870,7 @@ char *Document::TransformLineEnds(int *pLenOut, const char *s, size_t len, int e
 }
 
 void Document::ConvertLineEnds(int eolModeSet) {
-	BeginUndoAction();
+	UndoGroup ug(this);
 
 	for (int pos = 0; pos < Length(); pos++) {
 		if (cb.CharAt(pos) == '\r') {
@@ -832,7 +905,6 @@ void Document::ConvertLineEnds(int eolModeSet) {
 		}
 	}
 
-	EndUndoAction();
 }
 
 bool Document::IsWhiteLine(int line) const {
@@ -995,16 +1067,6 @@ bool Document::IsWordAt(int start, int end) {
 	return IsWordStartAt(start) && IsWordEndAt(end);
 }
 
-// The comparison and case changing functions here assume ASCII
-// or extended ASCII such as the normal Windows code page.
-
-static inline char MakeUpperCase(char ch) {
-	if (ch < 'a' || ch > 'z')
-		return ch;
-	else
-		return static_cast<char>(ch - 'a' + 'A');
-}
-
 static inline char MakeLowerCase(char ch) {
 	if (ch < 'A' || ch > 'Z')
 		return ch;
@@ -1059,8 +1121,8 @@ long Document::FindText(int minPos, int maxPos, const char *s,
 					}
 					if (found) {
 						if ((!word && !wordStart) ||
-						        word && IsWordAt(pos, pos + lengthFind) ||
-						        wordStart && IsWordStartAt(pos))
+						        (word && IsWordAt(pos, pos + lengthFind)) ||
+						        (wordStart && IsWordStartAt(pos)))
 							return pos;
 					}
 				}
@@ -1075,8 +1137,8 @@ long Document::FindText(int minPos, int maxPos, const char *s,
 					}
 					if (found) {
 						if ((!word && !wordStart) ||
-						        word && IsWordAt(pos, pos + lengthFind) ||
-						        wordStart && IsWordStartAt(pos))
+						        (word && IsWordAt(pos, pos + lengthFind)) ||
+						        (wordStart && IsWordStartAt(pos)))
 							return pos;
 					}
 				}
@@ -1155,7 +1217,7 @@ bool Document::SetStyleFor(int length, char style) {
 	}
 }
 
-bool Document::SetStyles(int length, char *styles) {
+bool Document::SetStyles(int length, const char *styles) {
 	if (enteredStyling != 0) {
 		return false;
 	} else {
@@ -1194,7 +1256,7 @@ void Document::EnsureStyledTo(int pos) {
 }
 
 int Document::SetLineState(int line, int state) {
-	int statePrevious = cb.SetLineState(line, state);
+	int statePrevious = static_cast<LineState*>(perLineData[ldState])->SetLineState(line, state);
 	if (state != statePrevious) {
 		DocModification mh(SC_MOD_CHANGELINESTATE, 0, 0, 0, 0, line);
 		NotifyModified(mh);
@@ -1202,6 +1264,89 @@ int Document::SetLineState(int line, int state) {
 	return statePrevious;
 }
 
+int Document::GetLineState(int line) { 
+	return static_cast<LineState*>(perLineData[ldState])->GetLineState(line); 
+}
+
+int Document::GetMaxLineState() { 
+	return static_cast<LineState*>(perLineData[ldState])->GetMaxLineState(); 
+}
+
+StyledText Document::MarginStyledText(int line) {
+	LineAnnotation *pla = static_cast<LineAnnotation*>(perLineData[ldMargin]);
+	return StyledText(pla->Length(line), pla->Text(line), 
+		pla->MultipleStyles(line), pla->Style(line), pla->Styles(line));
+}
+
+void Document::MarginSetText(int line, const char *text) {
+	static_cast<LineAnnotation*>(perLineData[ldMargin])->SetText(line, text); 
+	DocModification mh(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line);
+	NotifyModified(mh);
+}
+
+void Document::MarginSetStyle(int line, int style) {
+	static_cast<LineAnnotation*>(perLineData[ldMargin])->SetStyle(line, style); 
+}
+
+void Document::MarginSetStyles(int line, const unsigned char *styles) {
+	static_cast<LineAnnotation*>(perLineData[ldMargin])->SetStyles(line, styles); 
+}
+
+int Document::MarginLength(int line) const {
+	return static_cast<LineAnnotation*>(perLineData[ldMargin])->Length(line);
+}
+
+void Document::MarginClearAll() {
+	int maxEditorLine = LinesTotal();
+	for (int l=0;l<maxEditorLine;l++)
+		MarginSetText(l, 0);
+	// Free remaining data
+	static_cast<LineAnnotation*>(perLineData[ldMargin])->ClearAll();
+}
+
+bool Document::AnnotationAny() const {
+	return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->AnySet(); 
+}
+
+StyledText Document::AnnotationStyledText(int line) {
+	LineAnnotation *pla = static_cast<LineAnnotation*>(perLineData[ldAnnotation]);
+	return StyledText(pla->Length(line), pla->Text(line), 
+		pla->MultipleStyles(line), pla->Style(line), pla->Styles(line));
+}
+
+void Document::AnnotationSetText(int line, const char *text) {
+	const int linesBefore = AnnotationLines(line);
+	static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetText(line, text); 
+	const int linesAfter = AnnotationLines(line);
+	DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), 0, 0, 0, line);
+	mh.annotationLinesAdded = linesAfter - linesBefore;
+	NotifyModified(mh);
+}
+
+void Document::AnnotationSetStyle(int line, int style) {
+	static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetStyle(line, style); 
+}
+
+void Document::AnnotationSetStyles(int line, const unsigned char *styles) {
+	static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetStyles(line, styles); 
+}
+
+int Document::AnnotationLength(int line) const {
+	return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->Length(line);
+}
+
+int Document::AnnotationLines(int line) const {
+	return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->Lines(line);
+}
+
+void Document::AnnotationClearAll() {
+	int maxEditorLine = LinesTotal();
+	for (int l=0;l<maxEditorLine;l++)
+		AnnotationSetText(l, 0);
+	// Free remaining data
+	static_cast<LineAnnotation*>(perLineData[ldAnnotation])->ClearAll();
+}
+
 void Document::IncrementStyleClock() {
 	styleClock = (styleClock + 1) % 0x100000;
 }
@@ -1221,8 +1366,6 @@ bool Document::AddWatcher(DocWatcher *watcher, void *userData) {
 			return false;
 	}
 	WatcherWithUserData *pwNew = new WatcherWithUserData[lenWatchers + 1];
-	if (!pwNew)
-		return false;
 	for (int j = 0; j < lenWatchers; j++)
 		pwNew[j] = watchers[j];
 	pwNew[lenWatchers].watcher = watcher;
@@ -1243,8 +1386,6 @@ bool Document::RemoveWatcher(DocWatcher *watcher, void *userData) {
 				lenWatchers = 0;
 			} else {
 				WatcherWithUserData *pwNew = new WatcherWithUserData[lenWatchers];
-				if (!pwNew)
-					return false;
 				for (int j = 0; j < lenWatchers - 1; j++) {
 					pwNew[j] = (j < i) ? watchers[j] : watchers[j + 1];
 				}
@@ -1605,8 +1746,6 @@ const char *BuiltinRegex::SubstituteByPosition(Document* doc, const char *text,
 		}
 	}
 	substituted = new char[lenResult + 1];
-	if (!substituted)
-		return 0;
 	char *o = substituted;
 	for (int j = 0; j < *length; j++) {
 		if (text[j] == '\\') {
@@ -1657,8 +1796,18 @@ const char *BuiltinRegex::SubstituteByPosition(Document* doc, const char *text,
 
 #ifndef SCI_OWNREGEX
 
+#ifdef SCI_NAMESPACE
+
+RegexSearchBase *Scintilla::CreateRegexSearch(CharClassify *charClassTable) {
+	return new BuiltinRegex(charClassTable);
+}
+
+#else
+
 RegexSearchBase *CreateRegexSearch(CharClassify *charClassTable) {
 	return new BuiltinRegex(charClassTable);
 }
 
 #endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/Document.h b/plugins/scintilla/scintilla/Document.h
index 0457b47..240d59e 100644
--- a/plugins/scintilla/scintilla/Document.h
+++ b/plugins/scintilla/scintilla/Document.h
@@ -93,9 +93,31 @@ public:
 /// Factory function for RegexSearchBase
 extern RegexSearchBase* CreateRegexSearch(CharClassify *charClassTable);
 
+struct StyledText {
+	size_t length;
+	const char *text;
+	bool multipleStyles;
+	size_t style;
+	const unsigned char *styles;
+	StyledText(	size_t length_, const char *text_, bool multipleStyles_, int style_, const unsigned char *styles_) : 
+		length(length_), text(text_), multipleStyles(multipleStyles_), style(style_), styles(styles_) {
+	}
+	// Return number of bytes from start to before '\n' or end of text.
+	// Return 1 when start is outside text
+	size_t LineLength(size_t start) const {
+		size_t cur = start;
+		while ((cur < length) && (text[cur] != '\n'))
+			cur++;
+		return cur-start;
+	}
+	size_t StyleAt(size_t i) const {
+		return multipleStyles ? styles[i] : style;
+	}
+};
+
 /**
  */
-class Document {
+class Document : PerLine {
 
 public:
 	/** Used to pair watcher pointer with user data. */
@@ -110,7 +132,6 @@ public:
 	};
 
 	enum charClassification { ccSpace, ccNewLine, ccWord, ccPunctuation };
-
 private:
 	int refCount;
 	CellBuffer cb;
@@ -125,6 +146,10 @@ private:
 	WatcherWithUserData *watchers;
 	int lenWatchers;
 
+	// ldSize is not real data - it is for dimensions and loops
+	enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldSize };	
+	PerLine *perLineData[ldSize];
+
 	bool matchesValid;
 	RegexSearchBase* regex;
 
@@ -150,7 +175,11 @@ public:
 	int AddRef();
 	int Release();
 
-	int LineFromPosition(int pos);
+	virtual void Init();
+	virtual void InsertLine(int line);
+	virtual void RemoveLine(int line);
+
+	int LineFromPosition(int pos) const;
 	int ClampPositionIntoDocument(int pos);
 	bool IsCrLf(int pos);
 	int LenChar(int pos);
@@ -173,6 +202,7 @@ public:
 	bool IsCollectingUndo() { return cb.IsCollectingUndo(); }
 	void BeginUndoAction() { cb.BeginUndoAction(); }
 	void EndUndoAction() { cb.EndUndoAction(); }
+	void AddUndoAction(int token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); }
 	void SetSavePoint();
 	bool IsSavePoint() { return cb.IsSavePoint(); }
 	const char *BufferPointer() { return cb.BufferPointer(); }
@@ -199,21 +229,22 @@ public:
 		cb.GetCharRange(buffer, position, lengthRetrieve);
 	}
 	char StyleAt(int position) { return cb.StyleAt(position); }
-	int GetMark(int line) { return cb.GetMark(line); }
+	int GetMark(int line);
 	int AddMark(int line, int markerNum);
 	void AddMarkSet(int line, int valueSet);
 	void DeleteMark(int line, int markerNum);
 	void DeleteMarkFromHandle(int markerHandle);
 	void DeleteAllMarks(int markerNum);
-	int LineFromHandle(int markerHandle) { return cb.LineFromHandle(markerHandle); }
+	int LineFromHandle(int markerHandle);
 	int LineStart(int line) const;
 	int LineEnd(int line) const;
-	int LineEndPosition(int position);
-	int VCHomePosition(int position);
+	int LineEndPosition(int position) const;
+	bool IsLineEndPosition(int position) const;
+	int VCHomePosition(int position) const;
 
 	int SetLevel(int line, int level);
-	int GetLevel(int line) { return cb.GetLevel(line); }
-	void ClearLevels() { cb.ClearLevels(); }
+	int GetLevel(int line);
+	void ClearLevels();
 	int GetLastChild(int lineParent, int level=-1);
 	int GetFoldParent(int line);
 
@@ -236,7 +267,7 @@ public:
 	void SetStylingBits(int bits);
 	void StartStyling(int position, char mask);
 	bool SetStyleFor(int length, char style);
-	bool SetStyles(int length, char *styles);
+	bool SetStyles(int length, const char *styles);
 	int GetEndStyled() { return endStyled; }
 	void EnsureStyledTo(int pos);
 	int GetStyleClock() { return styleClock; }
@@ -244,8 +275,24 @@ public:
 	void DecorationFillRange(int position, int value, int fillLength);
 
 	int SetLineState(int line, int state);
-	int GetLineState(int line) { return cb.GetLineState(line); }
-	int GetMaxLineState() { return cb.GetMaxLineState(); }
+	int GetLineState(int line);
+	int GetMaxLineState();
+
+	StyledText MarginStyledText(int line);
+	void MarginSetStyle(int line, int style);
+	void MarginSetStyles(int line, const unsigned char *styles);
+	void MarginSetText(int line, const char *text);
+	int MarginLength(int line) const;
+	void MarginClearAll();
+
+	bool AnnotationAny() const;
+	StyledText AnnotationStyledText(int line);
+	void AnnotationSetText(int line, const char *text);
+	void AnnotationSetStyle(int line, int style);
+	void AnnotationSetStyles(int line, const unsigned char *styles);
+	int AnnotationLength(int line) const;
+	int AnnotationLines(int line) const;
+	void AnnotationClearAll();
 
 	bool AddWatcher(DocWatcher *watcher, void *userData);
 	bool RemoveWatcher(DocWatcher *watcher, void *userData);
@@ -273,6 +320,27 @@ private:
 	void NotifyModified(DocModification mh);
 };
 
+class UndoGroup {
+	Document *pdoc;
+	bool groupNeeded;
+public:
+	UndoGroup(Document *pdoc_, bool groupNeeded_=true) : 
+		pdoc(pdoc_), groupNeeded(groupNeeded_) {
+		if (groupNeeded) {
+			pdoc->BeginUndoAction();
+		}
+	}
+	~UndoGroup() {
+		if (groupNeeded) {
+			pdoc->EndUndoAction();
+		}
+	}
+	bool Needed() const {
+		return groupNeeded;
+	}
+};
+
+
 /**
  * To optimise processing of document modifications by DocWatchers, a hint is passed indicating the
  * scope of the change.
@@ -288,6 +356,8 @@ public:
  	int line;
 	int foldLevelNow;
 	int foldLevelPrev;
+	int annotationLinesAdded;
+	int token;
 
 	DocModification(int modificationType_, int position_=0, int length_=0,
 		int linesAdded_=0, const char *text_=0, int line_=0) :
@@ -298,7 +368,9 @@ public:
 		text(text_),
 		line(line_),
 		foldLevelNow(0),
-		foldLevelPrev(0) {}
+		foldLevelPrev(0),
+		annotationLinesAdded(0),
+		token(0) {}
 
 	DocModification(int modificationType_, const Action &act, int linesAdded_=0) :
 		modificationType(modificationType_),
@@ -308,7 +380,9 @@ public:
 		text(act.data),
 		line(0),
 		foldLevelNow(0),
-		foldLevelPrev(0) {}
+		foldLevelPrev(0),
+		annotationLinesAdded(0),
+		token(0) {}
 };
 
 /**
diff --git a/plugins/scintilla/scintilla/DocumentAccessor.h b/plugins/scintilla/scintilla/DocumentAccessor.h
index a3a939d..9244042 100644
--- a/plugins/scintilla/scintilla/DocumentAccessor.h
+++ b/plugins/scintilla/scintilla/DocumentAccessor.h
@@ -14,6 +14,7 @@ class Document;
 
 /**
  */
+
 class DocumentAccessor : public Accessor {
 	// Private so DocumentAccessor objects can not be copied
 	DocumentAccessor(const DocumentAccessor &source) : Accessor(), props(source.props) {}
@@ -21,7 +22,7 @@ class DocumentAccessor : public Accessor {
 
 protected:
 	Document *pdoc;
-	PropSet &props;
+	PropertyGet &props;
 	WindowID id;
 	int lenDoc;
 
@@ -37,7 +38,7 @@ protected:
 	void Fill(int position);
 
 public:
-	DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) : 
+	DocumentAccessor(Document *pdoc_, PropertyGet &props_, WindowID id_=0) : 
 		Accessor(), pdoc(pdoc_), props(props_), id(id_),
 		lenDoc(-1), validLen(0), chFlags(0), chWhile(0), 
 		startSeg(0), startPosStyling(0),
diff --git a/plugins/scintilla/scintilla/Editor.cxx b/plugins/scintilla/scintilla/Editor.cxx
index ffc2dee..2407d2b 100644
--- a/plugins/scintilla/scintilla/Editor.cxx
+++ b/plugins/scintilla/scintilla/Editor.cxx
@@ -10,11 +10,19 @@
 #include <stdio.h>
 #include <ctype.h>
 
+#include <string>
+#include <vector>
+
+// With Borland C++ 5.5, including <string> includes Windows.h leading to defining
+// FindText to FindTextA which makes calls here to Document::FindText fail.
+#ifdef __BORLANDC__
+#ifdef FindText
+#undef FindText
+#endif
+#endif
+
 #include "Platform.h"
 
-#ifndef PLAT_QT
-#define INCLUDE_DEPRECATED_FEATURES
-#endif
 #include "Scintilla.h"
 
 #include "SplitVector.h"
@@ -31,6 +39,7 @@
 #include "CharClassify.h"
 #include "Decoration.h"
 #include "Document.h"
+#include "Selection.h"
 #include "PositionCache.h"
 #include "Editor.h"
 
@@ -111,18 +120,14 @@ Editor::Editor() {
 	ptMouseLast.y = 0;
 	inDragDrop = ddNone;
 	dropWentOutside = false;
-	posDrag = invalidPosition;
-	posDrop = invalidPosition;
+	posDrag = SelectionPosition(invalidPosition);
+	posDrop = SelectionPosition(invalidPosition);
 	selectionType = selChar;
 
 	lastXChosen = 0;
 	lineAnchor = 0;
 	originalAnchorPos = 0;
 
-	selType = selStream;
-	moveExtendsSelection = false;
-	xStartSelect = 0;
-	xEndSelect = 0;
 	primarySelection = true;
 
 	caretXPolicy = CARET_SLOP | CARET_EVEN;
@@ -142,6 +147,10 @@ Editor::Editor() {
 	verticalScrollBarVisible = true;
 	endAtLastLine = true;
 	caretSticky = false;
+	multipleSelection = false;
+	additionalSelectionTyping = false;
+	additionalCaretsBlink = true;
+	virtualSpaceOptions = SCVS_NONE;
 
 	pixmapLine = Surface::Allocate();
 	pixmapSelMargin = Surface::Allocate();
@@ -149,9 +158,6 @@ Editor::Editor() {
 	pixmapIndentGuide = Surface::Allocate();
 	pixmapIndentGuideHighlight = Surface::Allocate();
 
-	currentPos = 0;
-	anchor = 0;
-
 	targetStart = 0;
 	targetEnd = 0;
 	searchFlags = 0;
@@ -187,7 +193,8 @@ Editor::Editor() {
 	wrapVisualFlags = 0;
 	wrapVisualFlagsLocation = 0;
 	wrapVisualStartIndent = 0;
-	actualWrapVisualStartIndent = 0;
+	wrapIndentMode = SC_WRAPINDENT_FIXED;
+	wrapAddIndent = 0;
 
 	convertPastes = true;
 
@@ -229,10 +236,6 @@ void Editor::InvalidateStyleData() {
 	palette.Release();
 	llc.Invalidate(LineLayout::llInvalid);
 	posCache.Clear();
-	if (selType == selRectangle) {
-		xStartSelect = XFromPosition(anchor);
-		xEndSelect = XFromPosition(currentPos);
-	}
 }
 
 void Editor::InvalidateStyleRedraw() {
@@ -255,7 +258,17 @@ void Editor::RefreshStyleData() {
 			palette.Allocate(wMain);
 			RefreshColourPalette(palette, false);
 		}
+		if (wrapIndentMode == SC_WRAPINDENT_INDENT) {
+			wrapAddIndent = pdoc->IndentSize() * vs.spaceWidth;
+		} else if (wrapIndentMode == SC_WRAPINDENT_SAME) {
+			wrapAddIndent = 0;
+		} else { //SC_WRAPINDENT_FIXED
+			wrapAddIndent = wrapVisualStartIndent * vs.aveCharWidth;
+			if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (wrapAddIndent <= 0))
+				wrapAddIndent = vs.aveCharWidth; // must indent to show start visual
+		}
 		SetScrollBars();
+		SetRectangularRange();
 	}
 }
 
@@ -340,98 +353,25 @@ public:
 	}
 };
 
-#ifdef SCI_NAMESPACE
-namespace Scintilla {
-#endif
-
-/**
- * Allows to iterate through the lines of a selection.
- * Althought it can be called for a stream selection, in most cases
- * it is inefficient and it should be used only for
- * a rectangular or a line selection.
- */
-class SelectionLineIterator {
-private:
-	Editor *ed;
-	int line;	///< Current line within the iteration.
-	bool forward;	///< True if iterating by increasing line number, false otherwise.
-	int selStart, selEnd;	///< Positions of the start and end of the selection relative to the start of the document.
-	int minX, maxX;	///< Left and right of selection rectangle.
-
-public:
-	int lineStart, lineEnd;	///< Line numbers, first and last lines of the selection.
-	int startPos, endPos;	///< Positions of the beginning and end of the selection on the current line.
-
-	void Reset() {
-		if (forward) {
-			line = lineStart;
-		} else {
-			line = lineEnd;
-		}
-	}
-
-	SelectionLineIterator(Editor *ed_, bool forward_ = true) : line(0), startPos(0), endPos(0) {
-		ed = ed_;
-		forward = forward_;
-		selStart = ed->SelectionStart();
-		selEnd = ed->SelectionEnd();
-		lineStart = ed->pdoc->LineFromPosition(selStart);
-		lineEnd = ed->pdoc->LineFromPosition(selEnd);
-		// Left of rectangle
-		minX = Platform::Minimum(ed->xStartSelect, ed->xEndSelect);
-		// Right of rectangle
-		maxX = Platform::Maximum(ed->xStartSelect, ed->xEndSelect);
-		Reset();
-	}
-	~SelectionLineIterator() {}
-
-	void SetAt(int line) {
-		if (line < lineStart || line > lineEnd) {
-			startPos = endPos = INVALID_POSITION;
-		} else {
-			if (ed->selType == ed->selRectangle) {
-				// Measure line and return character closest to minX
-				startPos = ed->PositionFromLineX(line, minX);
-				// Measure line and return character closest to maxX
-				endPos = ed->PositionFromLineX(line, maxX);
-			} else if (ed->selType == ed->selLines) {
-				startPos = ed->pdoc->LineStart(line);
-				endPos = ed->pdoc->LineStart(line + 1);
-			} else {	// Stream selection, here only for completion
-				if (line == lineStart) {
-					startPos = selStart;
-				} else {
-					startPos = ed->pdoc->LineStart(line);
-				}
-				if (line == lineEnd) {
-					endPos = selEnd;
-				} else {
-					endPos = ed->pdoc->LineStart(line + 1);
-				}
-			}
-		}
-	}
-	bool Iterate() {
-		SetAt(line);
-		if (forward) {
-			line++;
-		} else {
-			line--;
-		}
-		return startPos != INVALID_POSITION;
+SelectionPosition Editor::ClampPositionIntoDocument(SelectionPosition sp) const {
+	if (sp.Position() < 0) {
+		return SelectionPosition(0);
+	} else if (sp.Position() > pdoc->Length()) {
+		return SelectionPosition(pdoc->Length());
+	} else {
+		// If not at end of line then set offset to 0
+		if (!pdoc->IsLineEndPosition(sp.Position())) 
+			sp.SetVirtualSpace(0);
+		return sp;
 	}
-};
-
-#ifdef SCI_NAMESPACE
 }
-#endif
 
-Point Editor::LocationFromPosition(int pos) {
+Point Editor::LocationFromPosition(SelectionPosition pos) {
 	Point pt;
 	RefreshStyleData();
-	if (pos == INVALID_POSITION)
+	if (pos.Position() == INVALID_POSITION)
 		return pt;
-	int line = pdoc->LineFromPosition(pos);
+	int line = pdoc->LineFromPosition(pos.Position());
 	int lineVisible = cs.DisplayFromDoc(line);
 	//Platform::DebugPrintf("line=%d\n", line);
 	AutoSurface surface(this);
@@ -442,7 +382,7 @@ Point Editor::LocationFromPosition(int pos) {
 		pt.x = 0;
 		unsigned int posLineStart = pdoc->LineStart(line);
 		LayoutLine(line, surface, vs, ll, wrapWidth);
-		int posInLine = pos - posLineStart;
+		int posInLine = pos.Position() - posLineStart;
 		// In case of very long line put x at arbitrary large position
 		if (posInLine > ll->maxLineLength) {
 			pt.x = ll->positions[ll->maxLineLength] - ll->positions[ll->LineStart(ll->lines)];
@@ -451,10 +391,10 @@ Point Editor::LocationFromPosition(int pos) {
 		for (int subLine = 0; subLine < ll->lines; subLine++) {
 			if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine + 1))) {
 				pt.x = ll->positions[posInLine] - ll->positions[ll->LineStart(subLine)];
-				if (actualWrapVisualStartIndent != 0) {
+				if (ll->wrapIndent != 0) {
 					int lineStart = ll->LineStart(subLine);
 					if (lineStart != 0)	// Wrapped
-						pt.x += actualWrapVisualStartIndent * vs.aveCharWidth;
+						pt.x += ll->wrapIndent;
 				}
 			}
 			if (posInLine >= ll->LineStart(subLine)) {
@@ -463,14 +403,24 @@ Point Editor::LocationFromPosition(int pos) {
 		}
 		pt.x += vs.fixedColumnWidth - xOffset;
 	}
+	pt.x += pos.VirtualSpace() * static_cast<int>(vs.styles[ll->EndLineStyle()].spaceWidth);
 	return pt;
 }
 
+Point Editor::LocationFromPosition(int pos) {
+	return LocationFromPosition(SelectionPosition(pos));
+}
+
 int Editor::XFromPosition(int pos) {
 	Point pt = LocationFromPosition(pos);
 	return pt.x - vs.fixedColumnWidth + xOffset;
 }
 
+int Editor::XFromPosition(SelectionPosition sp) {
+	Point pt = LocationFromPosition(sp);
+	return pt.x - vs.fixedColumnWidth + xOffset;
+}
+
 int Editor::LineFromLocation(Point pt) {
 	return cs.DocFromDisplay(pt.y / vs.lineHeight + topLine);
 }
@@ -480,20 +430,31 @@ void Editor::SetTopLine(int topLineNew) {
 	posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine));
 }
 
-int Editor::PositionFromLocation(Point pt) {
+SelectionPosition Editor::SPositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition, bool virtualSpace) {
 	RefreshStyleData();
+	if (canReturnInvalid) {
+		PRectangle rcClient = GetTextRectangle();
+		if (!rcClient.Contains(pt))
+			return SelectionPosition(INVALID_POSITION);
+		if (pt.x < vs.fixedColumnWidth)
+			return SelectionPosition(INVALID_POSITION);
+		if (pt.y < 0)
+			return SelectionPosition(INVALID_POSITION);
+	}
 	pt.x = pt.x - vs.fixedColumnWidth + xOffset;
 	int visibleLine = pt.y / vs.lineHeight + topLine;
 	if (pt.y < 0) {	// Division rounds towards 0
 		visibleLine = (pt.y - (vs.lineHeight - 1)) / vs.lineHeight + topLine;
 	}
-	if (visibleLine < 0)
+	if (!canReturnInvalid && (visibleLine < 0))
 		visibleLine = 0;
 	int lineDoc = cs.DocFromDisplay(visibleLine);
+	if (canReturnInvalid && (lineDoc < 0))
+		return SelectionPosition(INVALID_POSITION);
 	if (lineDoc >= pdoc->LinesTotal())
-		return pdoc->Length();
+		return SelectionPosition(canReturnInvalid ? INVALID_POSITION : pdoc->Length());
 	unsigned int posLineStart = pdoc->LineStart(lineDoc);
-	int retVal = posLineStart;
+	SelectionPosition retVal(canReturnInvalid ? INVALID_POSITION : static_cast<int>(posLineStart));
 	AutoSurface surface(this);
 	AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
 	if (surface && ll) {
@@ -505,84 +466,91 @@ int Editor::PositionFromLocation(Point pt) {
 			int lineEnd = ll->LineLastVisible(subLine);
 			int subLineStart = ll->positions[lineStart];
 
-			if (actualWrapVisualStartIndent != 0) {
+			if (ll->wrapIndent != 0) {
 				if (lineStart != 0)	// Wrapped
-					pt.x -= actualWrapVisualStartIndent * vs.aveCharWidth;
+					pt.x -= ll->wrapIndent;
 			}
 			int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd);
 			while (i < lineEnd) {
-				if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
-					return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
+				if (charPosition) {
+					if ((pt.x + subLineStart) < (ll->positions[i + 1])) {
+						return SelectionPosition(pdoc->MovePositionOutsideChar(i + posLineStart, 1));
+					}
+				} else {
+					if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
+						return SelectionPosition(pdoc->MovePositionOutsideChar(i + posLineStart, 1));
+					}
 				}
 				i++;
 			}
-			return lineEnd + posLineStart;
+			if (virtualSpace) {
+				const int spaceWidth = static_cast<int>(vs.styles[ll->EndLineStyle()].spaceWidth);
+				int spaceOffset = (pt.x + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) / 
+					spaceWidth;
+				return SelectionPosition(lineEnd + posLineStart, spaceOffset);
+			} else if (canReturnInvalid) {
+				if (pt.x < (ll->positions[lineEnd] - subLineStart)) {
+					return SelectionPosition(pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1));
+				}
+			} else {
+				return SelectionPosition(lineEnd + posLineStart);
+			}
 		}
-		retVal = ll->numCharsInLine + posLineStart;
+		if (!canReturnInvalid)
+			return SelectionPosition(ll->numCharsInLine + posLineStart);
 	}
 	return retVal;
 }
 
-// Like PositionFromLocation but INVALID_POSITION returned when not near any text.
-int Editor::PositionFromLocationClose(Point pt) {
+int Editor::PositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition) {
+	return SPositionFromLocation(pt, canReturnInvalid, charPosition, false).Position();
+}
+
+/**
+ * Find the document position corresponding to an x coordinate on a particular document line.
+ * Ensure is between whole characters when document is in multi-byte or UTF-8 mode.
+ */
+int Editor::PositionFromLineX(int lineDoc, int x) {
 	RefreshStyleData();
-	PRectangle rcClient = GetTextRectangle();
-	if (!rcClient.Contains(pt))
-		return INVALID_POSITION;
-	if (pt.x < vs.fixedColumnWidth)
-		return INVALID_POSITION;
-	if (pt.y < 0)
-		return INVALID_POSITION;
-	pt.x = pt.x - vs.fixedColumnWidth + xOffset;
-	int visibleLine = pt.y / vs.lineHeight + topLine;
-	if (pt.y < 0) {	// Division rounds towards 0
-		visibleLine = (pt.y - (vs.lineHeight - 1)) / vs.lineHeight + topLine;
-	}
-	int lineDoc = cs.DocFromDisplay(visibleLine);
-	if (lineDoc < 0)
-		return INVALID_POSITION;
 	if (lineDoc >= pdoc->LinesTotal())
-		return INVALID_POSITION;
+		return pdoc->Length();
+	//Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);
 	AutoSurface surface(this);
 	AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
+	int retVal = 0;
 	if (surface && ll) {
-		LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
 		unsigned int posLineStart = pdoc->LineStart(lineDoc);
-		int lineStartSet = cs.DisplayFromDoc(lineDoc);
-		int subLine = visibleLine - lineStartSet;
-		if (subLine < ll->lines) {
-			int lineStart = ll->LineStart(subLine);
-			int lineEnd = ll->LineLastVisible(subLine);
-			int subLineStart = ll->positions[lineStart];
+		LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
+		retVal = ll->numCharsBeforeEOL + posLineStart;
+		int subLine = 0;
+		int lineStart = ll->LineStart(subLine);
+		int lineEnd = ll->LineLastVisible(subLine);
+		int subLineStart = ll->positions[lineStart];
 
-			if (actualWrapVisualStartIndent != 0) {
-				if (lineStart != 0)	// Wrapped
-					pt.x -= actualWrapVisualStartIndent * vs.aveCharWidth;
-			}
-			int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd);
-			while (i < lineEnd) {
-				if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
-					return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
-				}
-				i++;
-			}
-			if (pt.x < (ll->positions[lineEnd] - subLineStart)) {
-				return pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1);
+		if (ll->wrapIndent != 0) {
+			if (lineStart != 0)	// Wrapped
+				x -= ll->wrapIndent;
+		}
+		int i = ll->FindBefore(x + subLineStart, lineStart, lineEnd);
+		while (i < lineEnd) {
+			if ((x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
+				retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1);
+				break;
 			}
+			i++;
 		}
 	}
-
-	return INVALID_POSITION;
+	return retVal;
 }
 
 /**
  * Find the document position corresponding to an x coordinate on a particular document line.
  * Ensure is between whole characters when document is in multi-byte or UTF-8 mode.
  */
-int Editor::PositionFromLineX(int lineDoc, int x) {
+SelectionPosition Editor::SPositionFromLineX(int lineDoc, int x) {
 	RefreshStyleData();
 	if (lineDoc >= pdoc->LinesTotal())
-		return pdoc->Length();
+		return SelectionPosition(pdoc->Length());
 	//Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);
 	AutoSurface surface(this);
 	AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
@@ -590,26 +558,28 @@ int Editor::PositionFromLineX(int lineDoc, int x) {
 	if (surface && ll) {
 		unsigned int posLineStart = pdoc->LineStart(lineDoc);
 		LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
-		retVal = ll->numCharsInLine + posLineStart;
 		int subLine = 0;
 		int lineStart = ll->LineStart(subLine);
 		int lineEnd = ll->LineLastVisible(subLine);
 		int subLineStart = ll->positions[lineStart];
 
-		if (actualWrapVisualStartIndent != 0) {
+		if (ll->wrapIndent != 0) {
 			if (lineStart != 0)	// Wrapped
-				x -= actualWrapVisualStartIndent * vs.aveCharWidth;
+				x -= ll->wrapIndent;
 		}
 		int i = ll->FindBefore(x + subLineStart, lineStart, lineEnd);
 		while (i < lineEnd) {
 			if ((x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
 				retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1);
-				break;
+				return SelectionPosition(retVal);
 			}
 			i++;
 		}
+		const int spaceWidth = static_cast<int>(vs.styles[ll->EndLineStyle()].spaceWidth);
+		int spaceOffset = (x + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) / spaceWidth;
+		return SelectionPosition(lineEnd + posLineStart, spaceOffset);
 	}
-	return retVal;
+	return SelectionPosition(retVal);
 }
 
 /**
@@ -697,80 +667,113 @@ void Editor::InvalidateRange(int start, int end) {
 }
 
 int Editor::CurrentPosition() {
-	return currentPos;
+	return sel.MainCaret();
 }
 
 bool Editor::SelectionEmpty() {
-	return anchor == currentPos;
+	return sel.Empty();
 }
 
-int Editor::SelectionStart() {
-	return Platform::Minimum(currentPos, anchor);
+SelectionPosition Editor::SelectionStart() {
+	return sel.RangeMain().Start();
 }
 
-int Editor::SelectionEnd() {
-	return Platform::Maximum(currentPos, anchor);
+SelectionPosition Editor::SelectionEnd() {
+	return sel.RangeMain().End();
 }
 
 void Editor::SetRectangularRange() {
-	if (selType == selRectangle) {
-		xStartSelect = XFromPosition(anchor);
-		xEndSelect = XFromPosition(currentPos);
+	if (sel.IsRectangular()) {
+		int xAnchor = XFromPosition(sel.Rectangular().anchor);
+		int xCaret = XFromPosition(sel.Rectangular().caret);
+		if (sel.selType == Selection::selThin) {
+			xCaret = xAnchor;
+		}
+		int lineAnchor = pdoc->LineFromPosition(sel.Rectangular().anchor.Position());
+		int lineCaret = pdoc->LineFromPosition(sel.Rectangular().caret.Position());
+		int increment = (lineCaret > lineAnchor) ? 1 : -1;
+		for (int line=lineAnchor; line != lineCaret+increment; line += increment) {
+			SelectionRange range(SPositionFromLineX(line, xCaret), SPositionFromLineX(line, xAnchor));
+			if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) == 0)
+				range.ClearVirtualSpace();
+			if (line == lineAnchor)
+				sel.SetSelection(range);
+			else
+				sel.AddSelection(range);
+		}
 	}
 }
 
-void Editor::InvalidateSelection(int currentPos_, int anchor_, bool invalidateWholeSelection) {
-	if (anchor != anchor_ || selType == selRectangle) {
+void Editor::InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection) {
+	if (sel.Count() > 1 || !(sel.RangeMain().anchor == newMain.anchor) || sel.IsRectangular()) {
 		invalidateWholeSelection = true;
 	}
-	int firstAffected = currentPos;
+	int firstAffected = Platform::Minimum(sel.RangeMain().Start().Position(), newMain.Start().Position());
+	// +1 for lastAffected ensures caret repainted
+	int lastAffected = Platform::Maximum(newMain.caret.Position()+1, newMain.anchor.Position());
+	lastAffected = Platform::Maximum(lastAffected, sel.RangeMain().End().Position());
 	if (invalidateWholeSelection) {
-		if (firstAffected > anchor)
-			firstAffected = anchor;
-		if (firstAffected > anchor_)
-			firstAffected = anchor_;
-	}
-	if (firstAffected > currentPos_)
-		firstAffected = currentPos_;
-	int lastAffected = currentPos;
-	if (invalidateWholeSelection) {
-		if (lastAffected < anchor)
-			lastAffected = anchor;
-		if (lastAffected < anchor_)
-			lastAffected = anchor_;
+		for (size_t r=0; r<sel.Count(); r++) {
+			firstAffected = Platform::Minimum(firstAffected, sel.Range(r).caret.Position());
+			firstAffected = Platform::Minimum(firstAffected, sel.Range(r).anchor.Position());
+			lastAffected = Platform::Maximum(lastAffected, sel.Range(r).caret.Position()+1);
+			lastAffected = Platform::Maximum(lastAffected, sel.Range(r).anchor.Position());
+		}
 	}
-	if (lastAffected < (currentPos_ + 1))	// +1 ensures caret repainted
-		lastAffected = (currentPos_ + 1);
 	needUpdateUI = true;
 	InvalidateRange(firstAffected, lastAffected);
 }
 
-void Editor::SetSelection(int currentPos_, int anchor_) {
-	currentPos_ = pdoc->ClampPositionIntoDocument(currentPos_);
-	anchor_ = pdoc->ClampPositionIntoDocument(anchor_);
-	if ((currentPos != currentPos_) || (anchor != anchor_)) {
-		InvalidateSelection(currentPos_, anchor_, true);
-		currentPos = currentPos_;
-		anchor = anchor_;
+void Editor::SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_) {
+	SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_), 
+		ClampPositionIntoDocument(anchor_));
+	if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) {
+		InvalidateSelection(rangeNew);
 	}
+	sel.RangeMain() = rangeNew;
 	SetRectangularRange();
 	ClaimSelection();
 }
 
+void Editor::SetSelection(int currentPos_, int anchor_) {
+	SetSelection(SelectionPosition(currentPos_), SelectionPosition(anchor_));
+}
+
+// Just move the caret on the main selection
+void Editor::SetSelection(SelectionPosition currentPos_) {
+	currentPos_ = ClampPositionIntoDocument(currentPos_);
+	if (sel.Count() > 1 || !(sel.RangeMain().caret == currentPos_)) {
+		InvalidateSelection(SelectionRange(currentPos_));
+	}
+	if (sel.IsRectangular()) {
+		sel.Rectangular() =
+			SelectionRange(SelectionPosition(currentPos_), sel.Rectangular().anchor);
+		SetRectangularRange();
+	} else {
+		sel.RangeMain() =
+			SelectionRange(SelectionPosition(currentPos_), sel.RangeMain().anchor);
+	}
+	ClaimSelection();
+}
+
 void Editor::SetSelection(int currentPos_) {
-	currentPos_ = pdoc->ClampPositionIntoDocument(currentPos_);
-	if (currentPos != currentPos_) {
-		InvalidateSelection(currentPos_, anchor, false);
-		currentPos = currentPos_;
+	SetSelection(SelectionPosition(currentPos_));
+}
+
+void Editor::SetEmptySelection(SelectionPosition currentPos_) {
+	SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_));
+	if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) {
+		InvalidateSelection(rangeNew);
 	}
+	sel.Clear();
+	sel.RangeMain() = rangeNew;
 	SetRectangularRange();
 	ClaimSelection();
+
 }
 
 void Editor::SetEmptySelection(int currentPos_) {
-	selType = selStream;
-	moveExtendsSelection = false;
-	SetSelection(currentPos_, currentPos_);
+	SetEmptySelection(SelectionPosition(currentPos_));
 }
 
 bool Editor::RangeContainsProtected(int start, int end) const {
@@ -790,54 +793,59 @@ bool Editor::RangeContainsProtected(int start, int end) const {
 }
 
 bool Editor::SelectionContainsProtected() {
-	// DONE, but untested...: make support rectangular selection
-	bool scp = false;
-	if (selType == selStream) {
-		scp = RangeContainsProtected(anchor, currentPos);
-	} else {
-		SelectionLineIterator lineIterator(this);
-		while (lineIterator.Iterate()) {
-			if (RangeContainsProtected(lineIterator.startPos, lineIterator.endPos)) {
-				scp = true;
-				break;
-			}
+	for (size_t r=0; r<sel.Count(); r++) {
+		if (RangeContainsProtected(sel.Range(r).Start().Position(), 
+			sel.Range(r).End().Position())) {
+			return true;
 		}
 	}
-	return scp;
+	return false;
 }
 
 /**
  * Asks document to find a good position and then moves out of any invisible positions.
  */
-int Editor::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
-	pos = pdoc->MovePositionOutsideChar(pos, moveDir, checkLineEnd);
+int Editor::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) const {
+	return MovePositionOutsideChar(SelectionPosition(pos), moveDir, checkLineEnd).Position();
+}
+
+SelectionPosition Editor::MovePositionOutsideChar(SelectionPosition pos, int moveDir, bool checkLineEnd) const {
+	int posMoved = pdoc->MovePositionOutsideChar(pos.Position(), moveDir, checkLineEnd);
+	if (posMoved != pos.Position())
+		pos.SetPosition(posMoved);
 	if (vs.ProtectionActive()) {
 		int mask = pdoc->stylingBitsMask;
 		if (moveDir > 0) {
-			if ((pos > 0) && vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()) {
-				while ((pos < pdoc->Length()) &&
-				        (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()))
-					pos++;
+			if ((pos.Position() > 0) && vs.styles[pdoc->StyleAt(pos.Position() - 1) & mask].IsProtected()) {
+				while ((pos.Position() < pdoc->Length()) &&
+				        (vs.styles[pdoc->StyleAt(pos.Position()) & mask].IsProtected()))
+					pos.Add(1);
 			}
 		} else if (moveDir < 0) {
-			if (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()) {
-				while ((pos > 0) &&
-				        (vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()))
-					pos--;
+			if (vs.styles[pdoc->StyleAt(pos.Position()) & mask].IsProtected()) {
+				while ((pos.Position() > 0) &&
+				        (vs.styles[pdoc->StyleAt(pos.Position() - 1) & mask].IsProtected()))
+					pos.Add(-1);
 			}
 		}
 	}
 	return pos;
 }
 
-int Editor::MovePositionTo(int newPos, selTypes sel, bool ensureVisible) {
-	int delta = newPos - currentPos;
-	newPos = pdoc->ClampPositionIntoDocument(newPos);
+int Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, bool ensureVisible) {
+	int delta = newPos.Position() - sel.MainCaret();
+	newPos = ClampPositionIntoDocument(newPos);
 	newPos = MovePositionOutsideChar(newPos, delta);
-	if (sel != noSel) {
-		selType = sel;
+	if (!sel.IsRectangular() && (selt == Selection::selRectangle)) {
+		// Switching to rectangular
+		SelectionRange rangeMain = sel.RangeMain();
+		sel.Clear();
+		sel.Rectangular() = rangeMain;
 	}
-	if (sel != noSel || moveExtendsSelection) {
+	if (selt != Selection::noSel) {
+		sel.selType = selt;
+	}
+	if (selt != Selection::noSel || sel.MoveExtends()) {
 		SetSelection(newPos);
 	} else {
 		SetEmptySelection(newPos);
@@ -846,14 +854,17 @@ int Editor::MovePositionTo(int newPos, selTypes sel, bool ensureVisible) {
 	if (ensureVisible) {
 		EnsureCaretVisible();
 	}
-	NotifyMove(newPos);
 	return 0;
 }
 
-int Editor::MovePositionSoVisible(int pos, int moveDir) {
-	pos = pdoc->ClampPositionIntoDocument(pos);
+int Editor::MovePositionTo(int newPos, Selection::selTypes selt, bool ensureVisible) {
+	return MovePositionTo(SelectionPosition(newPos), selt, ensureVisible);
+}
+
+SelectionPosition Editor::MovePositionSoVisible(SelectionPosition pos, int moveDir) {
+	pos = ClampPositionIntoDocument(pos);
 	pos = MovePositionOutsideChar(pos, moveDir);
-	int lineDoc = pdoc->LineFromPosition(pos);
+	int lineDoc = pdoc->LineFromPosition(pos.Position());
 	if (cs.GetVisible(lineDoc)) {
 		return pos;
 	} else {
@@ -861,20 +872,28 @@ int Editor::MovePositionSoVisible(int pos, int moveDir) {
 		if (moveDir > 0) {
 			// lineDisplay is already line before fold as lines in fold use display line of line after fold
 			lineDisplay = Platform::Clamp(lineDisplay, 0, cs.LinesDisplayed());
-			return pdoc->LineStart(cs.DocFromDisplay(lineDisplay));
+			return SelectionPosition(pdoc->LineStart(cs.DocFromDisplay(lineDisplay)));
 		} else {
 			lineDisplay = Platform::Clamp(lineDisplay - 1, 0, cs.LinesDisplayed());
-			return pdoc->LineEnd(cs.DocFromDisplay(lineDisplay));
+			return SelectionPosition(pdoc->LineEnd(cs.DocFromDisplay(lineDisplay)));
 		}
 	}
 }
 
+SelectionPosition Editor::MovePositionSoVisible(int pos, int moveDir) {
+	return MovePositionSoVisible(SelectionPosition(pos), moveDir);
+}
+
+Point Editor::PointMainCaret() {
+	return LocationFromPosition(sel.Range(sel.Main()).caret);
+}
+
 /**
  * Choose the x position that the caret will try to stick to
  * as it moves up and down.
  */
 void Editor::SetLastXChosen() {
-	Point pt = LocationFromPosition(currentPos);
+	Point pt = PointMainCaret();
 	lastXChosen = pt.x;
 }
 
@@ -919,16 +938,16 @@ void Editor::HorizontalScrollTo(int xPos) {
 
 void Editor::MoveCaretInsideView(bool ensureVisible) {
 	PRectangle rcClient = GetTextRectangle();
-	Point pt = LocationFromPosition(currentPos);
+	Point pt = PointMainCaret();
 	if (pt.y < rcClient.top) {
-		MovePositionTo(PositionFromLocation(
+		MovePositionTo(SPositionFromLocation(
 		            Point(lastXChosen, rcClient.top)),
-		        noSel, ensureVisible);
+					Selection::noSel, ensureVisible);
 	} else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) {
 		int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight;
-		MovePositionTo(PositionFromLocation(
+		MovePositionTo(SPositionFromLocation(
 		            Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)),
-		        noSel, ensureVisible);
+		        Selection::noSel, ensureVisible);
 	}
 }
 
@@ -979,7 +998,7 @@ This way, we favour the displaying of useful information: the begining of lines,
 where most code reside, and the lines after the caret, eg. the body of a function.
 
      |        |       |      |                                            |
-slop | strict | jumps | even | Caret can go to the margin                 | When reaching limitÝ(caret going out of
+slop | strict | jumps | even | Caret can go to the margin                 | When reaching limit (caret going out of
      |        |       |      |                                            | visibility or going into the UZ) display is...
 -----+--------+-------+------+--------------------------------------------+--------------------------------------------------------------
   0  |   0    |   0   |   0  | Yes                                        | moved to put caret on top/on right
@@ -1000,14 +1019,14 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
 	//Platform::DebugPrintf("EnsureCaretVisible %d %s\n", xOffset, useMargin ? " margin" : " ");
 	PRectangle rcClient = GetTextRectangle();
 	//int rcClientFullWidth = rcClient.Width();
-	int posCaret = currentPos;
-	if (posDrag >= 0) {
+	SelectionPosition posCaret = sel.RangeMain().caret;
+	if (posDrag.IsValid()) {
 		posCaret = posDrag;
 	}
 	Point pt = LocationFromPosition(posCaret);
 	Point ptBottomCaret = pt;
 	ptBottomCaret.y += vs.lineHeight - 1;
-	int lineCaret = DisplayFromPosition(posCaret);
+	int lineCaret = DisplayFromPosition(posCaret.Position());
 	bool bSlop, bStrict, bJump, bEven;
 
 	// Vertical positioning
@@ -1244,10 +1263,13 @@ void Editor::DropCaret() {
 }
 
 void Editor::InvalidateCaret() {
-	if (posDrag >= 0)
-		InvalidateRange(posDrag, posDrag + 1);
-	else
-		InvalidateRange(currentPos, currentPos + 1);
+	if (posDrag.IsValid()) {
+		InvalidateRange(posDrag.Position(), posDrag.Position() + 1);
+	} else {
+		for (size_t r=0; r<sel.Count(); r++) {
+			InvalidateRange(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1);
+		}
+	}
 	UpdateSystemCaret();
 }
 
@@ -1277,13 +1299,14 @@ bool Editor::WrapOneLine(Surface *surface, int lineToWrap) {
 		LayoutLine(lineToWrap, surface, vs, ll, wrapWidth);
 		linesWrapped = ll->lines;
 	}
-	return cs.SetHeight(lineToWrap, linesWrapped);
+	return cs.SetHeight(lineToWrap, linesWrapped + 
+		(vs.annotationVisible ? pdoc->AnnotationLines(lineToWrap) : 0));
 }
 
 // Check if wrapping needed and perform any needed wrapping.
 // fullwrap: if true, all lines which need wrapping will be done,
 //           in this single call.
-// priorityWrapLineStart: If greater than zero, all lines starting from
+// priorityWrapLineStart: If greater than or equal to zero, all lines starting from
 //           here to 1 page + 100 lines past will be wrapped (even if there are
 //           more lines under wrapping process in idle).
 // If it is neither fullwrap, nor priorityWrap, then 1 page + 100 lines will be
@@ -1315,7 +1338,8 @@ bool Editor::WrapLines(bool fullWrap, int priorityWrapLineStart) {
 			if (wrapWidth != LineLayout::wrapWidthInfinite) {
 				wrapWidth = LineLayout::wrapWidthInfinite;
 				for (int lineDoc = 0; lineDoc < pdoc->LinesTotal(); lineDoc++) {
-					cs.SetHeight(lineDoc, 1);
+					cs.SetHeight(lineDoc, 1 + 
+						(vs.annotationVisible ? pdoc->AnnotationLines(lineDoc) : 0));
 				}
 				wrapOccurred = true;
 			}
@@ -1388,7 +1412,7 @@ bool Editor::WrapLines(bool fullWrap, int priorityWrapLineStart) {
 
 void Editor::LinesJoin() {
 	if (!RangeContainsProtected(targetStart, targetEnd)) {
-		pdoc->BeginUndoAction();
+		UndoGroup ug(pdoc);
 		bool prevNonWS = true;
 		for (int pos = targetStart; pos < targetEnd; pos++) {
 			if (IsEOLChar(pdoc->CharAt(pos))) {
@@ -1403,7 +1427,6 @@ void Editor::LinesJoin() {
 				prevNonWS = pdoc->CharAt(pos) != ' ';
 			}
 		}
-		pdoc->EndUndoAction();
 	}
 }
 
@@ -1426,7 +1449,7 @@ void Editor::LinesSplit(int pixelWidth) {
 		int lineStart = pdoc->LineFromPosition(targetStart);
 		int lineEnd = pdoc->LineFromPosition(targetEnd);
 		const char *eol = StringFromEOLMode(pdoc->eolMode);
-		pdoc->BeginUndoAction();
+		UndoGroup ug(pdoc);
 		for (int line = lineStart; line <= lineEnd; line++) {
 			AutoSurface surface(this);
 			AutoLineLayout ll(llc, RetrieveLineLayout(line));
@@ -1441,7 +1464,6 @@ void Editor::LinesSplit(int pixelWidth) {
 			}
 			lineEnd = pdoc->LineFromPosition(targetEnd);
 		}
-		pdoc->EndUndoAction();
 	}
 }
 
@@ -1457,6 +1479,84 @@ static int istrlen(const char *s) {
 	return static_cast<int>(strlen(s));
 }
 
+bool ValidStyledText(ViewStyle &vs, size_t styleOffset, const StyledText &st) {
+	if (st.multipleStyles) {
+		for (size_t iStyle=0;iStyle<st.length; iStyle++) {
+			if (!vs.ValidStyle(styleOffset + st.styles[iStyle]))
+				return false;
+		}
+	} else {
+		if (!vs.ValidStyle(styleOffset + st.style))
+			return false;
+	}
+	return true;
+}
+
+static int WidthStyledText(Surface *surface, ViewStyle &vs, int styleOffset,
+	const char *text, const unsigned char *styles, size_t len) {
+	int width = 0;
+	size_t start = 0;
+	while (start < len) {
+		size_t style = styles[start];
+		size_t endSegment = start;
+		while ((endSegment+1 < len) && (static_cast<size_t>(styles[endSegment+1]) == style))
+			endSegment++;
+		width += surface->WidthText(vs.styles[style+styleOffset].font, text + start, endSegment - start + 1);
+		start = endSegment + 1;
+	}
+	return width;
+}
+
+static int WidestLineWidth(Surface *surface, ViewStyle &vs, int styleOffset, const StyledText &st) {
+	int widthMax = 0;
+	size_t start = 0;
+	while (start < st.length) {
+		size_t lenLine = st.LineLength(start);
+		int widthSubLine;
+		if (st.multipleStyles) {
+			widthSubLine = WidthStyledText(surface, vs, styleOffset, st.text + start, st.styles + start, lenLine);
+		} else {
+			widthSubLine = surface->WidthText(vs.styles[styleOffset + st.style].font, st.text + start, lenLine);
+		}
+		if (widthSubLine > widthMax)
+			widthMax = widthSubLine;
+		start += lenLine + 1;
+	}
+	return widthMax;
+}
+
+void DrawStyledText(Surface *surface, ViewStyle &vs, int styleOffset, PRectangle rcText, int ascent, 
+	const StyledText &st, size_t start, size_t length) {
+
+	if (st.multipleStyles) {
+		int x = rcText.left;
+		size_t i = 0;
+		while (i < length) {
+			size_t end = i;
+			int style = st.styles[i + start];
+			while (end < length-1 && st.styles[start+end+1] == style)
+				end++;
+			style += styleOffset;
+			int width = surface->WidthText(vs.styles[style].font, st.text + start + i, end - i + 1);
+			PRectangle rcSegment = rcText;
+			rcSegment.left = x;
+			rcSegment.right = x + width + 1;
+			surface->DrawTextNoClip(rcSegment, vs.styles[style].font,
+					ascent, st.text + start + i, end - i + 1,
+					vs.styles[style].fore.allocated,
+					vs.styles[style].back.allocated);
+			x += width;
+			i = end + 1;
+		}
+	} else {
+		int style = st.style + styleOffset;
+		surface->DrawTextNoClip(rcText, vs.styles[style].font,
+				rcText.top + vs.maxAscent, st.text + start, length,
+				vs.styles[style].fore.allocated,
+				vs.styles[style].back.allocated);
+	}
+}
+
 void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
 	if (vs.fixedColumnWidth == 0)
 		return;
@@ -1638,6 +1738,20 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
 					        rcNumber.top + vs.maxAscent, number, istrlen(number),
 					        vs.styles[STYLE_LINENUMBER].fore.allocated,
 					        vs.styles[STYLE_LINENUMBER].back.allocated);
+				} else if (vs.ms[margin].style == SC_MARGIN_TEXT || vs.ms[margin].style == SC_MARGIN_RTEXT) {
+					if (firstSubLine) {
+						const StyledText stMargin  = pdoc->MarginStyledText(lineDoc);
+						if (stMargin.text && ValidStyledText(vs, vs.marginStyleOffset, stMargin)) {
+							surface->FillRectangle(rcMarker, 
+								vs.styles[stMargin.StyleAt(0)+vs.marginStyleOffset].back.allocated);
+							if (vs.ms[margin].style == SC_MARGIN_RTEXT) {
+								int width = WidestLineWidth(surface, vs, vs.marginStyleOffset, stMargin);
+								rcMarker.left = rcMarker.right - width - 3;
+							}
+							DrawStyledText(surface, vs, vs.marginStyleOffset, rcMarker, rcMarker.top + vs.maxAscent, 
+								stMargin, 0, stMargin.length);
+						}
+					}
 				}
 
 				if (marks) {
@@ -1685,7 +1799,7 @@ LineLayout *Editor::RetrieveLineLayout(int lineNumber) {
 	int posLineStart = pdoc->LineStart(lineNumber);
 	int posLineEnd = pdoc->LineStart(lineNumber + 1);
 	PLATFORM_ASSERT(posLineEnd >= posLineStart);
-	int lineCaret = pdoc->LineFromPosition(currentPos);
+	int lineCaret = pdoc->LineFromPosition(sel.MainCaret());
 	return llc.Retrieve(lineNumber, lineCaret,
 	        posLineEnd - posLineStart, pdoc->GetStyleClock(),
 	        LinesOnScreen() + 1, pdoc->LinesTotal());
@@ -1812,6 +1926,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
 		ll->widthLine = LineLayout::wrapWidthInfinite;
 		ll->lines = 1;
 		int numCharsInLine = 0;
+		int numCharsBeforeEOL = 0;
 		if (vstyle.edgeState == EDGE_BACKGROUND) {
 			ll->edgeColumn = pdoc->FindColumn(line, theEdge);
 			if (ll->edgeColumn >= posLineStart) {
@@ -1838,6 +1953,8 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
 				else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
 					ll->chars[numCharsInLine] = static_cast<char>(tolower(chDoc));
 				numCharsInLine++;
+				if (!IsEOLChar(chDoc))
+					numCharsBeforeEOL++;
 			}
 		}
 		ll->xHighlightGuide = 0;
@@ -1920,6 +2037,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
 			ll->positions[startseg] += 2;
 		}
 		ll->numCharsInLine = numCharsInLine;
+		ll->numCharsBeforeEOL = numCharsBeforeEOL;
 		ll->validity = LineLayout::llPositions;
 	}
 	// Hard to cope when too narrow, so just assume there is space
@@ -1937,6 +2055,20 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
 			if (wrapVisualFlags & SC_WRAPVISUALFLAG_END) {
 				width -= vstyle.aveCharWidth; // take into account the space for end wrap mark
 			}
+			ll->wrapIndent = wrapAddIndent;
+			if (wrapIndentMode != SC_WRAPINDENT_FIXED)
+				for (int i = 0; i < ll->numCharsInLine; i++) {
+					if (!IsSpaceOrTab(ll->chars[i])) {
+						ll->wrapIndent += ll->positions[i]; // Add line indent
+						break;
+					}
+				}
+			// Check for text width minimum
+			if (ll->wrapIndent > width - static_cast<int>(vstyle.aveCharWidth) * 15)
+				ll->wrapIndent = wrapAddIndent;
+			// Check for wrapIndent minimum
+			if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (ll->wrapIndent < static_cast<int>(vstyle.aveCharWidth)))
+				ll->wrapIndent = vstyle.aveCharWidth; // Indent to show start visual
 			ll->lines = 0;
 			// Calculate line start positions based upon width.
 			int lastGoodBreak = 0;
@@ -1962,7 +2094,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
 					ll->SetLineStart(ll->lines, lastGoodBreak);
 					startOffset = ll->positions[lastGoodBreak];
 					// take into account the space for start wrap mark and indent
-					startOffset -= actualWrapVisualStartIndent * vstyle.aveCharWidth;
+					startOffset -= ll->wrapIndent;
 					p = lastGoodBreak + 1;
 					continue;
 				}
@@ -1986,15 +2118,21 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
 	}
 }
 
-ColourAllocated Editor::SelectionBackground(ViewStyle &vsDraw) {
-	return primarySelection ? vsDraw.selbackground.allocated : vsDraw.selbackground2.allocated;
+ColourAllocated Editor::SelectionBackground(ViewStyle &vsDraw, bool main) {
+	return main ? 
+		(primarySelection ? vsDraw.selbackground.allocated : vsDraw.selbackground2.allocated) : 
+		vsDraw.selAdditionalBackground.allocated;
 }
 
 ColourAllocated Editor::TextBackground(ViewStyle &vsDraw, bool overrideBackground,
-        ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) {
-	if (inSelection) {
+        ColourAllocated background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) {
+	if (inSelection == 1) {
 		if (vsDraw.selbackset && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) {
-			return SelectionBackground(vsDraw);
+			return SelectionBackground(vsDraw, true);
+		}
+	} else if (inSelection == 2) {
+		if (vsDraw.selbackset && (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA)) {
+			return SelectionBackground(vsDraw, false);
 		}
 	} else {
 		if ((vsDraw.edgeState == EDGE_BACKGROUND) &&
@@ -2068,40 +2206,130 @@ static void SimpleAlphaRectangle(Surface *surface, PRectangle rc, ColourAllocate
 	}
 }
 
+void DrawTextBlob(Surface *surface, ViewStyle &vsDraw, PRectangle rcSegment,
+				  const char *s, ColourAllocated textBack, ColourAllocated textFore, bool twoPhaseDraw) {
+	if (!twoPhaseDraw) {
+		surface->FillRectangle(rcSegment, textBack);
+	}
+	Font &ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font;
+	int normalCharHeight = surface->Ascent(ctrlCharsFont) -
+	        surface->InternalLeading(ctrlCharsFont);
+	PRectangle rcCChar = rcSegment;
+	rcCChar.left = rcCChar.left + 1;
+	rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight;
+	rcCChar.bottom = rcSegment.top + vsDraw.maxAscent + 1;
+	PRectangle rcCentral = rcCChar;
+	rcCentral.top++;
+	rcCentral.bottom--;
+	surface->FillRectangle(rcCentral, textFore);
+	PRectangle rcChar = rcCChar;
+	rcChar.left++;
+	rcChar.right--;
+	surface->DrawTextClipped(rcChar, ctrlCharsFont,
+	        rcSegment.top + vsDraw.maxAscent, s, istrlen(s),
+	        textBack, textFore);
+}
+
 void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll,
         int line, int lineEnd, int xStart, int subLine, int subLineStart,
         bool overrideBackground, ColourAllocated background,
         bool drawWrapMarkEnd, ColourAllocated wrapColour) {
 
-	int styleMask = pdoc->stylingBitsMask;
+	const int posLineStart = pdoc->LineStart(line);
+	const int styleMask = pdoc->stylingBitsMask;
 	PRectangle rcSegment = rcLine;
 
+	const bool lastSubLine = subLine == (ll->lines - 1);
+	int virtualSpace = 0;
+	if (lastSubLine) {
+		const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+		virtualSpace = sel.VirtualSpaceFor(pdoc->LineEnd(line)) * spaceWidth;
+	}
+
 	// Fill in a PRectangle representing the end of line characters
+
 	int xEol = ll->positions[lineEnd] - subLineStart;
-	rcSegment.left = xEol + xStart;
-	rcSegment.right = xEol + vsDraw.aveCharWidth + xStart;
-	int posLineEnd = pdoc->LineStart(line + 1);
-	bool eolInSelection = (subLine == (ll->lines - 1)) &&
-	        (posLineEnd > ll->selStart) && (posLineEnd <= ll->selEnd) && (ll->selStart != ll->selEnd);
 
-	if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) {
-		surface->FillRectangle(rcSegment, SelectionBackground(vsDraw));
+	// Fill the virtual space and show selections within it
+	if (virtualSpace) {
+		rcSegment.left = xEol + xStart;
+		rcSegment.right = xEol + xStart + virtualSpace;
+		surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+		if (!hideSelection && ((vsDraw.selAlpha == SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA))) {
+			SelectionSegment virtualSpaceRange(SelectionPosition(pdoc->LineEnd(line)), SelectionPosition(pdoc->LineEnd(line), sel.VirtualSpaceFor(pdoc->LineEnd(line))));
+			for (size_t r=0; r<sel.Count(); r++) {
+				int alpha = (r == sel.Main()) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha;
+				if (alpha == SC_ALPHA_NOALPHA) {
+					SelectionSegment portion = sel.Range(r).Intersect(virtualSpaceRange);
+					if (!portion.Empty()) {
+						const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+						rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - subLineStart + portion.start.VirtualSpace() * spaceWidth;
+						rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - subLineStart + portion.end.VirtualSpace() * spaceWidth;
+						rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
+						rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
+						surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, r == sel.Main()));
+					}
+				}
+			}
+		}
+	}
+
+	int posAfterLineEnd = pdoc->LineStart(line + 1);
+	int eolInSelection = (subLine == (ll->lines - 1)) ? sel.InSelectionForEOL(posAfterLineEnd) : 0;
+	int alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha;
+
+	// Draw the [CR], [LF], or [CR][LF] blobs if visible line ends are on
+	int blobsWidth = 0;
+	if (lastSubLine) {
+		for (int eolPos=ll->numCharsBeforeEOL; eolPos<ll->numCharsInLine; eolPos++) {
+			rcSegment.left = xStart + ll->positions[eolPos] - subLineStart + virtualSpace;
+			rcSegment.right = xStart + ll->positions[eolPos+1] - subLineStart + virtualSpace;
+			blobsWidth += rcSegment.Width();
+			const char *ctrlChar = ControlCharacterString(ll->chars[eolPos]);
+			int inSelection = 0;
+			bool inHotspot = false;
+			int styleMain = ll->styles[eolPos];
+			ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, eolPos, ll);
+			ColourAllocated textFore = vsDraw.styles[styleMain].fore.allocated;
+			if (!hideSelection && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1)) {
+				if (alpha == SC_ALPHA_NOALPHA) {
+					surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1));
+				} else {
+					surface->FillRectangle(rcSegment, textBack);
+					SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha);
+				}
+			} else {
+				surface->FillRectangle(rcSegment, textBack);
+			}
+			DrawTextBlob(surface, vsDraw, rcSegment, ctrlChar, textBack, textFore, twoPhaseDraw);
+		}
+	}
+
+	// Draw the eol-is-selected rectangle
+	rcSegment.left = xEol + xStart + virtualSpace + blobsWidth;
+	rcSegment.right = xEol + xStart + virtualSpace + blobsWidth + vsDraw.aveCharWidth;
+
+	if (!hideSelection && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) {
+		surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1));
 	} else {
 		if (overrideBackground) {
 			surface->FillRectangle(rcSegment, background);
-		} else {
+		} else if (line < pdoc->LinesTotal() - 1) {
 			surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+		} else {
+			surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated);
 		}
-		if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (vsDraw.selAlpha != SC_ALPHA_NOALPHA)) {
-			SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw), vsDraw.selAlpha);
+		if (!hideSelection && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) {
+			SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha);
 		}
 	}
 
-	rcSegment.left = xEol + vsDraw.aveCharWidth + xStart;
+	// Fill the remainder of the line
+	rcSegment.left = xEol + xStart + virtualSpace + blobsWidth + vsDraw.aveCharWidth;
 	rcSegment.right = rcLine.right;
 
-	if (vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) {
-		surface->FillRectangle(rcSegment, SelectionBackground(vsDraw));
+	if (!hideSelection && vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) {
+		surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1));
 	} else {
 		if (overrideBackground) {
 			surface->FillRectangle(rcSegment, background);
@@ -2110,8 +2338,8 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
 		} else {
 			surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated);
 		}
-		if (vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (vsDraw.selAlpha != SC_ALPHA_NOALPHA)) {
-			SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw), vsDraw.selAlpha);
+		if (!hideSelection && vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) {
+			SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha);
 		}
 	}
 
@@ -2119,7 +2347,7 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
 		PRectangle rcPlace = rcSegment;
 
 		if (wrapVisualFlagsLocation & SC_WRAPVISUALFLAGLOC_END_BY_TEXT) {
-			rcPlace.left = xEol + xStart;
+			rcPlace.left = ll->positions[ll->numCharsInLine] + xStart + virtualSpace;
 			rcPlace.right = rcPlace.left + vsDraw.aveCharWidth;
 		} else {
 			// draw left of the right text margin, to avoid clipping by the current clip rect
@@ -2197,28 +2425,56 @@ void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int x
 	}
 }
 
-void DrawTextBlob(Surface *surface, ViewStyle &vsDraw, PRectangle rcSegment,
-				  const char *s, ColourAllocated textBack, ColourAllocated textFore, bool twoPhaseDraw) {
-	if (!twoPhaseDraw) {
-		surface->FillRectangle(rcSegment, textBack);
+void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
+    PRectangle rcLine, LineLayout *ll, int subLine) {
+	int indent = pdoc->GetLineIndentation(line) * vsDraw.spaceWidth;
+	PRectangle rcSegment = rcLine;
+	int annotationLine = subLine - ll->lines;
+	const StyledText stAnnotation  = pdoc->AnnotationStyledText(line);
+	if (stAnnotation.text && ValidStyledText(vsDraw, vsDraw.annotationStyleOffset, stAnnotation)) {
+		surface->FillRectangle(rcSegment, vsDraw.styles[0].back.allocated);
+		if (vs.annotationVisible == ANNOTATION_BOXED) {
+			// Only care about calculating width if need to draw box
+			int widthAnnotation = WidestLineWidth(surface, vsDraw, vsDraw.annotationStyleOffset, stAnnotation);
+			widthAnnotation += vsDraw.spaceWidth * 2; // Margins
+			rcSegment.left = xStart + indent;
+			rcSegment.right = rcSegment.left + widthAnnotation;
+			surface->PenColour(vsDraw.styles[vsDraw.annotationStyleOffset].fore.allocated);
+		} else {
+			rcSegment.left = xStart;
+		}
+		const int annotationLines = pdoc->AnnotationLines(line);
+		size_t start = 0;
+		size_t lengthAnnotation = stAnnotation.LineLength(start);
+		int lineInAnnotation = 0;
+		while ((lineInAnnotation < annotationLine) && (start < stAnnotation.length)) {
+			start += lengthAnnotation + 1;
+			lengthAnnotation = stAnnotation.LineLength(start);
+			lineInAnnotation++;
+		}
+		PRectangle rcText = rcSegment;
+		if (vs.annotationVisible == ANNOTATION_BOXED) {
+			surface->FillRectangle(rcText, 
+				vsDraw.styles[stAnnotation.StyleAt(start) + vsDraw.annotationStyleOffset].back.allocated);
+			rcText.left += vsDraw.spaceWidth;
+		}
+		DrawStyledText(surface, vsDraw, vsDraw.annotationStyleOffset, rcText, rcText.top + vsDraw.maxAscent, 
+			stAnnotation, start, lengthAnnotation);
+		if (vs.annotationVisible == ANNOTATION_BOXED) {
+			surface->MoveTo(rcSegment.left, rcSegment.top);
+			surface->LineTo(rcSegment.left, rcSegment.bottom);
+			surface->MoveTo(rcSegment.right, rcSegment.top);
+			surface->LineTo(rcSegment.right, rcSegment.bottom);
+			if (subLine == ll->lines){
+				surface->MoveTo(rcSegment.left, rcSegment.top);
+				surface->LineTo(rcSegment.right, rcSegment.top);
+			} 
+			if (subLine == ll->lines+annotationLines-1) {
+				surface->MoveTo(rcSegment.left, rcSegment.bottom - 1);
+				surface->LineTo(rcSegment.right, rcSegment.bottom - 1);
+			}
+		}
 	}
-	Font &ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font;
-	int normalCharHeight = surface->Ascent(ctrlCharsFont) -
-	        surface->InternalLeading(ctrlCharsFont);
-	PRectangle rcCChar = rcSegment;
-	rcCChar.left = rcCChar.left + 1;
-	rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight;
-	rcCChar.bottom = rcSegment.top + vsDraw.maxAscent + 1;
-	PRectangle rcCentral = rcCChar;
-	rcCentral.top++;
-	rcCentral.bottom--;
-	surface->FillRectangle(rcCentral, textFore);
-	PRectangle rcChar = rcCChar;
-	rcChar.left++;
-	rcChar.right--;
-	surface->DrawTextClipped(rcChar, ctrlCharsFont,
-	        rcSegment.top + vsDraw.maxAscent, s, istrlen(s),
-	        textBack, textFore);
 }
 
 void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
@@ -2280,11 +2536,18 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 
 	int startseg = ll->LineStart(subLine);
 	int subLineStart = ll->positions[startseg];
+	if (subLine >= ll->lines) {
+		DrawAnnotation(surface, vsDraw, line, xStart, rcLine, ll, subLine);
+		return; // No further drawing
+	}
 	int lineStart = 0;
 	int lineEnd = 0;
 	if (subLine < ll->lines) {
 		lineStart = ll->LineStart(subLine);
 		lineEnd = ll->LineStart(subLine + 1);
+		if (subLine == ll->lines - 1) {
+			lineEnd = ll->numCharsBeforeEOL;
+		}
 	}
 
 	ColourAllocated wrapColour = vsDraw.styles[STYLE_DEFAULT].fore.allocated;
@@ -2299,7 +2562,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 		}
 	}
 
-	if (actualWrapVisualStartIndent != 0) {
+	if (ll->wrapIndent != 0) {
 
 		bool continuedWrapLine = false;
 		if (subLine < ll->lines) {
@@ -2311,7 +2574,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 			PRectangle rcPlace = rcSegment;
 
 			rcPlace.left = ll->positions[startseg] + xStart - subLineStart;
-			rcPlace.right = rcPlace.left + actualWrapVisualStartIndent * vsDraw.aveCharWidth;
+			rcPlace.right = rcPlace.left + ll->wrapIndent;
 
 			// default bgnd here..
 			surface->FillRectangle(rcSegment, overrideBackground ? background :
@@ -2332,13 +2595,14 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 				DrawWrapMarker(surface, rcPlace, false, wrapColour);
 			}
 
-			xStart += actualWrapVisualStartIndent * vsDraw.aveCharWidth;
+			xStart += ll->wrapIndent;
 		}
 	}
 
 	// Does not take margin into account but not significant
 	int xStartVisible = subLineStart - xStart;
 
+	ll->psel = &sel;
 	BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible);
 	int next = bfBack.First();
 
@@ -2360,7 +2624,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 			rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
 
 			int styleMain = ll->styles[i];
-			bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd);
+			const int inSelection = hideSelection ? 0 : sel.CharacterInSelection(iDoc);
 			bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd);
 			ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll);
 			if (ll->chars[i] == '\t') {
@@ -2414,6 +2678,19 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 		surface->FillRectangle(rcSegment, vsDraw.edgecolour.allocated);
 	}
 
+	// Draw underline mark as part of background if not transparent
+	int marks = pdoc->GetMark(line);
+	int markBit;
+	for (markBit = 0; (markBit < 32) && marks; markBit++) {
+		if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_UNDERLINE) &&
+		    (vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) {
+			PRectangle rcUnderline = rcLine;
+			rcUnderline.top = rcUnderline.bottom - 2;
+			surface->FillRectangle(rcUnderline, vsDraw.markers[markBit].back.allocated);
+		}
+		marks >>= 1;
+	}
+
 	inIndentation = subLine == 0;	// Do not handle indentation except on first subline.
 	// Foreground drawing loop
 	BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible);
@@ -2440,9 +2717,9 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 				if (vsDraw.hotspotForegroundSet)
 					textFore = vsDraw.hotspotForeground.allocated;
 			}
-			bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd);
+			const int inSelection = hideSelection ? 0 : sel.CharacterInSelection(iDoc);
 			if (inSelection && (vsDraw.selforeset)) {
-				textFore = vsDraw.selforeground.allocated;
+				textFore = (inSelection == 1) ? vsDraw.selforeground.allocated : vsDraw.selAdditionalForeground.allocated;
 			}
 			bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd);
 			ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll);
@@ -2563,6 +2840,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 	if ((vsDraw.viewIndentationGuides == ivLookForward || vsDraw.viewIndentationGuides == ivLookBoth)
 	        && (subLine == 0)) {
 		int indentSpace = pdoc->GetLineIndentation(line);
+		int xStartText = ll->positions[pdoc->GetLineIndentPosition(line) - posLineStart];
+
 		// Find the most recent line with some text
 
 		int lineLastWithText = line;
@@ -2570,6 +2849,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 			lineLastWithText--;
 		}
 		if (lineLastWithText < line) {
+			xStartText = 100000;	// Don't limit to visible indentation on empty line
 			// This line is empty, so use indentation of last line with text
 			int indentLastWithText = pdoc->GetLineIndentation(lineLastWithText);
 			int isFoldHeader = pdoc->GetLevel(lineLastWithText) & SC_FOLDLEVELHEADERFLAG;
@@ -2599,8 +2879,10 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 
 		for (int indentPos = pdoc->IndentSize(); indentPos < indentSpace; indentPos += pdoc->IndentSize()) {
 			int xIndent = indentPos * vsDraw.spaceWidth;
-			DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment,
-			        (ll->xHighlightGuide == xIndent));
+			if (xIndent < xStartText) {
+				DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment,
+					(ll->xHighlightGuide == xIndent));
+			}
 		}
 	}
 
@@ -2612,15 +2894,26 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 		        xStart, subLine, subLineStart, overrideBackground, background,
 		        drawWrapMarkEnd, wrapColour);
 	}
-	if ((vsDraw.selAlpha != SC_ALPHA_NOALPHA) && (ll->selStart >= 0) && (ll->selEnd >= 0)) {
-		int startPosSel = (ll->selStart < posLineStart) ? posLineStart : ll->selStart;
-		int endPosSel = (ll->selEnd < (lineEnd + posLineStart)) ? ll->selEnd : (lineEnd + posLineStart);
-		if (startPosSel < endPosSel) {
-			rcSegment.left = xStart + ll->positions[startPosSel - posLineStart] - subLineStart;
-			rcSegment.right = xStart + ll->positions[endPosSel - posLineStart] - subLineStart;
-			rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
-			rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
-			SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw), vsDraw.selAlpha);
+	if (!hideSelection && ((vsDraw.selAlpha != SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha != SC_ALPHA_NOALPHA))) {
+		// For each selection draw
+		int virtualSpaces = 0;
+		if (subLine == (ll->lines - 1)) {
+			virtualSpaces = sel.VirtualSpaceFor(pdoc->LineEnd(line));
+		}
+		SelectionSegment virtualSpaceRange(SelectionPosition(posLineStart), SelectionPosition(posLineStart + lineEnd, virtualSpaces));
+		for (size_t r=0; r<sel.Count(); r++) {
+			int alpha = (r == sel.Main()) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha;
+			if (alpha != SC_ALPHA_NOALPHA) {
+				SelectionSegment portion = sel.Range(r).Intersect(virtualSpaceRange);
+				if (!portion.Empty()) {
+					const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+					rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - subLineStart + portion.start.VirtualSpace() * spaceWidth;
+					rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - subLineStart + portion.end.VirtualSpace() * spaceWidth;
+					rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
+					rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
+					SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, r == sel.Main()), alpha);
+				}
+			}
 		}
 	}
 
@@ -2630,17 +2923,21 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 	if (caret.active && vsDraw.showCaretLineBackground && ll->containsCaret) {
 		SimpleAlphaRectangle(surface, rcSegment, vsDraw.caretLineBackground.allocated, vsDraw.caretLineAlpha);
 	}
-	int marks = pdoc->GetMark(line);
-	for (int markBit = 0; (markBit < 32) && marks; markBit++) {
+	marks = pdoc->GetMark(line);
+	for (markBit = 0; (markBit < 32) && marks; markBit++) {
 		if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_BACKGROUND)) {
 			SimpleAlphaRectangle(surface, rcSegment, vsDraw.markers[markBit].back.allocated, vsDraw.markers[markBit].alpha);
+		} else if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_UNDERLINE)) {
+			PRectangle rcUnderline = rcSegment;
+			rcUnderline.top = rcUnderline.bottom - 2;
+			SimpleAlphaRectangle(surface, rcUnderline, vsDraw.markers[markBit].back.allocated, vsDraw.markers[markBit].alpha);
 		}
 		marks >>= 1;
 	}
 	if (vsDraw.maskInLine) {
 		int marksMasked = pdoc->GetMark(line) & vsDraw.maskInLine;
 		if (marksMasked) {
-			for (int markBit = 0; (markBit < 32) && marksMasked; markBit++) {
+			for (markBit = 0; (markBit < 32) && marksMasked; markBit++) {
 				if ((marksMasked & 1) && (vsDraw.markers[markBit].markType != SC_MARK_EMPTY)) {
 					SimpleAlphaRectangle(surface, rcSegment, vsDraw.markers[markBit].back.allocated, vsDraw.markers[markBit].alpha);
 				}
@@ -2650,7 +2947,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 	}
 }
 
-void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, int xStart, int offset, int posCaret, PRectangle rcCaret) {
+void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, 
+							int xStart, int offset, int posCaret, PRectangle rcCaret, ColourAllocated caretColour) {
 
 	int lineStart = ll->LineStart(subLine);
 	int posBefore = posCaret;
@@ -2693,8 +2991,15 @@ void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll,
 	}
 
 	// We now know what to draw, update the caret drawing rectangle
-	rcCaret.left = ll->positions[offsetFirstChar] - ll->positions[ll->LineStart(subLine)] + xStart;
-	rcCaret.right = ll->positions[offsetFirstChar+numCharsToDraw] - ll->positions[ll->LineStart(subLine)] + xStart;
+	rcCaret.left = ll->positions[offsetFirstChar] - ll->positions[lineStart] + xStart;
+	rcCaret.right = ll->positions[offsetFirstChar+numCharsToDraw] - ll->positions[lineStart] + xStart;
+
+	// Adjust caret position to take into account any word wrapping symbols.
+	if ((ll->wrapIndent != 0) && (lineStart != 0)) {
+		int wordWrapCharWidth = ll->wrapIndent;
+		rcCaret.left += wordWrapCharWidth;
+		rcCaret.right += wordWrapCharWidth;
+	}
 
 	// This character is where the caret block is, we override the colours
 	// (inversed) for drawing the caret here.
@@ -2702,7 +3007,7 @@ void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll,
 	surface->DrawTextClipped(rcCaret, vsDraw.styles[styleMain].font,
 	        rcCaret.top + vsDraw.maxAscent, ll->chars + offsetFirstChar,
 	        numCharsToDraw, vsDraw.styles[styleMain].back.allocated,
-	        vsDraw.caretcolour.allocated);
+	        caretColour);
 }
 
 void Editor::RefreshPixMaps(Surface *surfaceWindow) {
@@ -2771,6 +3076,86 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) {
 	}
 }
 
+void Editor::DrawCarets(Surface *surface, ViewStyle &vsDraw, int lineDoc, int xStart,
+        PRectangle rcLine, LineLayout *ll, int subLine) {
+	// When drag is active it is the only caret drawn
+	bool drawDrag = posDrag.IsValid();
+	if (hideSelection && !drawDrag)
+		return;
+	const int posLineStart = pdoc->LineStart(lineDoc);
+	// For each selection draw
+	for (size_t r=0; (r<sel.Count()) || drawDrag; r++) {
+		const bool mainCaret = r == sel.Main();
+		const SelectionPosition posCaret = (drawDrag ? posDrag : sel.Range(r).caret);
+		const int offset = posCaret.Position() - posLineStart;
+		const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+		const int virtualOffset = posCaret.VirtualSpace() * spaceWidth;
+		if (ll->InLine(offset, subLine) && offset <= ll->numCharsBeforeEOL) {
+			int xposCaret = ll->positions[offset] + virtualOffset - ll->positions[ll->LineStart(subLine)] + xStart;
+			if (ll->wrapIndent != 0) {
+				int lineStart = ll->LineStart(subLine);
+				if (lineStart != 0)	// Wrapped
+					xposCaret += ll->wrapIndent;
+			}
+			if ((xposCaret >= 0) && (vsDraw.caretWidth > 0) && (vsDraw.caretStyle != CARETSTYLE_INVISIBLE) &&
+			        ((posDrag.IsValid()) || ((caret.active && caret.on) || (!additionalCaretsBlink && !mainCaret)))) {
+				bool caretAtEOF = false;
+				bool caretAtEOL = false;
+				bool drawBlockCaret = false;
+				int widthOverstrikeCaret;
+				int caretWidthOffset = 0;
+				PRectangle rcCaret = rcLine;
+
+				if (posCaret.Position() == pdoc->Length())	{   // At end of document
+					caretAtEOF = true;
+					widthOverstrikeCaret = vsDraw.aveCharWidth;
+				} else if ((posCaret.Position() - posLineStart) >= ll->numCharsInLine) {	// At end of line
+					caretAtEOL = true;
+					widthOverstrikeCaret = vsDraw.aveCharWidth;
+				} else {
+					widthOverstrikeCaret = ll->positions[offset + 1] - ll->positions[offset];
+				}
+				if (widthOverstrikeCaret < 3)	// Make sure its visible
+					widthOverstrikeCaret = 3;
+
+				if (posCaret > SelectionPosition(ll->LineStart(subLine) + posLineStart))
+					caretWidthOffset = 1;	// Move back so overlaps both character cells.
+				if (posDrag.IsValid()) {
+					/* Dragging text, use a line caret */
+					rcCaret.left = xposCaret - caretWidthOffset;
+					rcCaret.right = rcCaret.left + vsDraw.caretWidth;
+				} else if (inOverstrike) {
+					/* Overstrike (insert mode), use a modified bar caret */
+					rcCaret.top = rcCaret.bottom - 2;
+					rcCaret.left = xposCaret + 1;
+					rcCaret.right = rcCaret.left + widthOverstrikeCaret - 1;
+				} else if (vsDraw.caretStyle == CARETSTYLE_BLOCK) {
+					/* Block caret */
+					rcCaret.left = xposCaret;
+					if (!caretAtEOL && !caretAtEOF && (ll->chars[offset] != '\t') && !(IsControlCharacter(ll->chars[offset]))) {
+						drawBlockCaret = true;
+						rcCaret.right = xposCaret + widthOverstrikeCaret;
+					} else {
+						rcCaret.right = xposCaret + vsDraw.aveCharWidth;
+					}
+				} else {
+					/* Line caret */
+					rcCaret.left = xposCaret - caretWidthOffset;
+					rcCaret.right = rcCaret.left + vsDraw.caretWidth;
+				}
+				ColourAllocated caretColour = mainCaret ? vsDraw.caretcolour.allocated : vsDraw.additionalCaretColour.allocated;
+				if (drawBlockCaret) {
+					DrawBlockCaret(surface, vsDraw, ll, subLine, xStart, offset, posCaret.Position(), rcCaret, caretColour);
+				} else {
+					surface->FillRectangle(rcCaret, caretColour);
+				}
+			}
+		}
+		if (drawDrag) 
+			break;
+	}
+}
+
 void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 	//Platform::DebugPrintf("Paint:%1d (%3d,%3d) ... (%3d,%3d)\n",
 	//	paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom);
@@ -2793,7 +3178,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 	//Platform::DebugPrintf("Paint lines = %d .. %d\n", topLine + screenLinePaintFirst, lineStyleLast);
 	int endPosPaint = pdoc->Length();
 	if (lineStyleLast < cs.LinesDisplayed())
-		endPosPaint = pdoc->LineStart(cs.DocFromDisplay(lineStyleLast + 1));
+		endPosPaint = pdoc->LineStart(cs.DocFromDisplay(lineStyleLast) + 1);
 
 	int xStart = vs.fixedColumnWidth - xOffset;
 	int ypos = 0;
@@ -2823,7 +3208,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 	// 	lines first).
 	int startLineToWrap = cs.DocFromDisplay(topLine) - 5;
 	if (startLineToWrap < 0)
-		startLineToWrap = -1;
+		startLineToWrap = 0;
 	if (WrapLines(false, startLineToWrap)) {
 		// The wrapping process has changed the height of some lines so
 		// abandon this paint for a complete repaint.
@@ -2870,10 +3255,10 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 
 		int visibleLine = topLine + screenLinePaintFirst;
 
-		int posCaret = currentPos;
-		if (posDrag >= 0)
+		SelectionPosition posCaret = sel.RangeMain().caret;
+		if (posDrag.IsValid())
 			posCaret = posDrag;
-		int lineCaret = pdoc->LineFromPosition(posCaret);
+		int lineCaret = pdoc->LineFromPosition(posCaret.Position());
 
 		// Remove selection margin from drawing area so text will not be drawn
 		// on it in unbuffered mode.
@@ -2889,7 +3274,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 		//ElapsedTime etWhole;
 		int lineDocPrevious = -1;	// Used to avoid laying out one document line multiple times
 		AutoLineLayout ll(llc, 0);
-		SelectionLineIterator lineIterator(this);
 		while (visibleLine < cs.LinesDisplayed() && yposScreen < rcArea.bottom) {
 
 			int lineDoc = cs.DocFromDisplay(visibleLine);
@@ -2903,8 +3287,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 			//ElapsedTime et;
 			if (lineDoc != lineDocPrevious) {
 				ll.Set(0);
-				// For rectangular selection this accesses the layout cache so should be after layout returned.
-				lineIterator.SetAt(lineDoc);
 				ll.Set(RetrieveLineLayout(lineDoc));
 				LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
 				lineDocPrevious = lineDoc;
@@ -2912,17 +3294,8 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 			//durLayout += et.Duration(true);
 
 			if (ll) {
-				if (selType == selStream) {
-					ll->selStart = SelectionStart();
-					ll->selEnd = SelectionEnd();
-				} else {
-					ll->selStart = lineIterator.startPos;
-					ll->selEnd = lineIterator.endPos;
-				}
 				ll->containsCaret = lineDoc == lineCaret;
 				if (hideSelection) {
-					ll->selStart = -1;
-					ll->selEnd = -1;
 					ll->containsCaret = false;
 				}
 
@@ -2945,128 +3318,28 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 				ll->RestoreBracesHighlight(rangeLine, braces);
 
 				bool expanded = cs.GetExpanded(lineDoc);
-				if ((foldFlags & SC_FOLDFLAG_BOX) == 0) {
-					// Paint the line above the fold
-					if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED))
-					        ||
-					        (!expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) {
-						if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
-							PRectangle rcFoldLine = rcLine;
-							rcFoldLine.bottom = rcFoldLine.top + 1;
-							surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
-						}
-					}
-					// Paint the line below the fold
-					if ((expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED))
-					        ||
-					        (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
-						if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
-							PRectangle rcFoldLine = rcLine;
-							rcFoldLine.top = rcFoldLine.bottom - 1;
-							surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
-						}
-					}
-				} else {
-					int FoldLevelCurr = (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE;
-					int FoldLevelPrev = (pdoc->GetLevel(lineDoc - 1) & SC_FOLDLEVELNUMBERMASK) - SC_FOLDLEVELBASE;
-					int FoldLevelFlags = (pdoc->GetLevel(lineDoc) & ~SC_FOLDLEVELNUMBERMASK) & ~(0xFFF0000);
-					int indentationStep = pdoc->IndentSize();
-					// Draw line above fold
-					if ((FoldLevelPrev < FoldLevelCurr)
-					        ||
-					        (FoldLevelFlags & SC_FOLDLEVELBOXHEADERFLAG
-					         &&
-					         (pdoc->GetLevel(lineDoc - 1) & SC_FOLDLEVELBOXFOOTERFLAG) == 0)) {
+				// Paint the line above the fold
+				if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED))
+					||
+					(!expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) {
+					if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
 						PRectangle rcFoldLine = rcLine;
 						rcFoldLine.bottom = rcFoldLine.top + 1;
-						rcFoldLine.left += xStart + FoldLevelCurr * vs.spaceWidth * indentationStep - 1;
 						surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
 					}
-
-					// Line below the fold (or below a contracted fold)
-					if (FoldLevelFlags & SC_FOLDLEVELBOXFOOTERFLAG
-					        ||
-					        (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
+				}
+				// Paint the line below the fold
+				if ((expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED))
+					||
+					(!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
+					if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
 						PRectangle rcFoldLine = rcLine;
 						rcFoldLine.top = rcFoldLine.bottom - 1;
-						rcFoldLine.left += xStart + (FoldLevelCurr) * vs.spaceWidth * indentationStep - 1;
 						surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
 					}
-
-					PRectangle rcBoxLine = rcLine;
-					// Draw vertical line for every fold level
-					for (int i = 0; i <= FoldLevelCurr; i++) {
-						rcBoxLine.left = xStart + i * vs.spaceWidth * indentationStep - 1;
-						rcBoxLine.right = rcBoxLine.left + 1;
-						surface->FillRectangle(rcBoxLine, vs.styles[STYLE_DEFAULT].fore.allocated);
-					}
 				}
 
-				// Draw the Caret
-				if (lineDoc == lineCaret) {
-					int offset = Platform::Minimum(posCaret - rangeLine.start, ll->maxLineLength);
-					if (ll->InLine(offset, subLine)) {
-						int xposCaret = ll->positions[offset] - ll->positions[ll->LineStart(subLine)] + xStart;
-
-						if (actualWrapVisualStartIndent != 0) {
-							int lineStart = ll->LineStart(subLine);
-							if (lineStart != 0)	// Wrapped
-								xposCaret += actualWrapVisualStartIndent * vs.aveCharWidth;
-						}
-						if ((xposCaret >= 0) && (vs.caretWidth > 0) && (vs.caretStyle != CARETSTYLE_INVISIBLE) &&
-						        ((posDrag >= 0) || (caret.active && caret.on))) {
-							bool caretAtEOF = false;
-							bool caretAtEOL = false;
-							bool drawBlockCaret = false;
-							int widthOverstrikeCaret;
-							int caretWidthOffset = 0;
-							PRectangle rcCaret = rcLine;
-
-							if (posCaret == pdoc->Length())	{   // At end of document
-								caretAtEOF = true;
-								widthOverstrikeCaret = vs.aveCharWidth;
-							} else if ((posCaret - rangeLine.start) >= ll->numCharsInLine) {	// At end of line
-								caretAtEOL = true;
-								widthOverstrikeCaret = vs.aveCharWidth;
-							} else {
-								widthOverstrikeCaret = ll->positions[offset + 1] - ll->positions[offset];
-							}
-							if (widthOverstrikeCaret < 3)	// Make sure its visible
-								widthOverstrikeCaret = 3;
-
-							if (offset > ll->LineStart(subLine))
-								caretWidthOffset = 1;	// Move back so overlaps both character cells.
-							if (posDrag >= 0) {
-								/* Dragging text, use a line caret */
-								rcCaret.left = xposCaret - caretWidthOffset;
-								rcCaret.right = rcCaret.left + vs.caretWidth;
-							} else if (inOverstrike) {
-								/* Overstrike (insert mode), use a modified bar caret */
-								rcCaret.top = rcCaret.bottom - 2;
-								rcCaret.left = xposCaret + 1;
-								rcCaret.right = rcCaret.left + widthOverstrikeCaret - 1;
-							} else if (vs.caretStyle == CARETSTYLE_BLOCK) {
-								/* Block caret */
-								rcCaret.left = xposCaret;
-								if (!caretAtEOL && !caretAtEOF && (ll->chars[offset] != '\t') && !(IsControlCharacter(ll->chars[offset]))) {
-									drawBlockCaret = true;
-									rcCaret.right = xposCaret + widthOverstrikeCaret;
-								} else {
-									rcCaret.right = xposCaret + vs.aveCharWidth;
-								}
-							} else {
-								/* Line caret */
-								rcCaret.left = xposCaret - caretWidthOffset;
-								rcCaret.right = rcCaret.left + vs.caretWidth;
-							}
-							if (drawBlockCaret) {
-								DrawBlockCaret(surface, vs, ll, subLine, xStart, offset, posCaret, rcCaret);
-							} else {
-								surface->FillRectangle(rcCaret, vs.caretcolour.allocated);
-							}
-						}
-					}
-				}
+				DrawCarets(surface, vs, lineDoc, xStart, rcLine, ll, subLine);
 
 				if (bufferedDraw) {
 					Point from(vs.fixedColumnWidth, 0);
@@ -3133,7 +3406,7 @@ ColourDesired InvertedLight(ColourDesired orig) {
 // This is mostly copied from the Paint method but with some things omitted
 // such as the margin markers, line numbers, selection and caret
 // Should be merged back into a combined Draw method.
-long Editor::FormatRange(bool draw, RangeToFormat *pfr) {
+long Editor::FormatRange(bool draw, Sci_RangeToFormat *pfr) {
 	if (!pfr)
 		return 0;
 
@@ -3168,6 +3441,7 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) {
 	vsPrint.selbackset = false;
 	vsPrint.selforeset = false;
 	vsPrint.selAlpha = SC_ALPHA_NOALPHA;
+	vsPrint.selAdditionalAlpha = SC_ALPHA_NOALPHA;
 	vsPrint.whitespaceBackgroundSet = false;
 	vsPrint.whitespaceForegroundSet = false;
 	vsPrint.showCaretLineBackground = false;
@@ -3245,8 +3519,6 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) {
 		LineLayout ll(8000);
 		LayoutLine(lineDoc, surfaceMeasure, vsPrint, &ll, widthPrint);
 
-		ll.selStart = -1;
-		ll.selEnd = -1;
 		ll.containsCaret = false;
 
 		PRectangle rcLine;
@@ -3369,6 +3641,15 @@ void Editor::ChangeSize() {
 	}
 }
 
+int Editor::InsertSpace(int position, unsigned int spaces) {
+	if (spaces > 0) {
+		std::string spaceText(spaces, ' ');
+		pdoc->InsertString(position, spaceText.c_str(), spaces);
+		position += spaces;
+	}
+	return position;
+}
+
 void Editor::AddChar(char ch) {
 	char s[2];
 	s[0] = ch;
@@ -3376,34 +3657,63 @@ void Editor::AddChar(char ch) {
 	AddCharUTF(s, 1);
 }
 
+void Editor::FilterSelections() {
+	if (!additionalSelectionTyping && (sel.Count() > 1)) {
+		SelectionRange rangeOnly = sel.RangeMain();
+		InvalidateSelection(rangeOnly, true);
+		sel.SetSelection(rangeOnly);
+	}
+}
+
 // AddCharUTF inserts an array of bytes which may or may not be in UTF-8.
 void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
-	bool wasSelection = currentPos != anchor;
-	ClearSelection();
-	bool charReplaceAction = false;
-	if (inOverstrike && !wasSelection && !RangeContainsProtected(currentPos, currentPos + 1)) {
-		if (currentPos < (pdoc->Length())) {
-			if (!IsEOLChar(pdoc->CharAt(currentPos))) {
-				charReplaceAction = true;
-				pdoc->BeginUndoAction();
-				pdoc->DelChar(currentPos);
+	FilterSelections();
+	{
+		UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty() || inOverstrike);
+		for (size_t r=0; r<sel.Count(); r++) {
+			if (!RangeContainsProtected(sel.Range(r).Start().Position(), 
+				sel.Range(r).End().Position())) {
+				int positionInsert = sel.Range(r).Start().Position();
+				if (!sel.Range(r).Empty()) {
+					if (sel.Range(r).Length()) {
+						pdoc->DeleteChars(positionInsert, sel.Range(r).Length());
+						sel.Range(r).ClearVirtualSpace();
+					} else {
+						// Range is all virtual so collapse to start of virtual space
+						sel.Range(r).MinimizeVirtualSpace();
+					}
+				} else if (inOverstrike) {
+					if (positionInsert < pdoc->Length()) {
+						if (!IsEOLChar(pdoc->CharAt(positionInsert))) {
+							pdoc->DelChar(positionInsert);
+							sel.Range(r).ClearVirtualSpace();
+						}
+					}
+				}
+				positionInsert = InsertSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
+				if (pdoc->InsertString(positionInsert, s, len)) {
+					sel.Range(r).caret.SetPosition(positionInsert + len);
+					sel.Range(r).anchor.SetPosition(positionInsert + len);
+				}
+				sel.Range(r).ClearVirtualSpace();
+				// If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
+				if (wrapState != eWrapNone) {
+					AutoSurface surface(this);
+					if (surface) {
+						WrapOneLine(surface, pdoc->LineFromPosition(positionInsert));
+					}
+				}
 			}
 		}
 	}
-	if (pdoc->InsertString(currentPos, s, len)) {
-		SetEmptySelection(currentPos + len);
-	}
-	if (charReplaceAction) {
-		pdoc->EndUndoAction();
-	}
-	// If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
 	if (wrapState != eWrapNone) {
-		AutoSurface surface(this);
-		if (surface) {
-			WrapOneLine(surface, pdoc->LineFromPosition(currentPos));
-		}
 		SetScrollBars();
 	}
+	if (sel.IsRectangular()) {
+		sel.selType = Selection::selThin;
+		sel.Rectangular() = SelectionRange(sel.Rectangular().caret, sel.Range(0).anchor);
+	}
+	// If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
 	EnsureCaretVisible();
 	// Avoid blinking during rapid typing:
 	ShowCaretAtCurrentPosition();
@@ -3450,43 +3760,35 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
 }
 
 void Editor::ClearSelection() {
-	if (!SelectionContainsProtected()) {
-		int startPos = SelectionStart();
-		if (selType == selStream) {
-			unsigned int chars = SelectionEnd() - startPos;
-			if (0 != chars) {
-				pdoc->BeginUndoAction();
-				pdoc->DeleteChars(startPos, chars);
-				pdoc->EndUndoAction();
-			}
-		} else {
-			pdoc->BeginUndoAction();
-			SelectionLineIterator lineIterator(this, false);
-			while (lineIterator.Iterate()) {
-				startPos = lineIterator.startPos;
-				unsigned int chars = lineIterator.endPos - startPos;
-				if (0 != chars) {
-					pdoc->DeleteChars(startPos, chars);
-				}
+	FilterSelections();
+	UndoGroup ug(pdoc);
+	for (size_t r=0; r<sel.Count(); r++) {
+		if (!sel.Range(r).Empty()) {
+			if (!RangeContainsProtected(sel.Range(r).Start().Position(), 
+				sel.Range(r).End().Position())) {
+				pdoc->DeleteChars(sel.Range(r).Start().Position(), 
+					sel.Range(r).Length());
+				sel.Range(r).ClearVirtualSpace();
 			}
-			pdoc->EndUndoAction();
-			selType = selStream;
 		}
-		SetEmptySelection(startPos);
 	}
+	sel.RemoveDuplicates();
+	ClaimSelection();
 }
 
 void Editor::ClearAll() {
-	pdoc->BeginUndoAction();
-	if (0 != pdoc->Length()) {
-		pdoc->DeleteChars(0, pdoc->Length());
-	}
-	if (!pdoc->IsReadOnly()) {
-		cs.Clear();
+	{
+		UndoGroup ug(pdoc);
+		if (0 != pdoc->Length()) {
+			pdoc->DeleteChars(0, pdoc->Length());
+		}
+		if (!pdoc->IsReadOnly()) {
+			cs.Clear();
+			pdoc->AnnotationClearAll();
+			pdoc->MarginClearAll();
+		}
 	}
-	pdoc->EndUndoAction();
-	anchor = 0;
-	currentPos = 0;
+	sel.Clear();
 	SetTopLine(0);
 	SetVerticalScrollPos();
 	InvalidateStyleRedraw();
@@ -3523,15 +3825,18 @@ void Editor::Cut() {
 	}
 }
 
-void Editor::PasteRectangular(int pos, const char *ptr, int len) {
+void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, int len) {
 	if (pdoc->IsReadOnly() || SelectionContainsProtected()) {
 		return;
 	}
-	currentPos = pos;
-	int xInsert = XFromPosition(currentPos);
-	int line = pdoc->LineFromPosition(currentPos);
+	sel.Clear();
+	sel.RangeMain() = SelectionRange(pos);
+	int line = pdoc->LineFromPosition(sel.MainCaret());
+	UndoGroup ug(pdoc);
+	sel.RangeMain().caret = SelectionPosition(
+		InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace()));
+	int xInsert = XFromPosition(sel.RangeMain().caret);
 	bool prevCr = false;
-	pdoc->BeginUndoAction();
 	for (int i = 0; i < len; i++) {
 		if (IsEOLChar(ptr[i])) {
 			if ((ptr[i] == '\r') || (!prevCr))
@@ -3543,21 +3848,20 @@ void Editor::PasteRectangular(int pos, const char *ptr, int len) {
 					pdoc->InsertChar(pdoc->Length(), '\n');
 			}
 			// Pad the end of lines with spaces if required
-			currentPos = PositionFromLineX(line, xInsert);
-			if ((XFromPosition(currentPos) < xInsert) && (i + 1 < len)) {
-				for (int i = 0; i < xInsert - XFromPosition(currentPos); i++) {
-					pdoc->InsertChar(currentPos, ' ');
-					currentPos++;
+			sel.RangeMain().caret.SetPosition(PositionFromLineX(line, xInsert));
+			if ((XFromPosition(sel.MainCaret()) < xInsert) && (i + 1 < len)) {
+				while (XFromPosition(sel.MainCaret()) < xInsert) {
+					pdoc->InsertChar(sel.MainCaret(), ' ');
+					sel.RangeMain().caret.Add(1);
 				}
 			}
 			prevCr = ptr[i] == '\r';
 		} else {
-			pdoc->InsertString(currentPos, ptr + i, 1);
-			currentPos++;
+			pdoc->InsertString(sel.MainCaret(), ptr + i, 1);
+			sel.RangeMain().caret.Add(1);
 			prevCr = false;
 		}
 	}
-	pdoc->EndUndoAction();
 	SetEmptySelection(pos);
 }
 
@@ -3566,14 +3870,23 @@ bool Editor::CanPaste() {
 }
 
 void Editor::Clear() {
-	if (currentPos == anchor) {
-		if (!RangeContainsProtected(currentPos, currentPos + 1)) {
-			DelChar();
+	UndoGroup ug(pdoc);
+	// If multiple selections, don't delete EOLS
+	if (sel.Empty()) {
+		for (size_t r=0; r<sel.Count(); r++) {
+			if (!RangeContainsProtected(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1)) {
+				if ((sel.Count() == 1) || !IsEOLChar(pdoc->CharAt(sel.Range(r).caret.Position()))) {
+					pdoc->DelChar(sel.Range(r).caret.Position());
+					sel.Range(r).ClearVirtualSpace();
+				}  // else multiple selection so don't eat line ends
+			} else {
+				sel.Range(r).ClearVirtualSpace();
+			}
 		}
 	} else {
 		ClearSelection();
 	}
-	SetEmptySelection(currentPos);
+	sel.RemoveDuplicates();
 }
 
 void Editor::SelectAll() {
@@ -3601,39 +3914,58 @@ void Editor::Redo() {
 }
 
 void Editor::DelChar() {
-	if (!RangeContainsProtected(currentPos, currentPos + 1)) {
-		pdoc->DelChar(currentPos);
+	if (!RangeContainsProtected(sel.MainCaret(), sel.MainCaret() + 1)) {
+		pdoc->DelChar(sel.MainCaret());
 	}
 	// Avoid blinking during rapid typing:
 	ShowCaretAtCurrentPosition();
 }
 
 void Editor::DelCharBack(bool allowLineStartDeletion) {
-	if (currentPos == anchor) {
-		if (!RangeContainsProtected(currentPos - 1, currentPos)) {
-			int lineCurrentPos = pdoc->LineFromPosition(currentPos);
-			if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != currentPos)) {
-				if (pdoc->GetColumn(currentPos) <= pdoc->GetLineIndentation(lineCurrentPos) &&
-				        pdoc->GetColumn(currentPos) > 0 && pdoc->backspaceUnindents) {
-					pdoc->BeginUndoAction();
-					int indentation = pdoc->GetLineIndentation(lineCurrentPos);
-					int indentationStep = pdoc->IndentSize();
-					if (indentation % indentationStep == 0) {
-						pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
-					} else {
-						pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep));
-					}
-					SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
-					pdoc->EndUndoAction();
+	FilterSelections();
+	if (sel.IsRectangular())
+		allowLineStartDeletion = false;
+	UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty());
+	if (sel.Empty()) {
+		for (size_t r=0; r<sel.Count(); r++) {
+			if (!RangeContainsProtected(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1)) {
+				if (sel.Range(r).caret.VirtualSpace()) {
+					sel.Range(r).caret.SetVirtualSpace(sel.Range(r).caret.VirtualSpace() - 1);
+					sel.Range(r).anchor.SetVirtualSpace(sel.Range(r).caret.VirtualSpace());
 				} else {
-					pdoc->DelCharBack(currentPos);
+					int lineCurrentPos = pdoc->LineFromPosition(sel.Range(r).caret.Position());
+					if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != sel.Range(r).caret.Position())) {
+						if (pdoc->GetColumn(sel.Range(r).caret.Position()) <= pdoc->GetLineIndentation(lineCurrentPos) &&
+								pdoc->GetColumn(sel.Range(r).caret.Position()) > 0 && pdoc->backspaceUnindents) {
+							UndoGroup ugInner(pdoc, !ug.Needed());
+							int indentation = pdoc->GetLineIndentation(lineCurrentPos);
+							int indentationStep = pdoc->IndentSize();
+							if (indentation % indentationStep == 0) {
+								pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
+							} else {
+								pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep));
+							}
+							// SetEmptySelection
+							sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos), 
+								pdoc->GetLineIndentPosition(lineCurrentPos));
+						} else {
+							pdoc->DelCharBack(sel.Range(r).caret.Position());
+						}
+					}
 				}
+			} else {
+				sel.Range(r).ClearVirtualSpace();
 			}
 		}
 	} else {
 		ClearSelection();
-		SetEmptySelection(currentPos);
+		if (sel.IsRectangular()) {
+			sel.selType = Selection::selThin;
+			sel.Rectangular() = SelectionRange(sel.Rectangular().caret, sel.Range(0).anchor);
+		}
+		//SetEmptySelection(sel.MainCaret());
 	}
+	sel.RemoveDuplicates();
 	// Avoid blinking during rapid typing:
 	ShowCaretAtCurrentPosition();
 }
@@ -3684,7 +4016,7 @@ void Editor::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt) {
 	SCNotification scn = {0};
 	scn.nmhdr.code = SCN_DOUBLECLICK;
 	scn.line = LineFromLocation(pt);
-	scn.position = PositionFromLocationClose(pt);
+	scn.position = PositionFromLocation(pt, true);
 	scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
 	        (alt ? SCI_ALT : 0);
 	NotifyParent(scn);
@@ -3765,7 +4097,7 @@ void Editor::NotifyNeedShown(int pos, int len) {
 void Editor::NotifyDwelling(Point pt, bool state) {
 	SCNotification scn = {0};
 	scn.nmhdr.code = state ? SCN_DWELLSTART : SCN_DWELLEND;
-	scn.position = PositionFromLocationClose(pt);
+	scn.position = PositionFromLocation(pt, true);
 	scn.x = pt.x;
 	scn.y = pt.y;
 	NotifyParent(scn);
@@ -3783,13 +4115,6 @@ void Editor::NotifyModifyAttempt(Document*, void *) {
 	NotifyModifyAttempt();
 }
 
-void Editor::NotifyMove(int position) {
-	SCNotification scn = {0};
-	scn.nmhdr.code = SCN_POSCHANGED;
-	scn.position = position;
-	NotifyParent(scn);
-}
-
 void Editor::NotifySavePoint(Document*, void *, bool atSavePoint) {
 	//Platform::DebugPrintf("** Save Point %s\n", atSavePoint ? "On" : "Off");
 	NotifySavePoint(atSavePoint);
@@ -3803,6 +4128,10 @@ void Editor::CheckModificationForWrap(DocModification mh) {
 			int lines = Platform::Maximum(0, mh.linesAdded);
 			NeedWrapping(lineDoc, lineDoc + lines + 1);
 		}
+		// Fix up annotation heights
+		int lineDoc = pdoc->LineFromPosition(mh.position);
+		int lines = Platform::Maximum(0, mh.linesAdded);
+		SetAnnotationHeights(lineDoc, lineDoc + lines + 2);
 	}
 }
 
@@ -3861,13 +4190,11 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
 	} else {
 		// Move selection and brace highlights
 		if (mh.modificationType & SC_MOD_INSERTTEXT) {
-			currentPos = MovePositionForInsertion(currentPos, mh.position, mh.length);
-			anchor = MovePositionForInsertion(anchor, mh.position, mh.length);
+			sel.MovePositions(true, mh.position, mh.length);
 			braces[0] = MovePositionForInsertion(braces[0], mh.position, mh.length);
 			braces[1] = MovePositionForInsertion(braces[1], mh.position, mh.length);
 		} else if (mh.modificationType & SC_MOD_DELETETEXT) {
-			currentPos = MovePositionForDeletion(currentPos, mh.position, mh.length);
-			anchor = MovePositionForDeletion(anchor, mh.position, mh.length);
+			sel.MovePositions(false, mh.position, mh.length);
 			braces[0] = MovePositionForDeletion(braces[0], mh.position, mh.length);
 			braces[1] = MovePositionForDeletion(braces[1], mh.position, mh.length);
 		}
@@ -3890,6 +4217,12 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
 				cs.DeleteLines(lineOfPos, -mh.linesAdded);
 			}
 		}
+		if (mh.modificationType & SC_MOD_CHANGEANNOTATION) {
+			int lineDoc = pdoc->LineFromPosition(mh.position);
+			if (vs.annotationVisible) {
+				cs.SetHeight(lineDoc, cs.GetHeight(lineDoc) + mh.annotationLinesAdded);
+			}
+		}
 		CheckModificationForWrap(mh);
 		if (mh.linesAdded != 0) {
 			// Avoid scrolling of display if change before current display
@@ -3920,7 +4253,7 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
 		SetScrollBars();
 	}
 
-	if (mh.modificationType & SC_MOD_CHANGEMARKER) {
+	if ((mh.modificationType & SC_MOD_CHANGEMARKER) || (mh.modificationType & SC_MOD_CHANGEMARGIN)) {
 		if ((paintState == notPainting) || !PaintContainsMargin()) {
 			if (mh.modificationType & SC_MOD_CHANGEFOLD) {
 				// Fold changes can affect the drawing of following lines so redraw whole margin
@@ -3954,6 +4287,8 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
 		scn.line = mh.line;
 		scn.foldLevelNow = mh.foldLevelNow;
 		scn.foldLevelPrev = mh.foldLevelPrev;
+		scn.token = mh.token;
+		scn.annotationLinesAdded = mh.annotationLinesAdded;
 		NotifyParent(scn);
 	}
 }
@@ -4091,11 +4426,11 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
  * If stuttered = true and not already at first/last row, move to first/last row of window.
  * If stuttered = true and already at first/last row, scroll as normal.
  */
-void Editor::PageMove(int direction, selTypes sel, bool stuttered) {
+void Editor::PageMove(int direction, Selection::selTypes selt, bool stuttered) {
 	int topLineNew, newPos;
 
 	// I consider only the caretYSlop, and ignore the caretYPolicy-- is that a problem?
-	int currentLine = pdoc->LineFromPosition(currentPos);
+	int currentLine = pdoc->LineFromPosition(sel.MainCaret());
 	int topStutterLine = topLine + caretYSlop;
 	int bottomStutterLine =
 	    pdoc->LineFromPosition(PositionFromLocation(
@@ -4111,7 +4446,7 @@ void Editor::PageMove(int direction, selTypes sel, bool stuttered) {
 		newPos = PositionFromLocation(Point(lastXChosen, vs.lineHeight * (LinesToScroll() - caretYSlop)));
 
 	} else {
-		Point pt = LocationFromPosition(currentPos);
+		Point pt = LocationFromPosition(sel.MainCaret());
 
 		topLineNew = Platform::Clamp(
 		            topLine + direction * LinesToScroll(), 0, MaxScrollPos());
@@ -4121,39 +4456,29 @@ void Editor::PageMove(int direction, selTypes sel, bool stuttered) {
 
 	if (topLineNew != topLine) {
 		SetTopLine(topLineNew);
-		MovePositionTo(newPos, sel);
+		MovePositionTo(SelectionPosition(newPos), selt);
 		Redraw();
 		SetVerticalScrollPos();
 	} else {
-		MovePositionTo(newPos, sel);
+		MovePositionTo(SelectionPosition(newPos), selt);
 	}
 }
 
 void Editor::ChangeCaseOfSelection(bool makeUpperCase) {
-	pdoc->BeginUndoAction();
-	int startCurrent = currentPos;
-	int startAnchor = anchor;
-	if (selType == selStream) {
-		pdoc->ChangeCase(Range(SelectionStart(), SelectionEnd()),
-		        makeUpperCase);
-		SetSelection(startCurrent, startAnchor);
-	} else {
-		SelectionLineIterator lineIterator(this, false);
-		while (lineIterator.Iterate()) {
-			pdoc->ChangeCase(
-			    Range(lineIterator.startPos, lineIterator.endPos),
-			    makeUpperCase);
-		}
-		// Would be nicer to keep the rectangular selection but this is complex
-		SetEmptySelection(startCurrent);
+	UndoGroup ug(pdoc);
+	for (size_t r=0; r<sel.Count(); r++) {
+		SelectionRange current = sel.Range(r);
+		pdoc->ChangeCase(Range(current.Start().Position(), current.End().Position()),
+	        makeUpperCase);
+		// Automatic movement cuts off last character so reset to exactly the same as it was.
+		sel.Range(r) = current;
 	}
-	pdoc->EndUndoAction();
 }
 
 void Editor::LineTranspose() {
-	int line = pdoc->LineFromPosition(currentPos);
+	int line = pdoc->LineFromPosition(sel.MainCaret());
 	if (line > 0) {
-		pdoc->BeginUndoAction();
+		UndoGroup ug(pdoc);
 		int startPrev = pdoc->LineStart(line - 1);
 		int endPrev = pdoc->LineEnd(line - 1);
 		int start = pdoc->LineStart(line);
@@ -4166,37 +4491,39 @@ void Editor::LineTranspose() {
 		pdoc->DeleteChars(startPrev, len1);
 		pdoc->InsertString(startPrev, line2, len2);
 		pdoc->InsertString(start - len1 + len2, line1, len1);
-		MovePositionTo(start - len1 + len2);
+		MovePositionTo(SelectionPosition(start - len1 + len2));
 		delete []line1;
 		delete []line2;
-		pdoc->EndUndoAction();
 	}
 }
 
 void Editor::Duplicate(bool forLine) {
-	int start = SelectionStart();
-	int end = SelectionEnd();
-	if (start == end) {
+	if (sel.Empty()) {
 		forLine = true;
 	}
-	if (forLine) {
-		int line = pdoc->LineFromPosition(currentPos);
-		start = pdoc->LineStart(line);
-		end = pdoc->LineEnd(line);
-	}
-	char *text = CopyRange(start, end);
-	if (forLine) {
-		const char *eol = StringFromEOLMode(pdoc->eolMode);
-		pdoc->InsertCString(end, eol);
-		pdoc->InsertString(end + istrlen(eol), text, end - start);
-	} else {
-		pdoc->InsertString(end, text, end - start);
+	UndoGroup ug(pdoc, sel.Count() > 1);
+	for (size_t r=0; r<sel.Count(); r++) {
+		SelectionPosition start = sel.Range(r).Start();
+		SelectionPosition end = sel.Range(r).End();
+		if (forLine) {
+			int line = pdoc->LineFromPosition(sel.Range(r).caret.Position());
+			start = SelectionPosition(pdoc->LineStart(line));
+			end = SelectionPosition(pdoc->LineEnd(line));
+		}
+		char *text = CopyRange(start.Position(), end.Position());
+		if (forLine) {
+			const char *eol = StringFromEOLMode(pdoc->eolMode);
+			pdoc->InsertCString(end.Position(), eol);
+			pdoc->InsertString(end.Position() + istrlen(eol), text, SelectionRange(end, start).Length());
+		} else {
+			pdoc->InsertString(end.Position(), text, SelectionRange(end, start).Length());
+		}
+		delete []text;
 	}
-	delete []text;
 }
 
 void Editor::CancelModes() {
-	moveExtendsSelection = false;
+	sel.SetMoveExtends(false);
 }
 
 void Editor::NewLine() {
@@ -4207,8 +4534,8 @@ void Editor::NewLine() {
 	} else if (pdoc->eolMode == SC_EOL_CR) {
 		eol = "\r";
 	} // else SC_EOL_LF -> "\n" already set
-	if (pdoc->InsertCString(currentPos, eol)) {
-		SetEmptySelection(currentPos + istrlen(eol));
+	if (pdoc->InsertCString(sel.MainCaret(), eol)) {
+		SetEmptySelection(sel.MainCaret() + istrlen(eol));
 		while (*eol) {
 			NotifyChar(*eol);
 			eol++;
@@ -4221,33 +4548,42 @@ void Editor::NewLine() {
 	ShowCaretAtCurrentPosition();
 }
 
-void Editor::CursorUpOrDown(int direction, selTypes sel) {
-	Point pt = LocationFromPosition(currentPos);
-	int posNew = PositionFromLocation(
-	            Point(lastXChosen, pt.y + direction * vs.lineHeight));
+void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) {
+	Point pt = PointMainCaret();
+	int lineDoc = pdoc->LineFromPosition(sel.MainCaret());
+	Point ptStartLine = LocationFromPosition(pdoc->LineStart(lineDoc));
+	int subLine = (pt.y - ptStartLine.y) / vs.lineHeight;
+	int commentLines = vs.annotationVisible ? pdoc->AnnotationLines(lineDoc) : 0;
+	SelectionPosition posNew = SPositionFromLocation(
+	            Point(lastXChosen, pt.y + direction * vs.lineHeight), false, false, UserVirtualSpace());
+	if ((direction > 0) && (subLine >= (cs.GetHeight(lineDoc) - 1 - commentLines))) {
+		posNew = SPositionFromLocation(
+	            Point(lastXChosen, pt.y + (commentLines + 1) * vs.lineHeight), false, false, UserVirtualSpace());
+	}
 	if (direction < 0) {
 		// Line wrapping may lead to a location on the same line, so
 		// seek back if that is the case.
 		// There is an equivalent case when moving down which skips
 		// over a line but as that does not trap the user it is fine.
-		Point ptNew = LocationFromPosition(posNew);
-		while ((posNew > 0) && (pt.y == ptNew.y)) {
-			posNew--;
-			ptNew = LocationFromPosition(posNew);
+		Point ptNew = LocationFromPosition(posNew.Position());
+		while ((posNew.Position() > 0) && (pt.y == ptNew.y)) {
+			posNew.Add(- 1);
+			posNew.SetVirtualSpace(0);
+			ptNew = LocationFromPosition(posNew.Position());
 		}
 	}
-	MovePositionTo(posNew, sel);
+	MovePositionTo(posNew, selt);
 }
 
-void Editor::ParaUpOrDown(int direction, selTypes sel) {
-	int lineDoc, savedPos = currentPos;
+void Editor::ParaUpOrDown(int direction, Selection::selTypes selt) {
+	int lineDoc, savedPos = sel.MainCaret();
 	do {
-		MovePositionTo(direction > 0 ? pdoc->ParaDown(currentPos) : pdoc->ParaUp(currentPos), sel);
-		lineDoc = pdoc->LineFromPosition(currentPos);
+		MovePositionTo(SelectionPosition(direction > 0 ? pdoc->ParaDown(sel.MainCaret()) : pdoc->ParaUp(sel.MainCaret())), selt);
+		lineDoc = pdoc->LineFromPosition(sel.MainCaret());
 		if (direction > 0) {
-			if (currentPos >= pdoc->Length() && !cs.GetVisible(lineDoc)) {
-				if (sel == noSel) {
-					MovePositionTo(pdoc->LineEndPosition(savedPos));
+			if (sel.MainCaret() >= pdoc->Length() && !cs.GetVisible(lineDoc)) {
+				if (selt == Selection::noSel) {
+					MovePositionTo(SelectionPosition(pdoc->LineEndPosition(savedPos)));
 				}
 				break;
 			}
@@ -4293,16 +4629,16 @@ int Editor::KeyCommand(unsigned int iMessage) {
 		CursorUpOrDown(1);
 		break;
 	case SCI_LINEDOWNEXTEND:
-		CursorUpOrDown(1, selStream);
+		CursorUpOrDown(1, Selection::selStream);
 		break;
 	case SCI_LINEDOWNRECTEXTEND:
-		CursorUpOrDown(1, selRectangle);
+		CursorUpOrDown(1, Selection::selRectangle);
 		break;
 	case SCI_PARADOWN:
 		ParaUpOrDown(1);
 		break;
 	case SCI_PARADOWNEXTEND:
-		ParaUpOrDown(1, selStream);
+		ParaUpOrDown(1, Selection::selStream);
 		break;
 	case SCI_LINESCROLLDOWN:
 		ScrollTo(topLine + 1);
@@ -4312,144 +4648,180 @@ int Editor::KeyCommand(unsigned int iMessage) {
 		CursorUpOrDown(-1);
 		break;
 	case SCI_LINEUPEXTEND:
-		CursorUpOrDown(-1, selStream);
+		CursorUpOrDown(-1, Selection::selStream);
 		break;
 	case SCI_LINEUPRECTEXTEND:
-		CursorUpOrDown(-1, selRectangle);
+		CursorUpOrDown(-1, Selection::selRectangle);
 		break;
 	case SCI_PARAUP:
 		ParaUpOrDown(-1);
 		break;
 	case SCI_PARAUPEXTEND:
-		ParaUpOrDown(-1, selStream);
+		ParaUpOrDown(-1, Selection::selStream);
 		break;
 	case SCI_LINESCROLLUP:
 		ScrollTo(topLine - 1);
 		MoveCaretInsideView(false);
 		break;
 	case SCI_CHARLEFT:
-		if (SelectionEmpty() || moveExtendsSelection) {
-			MovePositionTo(MovePositionSoVisible(currentPos - 1, -1));
+		if (SelectionEmpty() || sel.MoveExtends()) {
+			if (pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) {
+				SelectionPosition spCaret = sel.RangeMain().caret;
+				spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
+				MovePositionTo(spCaret);
+			} else {
+				MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1));
+			}
 		} else {
-			MovePositionTo(SelectionStart());
+			MovePositionTo(sel.RangeMain().Start());
 		}
 		SetLastXChosen();
 		break;
 	case SCI_CHARLEFTEXTEND:
-		MovePositionTo(MovePositionSoVisible(currentPos - 1, -1), selStream);
+		if (pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) {
+			SelectionPosition spCaret = sel.RangeMain().caret;
+			spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
+			MovePositionTo(spCaret, Selection::selStream);
+		} else {
+			MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1), Selection::selStream);
+		}
 		SetLastXChosen();
 		break;
 	case SCI_CHARLEFTRECTEXTEND:
-		MovePositionTo(MovePositionSoVisible(currentPos - 1, -1), selRectangle);
+		if (pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) {
+			SelectionPosition spCaret = sel.RangeMain().caret;
+			spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
+			MovePositionTo(spCaret, Selection::selRectangle);
+		} else {
+			MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1), Selection::selRectangle);
+		}
 		SetLastXChosen();
 		break;
 	case SCI_CHARRIGHT:
-		if (SelectionEmpty() || moveExtendsSelection) {
-			MovePositionTo(MovePositionSoVisible(currentPos + 1, 1));
+		if (SelectionEmpty() || sel.MoveExtends()) {
+			if ((virtualSpaceOptions & SCVS_USERACCESSIBLE) && pdoc->IsLineEndPosition(sel.MainCaret())) {
+				SelectionPosition spCaret = sel.RangeMain().caret;
+				spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1);
+				MovePositionTo(spCaret);
+			} else {
+				MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() + 1), 1));
+			}
 		} else {
-			MovePositionTo(SelectionEnd());
+			MovePositionTo(sel.RangeMain().End());
 		}
 		SetLastXChosen();
 		break;
 	case SCI_CHARRIGHTEXTEND:
-		MovePositionTo(MovePositionSoVisible(currentPos + 1, 1), selStream);
+		if ((virtualSpaceOptions & SCVS_USERACCESSIBLE) && pdoc->IsLineEndPosition(sel.MainCaret())) {
+			SelectionPosition spCaret = sel.RangeMain().caret;
+			spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1);
+			MovePositionTo(spCaret, Selection::selStream);
+		} else {
+			MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() + 1), 1), Selection::selStream);
+		}
 		SetLastXChosen();
 		break;
 	case SCI_CHARRIGHTRECTEXTEND:
-		MovePositionTo(MovePositionSoVisible(currentPos + 1, 1), selRectangle);
+		if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) && pdoc->IsLineEndPosition(sel.MainCaret())) {
+			SelectionPosition spCaret = sel.RangeMain().caret;
+			spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1);
+			MovePositionTo(spCaret, Selection::selRectangle);
+		} else {
+			MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() + 1), 1), Selection::selRectangle);
+		}
 		SetLastXChosen();
 		break;
 	case SCI_WORDLEFT:
-		MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(currentPos, -1), -1));
+		MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), -1), -1));
 		SetLastXChosen();
 		break;
 	case SCI_WORDLEFTEXTEND:
-		MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(currentPos, -1), -1), selStream);
+		MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), -1), -1), Selection::selStream);
 		SetLastXChosen();
 		break;
 	case SCI_WORDRIGHT:
-		MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(currentPos, 1), 1));
+		MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), 1), 1));
 		SetLastXChosen();
 		break;
 	case SCI_WORDRIGHTEXTEND:
-		MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(currentPos, 1), 1), selStream);
+		MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), 1), 1), Selection::selStream);
 		SetLastXChosen();
 		break;
 
 	case SCI_WORDLEFTEND:
-		MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(currentPos, -1), -1));
+		MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), -1), -1));
 		SetLastXChosen();
 		break;
 	case SCI_WORDLEFTENDEXTEND:
-		MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(currentPos, -1), -1), selStream);
+		MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), -1), -1), Selection::selStream);
 		SetLastXChosen();
 		break;
 	case SCI_WORDRIGHTEND:
-		MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(currentPos, 1), 1));
+		MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), 1), 1));
 		SetLastXChosen();
 		break;
 	case SCI_WORDRIGHTENDEXTEND:
-		MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(currentPos, 1), 1), selStream);
+		MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), 1), 1), Selection::selStream);
 		SetLastXChosen();
 		break;
 
 	case SCI_HOME:
-		MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(currentPos)));
+		MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())));
 		SetLastXChosen();
 		break;
 	case SCI_HOMEEXTEND:
-		MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(currentPos)), selStream);
+		MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())), Selection::selStream);
 		SetLastXChosen();
 		break;
 	case SCI_HOMERECTEXTEND:
-		MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(currentPos)), selRectangle);
+		MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())), Selection::selRectangle);
 		SetLastXChosen();
 		break;
 	case SCI_LINEEND:
-		MovePositionTo(pdoc->LineEndPosition(currentPos));
+		MovePositionTo(pdoc->LineEndPosition(sel.MainCaret()));
 		SetLastXChosen();
 		break;
 	case SCI_LINEENDEXTEND:
-		MovePositionTo(pdoc->LineEndPosition(currentPos), selStream);
+		MovePositionTo(pdoc->LineEndPosition(sel.MainCaret()), Selection::selStream);
 		SetLastXChosen();
 		break;
 	case SCI_LINEENDRECTEXTEND:
-		MovePositionTo(pdoc->LineEndPosition(currentPos), selRectangle);
+		MovePositionTo(pdoc->LineEndPosition(sel.MainCaret()), Selection::selRectangle);
 		SetLastXChosen();
 		break;
 	case SCI_HOMEWRAP: {
-			int homePos = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
-			if (currentPos <= homePos)
-				homePos = pdoc->LineStart(pdoc->LineFromPosition(currentPos));
+			SelectionPosition homePos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1);
+			if (sel.RangeMain().caret <= homePos)
+				homePos = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())));
 			MovePositionTo(homePos);
 			SetLastXChosen();
 		}
 		break;
 	case SCI_HOMEWRAPEXTEND: {
-			int homePos = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
-			if (currentPos <= homePos)
-				homePos = pdoc->LineStart(pdoc->LineFromPosition(currentPos));
-			MovePositionTo(homePos, selStream);
+			SelectionPosition homePos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1);
+			if (sel.RangeMain().caret <= homePos)
+				homePos = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())));
+			MovePositionTo(homePos, Selection::selStream);
 			SetLastXChosen();
 		}
 		break;
 	case SCI_LINEENDWRAP: {
-			int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1);
-			int realEndPos = pdoc->LineEndPosition(currentPos);
+			SelectionPosition endPos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), false), 1);
+			SelectionPosition realEndPos = SelectionPosition(pdoc->LineEndPosition(sel.MainCaret()));
 			if (endPos > realEndPos      // if moved past visible EOLs
-			        || currentPos >= endPos) // if at end of display line already
+			        || sel.RangeMain().caret >= endPos) // if at end of display line already
 				endPos = realEndPos;
 			MovePositionTo(endPos);
 			SetLastXChosen();
 		}
 		break;
 	case SCI_LINEENDWRAPEXTEND: {
-			int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1);
-			int realEndPos = pdoc->LineEndPosition(currentPos);
+			SelectionPosition endPos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), false), 1);
+			SelectionPosition realEndPos = SelectionPosition(pdoc->LineEndPosition(sel.MainCaret()));
 			if (endPos > realEndPos      // if moved past visible EOLs
-			        || currentPos >= endPos) // if at end of display line already
+			        || sel.RangeMain().caret >= endPos) // if at end of display line already
 				endPos = realEndPos;
-			MovePositionTo(endPos, selStream);
+			MovePositionTo(endPos, Selection::selStream);
 			SetLastXChosen();
 		}
 		break;
@@ -4458,7 +4830,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
 		SetLastXChosen();
 		break;
 	case SCI_DOCUMENTSTARTEXTEND:
-		MovePositionTo(0, selStream);
+		MovePositionTo(0, Selection::selStream);
 		SetLastXChosen();
 		break;
 	case SCI_DOCUMENTEND:
@@ -4466,38 +4838,38 @@ int Editor::KeyCommand(unsigned int iMessage) {
 		SetLastXChosen();
 		break;
 	case SCI_DOCUMENTENDEXTEND:
-		MovePositionTo(pdoc->Length(), selStream);
+		MovePositionTo(pdoc->Length(), Selection::selStream);
 		SetLastXChosen();
 		break;
 	case SCI_STUTTEREDPAGEUP:
-		PageMove(-1, noSel, true);
+		PageMove(-1, Selection::noSel, true);
 		break;
 	case SCI_STUTTEREDPAGEUPEXTEND:
-		PageMove(-1, selStream, true);
+		PageMove(-1, Selection::selStream, true);
 		break;
 	case SCI_STUTTEREDPAGEDOWN:
-		PageMove(1, noSel, true);
+		PageMove(1, Selection::noSel, true);
 		break;
 	case SCI_STUTTEREDPAGEDOWNEXTEND:
-		PageMove(1, selStream, true);
+		PageMove(1, Selection::selStream, true);
 		break;
 	case SCI_PAGEUP:
 		PageMove(-1);
 		break;
 	case SCI_PAGEUPEXTEND:
-		PageMove(-1, selStream);
+		PageMove(-1, Selection::selStream);
 		break;
 	case SCI_PAGEUPRECTEXTEND:
-		PageMove(-1, selRectangle);
+		PageMove(-1, Selection::selRectangle);
 		break;
 	case SCI_PAGEDOWN:
 		PageMove(1);
 		break;
 	case SCI_PAGEDOWNEXTEND:
-		PageMove(1, selStream);
+		PageMove(1, Selection::selStream);
 		break;
 	case SCI_PAGEDOWNRECTEXTEND:
-		PageMove(1, selRectangle);
+		PageMove(1, Selection::selRectangle);
 		break;
 	case SCI_EDITTOGGLEOVERTYPE:
 		inOverstrike = !inOverstrike;
@@ -4529,6 +4901,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
 			SetLastXChosen();
 		}
 		EnsureCaretVisible();
+		ShowCaretAtCurrentPosition();		// Avoid blinking
 		break;
 	case SCI_BACKTAB:
 		Indent(false);
@@ -4536,6 +4909,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
 			SetLastXChosen();
 		}
 		EnsureCaretVisible();
+		ShowCaretAtCurrentPosition();		// Avoid blinking
 		break;
 	case SCI_NEWLINE:
 		NewLine();
@@ -4544,21 +4918,21 @@ int Editor::KeyCommand(unsigned int iMessage) {
 		AddChar('\f');
 		break;
 	case SCI_VCHOME:
-		MovePositionTo(pdoc->VCHomePosition(currentPos));
+		MovePositionTo(pdoc->VCHomePosition(sel.MainCaret()));
 		SetLastXChosen();
 		break;
 	case SCI_VCHOMEEXTEND:
-		MovePositionTo(pdoc->VCHomePosition(currentPos), selStream);
+		MovePositionTo(pdoc->VCHomePosition(sel.MainCaret()), Selection::selStream);
 		SetLastXChosen();
 		break;
 	case SCI_VCHOMERECTEXTEND:
-		MovePositionTo(pdoc->VCHomePosition(currentPos), selRectangle);
+		MovePositionTo(pdoc->VCHomePosition(sel.MainCaret()), Selection::selRectangle);
 		SetLastXChosen();
 		break;
 	case SCI_VCHOMEWRAP: {
-			int homePos = pdoc->VCHomePosition(currentPos);
-			int viewLineStart = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
-			if ((viewLineStart < currentPos) && (viewLineStart > homePos))
+			SelectionPosition homePos = SelectionPosition(pdoc->VCHomePosition(sel.MainCaret()));
+			SelectionPosition viewLineStart = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1);
+			if ((viewLineStart < sel.RangeMain().caret) && (viewLineStart > homePos))
 				homePos = viewLineStart;
 
 			MovePositionTo(homePos);
@@ -4566,12 +4940,12 @@ int Editor::KeyCommand(unsigned int iMessage) {
 		}
 		break;
 	case SCI_VCHOMEWRAPEXTEND: {
-			int homePos = pdoc->VCHomePosition(currentPos);
-			int viewLineStart = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
-			if ((viewLineStart < currentPos) && (viewLineStart > homePos))
+			SelectionPosition homePos = SelectionPosition(pdoc->VCHomePosition(sel.MainCaret()));
+			SelectionPosition viewLineStart = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1);
+			if ((viewLineStart < sel.RangeMain().caret) && (viewLineStart > homePos))
 				homePos = viewLineStart;
 
-			MovePositionTo(homePos, selStream);
+			MovePositionTo(homePos, Selection::selStream);
 			SetLastXChosen();
 		}
 		break;
@@ -4590,44 +4964,44 @@ int Editor::KeyCommand(unsigned int iMessage) {
 		}
 		break;
 	case SCI_DELWORDLEFT: {
-			int startWord = pdoc->NextWordStart(currentPos, -1);
-			pdoc->DeleteChars(startWord, currentPos - startWord);
+			int startWord = pdoc->NextWordStart(sel.MainCaret(), -1);
+			pdoc->DeleteChars(startWord, sel.MainCaret() - startWord);
 			SetLastXChosen();
 		}
 		break;
 	case SCI_DELWORDRIGHT: {
-			int endWord = pdoc->NextWordStart(currentPos, 1);
-			pdoc->DeleteChars(currentPos, endWord - currentPos);
+			int endWord = pdoc->NextWordStart(sel.MainCaret(), 1);
+			pdoc->DeleteChars(sel.MainCaret(), endWord - sel.MainCaret());
 		}
 		break;
 	case SCI_DELWORDRIGHTEND: {
-			int endWord = pdoc->NextWordEnd(currentPos, 1);
-			pdoc->DeleteChars(currentPos, endWord - currentPos);
+			int endWord = pdoc->NextWordEnd(sel.MainCaret(), 1);
+			pdoc->DeleteChars(sel.MainCaret(), endWord - sel.MainCaret());
 		}
 		break;
 	case SCI_DELLINELEFT: {
-			int line = pdoc->LineFromPosition(currentPos);
+			int line = pdoc->LineFromPosition(sel.MainCaret());
 			int start = pdoc->LineStart(line);
-			pdoc->DeleteChars(start, currentPos - start);
+			pdoc->DeleteChars(start, sel.MainCaret() - start);
 			SetLastXChosen();
 		}
 		break;
 	case SCI_DELLINERIGHT: {
-			int line = pdoc->LineFromPosition(currentPos);
+			int line = pdoc->LineFromPosition(sel.MainCaret());
 			int end = pdoc->LineEnd(line);
-			pdoc->DeleteChars(currentPos, end - currentPos);
+			pdoc->DeleteChars(sel.MainCaret(), end - sel.MainCaret());
 		}
 		break;
 	case SCI_LINECOPY: {
-			int lineStart = pdoc->LineFromPosition(SelectionStart());
-			int lineEnd = pdoc->LineFromPosition(SelectionEnd());
+			int lineStart = pdoc->LineFromPosition(SelectionStart().Position());
+			int lineEnd = pdoc->LineFromPosition(SelectionEnd().Position());
 			CopyRangeToClipboard(pdoc->LineStart(lineStart),
 			        pdoc->LineStart(lineEnd + 1));
 		}
 		break;
 	case SCI_LINECUT: {
-			int lineStart = pdoc->LineFromPosition(SelectionStart());
-			int lineEnd = pdoc->LineFromPosition(SelectionEnd());
+			int lineStart = pdoc->LineFromPosition(SelectionStart().Position());
+			int lineEnd = pdoc->LineFromPosition(SelectionEnd().Position());
 			int start = pdoc->LineStart(lineStart);
 			int end = pdoc->LineStart(lineEnd + 1);
 			SetSelection(start, end);
@@ -4636,7 +5010,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
 		}
 		break;
 	case SCI_LINEDELETE: {
-			int line = pdoc->LineFromPosition(currentPos);
+			int line = pdoc->LineFromPosition(sel.MainCaret());
 			int start = pdoc->LineStart(line);
 			int end = pdoc->LineStart(line + 1);
 			pdoc->DeleteChars(start, end - start);
@@ -4658,39 +5032,39 @@ int Editor::KeyCommand(unsigned int iMessage) {
 		ChangeCaseOfSelection(true);
 		break;
 	case SCI_WORDPARTLEFT:
-		MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(currentPos), -1));
+		MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(sel.MainCaret()), -1));
 		SetLastXChosen();
 		break;
 	case SCI_WORDPARTLEFTEXTEND:
-		MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(currentPos), -1), selStream);
+		MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(sel.MainCaret()), -1), Selection::selStream);
 		SetLastXChosen();
 		break;
 	case SCI_WORDPARTRIGHT:
-		MovePositionTo(MovePositionSoVisible(pdoc->WordPartRight(currentPos), 1));
+		MovePositionTo(MovePositionSoVisible(pdoc->WordPartRight(sel.MainCaret()), 1));
 		SetLastXChosen();
 		break;
 	case SCI_WORDPARTRIGHTEXTEND:
-		MovePositionTo(MovePositionSoVisible(pdoc->WordPartRight(currentPos), 1), selStream);
+		MovePositionTo(MovePositionSoVisible(pdoc->WordPartRight(sel.MainCaret()), 1), Selection::selStream);
 		SetLastXChosen();
 		break;
 	case SCI_HOMEDISPLAY:
 		MovePositionTo(MovePositionSoVisible(
-		            StartEndDisplayLine(currentPos, true), -1));
+		            StartEndDisplayLine(sel.MainCaret(), true), -1));
 		SetLastXChosen();
 		break;
 	case SCI_HOMEDISPLAYEXTEND:
 		MovePositionTo(MovePositionSoVisible(
-		            StartEndDisplayLine(currentPos, true), -1), selStream);
+		            StartEndDisplayLine(sel.MainCaret(), true), -1), Selection::selStream);
 		SetLastXChosen();
 		break;
 	case SCI_LINEENDDISPLAY:
 		MovePositionTo(MovePositionSoVisible(
-		            StartEndDisplayLine(currentPos, false), 1));
+		            StartEndDisplayLine(sel.MainCaret(), false), 1));
 		SetLastXChosen();
 		break;
 	case SCI_LINEENDDISPLAYEXTEND:
 		MovePositionTo(MovePositionSoVisible(
-		            StartEndDisplayLine(currentPos, false), 1), selStream);
+		            StartEndDisplayLine(sel.MainCaret(), false), 1), Selection::selStream);
 		SetLastXChosen();
 		break;
 	}
@@ -4726,77 +5100,79 @@ int Editor::GetWhitespaceVisible() {
 }
 
 void Editor::Indent(bool forwards) {
-	//Platform::DebugPrintf("INdent %d\n", forwards);
-	int lineOfAnchor = pdoc->LineFromPosition(anchor);
-	int lineCurrentPos = pdoc->LineFromPosition(currentPos);
-	if (lineOfAnchor == lineCurrentPos) {
-		if (forwards) {
-			pdoc->BeginUndoAction();
-			ClearSelection();
-			if (pdoc->GetColumn(currentPos) <= pdoc->GetColumn(pdoc->GetLineIndentPosition(lineCurrentPos)) &&
-			        pdoc->tabIndents) {
-				int indentation = pdoc->GetLineIndentation(lineCurrentPos);
-				int indentationStep = pdoc->IndentSize();
-				pdoc->SetLineIndentation(lineCurrentPos, indentation + indentationStep - indentation % indentationStep);
-				SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
-			} else {
-				if (pdoc->useTabs) {
-					pdoc->InsertChar(currentPos, '\t');
-					SetEmptySelection(currentPos + 1);
+	for (size_t r=0; r<sel.Count(); r++) {
+		int lineOfAnchor = pdoc->LineFromPosition(sel.Range(r).anchor.Position());
+		int caretPosition = sel.Range(r).caret.Position();
+		int lineCurrentPos = pdoc->LineFromPosition(caretPosition);
+		if (lineOfAnchor == lineCurrentPos) {
+			if (forwards) {
+				UndoGroup ug(pdoc);
+				pdoc->DeleteChars(sel.Range(r).Start().Position(), sel.Range(r).Length()); 
+				caretPosition = sel.Range(r).caret.Position();
+				if (pdoc->GetColumn(caretPosition) <= pdoc->GetColumn(pdoc->GetLineIndentPosition(lineCurrentPos)) &&
+						pdoc->tabIndents) {
+					int indentation = pdoc->GetLineIndentation(lineCurrentPos);
+					int indentationStep = pdoc->IndentSize();
+					pdoc->SetLineIndentation(lineCurrentPos, indentation + indentationStep - indentation % indentationStep);
+					sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos));
 				} else {
-					int numSpaces = (pdoc->tabInChars) -
-					        (pdoc->GetColumn(currentPos) % (pdoc->tabInChars));
-					if (numSpaces < 1)
-						numSpaces = pdoc->tabInChars;
-					for (int i = 0; i < numSpaces; i++) {
-						pdoc->InsertChar(currentPos + i, ' ');
+					if (pdoc->useTabs) {
+						pdoc->InsertChar(caretPosition, '\t');
+						sel.Range(r) = SelectionRange(caretPosition+1);
+					} else {
+						int numSpaces = (pdoc->tabInChars) -
+								(pdoc->GetColumn(caretPosition) % (pdoc->tabInChars));
+						if (numSpaces < 1)
+							numSpaces = pdoc->tabInChars;
+						for (int i = 0; i < numSpaces; i++) {
+							pdoc->InsertChar(caretPosition + i, ' ');
+						}
+						sel.Range(r) = SelectionRange(caretPosition+numSpaces);
 					}
-					SetEmptySelection(currentPos + numSpaces);
+				}
+			} else {
+				if (pdoc->GetColumn(caretPosition) <= pdoc->GetLineIndentation(lineCurrentPos) &&
+						pdoc->tabIndents) {
+					UndoGroup ug(pdoc);
+					int indentation = pdoc->GetLineIndentation(lineCurrentPos);
+					int indentationStep = pdoc->IndentSize();
+					pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
+					SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
+				} else {
+					int newColumn = ((pdoc->GetColumn(caretPosition) - 1) / pdoc->tabInChars) *
+							pdoc->tabInChars;
+					if (newColumn < 0)
+						newColumn = 0;
+					int newPos = caretPosition;
+					while (pdoc->GetColumn(newPos) > newColumn)
+						newPos--;
+					sel.Range(r) = SelectionRange(newPos);
 				}
 			}
-			pdoc->EndUndoAction();
-		} else {
-			if (pdoc->GetColumn(currentPos) <= pdoc->GetLineIndentation(lineCurrentPos) &&
-			        pdoc->tabIndents) {
-				pdoc->BeginUndoAction();
-				int indentation = pdoc->GetLineIndentation(lineCurrentPos);
-				int indentationStep = pdoc->IndentSize();
-				pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
-				SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
-				pdoc->EndUndoAction();
+		} else {	// Multiline
+			int anchorPosOnLine = sel.Range(r).anchor.Position() - pdoc->LineStart(lineOfAnchor);
+			int currentPosPosOnLine = caretPosition - pdoc->LineStart(lineCurrentPos);
+			// Multiple lines selected so indent / dedent
+			int lineTopSel = Platform::Minimum(lineOfAnchor, lineCurrentPos);
+			int lineBottomSel = Platform::Maximum(lineOfAnchor, lineCurrentPos);
+			if (pdoc->LineStart(lineBottomSel) == sel.Range(r).anchor.Position() || pdoc->LineStart(lineBottomSel) == caretPosition)
+				lineBottomSel--;  	// If not selecting any characters on a line, do not indent
+			{
+				UndoGroup ug(pdoc);
+				pdoc->Indent(forwards, lineBottomSel, lineTopSel);
+			}
+			if (lineOfAnchor < lineCurrentPos) {
+				if (currentPosPosOnLine == 0)
+					sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor));
+				else
+					sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos + 1), pdoc->LineStart(lineOfAnchor));
 			} else {
-				int newColumn = ((pdoc->GetColumn(currentPos) - 1) / pdoc->tabInChars) *
-				        pdoc->tabInChars;
-				if (newColumn < 0)
-					newColumn = 0;
-				int newPos = currentPos;
-				while (pdoc->GetColumn(newPos) > newColumn)
-					newPos--;
-				SetEmptySelection(newPos);
+				if (anchorPosOnLine == 0)
+					sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor));
+				else
+					sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor + 1));
 			}
 		}
-	} else {
-		int anchorPosOnLine = anchor - pdoc->LineStart(lineOfAnchor);
-		int currentPosPosOnLine = currentPos - pdoc->LineStart(lineCurrentPos);
-		// Multiple lines selected so indent / dedent
-		int lineTopSel = Platform::Minimum(lineOfAnchor, lineCurrentPos);
-		int lineBottomSel = Platform::Maximum(lineOfAnchor, lineCurrentPos);
-		if (pdoc->LineStart(lineBottomSel) == anchor || pdoc->LineStart(lineBottomSel) == currentPos)
-			lineBottomSel--;  	// If not selecting any characters on a line, do not indent
-		pdoc->BeginUndoAction();
-		pdoc->Indent(forwards, lineBottomSel, lineTopSel);
-		pdoc->EndUndoAction();
-		if (lineOfAnchor < lineCurrentPos) {
-			if (currentPosPosOnLine == 0)
-				SetSelection(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor));
-			else
-				SetSelection(pdoc->LineStart(lineCurrentPos + 1), pdoc->LineStart(lineOfAnchor));
-		} else {
-			if (anchorPosOnLine == 0)
-				SetSelection(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor));
-			else
-				SetSelection(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor + 1));
-		}
 	}
 }
 
@@ -4809,7 +5185,7 @@ long Editor::FindText(
     ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX.
     sptr_t lParam) {	///< @c TextToFind structure: The text to search for in the given range.
 
-	TextToFind *ft = reinterpret_cast<TextToFind *>(lParam);
+	Sci_TextToFind *ft = reinterpret_cast<Sci_TextToFind *>(lParam);
 	int lengthFound = istrlen(ft->lpstrText);
 	int pos = pdoc->FindText(ft->chrg.cpMin, ft->chrg.cpMax, ft->lpstrText,
 	        (wParam & SCFIND_MATCHCASE) != 0,
@@ -4837,7 +5213,7 @@ long Editor::FindText(
  * operation is self-contained.
  */
 void Editor::SearchAnchor() {
-	searchAnchor = SelectionStart();
+	searchAnchor = SelectionStart().Position();
 }
 
 /**
@@ -4922,85 +5298,68 @@ char *Editor::CopyRange(int start, int end) {
 	if (start < end) {
 		int len = end - start;
 		text = new char[len + 1];
-		if (text) {
-			for (int i = 0; i < len; i++) {
-				text[i] = pdoc->CharAt(start + i);
-			}
-			text[len] = '\0';
+		for (int i = 0; i < len; i++) {
+			text[i] = pdoc->CharAt(start + i);
 		}
+		text[len] = '\0';
 	}
 	return text;
 }
 
-void Editor::CopySelectionFromRange(SelectionText *ss, bool allowLineCopy, int start, int end) {
-	bool isLine = allowLineCopy && (start == end);
-	if (isLine) {
-		int currentLine = pdoc->LineFromPosition(currentPos);
-		start = pdoc->LineStart(currentLine);
-		end = pdoc->LineEnd(currentLine);
-
-		char *text = CopyRange(start, end);
-		int textLen = text ? strlen(text) : 0;
-		// include room for \r\n\0
-		textLen += 3;
-		char *textWithEndl = new char[textLen];
-		textWithEndl[0] = '\0';
-		if (text)
-			strncat(textWithEndl, text, textLen);
-		if (pdoc->eolMode != SC_EOL_LF)
-			strncat(textWithEndl, "\r", textLen);
-		if (pdoc->eolMode != SC_EOL_CR)
-			strncat(textWithEndl, "\n", textLen);
-		ss->Set(textWithEndl, strlen(textWithEndl),
-			pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, true);
-		delete []text;
-	} else {
-		ss->Set(CopyRange(start, end), end - start + 1,
-			pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, false);
-	}
-}
-
 void Editor::CopySelectionRange(SelectionText *ss, bool allowLineCopy) {
-	if (selType == selStream) {
-		CopySelectionFromRange(ss, allowLineCopy, SelectionStart(), SelectionEnd());
+	if (sel.Empty()) {
+		if (allowLineCopy) {
+			int currentLine = pdoc->LineFromPosition(sel.MainCaret());
+			int start = pdoc->LineStart(currentLine);
+			int end = pdoc->LineEnd(currentLine);
+
+			char *text = CopyRange(start, end);
+			int textLen = text ? strlen(text) : 0;
+			// include room for \r\n\0
+			textLen += 3;
+			char *textWithEndl = new char[textLen];
+			textWithEndl[0] = '\0';
+			if (text)
+				strncat(textWithEndl, text, textLen);
+			if (pdoc->eolMode != SC_EOL_LF)
+				strncat(textWithEndl, "\r", textLen);
+			if (pdoc->eolMode != SC_EOL_CR)
+				strncat(textWithEndl, "\n", textLen);
+			ss->Set(textWithEndl, strlen(textWithEndl),
+				pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, true);
+			delete []text;
+		}
 	} else {
-		char *text = 0;
-		int size = 0;
-		SelectionLineIterator lineIterator(this);
-		while (lineIterator.Iterate()) {
-			size += lineIterator.endPos - lineIterator.startPos;
-			if (selType != selLines) {
-				size++;
-				if (pdoc->eolMode == SC_EOL_CRLF) {
-					size++;
-				}
+		int delimiterLength = 0;
+		if (sel.selType == Selection::selRectangle) {
+			if (pdoc->eolMode == SC_EOL_CRLF) {
+				delimiterLength = 2;
+			} else {
+				delimiterLength = 1;
 			}
 		}
-		if (size > 0) {
-			text = new char[size + 1];
-			if (text) {
-				int j = 0;
-				lineIterator.Reset();
-				while (lineIterator.Iterate()) {
-					for (int i = lineIterator.startPos;
-					        i < lineIterator.endPos;
-					        i++) {
-						text[j++] = pdoc->CharAt(i);
-					}
-					if (selType != selLines) {
-						if (pdoc->eolMode != SC_EOL_LF) {
-							text[j++] = '\r';
-						}
-						if (pdoc->eolMode != SC_EOL_CR) {
-							text[j++] = '\n';
-						}
-					}
+		int size = sel.Length() + delimiterLength * sel.Count();
+		char *text = new char[size + 1];
+		int j = 0;
+		for (size_t r=0; r<sel.Count(); r++) {
+			SelectionRange current = sel.Range(r);
+			for (int i = current.Start().Position();
+			        i < current.End().Position();
+			        i++) {
+				text[j++] = pdoc->CharAt(i);
+			}
+			if (sel.selType == Selection::selRectangle) {
+				if (pdoc->eolMode != SC_EOL_LF) {
+					text[j++] = '\r';
+				}
+				if (pdoc->eolMode != SC_EOL_CR) {
+					text[j++] = '\n';
 				}
-				text[size] = '\0';
 			}
 		}
+		text[size] = '\0';
 		ss->Set(text, size + 1, pdoc->dbcsCodePage,
-			vs.styles[STYLE_DEFAULT].characterSet, selType == selRectangle, selType == selLines);
+			vs.styles[STYLE_DEFAULT].characterSet, sel.IsRectangular(), sel.selType == Selection::selLines);
 	}
 }
 
@@ -5020,12 +5379,12 @@ void Editor::CopyText(int length, const char *text) {
 	CopyToClipboard(selectedText);
 }
 
-void Editor::SetDragPosition(int newPos) {
-	if (newPos >= 0) {
+void Editor::SetDragPosition(SelectionPosition newPos) {
+	if (newPos.Position() >= 0) {
 		newPos = MovePositionOutsideChar(newPos, 1);
 		posDrop = newPos;
 	}
-	if (posDrag != newPos) {
+	if (!(posDrag == newPos)) {
 		caret.on = true;
 		SetTicking(true);
 		InvalidateCaret();
@@ -5054,41 +5413,40 @@ void Editor::StartDrag() {
 	//DisplayCursor(Window::cursorArrow);
 }
 
-void Editor::DropAt(int position, const char *value, bool moving, bool rectangular) {
+void Editor::DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular) {
 	//Platform::DebugPrintf("DropAt %d %d\n", inDragDrop, position);
 	if (inDragDrop == ddDragging)
 		dropWentOutside = false;
 
-	int positionWasInSelection = PositionInSelection(position);
+	bool positionWasInSelection = PositionInSelection(position.Position());
 
 	bool positionOnEdgeOfSelection =
 	    (position == SelectionStart()) || (position == SelectionEnd());
 
-	if ((inDragDrop != ddDragging) || !(0 == positionWasInSelection) ||
+	if ((inDragDrop != ddDragging) || !(positionWasInSelection) ||
 	        (positionOnEdgeOfSelection && !moving)) {
 
-		int selStart = SelectionStart();
-		int selEnd = SelectionEnd();
+		SelectionPosition selStart = SelectionStart();
+		SelectionPosition selEnd = SelectionEnd();
 
-		pdoc->BeginUndoAction();
+		UndoGroup ug(pdoc);
 
-		int positionAfterDeletion = position;
+		SelectionPosition positionAfterDeletion = position;
 		if ((inDragDrop == ddDragging) && moving) {
 			// Remove dragged out text
-			if (rectangular || selType == selLines) {
-				SelectionLineIterator lineIterator(this);
-				while (lineIterator.Iterate()) {
-					if (position >= lineIterator.startPos) {
-						if (position > lineIterator.endPos) {
-							positionAfterDeletion -= lineIterator.endPos - lineIterator.startPos;
+			if (rectangular || sel.selType == Selection::selLines) {
+				for (size_t r=0; r<sel.Count(); r++) {
+					if (position >= sel.Range(r).Start()) {
+						if (position > sel.Range(r).End()) {
+							positionAfterDeletion.Add(-sel.Range(r).Length());
 						} else {
-							positionAfterDeletion -= position - lineIterator.startPos;
+							positionAfterDeletion.Add(-SelectionRange(position, sel.Range(r).Start()).Length());
 						}
 					}
 				}
 			} else {
 				if (position > selStart) {
-					positionAfterDeletion -= selEnd - selStart;
+					positionAfterDeletion.Add(-SelectionRange(selEnd, selStart).Length());
 				}
 			}
 			ClearSelection();
@@ -5097,15 +5455,16 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul
 
 		if (rectangular) {
 			PasteRectangular(position, value, istrlen(value));
-			pdoc->EndUndoAction();
 			// Should try to select new rectangle but it may not be a rectangle now so just select the drop position
 			SetEmptySelection(position);
 		} else {
-			position = MovePositionOutsideChar(position, currentPos - position);
-			if (pdoc->InsertCString(position, value)) {
-				SetSelection(position + istrlen(value), position);
+			position = MovePositionOutsideChar(position, sel.MainCaret() - position.Position());
+			position = SelectionPosition(InsertSpace(position.Position(), position.VirtualSpace()));
+			if (pdoc->InsertCString(position.Position(), value)) {
+				SelectionPosition posAfterInsertion = position;
+				posAfterInsertion.Add(istrlen(value));
+				SetSelection(posAfterInsertion, position);
 			}
-			pdoc->EndUndoAction();
 		}
 	} else if (inDragDrop == ddDragging) {
 		SetEmptySelection(position);
@@ -5113,62 +5472,39 @@ void Editor::DropAt(int position, const char *value, bool moving, bool rectangul
 }
 
 /**
- * @return -1 if given position is before the selection,
- *          1 if position is after the selection,
- *          0 if position is inside the selection,
+ * @return true if given position is inside the selection,
  */
-int Editor::PositionInSelection(int pos) {
-	pos = MovePositionOutsideChar(pos, currentPos - pos);
-	if (pos < SelectionStart()) {
-		return -1;
-	}
-	if (pos > SelectionEnd()) {
-		return 1;
-	}
-	if (selType == selStream) {
-		return 0;
-	} else {
-		SelectionLineIterator lineIterator(this);
-		lineIterator.SetAt(pdoc->LineFromPosition(pos));
-		if (pos < lineIterator.startPos) {
-			return -1;
-		} else if (pos > lineIterator.endPos) {
-			return 1;
-		} else {
-			return 0;
-		}
+bool Editor::PositionInSelection(int pos) {
+	pos = MovePositionOutsideChar(pos, sel.MainCaret() - pos);
+	for (size_t r=0; r<sel.Count(); r++) {
+		if (sel.Range(r).Contains(pos)) 
+			return true;
 	}
+	return false;
 }
 
 bool Editor::PointInSelection(Point pt) {
-	int pos = PositionFromLocation(pt);
-	if (0 == PositionInSelection(pos)) {
-		// Probably inside, but we must make a finer test
-		int selStart, selEnd;
-		if (selType == selStream) {
-			selStart = SelectionStart();
-			selEnd = SelectionEnd();
-		} else {
-			SelectionLineIterator lineIterator(this);
-			lineIterator.SetAt(pdoc->LineFromPosition(pos));
-			selStart = lineIterator.startPos;
-			selEnd = lineIterator.endPos;
-		}
-		if (pos == selStart) {
-			// see if just before selection
-			Point locStart = LocationFromPosition(pos);
-			if (pt.x < locStart.x) {
-				return false;
+	SelectionPosition pos = SPositionFromLocation(pt);
+	int xPos = XFromPosition(pos);
+	for (size_t r=0; r<sel.Count(); r++) {
+		SelectionRange range = sel.Range(r);
+		if (range.Contains(pos)) {
+			bool hit = true;
+			if (pos == range.Start()) {
+				// see if just before selection
+				if (pt.x < xPos) {
+					hit = false;
+				}
 			}
-		}
-		if (pos == selEnd) {
-			// see if just after selection
-			Point locEnd = LocationFromPosition(pos);
-			if (pt.x > locEnd.x) {
-				return false;
+			if (pos == range.End()) {
+				// see if just after selection
+				if (pt.x > xPos) {
+					hit = false;
+				}
 			}
+			if (hit)
+				return true;
 		}
-		return true;
 	}
 	return false;
 }
@@ -5208,28 +5544,33 @@ void Editor::DwellEnd(bool mouseMoved) {
 	}
 }
 
+static bool AllowVirtualSpace(int	virtualSpaceOptions, bool rectangular) {
+	return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0)
+		|| (rectangular && ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) != 0));
+}
+
 void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
 	//Platform::DebugPrintf("ButtonDown %d %d = %d alt=%d %d\n", curTime, lastClickTime, curTime - lastClickTime, alt, inDragDrop);
 	ptMouseLast = pt;
-	int newPos = PositionFromLocation(pt);
-	newPos = MovePositionOutsideChar(newPos, currentPos - newPos);
+	SelectionPosition newPos = SPositionFromLocation(pt, false, false, AllowVirtualSpace(virtualSpaceOptions, alt));
+	newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position());
 	inDragDrop = ddNone;
-	moveExtendsSelection = false;
+	sel.SetMoveExtends(false);
 
 	bool processed = NotifyMarginClick(pt, shift, ctrl, alt);
 	if (processed)
 		return;
 
-	NotifyIndicatorClick(true, newPos, shift, ctrl, alt);
+	NotifyIndicatorClick(true, newPos.Position(), shift, ctrl, alt);
 
 	bool inSelMargin = PointInSelMargin(pt);
 	if (shift & !inSelMargin) {
-		SetSelection(newPos);
+		SetSelection(newPos.Position());
 	}
 	if (((curTime - lastClickTime) < Platform::DoubleClickTime()) && Close(pt, lastClick)) {
 		//Platform::DebugPrintf("Double click %d %d = %d\n", curTime, lastClickTime, curTime - lastClickTime);
 		SetMouseCapture(true);
-		SetEmptySelection(newPos);
+		SetEmptySelection(newPos.Position());
 		bool doubleClick = false;
 		// Stop mouse button bounce changing selection type
 		if (!Platform::MouseButtonBounce() || curTime != lastClickTime) {
@@ -5240,16 +5581,16 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
 				selectionType = selLine;
 			} else {
 				selectionType = selChar;
-				originalAnchorPos = currentPos;
+				originalAnchorPos = sel.MainCaret();
 			}
 		}
 
 		if (selectionType == selWord) {
-			if (currentPos >= originalAnchorPos) {	// Moved forward
-				SetSelection(pdoc->ExtendWordSelect(currentPos, 1),
+			if (sel.MainCaret() >= originalAnchorPos) {	// Moved forward
+				SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), 1),
 				        pdoc->ExtendWordSelect(originalAnchorPos, -1));
 			} else {	// Moved backward
-				SetSelection(pdoc->ExtendWordSelect(currentPos, -1),
+				SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), -1),
 				        pdoc->ExtendWordSelect(originalAnchorPos, 1));
 			}
 		} else if (selectionType == selLine) {
@@ -5257,17 +5598,17 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
 			SetSelection(pdoc->LineStart(lineAnchor + 1), pdoc->LineStart(lineAnchor));
 			//Platform::DebugPrintf("Triple click: %d - %d\n", anchor, currentPos);
 		} else {
-			SetEmptySelection(currentPos);
+			SetEmptySelection(sel.MainCaret());
 		}
 		//Platform::DebugPrintf("Double click: %d - %d\n", anchor, currentPos);
 		if (doubleClick) {
 			NotifyDoubleClick(pt, shift, ctrl, alt);
-			if (PositionIsHotspot(newPos))
-				NotifyHotSpotDoubleClicked(newPos, shift, ctrl, alt);
+			if (PositionIsHotspot(newPos.Position()))
+				NotifyHotSpotDoubleClicked(newPos.Position(), shift, ctrl, alt);
 		}
 	} else {	// Single click
 		if (inSelMargin) {
-			selType = selStream;
+			sel.selType = Selection::selStream;
 			if (ctrl) {
 				SelectAll();
 				lastClickTime = curTime;
@@ -5281,21 +5622,21 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
 				        pdoc->LineStart(lineAnchor));
 			} else {
 				// Single shift+click in margin: select from line anchor to clicked line
-				if (anchor > currentPos)
-					lineAnchor = pdoc->LineFromPosition(anchor - 1);
+				if (sel.MainAnchor() > sel.MainCaret())
+					lineAnchor = pdoc->LineFromPosition(sel.MainAnchor() - 1);
 				else
-					lineAnchor = pdoc->LineFromPosition(anchor);
+					lineAnchor = pdoc->LineFromPosition(sel.MainAnchor());
 				int lineStart = LineFromLocation(pt);
 				LineSelection(lineStart, lineAnchor);
 				//lineAnchor = lineStart; // Keep the same anchor for ButtonMove
 			}
 
-			SetDragPosition(invalidPosition);
+			SetDragPosition(SelectionPosition(invalidPosition));
 			SetMouseCapture(true);
 			selectionType = selLine;
 		} else {
 			if (PointIsHotspot(pt)) {
-				NotifyHotSpotClicked(newPos, shift, ctrl, alt);
+				NotifyHotSpotClicked(newPos.Position(), shift, ctrl, alt);
 			}
 			if (!shift) {
 				if (PointInSelection(pt) && !SelectionEmpty())
@@ -5305,13 +5646,25 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
 			}
 			SetMouseCapture(true);
 			if (inDragDrop != ddInitial) {
-				SetDragPosition(invalidPosition);
+				SetDragPosition(SelectionPosition(invalidPosition));
 				if (!shift) {
-					SetEmptySelection(newPos);
+					if (ctrl && multipleSelection) {
+						SelectionRange range(newPos);
+						sel.TentativeSelection(range);
+						InvalidateSelection(range, true);
+					} else {
+						InvalidateSelection(SelectionRange(newPos), true);
+						if (sel.Count() > 1) 
+							Redraw();
+						sel.Clear();
+						sel.selType = alt ? Selection::selRectangle : Selection::selStream;
+						SetSelection(newPos, newPos);
+					}
 				}
-				selType = alt ? selRectangle : selStream;
+				sel.selType = alt ? Selection::selRectangle : Selection::selStream;
 				selectionType = selChar;
-				originalAnchorPos = currentPos;
+				originalAnchorPos = sel.MainCaret();
+				sel.Rectangular() = SelectionRange(newPos);
 				SetRectangularRange();
 			}
 		}
@@ -5326,7 +5679,7 @@ bool Editor::PositionIsHotspot(int position) {
 }
 
 bool Editor::PointIsHotspot(Point pt) {
-	int pos = PositionFromLocationClose(pt);
+	int pos = PositionFromLocation(pt, true);
 	if (pos == INVALID_POSITION)
 		return false;
 	return PositionIsHotspot(pos);
@@ -5375,8 +5728,9 @@ void Editor::ButtonMove(Point pt) {
 		DwellEnd(true);
 	}
 
-	int movePos = PositionFromLocation(pt);
-	movePos = MovePositionOutsideChar(movePos, currentPos - movePos);
+	SelectionPosition movePos = SPositionFromLocation(pt, false, false, 
+		AllowVirtualSpace(virtualSpaceOptions, sel.IsRectangular()));
+	movePos = MovePositionOutsideChar(movePos, sel.MainCaret() - movePos.Position());
 
 	if (inDragDrop == ddInitial) {
 		if (DragThreshold(ptMouseLast, pt)) {
@@ -5399,14 +5753,23 @@ void Editor::ButtonMove(Point pt) {
 		autoScrollTimer.ticksToWait = autoScrollDelay;
 
 		// Adjust selection
-		if (posDrag >= 0) {
+		if (posDrag.IsValid()) {
 			SetDragPosition(movePos);
 		} else {
 			if (selectionType == selChar) {
-				SetSelection(movePos);
+				if (sel.IsRectangular()) {
+					sel.Rectangular() = SelectionRange(movePos, sel.Rectangular().anchor);
+					SetSelection(movePos, sel.RangeMain().anchor);
+				} else if (sel.Count() > 1) {
+					SelectionRange range(movePos, sel.RangeMain().anchor);
+					sel.TentativeSelection(range);
+					InvalidateSelection(range, true);
+				} else {
+					SetSelection(movePos, sel.RangeMain().anchor);
+				}
 			} else if (selectionType == selWord) {
 				// Continue selecting by word
-				if (movePos == originalAnchorPos) {	// Didn't move
+				if (movePos.Position() == originalAnchorPos) {	// Didn't move
 					// No need to do anything. Previously this case was lumped
 					// in with "Moved forward", but that can be harmful in this
 					// case: a handler for the NotifyDoubleClick re-adjusts
@@ -5416,11 +5779,11 @@ void Editor::ButtonMove(Point pt) {
 					// the ButtonMove() called via Tick() for auto-scrolling
 					// could result in the fancier word selection adjustment
 					// being unmade.
-				} else if (movePos > originalAnchorPos) {	// Moved forward
-					SetSelection(pdoc->ExtendWordSelect(movePos, 1),
+				} else if (movePos.Position() > originalAnchorPos) {	// Moved forward
+					SetSelection(pdoc->ExtendWordSelect(movePos.Position(), 1),
 					        pdoc->ExtendWordSelect(originalAnchorPos, -1));
 				} else {	// Moved backward
-					SetSelection(pdoc->ExtendWordSelect(movePos, -1),
+					SetSelection(pdoc->ExtendWordSelect(movePos.Position(), -1),
 					        pdoc->ExtendWordSelect(originalAnchorPos, 1));
 				}
 			} else {
@@ -5429,10 +5792,6 @@ void Editor::ButtonMove(Point pt) {
 				LineSelection(lineMove, lineAnchor);
 			}
 		}
-		// While dragging to make rectangular selection, we don't want the current
-		// position to jump to the end of smaller or empty lines.
-		//xEndSelect = pt.x - vs.fixedColumnWidth + xOffset;
-		xEndSelect = XFromPosition(movePos);
 
 		// Autoscroll
 		PRectangle rcClient = GetClientRectangle();
@@ -5450,7 +5809,7 @@ void Editor::ButtonMove(Point pt) {
 		}
 		EnsureCaretVisible(false, false, true);
 
-		if (hsStart != -1 && !PositionIsHotspot(movePos))
+		if (hsStart != -1 && !PositionIsHotspot(movePos.Position()))
 			SetHotSpotRange(NULL);
 
 	} else {
@@ -5475,11 +5834,12 @@ void Editor::ButtonMove(Point pt) {
 
 void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
 	//Platform::DebugPrintf("ButtonUp %d %d\n", HaveMouseCapture(), inDragDrop);
-	int newPos = PositionFromLocation(pt);
-	newPos = MovePositionOutsideChar(newPos, currentPos - newPos);
+	SelectionPosition newPos = SPositionFromLocation(pt, false, false, 
+		AllowVirtualSpace(virtualSpaceOptions, sel.IsRectangular()));
+	newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position());
 	if (inDragDrop == ddInitial) {
 		inDragDrop = ddNone;
-		SetEmptySelection(newPos);
+		SetEmptySelection(newPos.Position());
 	}
 	if (HaveMouseCapture()) {
 		if (PointInSelMargin(pt)) {
@@ -5490,31 +5850,29 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
 		}
 		ptMouseLast = pt;
 		SetMouseCapture(false);
-		int newPos = PositionFromLocation(pt);
-		newPos = MovePositionOutsideChar(newPos, currentPos - newPos);
-		NotifyIndicatorClick(false, newPos, false, false, false);
+		NotifyIndicatorClick(false, newPos.Position(), false, false, false);
 		if (inDragDrop == ddDragging) {
-			int selStart = SelectionStart();
-			int selEnd = SelectionEnd();
+			SelectionPosition selStart = SelectionStart();
+			SelectionPosition selEnd = SelectionEnd();
 			if (selStart < selEnd) {
 				if (drag.len) {
 					if (ctrl) {
-						if (pdoc->InsertString(newPos, drag.s, drag.len)) {
-							SetSelection(newPos, newPos + drag.len);
+						if (pdoc->InsertString(newPos.Position(), drag.s, drag.len)) {
+							SetSelection(newPos.Position(), newPos.Position() + drag.len);
 						}
 					} else if (newPos < selStart) {
-						pdoc->DeleteChars(selStart, drag.len);
-						if (pdoc->InsertString(newPos, drag.s, drag.len)) {
-							SetSelection(newPos, newPos + drag.len);
+						pdoc->DeleteChars(selStart.Position(), drag.len);
+						if (pdoc->InsertString(newPos.Position(), drag.s, drag.len)) {
+							SetSelection(newPos.Position(), newPos.Position() + drag.len);
 						}
 					} else if (newPos > selEnd) {
-						pdoc->DeleteChars(selStart, drag.len);
-						newPos -= drag.len;
-						if (pdoc->InsertString(newPos, drag.s, drag.len)) {
-							SetSelection(newPos, newPos + drag.len);
+						pdoc->DeleteChars(selStart.Position(), drag.len);
+						newPos.Add(-drag.len);
+						if (pdoc->InsertString(newPos.Position(), drag.s, drag.len)) {
+							SetSelection(newPos.Position(), newPos.Position() + drag.len);
 						}
 					} else {
-						SetEmptySelection(newPos);
+						SetEmptySelection(newPos.Position());
 					}
 					drag.Free();
 				}
@@ -5522,14 +5880,21 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
 			}
 		} else {
 			if (selectionType == selChar) {
-				SetSelection(newPos);
+				if (sel.Count() > 1) {
+					sel.RangeMain() = 
+						SelectionRange(newPos, sel.Range(sel.Count() - 1).anchor);
+					InvalidateSelection(sel.RangeMain(), true);
+				} else {
+					SetSelection(newPos, sel.RangeMain().anchor);
+				}
 			}
+			sel.CommitTentative();
 		}
 		SetRectangularRange();
 		lastClickTime = curTime;
 		lastClick = pt;
 		lastXChosen = pt.x;
-		if (selType == selStream) {
+		if (sel.selType == Selection::selStream) {
 			SetLastXChosen();
 		}
 		inDragDrop = ddNone;
@@ -5658,6 +6023,14 @@ void Editor::SetBraceHighlight(Position pos0, Position pos1, int matchStyle) {
 	}
 }
 
+void Editor::SetAnnotationHeights(int start, int end) {
+	if (vs.annotationVisible) {
+		for (int line=start; line<end; line++) {
+			cs.SetHeight(line, pdoc->AnnotationLines(line) + 1);
+		}
+	}
+}
+
 void Editor::SetDocPointer(Document *document) {
 	//Platform::DebugPrintf("** %x setdoc to %x\n", pdoc, document);
 	pdoc->RemoveWatcher(this, 0);
@@ -5670,9 +6043,7 @@ void Editor::SetDocPointer(Document *document) {
 	pdoc->AddRef();
 
 	// Ensure all positions within document
-	selType = selStream;
-	currentPos = 0;
-	anchor = 0;
+	sel.Clear();
 	targetStart = 0;
 	targetEnd = 0;
 
@@ -5682,6 +6053,7 @@ void Editor::SetDocPointer(Document *document) {
 	// Reset the contraction state to fully shown.
 	cs.Clear();
 	cs.InsertLines(0, pdoc->LinesTotal() - 1);
+	SetAnnotationHeights(0, pdoc->LinesTotal());
 	llc.Deallocate();
 	NeedWrapping();
 
@@ -5690,6 +6062,22 @@ void Editor::SetDocPointer(Document *document) {
 	Redraw();
 }
 
+void Editor::SetAnnotationVisible(int visible) {
+	if (vs.annotationVisible != visible) {
+		bool changedFromOrToHidden = ((vs.annotationVisible != 0) != (visible != 0));
+		vs.annotationVisible = visible;
+		if (changedFromOrToHidden) {
+			int dir = vs.annotationVisible ? 1 : -1;
+			for (int line=0; line<pdoc->LinesTotal(); line++) {
+				int annotationLines = pdoc->AnnotationLines(line);
+				if (annotationLines > 0) {
+					cs.SetHeight(line, cs.GetHeight(line) + annotationLines * dir);
+				}
+			}
+		}
+	}
+}
+
 /**
  * Recursively expand a fold, making lines visible except where they have an unexpanded parent.
  */
@@ -5726,7 +6114,7 @@ void Editor::ToggleContraction(int line) {
 			if (lineMaxSubord > line) {
 				cs.SetVisible(line + 1, lineMaxSubord, false);
 
-				int lineCurrent = pdoc->LineFromPosition(currentPos);
+				int lineCurrent = pdoc->LineFromPosition(sel.MainCaret());
 				if (lineCurrent > line && lineCurrent <= lineMaxSubord) {
 					// This does not re-expand the fold
 					EnsureCaretVisible();
@@ -5795,13 +6183,12 @@ void Editor::EnsureLineVisible(int lineDoc, bool enforcePolicy) {
 }
 
 int Editor::ReplaceTarget(bool replacePatterns, const char *text, int length) {
-	pdoc->BeginUndoAction();
+	UndoGroup ug(pdoc);
 	if (length == -1)
 		length = istrlen(text);
 	if (replacePatterns) {
 		text = pdoc->SubstituteByPosition(text, &length);
 		if (!text) {
-			pdoc->EndUndoAction();
 			return 0;
 		}
 	}
@@ -5810,7 +6197,6 @@ int Editor::ReplaceTarget(bool replacePatterns, const char *text, int length) {
 	targetEnd = targetStart;
 	pdoc->InsertString(targetStart, text, length);
 	targetEnd = targetStart + length;
-	pdoc->EndUndoAction();
 	return length;
 }
 
@@ -5841,20 +6227,18 @@ void Editor::AddStyledText(char *buffer, int appendLength) {
 	// The buffer consists of alternating character bytes and style bytes
 	size_t textLength = appendLength / 2;
 	char *text = new char[textLength];
-	if (text) {
-		size_t i;
-		for (i = 0;i < textLength;i++) {
-			text[i] = buffer[i*2];
-		}
-		pdoc->InsertString(CurrentPosition(), text, textLength);
-		for (i = 0;i < textLength;i++) {
-			text[i] = buffer[i*2+1];
-		}
-		pdoc->StartStyling(CurrentPosition(), static_cast<char>(0xff));
-		pdoc->SetStyles(textLength, text);
-		delete []text;
+	size_t i;
+	for (i = 0;i < textLength;i++) {
+		text[i] = buffer[i*2];
 	}
-	SetEmptySelection(currentPos + textLength);
+	pdoc->InsertString(CurrentPosition(), text, textLength);
+	for (i = 0;i < textLength;i++) {
+		text[i] = buffer[i*2+1];
+	}
+	pdoc->StartStyling(CurrentPosition(), static_cast<char>(0xff));
+	pdoc->SetStyles(textLength, text);
+	delete []text;
+	SetEmptySelection(sel.MainCaret() + textLength);
 }
 
 static bool ValidMargin(unsigned long wParam) {
@@ -5973,11 +6357,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	case SCI_SETTEXT: {
 			if (lParam == 0)
 				return 0;
-			pdoc->BeginUndoAction();
+			UndoGroup ug(pdoc);
 			pdoc->DeleteChars(0, pdoc->Length());
 			SetEmptySelection(0);
 			pdoc->InsertCString(0, CharPtrFromSPtr(lParam));
-			pdoc->EndUndoAction();
 			return 1;
 		}
 
@@ -6064,41 +6447,28 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 				nEnd = pdoc->Length();
 			if (nStart < 0)
 				nStart = nEnd; 	// Remove selection
-			selType = selStream;
+			sel.selType = Selection::selStream;
 			SetSelection(nEnd, nStart);
 			EnsureCaretVisible();
 		}
 		break;
 
 	case SCI_GETSELTEXT: {
-			if (lParam == 0) {
-				if (selType == selStream) {
-					return 1 + SelectionEnd() - SelectionStart();
-				} else {
-					// TODO: why is selLines handled the slow way?
-					int size = 0;
-					int extraCharsPerLine = 0;
-					if (selType != selLines)
-						extraCharsPerLine = (pdoc->eolMode == SC_EOL_CRLF) ? 2 : 1;
-					SelectionLineIterator lineIterator(this);
-					while (lineIterator.Iterate()) {
-						size += lineIterator.endPos + extraCharsPerLine - lineIterator.startPos;
-					}
-
-					return 1 + size;
-				}
-			}
 			SelectionText selectedText;
 			CopySelectionRange(&selectedText);
-			char *ptr = CharPtrFromSPtr(lParam);
-			int iChar = 0;
-			if (selectedText.len) {
-				for (; iChar < selectedText.len; iChar++)
-					ptr[iChar] = selectedText.s[iChar];
+			if (lParam == 0) {
+				return selectedText.len + 1;
 			} else {
-				ptr[0] = '\0';
+				char *ptr = CharPtrFromSPtr(lParam);
+				int iChar = 0;
+				if (selectedText.len) {
+					for (; iChar < selectedText.len; iChar++)
+						ptr[iChar] = selectedText.s[iChar];
+				} else {
+					ptr[0] = '\0';
+				}
+				return iChar;
 			}
-			return iChar;
 		}
 
 	case SCI_LINEFROMPOSITION:
@@ -6108,7 +6478,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
 	case SCI_POSITIONFROMLINE:
 		if (static_cast<int>(wParam) < 0)
-			wParam = pdoc->LineFromPosition(SelectionStart());
+			wParam = pdoc->LineFromPosition(SelectionStart().Position());
 		if (wParam == 0)
 			return 0; 	// Even if there is no text, there is a first line that starts at 0
 		if (static_cast<int>(wParam) > pdoc->LinesTotal())
@@ -6127,12 +6497,11 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	case SCI_REPLACESEL: {
 			if (lParam == 0)
 				return 0;
-			pdoc->BeginUndoAction();
+			UndoGroup ug(pdoc);
 			ClearSelection();
 			char *replacement = CharPtrFromSPtr(lParam);
-			pdoc->InsertCString(currentPos, replacement);
-			pdoc->EndUndoAction();
-			SetEmptySelection(currentPos + istrlen(replacement));
+			pdoc->InsertCString(sel.MainCaret(), replacement);
+			SetEmptySelection(sel.MainCaret() + istrlen(replacement));
 			EnsureCaretVisible();
 		}
 		break;
@@ -6152,12 +6521,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		return targetEnd;
 
 	case SCI_TARGETFROMSELECTION:
-		if (currentPos < anchor) {
-			targetStart = currentPos;
-			targetEnd = anchor;
+		if (sel.MainCaret() < sel.MainAnchor()) {
+			targetStart = sel.MainCaret();
+			targetEnd = sel.MainAnchor();
 		} else {
-			targetStart = anchor;
-			targetEnd = currentPos;
+			targetStart = sel.MainAnchor();
+			targetEnd = sel.MainCaret();
 		}
 		break;
 
@@ -6240,7 +6609,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	case SCI_GETTEXTRANGE: {
 			if (lParam == 0)
 				return 0;
-			TextRange *tr = reinterpret_cast<TextRange *>(lParam);
+			Sci_TextRange *tr = reinterpret_cast<Sci_TextRange *>(lParam);
 			int cpMax = tr->chrg.cpMax;
 			if (cpMax == -1)
 				cpMax = pdoc->Length();
@@ -6258,7 +6627,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		break;
 
 	case SCI_FORMATRANGE:
-		return FormatRange(wParam != 0, reinterpret_cast<RangeToFormat *>(lParam));
+		return FormatRange(wParam != 0, reinterpret_cast<Sci_RangeToFormat *>(lParam));
 
 	case SCI_GETMARGINLEFT:
 		return vs.leftMarginWidth;
@@ -6282,7 +6651,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 			if (lParam == 0)
 				return 0;
 			pdoc->InsertString(CurrentPosition(), CharPtrFromSPtr(lParam), wParam);
-			SetEmptySelection(currentPos + wParam);
+			SetEmptySelection(sel.MainCaret() + wParam);
 			return 0;
 		}
 
@@ -6370,32 +6739,32 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		return pdoc->CharAt(wParam);
 
 	case SCI_SETCURRENTPOS:
-		SetSelection(wParam, anchor);
+		SetSelection(wParam, sel.MainAnchor());
 		break;
 
 	case SCI_GETCURRENTPOS:
-		return currentPos;
+		return sel.MainCaret();
 
 	case SCI_SETANCHOR:
-		SetSelection(currentPos, wParam);
+		SetSelection(sel.MainCaret(), wParam);
 		break;
 
 	case SCI_GETANCHOR:
-		return anchor;
+		return sel.MainAnchor();
 
 	case SCI_SETSELECTIONSTART:
-		SetSelection(Platform::Maximum(currentPos, wParam), wParam);
+		SetSelection(Platform::Maximum(sel.MainCaret(), wParam), wParam);
 		break;
 
 	case SCI_GETSELECTIONSTART:
-		return Platform::Minimum(anchor, currentPos);
+		return Platform::Minimum(sel.MainAnchor(), sel.MainCaret());
 
 	case SCI_SETSELECTIONEND:
-		SetSelection(wParam, Platform::Minimum(anchor, wParam));
+		SetSelection(wParam, Platform::Minimum(sel.MainAnchor(), wParam));
 		break;
 
 	case SCI_GETSELECTIONEND:
-		return Platform::Maximum(anchor, currentPos);
+		return Platform::Maximum(sel.MainAnchor(), sel.MainCaret());
 
 	case SCI_SETPRINTMAGNIFICATION:
 		printMagnification = wParam;
@@ -6439,7 +6808,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	case SCI_GETSTYLEDTEXT: {
 			if (lParam == 0)
 				return 0;
-			TextRange *tr = reinterpret_cast<TextRange *>(lParam);
+			Sci_TextRange *tr = reinterpret_cast<Sci_TextRange *>(lParam);
 			int iPlace = 0;
 			for (int iChar = tr->chrg.cpMin; iChar < tr->chrg.cpMax; iChar++) {
 				tr->lpstrText[iPlace++] = pdoc->CharAt(iChar);
@@ -6469,10 +6838,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		break;
 
 	case SCI_POSITIONFROMPOINT:
-		return PositionFromLocation(Point(wParam, lParam));
+		return PositionFromLocation(Point(wParam, lParam), false, false);
 
 	case SCI_POSITIONFROMPOINTCLOSE:
-		return PositionFromLocationClose(Point(wParam, lParam));
+		return PositionFromLocation(Point(wParam, lParam), true, false);
+
+	case SCI_CHARPOSITIONFROMPOINT:
+		return PositionFromLocation(Point(wParam, lParam), false, true);
+
+	case SCI_CHARPOSITIONFROMPOINTCLOSE:
+		return PositionFromLocation(Point(wParam, lParam), true, true);
 
 	case SCI_GOTOLINE:
 		GoToLine(wParam);
@@ -6485,7 +6860,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		break;
 
 	case SCI_GETCURLINE: {
-			int lineCurrentPos = pdoc->LineFromPosition(currentPos);
+			int lineCurrentPos = pdoc->LineFromPosition(sel.MainCaret());
 			int lineStart = pdoc->LineStart(lineCurrentPos);
 			unsigned int lineEnd = pdoc->LineStart(lineCurrentPos + 1);
 			if (lParam == 0) {
@@ -6498,7 +6873,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 				ptr[iPlace++] = pdoc->CharAt(iChar);
 			}
 			ptr[iPlace] = '\0';
-			return currentPos - lineStart;
+			return sel.MainCaret() - lineStart;
 		}
 
 	case SCI_GETENDSTYLED:
@@ -6632,9 +7007,6 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
 	case SCI_SETWRAPVISUALFLAGS:
 		wrapVisualFlags = wParam;
-		actualWrapVisualStartIndent = wrapVisualStartIndent;
-		if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (actualWrapVisualStartIndent == 0))
-			actualWrapVisualStartIndent = 1; // must indent to show start visual
 		InvalidateStyleRedraw();
 		ReconfigureScrollBars();
 		break;
@@ -6652,9 +7024,6 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
 	case SCI_SETWRAPSTARTINDENT:
 		wrapVisualStartIndent = wParam;
-		actualWrapVisualStartIndent = wrapVisualStartIndent;
-		if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (actualWrapVisualStartIndent == 0))
-			actualWrapVisualStartIndent = 1; // must indent to show start visual
 		InvalidateStyleRedraw();
 		ReconfigureScrollBars();
 		break;
@@ -6662,6 +7031,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	case SCI_GETWRAPSTARTINDENT:
 		return wrapVisualStartIndent;
 
+	case SCI_SETWRAPINDENTMODE:
+		wrapIndentMode = wParam;
+		InvalidateStyleRedraw();
+		ReconfigureScrollBars();
+		break;
+
+	case SCI_GETWRAPINDENTMODE:
+		return wrapIndentMode;
+
 	case SCI_SETLAYOUTCACHE:
 		llc.SetLevel(wParam);
 		break;
@@ -6810,6 +7188,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		InvalidateStyleData();
 		RedrawSelMargin();
 		break;
+
+	case SCI_MARKERSYMBOLDEFINED:
+		if (wParam <= MARKER_MAX)
+			return vs.markers[wParam].markType;
+		else
+			return 0;
+
 	case SCI_MARKERSETFORE:
 		if (wParam <= MARKER_MAX)
 			vs.markers[wParam].fore.desired = ColourDesired(lParam);
@@ -7080,13 +7465,6 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	case SCI_SEARCHPREV:
 		return SearchText(iMessage, wParam, lParam);
 
-#ifdef INCLUDE_DEPRECATED_FEATURES
-	case SCI_SETCARETPOLICY:  	// Deprecated
-		caretXPolicy = caretYPolicy = wParam;
-		caretXSlop = caretYSlop = lParam;
-		break;
-#endif
-
 	case SCI_SETXCARETPOLICY:
 		caretXPolicy = wParam;
 		caretXSlop = lParam;
@@ -7108,17 +7486,20 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	case SCI_SETSELFORE:
 		vs.selforeset = wParam != 0;
 		vs.selforeground.desired = ColourDesired(lParam);
+		vs.selAdditionalForeground.desired = ColourDesired(lParam);
 		InvalidateStyleRedraw();
 		break;
 
 	case SCI_SETSELBACK:
 		vs.selbackset = wParam != 0;
 		vs.selbackground.desired = ColourDesired(lParam);
+		vs.selAdditionalBackground.desired = ColourDesired(lParam);
 		InvalidateStyleRedraw();
 		break;
 
 	case SCI_SETSELALPHA:
 		vs.selAlpha = wParam;
+		vs.selAdditionalAlpha = wParam;
 		InvalidateStyleRedraw();
 		break;
 
@@ -7222,6 +7603,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	case SCI_INDICGETUNDER:
 		return (wParam <= INDIC_MAX) ? vs.indicators[wParam].under : 0;
 
+	case SCI_INDICSETALPHA:
+		if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 100) {
+			vs.indicators[wParam].fillAlpha = lParam;
+			InvalidateStyleRedraw();
+		}
+		break;
+
+	case SCI_INDICGETALPHA:
+		return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fillAlpha : 0;
+
 	case SCI_SETINDICATORCURRENT:
 		pdoc->decorations.SetCurrentIndicator(wParam);
 		break;
@@ -7430,7 +7821,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
 	case SCI_CONVERTEOLS:
 		pdoc->ConvertLineEnds(wParam);
-		SetSelection(currentPos, anchor);	// Ensure selection inside document
+		SetSelection(sel.MainCaret(), sel.MainAnchor());	// Ensure selection inside document
 		return 0;
 
 	case SCI_SETLENGTHFORENCODE:
@@ -7438,48 +7829,56 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		return 0;
 
 	case SCI_SELECTIONISRECTANGLE:
-		return selType == selRectangle ? 1 : 0;
+		return sel.selType == Selection::selRectangle ? 1 : 0;
 
 	case SCI_SETSELECTIONMODE: {
 			switch (wParam) {
 			case SC_SEL_STREAM:
-				moveExtendsSelection = !moveExtendsSelection || (selType != selStream);
-				selType = selStream;
+				sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selStream));
+				sel.selType = Selection::selStream;
 				break;
 			case SC_SEL_RECTANGLE:
-				moveExtendsSelection = !moveExtendsSelection || (selType != selRectangle);
-				selType = selRectangle;
+				sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selRectangle));
+				sel.selType = Selection::selRectangle;
 				break;
 			case SC_SEL_LINES:
-				moveExtendsSelection = !moveExtendsSelection || (selType != selLines);
-				selType = selLines;
+				sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selLines));
+				sel.selType = Selection::selLines;
+				break;
+			case SC_SEL_THIN:
+				sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selThin));
+				sel.selType = Selection::selThin;
 				break;
 			default:
-				moveExtendsSelection = !moveExtendsSelection || (selType != selStream);
-				selType = selStream;
+				sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selStream));
+				sel.selType = Selection::selStream;
 			}
-			InvalidateSelection(currentPos, anchor, true);
+			InvalidateSelection(sel.RangeMain(), true);
 		}
 	case SCI_GETSELECTIONMODE:
-		switch (selType) {
-		case selStream:
+		switch (sel.selType) {
+		case Selection::selStream:
 			return SC_SEL_STREAM;
-		case selRectangle:
+		case Selection::selRectangle:
 			return SC_SEL_RECTANGLE;
-		case selLines:
+		case Selection::selLines:
 			return SC_SEL_LINES;
+		case Selection::selThin:
+			return SC_SEL_THIN;
 		default:	// ?!
 			return SC_SEL_STREAM;
 		}
-	case SCI_GETLINESELSTARTPOSITION: {
-			SelectionLineIterator lineIterator(this);
-			lineIterator.SetAt(wParam);
-			return lineIterator.startPos;
-		}
+	case SCI_GETLINESELSTARTPOSITION:
 	case SCI_GETLINESELENDPOSITION: {
-			SelectionLineIterator lineIterator(this);
-			lineIterator.SetAt(wParam);
-			return lineIterator.endPos;
+			SelectionSegment segmentLine(SelectionPosition(pdoc->LineStart(wParam)), 
+				SelectionPosition(pdoc->LineEnd(wParam)));
+			for (size_t r=0; r<sel.Count(); r++) {
+				SelectionSegment portion = sel.Range(r).Intersect(segmentLine);
+				if (portion.start.IsValid()) {
+					return (iMessage == SCI_GETLINESELSTARTPOSITION) ? portion.start.Position() : portion.end.Position();
+				}
+			}
+			return INVALID_POSITION;
 		}
 
 	case SCI_SETOVERTYPE:
@@ -7593,6 +7992,326 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	case SCI_GETCHARACTERPOINTER:
 		return reinterpret_cast<sptr_t>(pdoc->BufferPointer());
 
+	case SCI_SETEXTRAASCENT:
+		vs.extraAscent = wParam;
+		InvalidateStyleRedraw();
+		break;
+
+	case SCI_GETEXTRAASCENT:
+		return vs.extraAscent;
+
+	case SCI_SETEXTRADESCENT:
+		vs.extraDescent = wParam;
+		InvalidateStyleRedraw();
+		break;
+
+	case SCI_GETEXTRADESCENT:
+		return vs.extraDescent;
+
+	case SCI_MARGINSETSTYLEOFFSET:
+		vs.marginStyleOffset = wParam;
+		InvalidateStyleRedraw();
+		break;
+
+	case SCI_MARGINGETSTYLEOFFSET:
+		return vs.marginStyleOffset;
+
+	case SCI_MARGINSETTEXT:
+		pdoc->MarginSetText(wParam, CharPtrFromSPtr(lParam));
+		break;
+
+	case SCI_MARGINGETTEXT: {
+			const StyledText st = pdoc->MarginStyledText(wParam);
+			if (lParam) {
+				if (st.text)
+					memcpy(CharPtrFromSPtr(lParam), st.text, st.length);
+				else
+					strcpy(CharPtrFromSPtr(lParam), "");
+			}
+			return st.length;
+		}
+
+	case SCI_MARGINSETSTYLE:
+		pdoc->MarginSetStyle(wParam, lParam);
+		break;
+
+	case SCI_MARGINGETSTYLE: {
+			const StyledText st = pdoc->MarginStyledText(wParam);
+			return st.style;
+		}
+
+	case SCI_MARGINSETSTYLES:
+		pdoc->MarginSetStyles(wParam, reinterpret_cast<const unsigned char *>(lParam));
+		break;
+
+	case SCI_MARGINGETSTYLES: {
+			const StyledText st = pdoc->MarginStyledText(wParam);
+			if (lParam) {
+				if (st.styles)
+					memcpy(CharPtrFromSPtr(lParam), st.styles, st.length);
+				else
+					strcpy(CharPtrFromSPtr(lParam), "");
+			}
+			return st.styles ? st.length : 0;
+		}
+
+	case SCI_MARGINTEXTCLEARALL:
+		pdoc->MarginClearAll();
+		break;
+
+	case SCI_ANNOTATIONSETTEXT:
+		pdoc->AnnotationSetText(wParam, CharPtrFromSPtr(lParam));
+		break;
+
+	case SCI_ANNOTATIONGETTEXT: {
+			const StyledText st = pdoc->AnnotationStyledText(wParam);
+			if (lParam) {
+				if (st.text)
+					memcpy(CharPtrFromSPtr(lParam), st.text, st.length);
+				else
+					strcpy(CharPtrFromSPtr(lParam), "");
+			}
+			return st.length;
+		}
+
+	case SCI_ANNOTATIONGETSTYLE: {
+			const StyledText st = pdoc->AnnotationStyledText(wParam);
+			return st.style;
+		}
+
+	case SCI_ANNOTATIONSETSTYLE:
+		pdoc->AnnotationSetStyle(wParam, lParam);
+		break;
+
+	case SCI_ANNOTATIONSETSTYLES:
+		pdoc->AnnotationSetStyles(wParam, reinterpret_cast<const unsigned char *>(lParam));
+		break;
+
+	case SCI_ANNOTATIONGETSTYLES: {
+			const StyledText st = pdoc->AnnotationStyledText(wParam);
+			if (lParam) {
+				if (st.styles)
+					memcpy(CharPtrFromSPtr(lParam), st.styles, st.length);
+				else
+					strcpy(CharPtrFromSPtr(lParam), "");
+			}
+			return st.styles ? st.length : 0;
+		}
+
+	case SCI_ANNOTATIONGETLINES:
+		return pdoc->AnnotationLines(wParam);
+
+	case SCI_ANNOTATIONCLEARALL:
+		pdoc->AnnotationClearAll();
+		break;
+
+	case SCI_ANNOTATIONSETVISIBLE:
+		SetAnnotationVisible(wParam);
+		break;
+
+	case SCI_ANNOTATIONGETVISIBLE:
+		return vs.annotationVisible;
+
+	case SCI_ANNOTATIONSETSTYLEOFFSET:
+		vs.annotationStyleOffset = wParam;
+		InvalidateStyleRedraw();
+		break;
+
+	case SCI_ANNOTATIONGETSTYLEOFFSET:
+		return vs.annotationStyleOffset;
+
+	case SCI_ADDUNDOACTION:
+		pdoc->AddUndoAction(wParam, lParam & UNDO_MAY_COALESCE);
+		break;
+
+	case SCI_SETMULTIPLESELECTION:
+		multipleSelection = wParam != 0;
+		InvalidateCaret();
+		break;
+
+	case SCI_GETMULTIPLESELECTION:
+		return multipleSelection;
+
+	case SCI_SETADDITIONALSELECTIONTYPING:
+		additionalSelectionTyping = wParam != 0;
+		InvalidateCaret();
+		break;
+
+	case SCI_GETADDITIONALSELECTIONTYPING:
+		return additionalSelectionTyping;
+
+	case SCI_SETADDITIONALCARETSBLINK:
+		additionalCaretsBlink = wParam != 0;
+		InvalidateCaret();
+		break;
+
+	case SCI_GETADDITIONALCARETSBLINK:
+		return additionalCaretsBlink;
+
+	case SCI_GETSELECTIONS:
+		return sel.Count();
+
+	case SCI_CLEARSELECTIONS:
+		sel.Clear();
+		Redraw();
+		break;
+
+	case SCI_SETSELECTION:
+		sel.SetSelection(SelectionRange(wParam, lParam));
+		Redraw();
+		break;
+
+	case SCI_ADDSELECTION:
+		sel.AddSelection(SelectionRange(wParam, lParam));
+		Redraw();
+		break;
+
+	case SCI_SETMAINSELECTION:
+		sel.SetMain(wParam);
+		Redraw();
+		break;
+
+	case SCI_GETMAINSELECTION:
+		return sel.Main();
+
+	case SCI_SETSELECTIONNCARET:
+		sel.Range(wParam).caret.SetPosition(lParam);
+		Redraw();
+		break;
+
+	case SCI_GETSELECTIONNCARET:
+		return sel.Range(wParam).caret.Position();
+
+	case SCI_SETSELECTIONNANCHOR:
+		sel.Range(wParam).anchor.SetPosition(lParam);
+		Redraw();
+		break;
+	case SCI_GETSELECTIONNANCHOR:
+		return sel.Range(wParam).anchor.Position();
+
+	case SCI_SETSELECTIONNCARETVIRTUALSPACE:
+		sel.Range(wParam).caret.SetVirtualSpace(lParam);
+		Redraw();
+		break;
+
+	case SCI_GETSELECTIONNCARETVIRTUALSPACE:
+		return sel.Range(wParam).caret.VirtualSpace();
+
+	case SCI_SETSELECTIONNANCHORVIRTUALSPACE:
+		sel.Range(wParam).anchor.SetVirtualSpace(lParam);
+		Redraw();
+		break;
+
+	case SCI_GETSELECTIONNANCHORVIRTUALSPACE:
+		return sel.Range(wParam).anchor.VirtualSpace();
+
+	case SCI_SETSELECTIONNSTART:
+		sel.Range(wParam).anchor.SetPosition(lParam);
+		Redraw();
+		break;
+
+	case SCI_GETSELECTIONNSTART:
+		return sel.Range(wParam).Start().Position();
+
+	case SCI_SETSELECTIONNEND:
+		sel.Range(wParam).caret.SetPosition(lParam);
+		Redraw();
+		break;
+
+	case SCI_GETSELECTIONNEND:
+		return sel.Range(wParam).End().Position();
+
+	case SCI_SETRECTANGULARSELECTIONCARET:
+		if (!sel.IsRectangular()) 
+			sel.Clear();
+		sel.selType = Selection::selRectangle;
+		sel.Rectangular().caret.SetPosition(wParam);
+		SetRectangularRange();
+		Redraw();
+		break;
+
+	case SCI_GETRECTANGULARSELECTIONCARET:
+		return sel.Rectangular().caret.Position();
+
+	case SCI_SETRECTANGULARSELECTIONANCHOR:
+		if (!sel.IsRectangular()) 
+			sel.Clear();
+		sel.selType = Selection::selRectangle;
+		sel.Rectangular().anchor.SetPosition(wParam);
+		SetRectangularRange();
+		Redraw();
+		break;
+
+	case SCI_GETRECTANGULARSELECTIONANCHOR:
+		return sel.Rectangular().anchor.Position();
+
+	case SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE:
+		if (!sel.IsRectangular()) 
+			sel.Clear();
+		sel.selType = Selection::selRectangle;
+		sel.Rectangular().caret.SetVirtualSpace(wParam);
+		SetRectangularRange();
+		Redraw();
+		break;
+
+	case SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE:
+		return sel.Rectangular().caret.VirtualSpace();
+
+	case SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE:
+		if (!sel.IsRectangular()) 
+			sel.Clear();
+		sel.selType = Selection::selRectangle;
+		sel.Rectangular().anchor.SetVirtualSpace(wParam);
+		SetRectangularRange();
+		Redraw();
+		break;
+
+	case SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE:
+		return sel.Rectangular().anchor.VirtualSpace();
+
+	case SCI_SETVIRTUALSPACEOPTIONS:
+		virtualSpaceOptions = wParam;
+		break;
+
+	case SCI_GETVIRTUALSPACEOPTIONS:
+		return virtualSpaceOptions;
+
+	case SCI_SETADDITIONALSELFORE:
+		vs.selAdditionalForeground.desired = ColourDesired(wParam);
+		InvalidateStyleRedraw();
+		break;
+
+	case SCI_SETADDITIONALSELBACK:
+		vs.selAdditionalBackground.desired = ColourDesired(wParam);
+		InvalidateStyleRedraw();
+		break;
+
+	case SCI_SETADDITIONALSELALPHA:
+		vs.selAdditionalAlpha = wParam;
+		InvalidateStyleRedraw();
+		break;
+
+	case SCI_GETADDITIONALSELALPHA:
+		return vs.selAdditionalAlpha;
+	
+	case SCI_SETADDITIONALCARETFORE:
+		vs.additionalCaretColour.desired = ColourDesired(wParam);
+		InvalidateStyleRedraw();
+		break;
+
+	case SCI_GETADDITIONALCARETFORE:
+		return vs.additionalCaretColour.desired.AsLong();
+
+	case SCI_ROTATESELECTION:
+		sel.RotateMain();
+		InvalidateSelection(sel.RangeMain(), true);
+		break;
+
+	case SCI_SWAPMAINANCHORCARET:
+		InvalidateSelection(sel.RangeMain());
+		sel.RangeMain() = SelectionRange(sel.RangeMain().anchor, sel.RangeMain().caret);
+		break;
+
 	default:
 		return DefWndProc(iMessage, wParam, lParam);
 	}
diff --git a/plugins/scintilla/scintilla/Editor.h b/plugins/scintilla/scintilla/Editor.h
index 0d0b8ac..8f1ca9b 100644
--- a/plugins/scintilla/scintilla/Editor.h
+++ b/plugins/scintilla/scintilla/Editor.h
@@ -78,14 +78,11 @@ public:
 	}
 	void Copy(const char *s_, int len_, int codePage_, int characterSet_, bool rectangular_, bool lineCopy_) {
 		delete []s;
+		s = 0;
 		s = new char[len_];
-		if (s) {
-			len = len_;
-			for (int i = 0; i < len_; i++) {
-				s[i] = s_[i];
-			}
-		} else {
-			len = 0;
+		len = len_;
+		for (int i = 0; i < len_; i++) {
+			s[i] = s_[i];
 		}
 		codePage = codePage_;
 		characterSet = characterSet_;
@@ -125,7 +122,6 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	bool hasFocus;
 	bool hideSelection;
 	bool inOverstrike;
-	int errorStatus;
 	bool mouseDownCaptures;
 
 	/** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to
@@ -144,6 +140,11 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	bool verticalScrollBarVisible;
 	bool endAtLastLine;
 	bool caretSticky;
+	bool multipleSelection;
+	bool additionalSelectionTyping;
+	bool additionalCaretsBlink;
+
+	int virtualSpaceOptions;
 
 	Surface *pixmapLine;
 	Surface *pixmapSelMargin;
@@ -172,13 +173,11 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	Point ptMouseLast;
 	enum { ddNone, ddInitial, ddDragging } inDragDrop;
 	bool dropWentOutside;
-	int posDrag;
-	int posDrop;
+	SelectionPosition posDrag;
+	SelectionPosition posDrop;
 	int lastXChosen;
 	int lineAnchor;
 	int originalAnchorPos;
-	int currentPos;
-	int anchor;
 	int targetStart;
 	int targetEnd;
 	int searchFlags;
@@ -200,11 +199,7 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	int modEventMask;
 
 	SelectionText drag;
-	enum selTypes { noSel, selStream, selRectangle, selLines };
-	selTypes selType;
-	bool moveExtendsSelection;
-	int xStartSelect;	///< x position of start of rectangular selection
-	int xEndSelect;		///< x position of end of rectangular selection
+	Selection sel;
 	bool primarySelection;
 
 	int caretXPolicy;
@@ -236,7 +231,8 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	int wrapVisualFlags;
 	int wrapVisualFlagsLocation;
 	int wrapVisualStartIndent;
-	int actualWrapVisualStartIndent;
+	int wrapAddIndent; // This will be added to initial indent of line
+	int wrapIndentMode; // SC_WRAPINDENT_FIXED, _SAME, _INDENT
 
 	bool convertPastes;
 
@@ -259,10 +255,14 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	int LinesOnScreen();
 	int LinesToScroll();
 	int MaxScrollPos();
+	SelectionPosition ClampPositionIntoDocument(SelectionPosition sp) const;
+	Point LocationFromPosition(SelectionPosition pos);
 	Point LocationFromPosition(int pos);
 	int XFromPosition(int pos);
-	int PositionFromLocation(Point pt);
-	int PositionFromLocationClose(Point pt);
+	int XFromPosition(SelectionPosition sp);
+	SelectionPosition SPositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false, bool virtualSpace=true);
+	int PositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false);
+	SelectionPosition SPositionFromLineX(int lineDoc, int x);
 	int PositionFromLineX(int line, int x);
 	int LineFromLocation(Point pt);
 	void SetTopLine(int topLineNew);
@@ -274,20 +274,30 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	PRectangle RectangleFromRange(int start, int end);
 	void InvalidateRange(int start, int end);
 
+	bool UserVirtualSpace() const {
+		return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0);
+	}
 	int CurrentPosition();
 	bool SelectionEmpty();
-	int SelectionStart();
-	int SelectionEnd();
+	SelectionPosition SelectionStart();
+	SelectionPosition SelectionEnd();
 	void SetRectangularRange();
-	void InvalidateSelection(int currentPos_, int anchor_, bool invalidateWholeSelection);
+	void InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection=false);
+	void SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_);
 	void SetSelection(int currentPos_, int anchor_);
+	void SetSelection(SelectionPosition currentPos_);
 	void SetSelection(int currentPos_);
+	void SetEmptySelection(SelectionPosition currentPos_);
 	void SetEmptySelection(int currentPos_);
 	bool RangeContainsProtected(int start, int end) const;
 	bool SelectionContainsProtected();
-	int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
-	int MovePositionTo(int newPos, selTypes sel=noSel, bool ensureVisible=true);
-	int MovePositionSoVisible(int pos, int moveDir);
+	int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true) const;
+	SelectionPosition MovePositionOutsideChar(SelectionPosition pos, int moveDir, bool checkLineEnd=true) const;
+	int MovePositionTo(SelectionPosition newPos, Selection::selTypes sel=Selection::noSel, bool ensureVisible=true);
+	int MovePositionTo(int newPos, Selection::selTypes sel=Selection::noSel, bool ensureVisible=true);
+	SelectionPosition MovePositionSoVisible(SelectionPosition pos, int moveDir);
+	SelectionPosition MovePositionSoVisible(int pos, int moveDir);
+	Point PointMainCaret();
 	void SetLastXChosen();
 
 	void ScrollTo(int line, bool moveThumb=true);
@@ -312,8 +322,8 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	LineLayout *RetrieveLineLayout(int lineNumber);
 	void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout *ll,
 		int width=LineLayout::wrapWidthInfinite);
-	ColourAllocated SelectionBackground(ViewStyle &vsDraw);
-	ColourAllocated TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll);
+	ColourAllocated SelectionBackground(ViewStyle &vsDraw, bool main);
+	ColourAllocated TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourAllocated background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll);
 	void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight);
 	void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourAllocated wrapColour);
 	void DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll,
@@ -322,12 +332,17 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 		bool drawWrapMark, ColourAllocated wrapColour);
 	void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
 		PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under);
+	void DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
+        PRectangle rcLine, LineLayout *ll, int subLine);
 	void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
-		PRectangle rcLine, LineLayout *ll, int subLine=0);
-	void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, int xStart, int offset, int posCaret, PRectangle rcCaret);
+		PRectangle rcLine, LineLayout *ll, int subLine);
+	void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, 
+		int xStart, int offset, int posCaret, PRectangle rcCaret, ColourAllocated caretColour);
+	void DrawCarets(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
+		PRectangle rcLine, LineLayout *ll, int subLine);
 	void RefreshPixMaps(Surface *surfaceWindow);
 	void Paint(Surface *surfaceWindow, PRectangle rcArea);
-	long FormatRange(bool draw, RangeToFormat *pfr);
+	long FormatRange(bool draw, Sci_RangeToFormat *pfr);
 	int TextWidth(int style, const char *text);
 
 	virtual void SetVerticalScrollPos() = 0;
@@ -337,13 +352,15 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	void SetScrollBars();
 	void ChangeSize();
 
+	void FilterSelections();
+	int InsertSpace(int position, unsigned int spaces);
 	void AddChar(char ch);
 	virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false);
 	void ClearSelection();
 	void ClearAll();
 	void ClearDocumentStyle();
 	void Cut();
-	void PasteRectangular(int pos, const char *ptr, int len);
+	void PasteRectangular(SelectionPosition pos, const char *ptr, int len);
 	virtual void Copy() = 0;
 	virtual void CopyAllowLine();
 	virtual bool CanPaste();
@@ -362,7 +379,6 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	virtual void NotifyParent(SCNotification scn) = 0;
 	virtual void NotifyStyleToNeeded(int endStyleNeeded);
 	void NotifyChar(int ch);
-	void NotifyMove(int position);
 	void NotifySavePoint(bool isSavePoint);
 	void NotifyModifyAttempt();
 	virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt);
@@ -384,14 +400,14 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	void NotifyStyleNeeded(Document *doc, void *userData, int endPos);
 	void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
 
-	void PageMove(int direction, selTypes sel=noSel, bool stuttered = false);
+	void PageMove(int direction, Selection::selTypes sel=Selection::noSel, bool stuttered = false);
 	void ChangeCaseOfSelection(bool makeUpperCase);
 	void LineTranspose();
 	void Duplicate(bool forLine);
 	virtual void CancelModes();
 	void NewLine();
-	void CursorUpOrDown(int direction, selTypes sel=noSel);
-	void ParaUpOrDown(int direction, selTypes sel=noSel);
+	void CursorUpOrDown(int direction, Selection::selTypes sel=Selection::noSel);
+	void ParaUpOrDown(int direction, Selection::selTypes sel=Selection::noSel);
 	int StartEndDisplayLine(int pos, bool start);
 	virtual int KeyCommand(unsigned int iMessage);
 	virtual int KeyDefault(int /* key */, int /*modifiers*/);
@@ -410,18 +426,16 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 
 	virtual void CopyToClipboard(const SelectionText &selectedText) = 0;
 	char *CopyRange(int start, int end);
-	void CopySelectionFromRange(SelectionText *ss, bool allowLineCopy, int start, int end);
 	void CopySelectionRange(SelectionText *ss, bool allowLineCopy=false);
 	void CopyRangeToClipboard(int start, int end);
 	void CopyText(int length, const char *text);
-	void SetDragPosition(int newPos);
+	void SetDragPosition(SelectionPosition newPos);
 	virtual void DisplayCursor(Window::Cursor c);
 	virtual bool DragThreshold(Point ptStart, Point ptNow);
 	virtual void StartDrag();
-	void DropAt(int position, const char *value, bool moving, bool rectangular);
-	/** PositionInSelection returns 0 if position in selection, -1 if position before selection, and 1 if after.
-	 * Before means either before any line of selection or before selection on its line, with a similar meaning to after. */
-	int PositionInSelection(int pos);
+	void DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular);
+	/** PositionInSelection returns true if position in selection. */
+	bool PositionInSelection(int pos);
 	bool PointInSelection(Point pt);
 	bool PointInSelMargin(Point pt);
 	void LineSelection(int lineCurrent_, int lineAnchor_);
@@ -443,7 +457,10 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	void CheckForChangeOutsidePaint(Range r);
 	void SetBraceHighlight(Position pos0, Position pos1, int matchStyle);
 
+	void SetAnnotationHeights(int start, int end);
 	void SetDocPointer(Document *document);
+	
+	void SetAnnotationVisible(int visible);
 
 	void Expand(int &line, bool doExpand);
 	void ToggleContraction(int line);
@@ -473,6 +490,8 @@ public:
 	virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
 	// Public so scintilla_set_id can use it.
 	int ctrlID;
+	// Public so COM methods for drag and drop can set it.
+	int errorStatus;
 	friend class AutoSurface;
 	friend class SelectionLineIterator;
 };
diff --git a/plugins/scintilla/scintilla/ExternalLexer.cxx b/plugins/scintilla/scintilla/ExternalLexer.cxx
index a4e29e3..098df4d 100644
--- a/plugins/scintilla/scintilla/ExternalLexer.cxx
+++ b/plugins/scintilla/scintilla/ExternalLexer.cxx
@@ -10,6 +10,8 @@
 #include <string.h>
 #include <ctype.h>
 
+#include <string>
+
 #include "Platform.h"
 
 #include "Scintilla.h"
@@ -39,7 +41,7 @@ char **WordListsToStrings(WordList *val[]) {
 		dim++;
 	char **wls = new char * [dim + 1];
 	for (int i = 0;i < dim;i++) {
-		SString words;
+		std::string words;
 		words = "";
 		for (int n = 0; n < val[i]->len; n++) {
 			words += val[i]->words[n];
diff --git a/plugins/scintilla/scintilla/ExternalLexer.h b/plugins/scintilla/scintilla/ExternalLexer.h
index 55e127b..3c1659a 100644
--- a/plugins/scintilla/scintilla/ExternalLexer.h
+++ b/plugins/scintilla/scintilla/ExternalLexer.h
@@ -68,7 +68,7 @@ public:
 	void Release();
 	
 	LexerLibrary	*next;
-	SString			m_sModuleName;
+	std::string			m_sModuleName;
 };
 
 /// LexerManager manages external lexers, contains LexerLibrarys.
diff --git a/plugins/scintilla/scintilla/Indicator.cxx b/plugins/scintilla/scintilla/Indicator.cxx
index 139e2b0..da95312 100644
--- a/plugins/scintilla/scintilla/Indicator.cxx
+++ b/plugins/scintilla/scintilla/Indicator.cxx
@@ -72,7 +72,7 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
 		rcBox.top = rcLine.top + 1;
 		rcBox.left = rc.left;
 		rcBox.right = rc.right;
-		surface->AlphaRectangle(rcBox, 1, fore.allocated, 30, fore.allocated, 50, 0);
+		surface->AlphaRectangle(rcBox, 1, fore.allocated, fillAlpha, fore.allocated, 50, 0);
 	} else {	// Either INDIC_PLAIN or unknown
 		surface->MoveTo(rc.left, ymid);
 		surface->LineTo(rc.right, ymid);
diff --git a/plugins/scintilla/scintilla/Indicator.h b/plugins/scintilla/scintilla/Indicator.h
index 2081db5..42b56f0 100644
--- a/plugins/scintilla/scintilla/Indicator.h
+++ b/plugins/scintilla/scintilla/Indicator.h
@@ -19,7 +19,8 @@ public:
 	int style;
 	bool under;
 	ColourPair fore;
-	Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)) {
+	int fillAlpha;
+	Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30) {
 	}
 	void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine);
 };
diff --git a/plugins/scintilla/scintilla/KeyWords.cxx b/plugins/scintilla/scintilla/KeyWords.cxx
index b38e515..366cb47 100644
--- a/plugins/scintilla/scintilla/KeyWords.cxx
+++ b/plugins/scintilla/scintilla/KeyWords.cxx
@@ -23,6 +23,192 @@
 using namespace Scintilla;
 #endif
 
+/**
+ * Creates an array that points into each word in the string and puts \0 terminators
+ * after each word.
+ */
+static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) {
+	int prev = '\n';
+	int words = 0;
+	// For rapid determination of whether a character is a separator, build
+	// a look up table.
+	bool wordSeparator[256];
+	for (int i=0;i<256; i++) {
+		wordSeparator[i] = false;
+	}
+	wordSeparator['\r'] = true;
+	wordSeparator['\n'] = true;
+	if (!onlyLineEnds) {
+		wordSeparator[' '] = true;
+		wordSeparator['\t'] = true;
+	}
+	for (int j = 0; wordlist[j]; j++) {
+		int curr = static_cast<unsigned char>(wordlist[j]);
+		if (!wordSeparator[curr] && wordSeparator[prev])
+			words++;
+		prev = curr;
+	}
+	char **keywords = new char *[words + 1];
+	if (keywords) {
+		words = 0;
+		prev = '\0';
+		size_t slen = strlen(wordlist);
+		for (size_t k = 0; k < slen; k++) {
+			if (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) {
+				if (!prev) {
+					keywords[words] = &wordlist[k];
+					words++;
+				}
+			} else {
+				wordlist[k] = '\0';
+			}
+			prev = wordlist[k];
+		}
+		keywords[words] = &wordlist[slen];
+		*len = words;
+	} else {
+		*len = 0;
+	}
+	return keywords;
+}
+
+void WordList::Clear() {
+	if (words) {
+		delete []list;
+		delete []words;
+	}
+	words = 0;
+	list = 0;
+	len = 0;
+	sorted = false;
+}
+
+void WordList::Set(const char *s) {
+	list = new char[strlen(s) + 1];
+	strcpy(list, s);
+	sorted = false;
+	words = ArrayFromWordList(list, &len, onlyLineEnds);
+}
+
+extern "C" int cmpString(const void *a1, const void *a2) {
+	// Can't work out the correct incantation to use modern casts here
+	return strcmp(*(char**)(a1), *(char**)(a2));
+}
+
+static void SortWordList(char **words, unsigned int len) {
+	qsort(reinterpret_cast<void*>(words), len, sizeof(*words),
+	      cmpString);
+}
+
+bool WordList::InList(const char *s) {
+	if (0 == words)
+		return false;
+	if (!sorted) {
+		sorted = true;
+		SortWordList(words, len);
+		for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
+			starts[k] = -1;
+		for (int l = len - 1; l >= 0; l--) {
+			unsigned char indexChar = words[l][0];
+			starts[indexChar] = l;
+		}
+	}
+	unsigned char firstChar = s[0];
+	int j = starts[firstChar];
+	if (j >= 0) {
+		while ((unsigned char)words[j][0] == firstChar) {
+			if (s[1] == words[j][1]) {
+				const char *a = words[j] + 1;
+				const char *b = s + 1;
+				while (*a && *a == *b) {
+					a++;
+					b++;
+				}
+				if (!*a && !*b)
+					return true;
+			}
+			j++;
+		}
+	}
+	j = starts['^'];
+	if (j >= 0) {
+		while (words[j][0] == '^') {
+			const char *a = words[j] + 1;
+			const char *b = s;
+			while (*a && *a == *b) {
+				a++;
+				b++;
+			}
+			if (!*a)
+				return true;
+			j++;
+		}
+	}
+	return false;
+}
+
+/** similar to InList, but word s can be a substring of keyword.
+ * eg. the keyword define is defined as def~ine. This means the word must start
+ * with def to be a keyword, but also defi, defin and define are valid.
+ * The marker is ~ in this case.
+ */
+bool WordList::InListAbbreviated(const char *s, const char marker) {
+	if (0 == words)
+		return false;
+	if (!sorted) {
+		sorted = true;
+		SortWordList(words, len);
+		for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
+			starts[k] = -1;
+		for (int l = len - 1; l >= 0; l--) {
+			unsigned char indexChar = words[l][0];
+			starts[indexChar] = l;
+		}
+	}
+	unsigned char firstChar = s[0];
+	int j = starts[firstChar];
+	if (j >= 0) {
+		while (words[j][0] == firstChar) {
+			bool isSubword = false;
+			int start = 1;
+			if (words[j][1] == marker) {
+				isSubword = true;
+				start++;
+			}
+			if (s[1] == words[j][start]) {
+				const char *a = words[j] + start;
+				const char *b = s + 1;
+				while (*a && *a == *b) {
+					a++;
+					if (*a == marker) {
+						isSubword = true;
+						a++;
+					}
+					b++;
+				}
+				if ((!*a || isSubword) && !*b)
+					return true;
+			}
+			j++;
+		}
+	}
+	j = starts['^'];
+	if (j >= 0) {
+		while (words[j][0] == '^') {
+			const char *a = words[j] + 1;
+			const char *b = s;
+			while (*a && *a == *b) {
+				a++;
+				b++;
+			}
+			if (!*a)
+				return true;
+			j++;
+		}
+	}
+	return false;
+}
+
 const LexerModule *LexerModule::base = 0;
 int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;
 
@@ -146,7 +332,6 @@ int Scintilla_LinkLexers() {
 	LINK_LEXER(lmAns1);
 	LINK_LEXER(lmAPDL);
 	LINK_LEXER(lmAsm);
-	LINK_LEXER(lmASP);
 	LINK_LEXER(lmASY);
 	LINK_LEXER(lmAU3);
 	LINK_LEXER(lmAVE);
@@ -159,6 +344,7 @@ int Scintilla_LinkLexers() {
 	LINK_LEXER(lmClw);
 	LINK_LEXER(lmClwNoCase);
 	LINK_LEXER(lmCmake);
+	LINK_LEXER(lmCOBOL);
 	LINK_LEXER(lmConf);
 	LINK_LEXER(lmCPP);
 	LINK_LEXER(lmCPPNoCase);
@@ -194,6 +380,7 @@ int Scintilla_LinkLexers() {
 	LINK_LEXER(lmMMIXAL);
 	LINK_LEXER(lmMSSQL);
 	LINK_LEXER(lmMySQL);
+	LINK_LEXER(lmNimrod);
 	LINK_LEXER(lmNncrontab);
 	LINK_LEXER(lmNsis);
 	LINK_LEXER(lmNull);
@@ -202,11 +389,11 @@ int Scintilla_LinkLexers() {
 	LINK_LEXER(lmPascal);
 	LINK_LEXER(lmPB);
 	LINK_LEXER(lmPerl);
-	LINK_LEXER(lmPHP);
 	LINK_LEXER(lmPHPSCRIPT);
 	LINK_LEXER(lmPLM);
 	LINK_LEXER(lmPo);
 	LINK_LEXER(lmPOV);
+	LINK_LEXER(lmPowerPro);
 	LINK_LEXER(lmPowerShell);
 	LINK_LEXER(lmProgress);
 	LINK_LEXER(lmProps);
@@ -218,10 +405,14 @@ int Scintilla_LinkLexers() {
 	LINK_LEXER(lmRuby);
 	LINK_LEXER(lmScriptol);
 	LINK_LEXER(lmSmalltalk);
+	LINK_LEXER(lmSML);
+	LINK_LEXER(lmSorc);
 	LINK_LEXER(lmSpecman);
 	LINK_LEXER(lmSpice);
 	LINK_LEXER(lmSQL);
+	LINK_LEXER(lmTACL);
 	LINK_LEXER(lmTADS3);
+	LINK_LEXER(lmTAL);
 	LINK_LEXER(lmTCL);
 	LINK_LEXER(lmTeX);
 	LINK_LEXER(lmVB);
diff --git a/plugins/scintilla/scintilla/LexAU3.cxx b/plugins/scintilla/scintilla/LexAU3.cxx
index cedf261..cfff927 100644
--- a/plugins/scintilla/scintilla/LexAU3.cxx
+++ b/plugins/scintilla/scintilla/LexAU3.cxx
@@ -253,11 +253,12 @@ static void ColouriseAU3Doc(unsigned int startPos,
 				//Reset at line end
 				if (sc.atLineEnd) {
 					ci=0;
-					if ((strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0))
+					if (strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0) {
 						if (sc.atLineEnd) 
 							sc.SetState(SCE_AU3_DEFAULT);
 						else	
 							sc.SetState(SCE_AU3_COMMENTBLOCK);
+					}
 					break;
 				}
 				//skip rest of line when a ; is encountered
diff --git a/plugins/scintilla/scintilla/LexAda.cxx b/plugins/scintilla/scintilla/LexAda.cxx
index f6c9e7e..654bfbe 100755
--- a/plugins/scintilla/scintilla/LexAda.cxx
+++ b/plugins/scintilla/scintilla/LexAda.cxx
@@ -10,6 +10,8 @@
 #include <string.h>
 #include <stdio.h>
 
+#include <string>
+
 #include "Platform.h"
 
 #include "Accessor.h"
@@ -17,7 +19,6 @@
 #include "PropSet.h"
 #include "KeyWords.h"
 #include "SciLexer.h"
-#include "SString.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -62,8 +63,8 @@ static inline bool IsDelimiterCharacter(int ch);
 static inline bool IsNumberStartCharacter(int ch);
 static inline bool IsNumberCharacter(int ch);
 static inline bool IsSeparatorOrDelimiterCharacter(int ch);
-static bool IsValidIdentifier(const SString& identifier);
-static bool IsValidNumber(const SString& number);
+static bool IsValidIdentifier(const std::string& identifier);
+static bool IsValidNumber(const std::string& number);
 static inline bool IsWordStartCharacter(int ch);
 static inline bool IsWordCharacter(int ch);
 
@@ -117,7 +118,7 @@ static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostroph
 	sc.Forward();
 	sc.Forward();
 
-	SString identifier;
+	std::string identifier;
 
 	while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
 		identifier += static_cast<char>(tolower(sc.ch));
@@ -144,7 +145,7 @@ static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostroph
 static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
 	apostropheStartsAttribute = true;
 
-	SString number;
+	std::string number;
 	sc.SetState(SCE_ADA_NUMBER);
 
 	// Get all characters up to a delimiter or a separator, including points, but excluding
@@ -192,7 +193,7 @@ static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostrophe
 	apostropheStartsAttribute = true;
 	sc.SetState(SCE_ADA_IDENTIFIER);
 
-	SString word;
+	std::string word;
 
 	while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
 		word += static_cast<char>(tolower(sc.ch));
@@ -321,7 +322,7 @@ static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
 	return IsASpace(ch) || IsDelimiterCharacter(ch);
 }
 
-static bool IsValidIdentifier(const SString& identifier) {
+static bool IsValidIdentifier(const std::string& identifier) {
 	// First character can't be '_', so initialize the flag to true
 	bool lastWasUnderscore = true;
 
@@ -355,8 +356,8 @@ static bool IsValidIdentifier(const SString& identifier) {
 	return true;
 }
 
-static bool IsValidNumber(const SString& number) {
-	int hashPos = number.search("#");
+static bool IsValidNumber(const std::string& number) {
+	size_t hashPos = number.find("#");
 	bool seenDot = false;
 
 	size_t i = 0;
@@ -366,7 +367,7 @@ static bool IsValidNumber(const SString& number) {
 		return false; // Just in case
 
 	// Decimal number
-	if (hashPos == -1) {
+	if (hashPos == std::string::npos) {
 		bool canBeSpecial = false;
 
 		for (; i < length; i++) {
diff --git a/plugins/scintilla/scintilla/LexBash.cxx b/plugins/scintilla/scintilla/LexBash.cxx
index 7b475a7..5801278 100644
--- a/plugins/scintilla/scintilla/LexBash.cxx
+++ b/plugins/scintilla/scintilla/LexBash.cxx
@@ -334,6 +334,10 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
 					}
 					char s[HERE_DELIM_MAX];
 					sc.GetCurrent(s, sizeof(s));
+					if (sc.LengthCurrent() == 0)
+						break;
+					if (s[strlen(s) - 1] == '\r')
+						s[strlen(s) - 1] = '\0';
 					if (strcmp(HereDoc.Delimiter, s) == 0) {
 						if ((prefixws > 0 && HereDoc.Indent) ||	// indentation rule
 							(prefixws == 0 && !HereDoc.Indent)) {
diff --git a/plugins/scintilla/scintilla/LexCOBOL.cxx b/plugins/scintilla/scintilla/LexCOBOL.cxx
new file mode 100644
index 0000000..d061d5c
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexCOBOL.cxx
@@ -0,0 +1,368 @@
+// Scintilla source code edit control
+/** @file LexCOBOL.cxx
+ ** Lexer for COBOL
+ ** Based on LexPascal.cxx
+ ** Written by Laurent le Tynevez
+ ** Updated by Simon Steele <s steele pnotepad org> September 2002
+ ** Updated by Mathias Rauen <scite madshi net> May 2003 (Delphi adjustments)
+ ** Updated by Rod Falck, Aug 2006 Converted to COBOL
+ **/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+#include "StyleContext.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+#define IN_DIVISION 0x01
+#define IN_DECLARATIVES 0x02
+#define IN_SECTION 0x04
+#define IN_PARAGRAPH 0x08
+#define IN_FLAGS 0xF
+#define NOT_HEADER 0x10
+
+inline bool isCOBOLoperator(char ch)
+    {
+    return isoperator(ch);
+    }
+
+inline bool isCOBOLwordchar(char ch)
+    {
+    return isascii(ch) && (isalnum(ch) || ch == '-');
+
+    }
+
+inline bool isCOBOLwordstart(char ch)
+    {
+    return isascii(ch) && isalnum(ch);
+    }
+
+static int CountBits(int nBits)
+	{
+	int count = 0;
+	for (int i = 0; i < 32; ++i)
+		{
+		count += nBits & 1;
+		nBits >>= 1;
+		}
+	return count;
+	}
+
+static void getRange(unsigned int start,
+        unsigned int end,
+        Accessor &styler,
+        char *s,
+        unsigned int len) {
+    unsigned int i = 0;
+    while ((i < end - start + 1) && (i < len-1)) {
+        s[i] = static_cast<char>(tolower(styler[start + i]));
+        i++;
+    }
+    s[i] = '\0';
+}
+
+static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr) {
+    styler.ColourTo(end, attr);
+}
+
+
+static int classifyWordCOBOL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, int nContainment, bool *bAarea) {
+    int ret = 0;
+
+    WordList& a_keywords = *keywordlists[0];
+    WordList& b_keywords = *keywordlists[1];
+    WordList& c_keywords = *keywordlists[2];
+
+    char s[100];
+    getRange(start, end, styler, s, sizeof(s));
+
+    char chAttr = SCE_C_IDENTIFIER;
+    if (isdigit(s[0]) || (s[0] == '.')) {
+        chAttr = SCE_C_NUMBER;
+		char *p = s + 1;
+		while (*p) {
+			if (!isdigit(*p) && isCOBOLwordchar(*p)) {
+				chAttr = SCE_C_IDENTIFIER;
+			    break;
+			}
+			++p;
+		}
+    }
+    else {
+        if (a_keywords.InList(s)) {
+            chAttr = SCE_C_WORD;
+        }
+        else if (b_keywords.InList(s)) {
+            chAttr = SCE_C_WORD2;
+        }
+        else if (c_keywords.InList(s)) {
+            chAttr = SCE_C_UUID;
+        }
+    }
+    if (*bAarea) {
+        if (strcmp(s, "division") == 0) {
+            ret = IN_DIVISION;
+			// we've determined the containment, anything else is just ignored for those purposes
+			*bAarea = false;
+		} else if (strcmp(s, "declaratives") == 0) {
+            ret = IN_DIVISION | IN_DECLARATIVES;
+			if (nContainment & IN_DECLARATIVES)
+				ret |= NOT_HEADER | IN_SECTION;
+			// we've determined the containment, anything else is just ignored for those purposes
+			*bAarea = false;
+		} else if (strcmp(s, "section") == 0) {
+            ret = (nContainment &~ IN_PARAGRAPH) | IN_SECTION;
+			// we've determined the containment, anything else is just ignored for those purposes
+			*bAarea = false;
+		} else if (strcmp(s, "end") == 0 && (nContainment & IN_DECLARATIVES)) {
+            ret = IN_DIVISION | IN_DECLARATIVES | IN_SECTION | NOT_HEADER;
+		} else {
+			ret = nContainment | IN_PARAGRAPH;
+        }
+    }
+    ColourTo(styler, end, chAttr);
+    return ret;
+}
+
+static void ColouriseCOBOLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+    Accessor &styler) {
+
+    styler.StartAt(startPos);
+
+    int state = initStyle;
+    if (state == SCE_C_CHARACTER)   // Does not leak onto next line
+        state = SCE_C_DEFAULT;
+    char chPrev = ' ';
+    char chNext = styler[startPos];
+    unsigned int lengthDoc = startPos + length;
+
+    int nContainment;
+
+    int currentLine = styler.GetLine(startPos);
+    if (currentLine > 0) {
+        styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
+        nContainment = styler.GetLineState(currentLine);
+		nContainment &= ~NOT_HEADER;
+    } else {
+        styler.SetLineState(currentLine, 0);
+        nContainment = 0;
+    }
+
+    styler.StartSegment(startPos);
+    bool bNewLine = true;
+    bool bAarea = !isspacechar(chNext);
+	int column = 0;
+    for (unsigned int i = startPos; i < lengthDoc; i++) {
+        char ch = chNext;
+
+        chNext = styler.SafeGetCharAt(i + 1);
+
+		++column;
+
+        if (bNewLine) {
+			column = 0;
+        }
+		if (column <= 1 && !bAarea) {
+			bAarea = !isspacechar(ch);
+			}
+        bool bSetNewLine = false;
+        if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+            // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
+            // Avoid triggering two times on Dos/Win
+            // End of line
+            if (state == SCE_C_CHARACTER) {
+                ColourTo(styler, i, state);
+                state = SCE_C_DEFAULT;
+            }
+            styler.SetLineState(currentLine, nContainment);
+            currentLine++;
+            bSetNewLine = true;
+			if (nContainment & NOT_HEADER)
+				nContainment &= ~(NOT_HEADER | IN_DECLARATIVES | IN_SECTION);
+        }
+
+        if (styler.IsLeadByte(ch)) {
+            chNext = styler.SafeGetCharAt(i + 2);
+            chPrev = ' ';
+            i += 1;
+            continue;
+        }
+
+        if (state == SCE_C_DEFAULT) {
+            if (isCOBOLwordstart(ch) || (ch == '$' && isalpha(chNext))) {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_IDENTIFIER;
+            } else if (column == 0 && ch == '*' && chNext != '*') {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_COMMENTLINE;
+            } else if (column == 0 && ch == '/' && chNext != '*') {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_COMMENTLINE;
+            } else if (column == 0 && ch == '*' && chNext == '*') {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_COMMENTDOC;
+            } else if (column == 0 && ch == '/' && chNext == '*') {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_COMMENTDOC;
+            } else if (ch == '"') {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_STRING;
+            } else if (ch == '\'') {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_CHARACTER;
+            } else if (ch == '?' && column == 0) {
+                ColourTo(styler, i-1, state);
+                state = SCE_C_PREPROCESSOR;
+            } else if (isCOBOLoperator(ch)) {
+                ColourTo(styler, i-1, state);
+                ColourTo(styler, i, SCE_C_OPERATOR);
+            }
+        } else if (state == SCE_C_IDENTIFIER) {
+            if (!isCOBOLwordchar(ch)) {
+                int lStateChange = classifyWordCOBOL(styler.GetStartSegment(), i - 1, keywordlists, styler, nContainment, &bAarea);
+
+                if(lStateChange != 0) {
+                    styler.SetLineState(currentLine, lStateChange);
+                    nContainment = lStateChange;
+                }
+
+                state = SCE_C_DEFAULT;
+                chNext = styler.SafeGetCharAt(i + 1);
+                if (ch == '"') {
+                    state = SCE_C_STRING;
+                } else if (ch == '\'') {
+                    state = SCE_C_CHARACTER;
+                } else if (isCOBOLoperator(ch)) {
+                    ColourTo(styler, i, SCE_C_OPERATOR);
+                }
+            }
+        } else {
+            if (state == SCE_C_PREPROCESSOR) {
+                if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
+                    ColourTo(styler, i-1, state);
+                    state = SCE_C_DEFAULT;
+                }
+            } else if (state == SCE_C_COMMENT) {
+                if (ch == '\r' || ch == '\n') {
+                    ColourTo(styler, i, state);
+                    state = SCE_C_DEFAULT;
+                }
+            } else if (state == SCE_C_COMMENTDOC) {
+                if (ch == '\r' || ch == '\n') {
+                    if (((i > styler.GetStartSegment() + 2) || (
+                        (initStyle == SCE_C_COMMENTDOC) &&
+                        (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
+                            ColourTo(styler, i, state);
+                            state = SCE_C_DEFAULT;
+                    }
+                }
+            } else if (state == SCE_C_COMMENTLINE) {
+                if (ch == '\r' || ch == '\n') {
+                    ColourTo(styler, i-1, state);
+                    state = SCE_C_DEFAULT;
+                }
+            } else if (state == SCE_C_STRING) {
+                if (ch == '"') {
+                    ColourTo(styler, i, state);
+                    state = SCE_C_DEFAULT;
+                }
+            } else if (state == SCE_C_CHARACTER) {
+                if (ch == '\'') {
+                    ColourTo(styler, i, state);
+                    state = SCE_C_DEFAULT;
+                }
+            }
+        }
+        chPrev = ch;
+        bNewLine = bSetNewLine;
+		if (bNewLine)
+			{
+			bAarea = false;
+			}
+    }
+    ColourTo(styler, lengthDoc - 1, state);
+}
+
+static void FoldCOBOLDoc(unsigned int startPos, int length, int, WordList *[],
+                            Accessor &styler) {
+    bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+    unsigned int endPos = startPos + length;
+    int visibleChars = 0;
+    int lineCurrent = styler.GetLine(startPos);
+    int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) & SC_FOLDLEVELNUMBERMASK : 0xFFF;
+    char chNext = styler[startPos];
+
+    bool bNewLine = true;
+    bool bAarea = !isspacechar(chNext);
+	int column = 0;
+	bool bComment = false;
+    for (unsigned int i = startPos; i < endPos; i++) {
+        char ch = chNext;
+        chNext = styler.SafeGetCharAt(i + 1);
+		++column;
+
+        if (bNewLine) {
+			column = 0;
+			bComment = (ch == '*' || ch == '/' || ch == '?');
+        }
+		if (column <= 1 && !bAarea) {
+			bAarea = !isspacechar(ch);
+			}
+        bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+        if (atEOL) {
+			int nContainment = styler.GetLineState(lineCurrent);
+            int lev = CountBits(nContainment & IN_FLAGS) | SC_FOLDLEVELBASE;
+			if (bAarea && !bComment)
+				--lev;
+            if (visibleChars == 0 && foldCompact)
+                lev |= SC_FOLDLEVELWHITEFLAG;
+            if ((bAarea) && (visibleChars > 0) && !(nContainment & NOT_HEADER) && !bComment)
+                lev |= SC_FOLDLEVELHEADERFLAG;
+            if (lev != styler.LevelAt(lineCurrent)) {
+                styler.SetLevel(lineCurrent, lev);
+            }
+			if ((lev & SC_FOLDLEVELNUMBERMASK) <= (levelPrev & SC_FOLDLEVELNUMBERMASK)) {
+				// this level is at the same level or less than the previous line
+				// therefore these is nothing for the previous header to collapse, so remove the header
+				styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);
+			}
+            levelPrev = lev;
+            visibleChars = 0;
+			bAarea = false;
+            bNewLine = true;
+            lineCurrent++;
+        } else {
+            bNewLine = false;
+        }
+
+
+        if (!isspacechar(ch))
+            visibleChars++;
+    }
+
+    // Fill in the real level of the next line, keeping the current flags as they will be filled in later
+    int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+    styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const COBOLWordListDesc[] = {
+    "A Keywords",
+    "B Keywords",
+    "Extended Keywords",
+    0
+};
+
+LexerModule lmCOBOL(SCLEX_COBOL, ColouriseCOBOLDoc, "COBOL", FoldCOBOLDoc, COBOLWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexCPP.cxx b/plugins/scintilla/scintilla/LexCPP.cxx
index c2933f4..9577afb 100644
--- a/plugins/scintilla/scintilla/LexCPP.cxx
+++ b/plugins/scintilla/scintilla/LexCPP.cxx
@@ -58,6 +58,9 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 	WordList &keywords3 = *keywordlists[2];
 	WordList &keywords4 = *keywordlists[3];
 
+	// property styling.within.preprocessor
+	//	For C++ code, determines whether all preprocessor code is styled in the preprocessor style (0, the default) 
+	//	or only from the initial # to the end of the command word(1). 
 	bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
 
 	CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
@@ -67,6 +70,9 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 
 	CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
 	CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
+
+	// property lexer.cpp.allow.dollars
+	//	Set to 0 to disallow the '$' character in identifiers with the cpp lexer. 
 	if (styler.GetPropertyInt("lexer.cpp.allow.dollars", 1) != 0) {
 		setWordStart.Add('$');
 		setWord.Add('$');
@@ -77,6 +83,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 	bool lastWordWasUUID = false;
 	int styleBeforeDCKeyword = SCE_C_DEFAULT;
 	bool continuationLine = false;
+	bool isIncludePreprocessor = false;
 
 	if (initStyle == SCE_C_PREPROCESSOR) {
 		// Set continuationLine if last character of previous line is '\'
@@ -118,6 +125,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 			// if different sets of lines lexed.
 			visibleChars = 0;
 			lastWordWasUUID = false;
+			isIncludePreprocessor = false;
 		}
 
 		// Handle line continuation generically.
@@ -230,6 +238,11 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 			case SCE_C_STRING:
 				if (sc.atLineEnd) {
 					sc.ChangeState(SCE_C_STRINGEOL);
+				} else if (isIncludePreprocessor) {
+					if (sc.ch == '>') {
+						sc.ForwardSetState(SCE_C_DEFAULT);
+						isIncludePreprocessor = false;
+					}
 				} else if (sc.ch == '\\') {
 					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 						sc.Forward();
@@ -321,6 +334,9 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 				sc.SetState(SCE_C_REGEX);	// JavaScript's RegEx
 			} else if (sc.ch == '\"') {
 				sc.SetState(SCE_C_STRING);
+				isIncludePreprocessor = false;	// ensure that '>' won't end the string
+			} else if (isIncludePreprocessor && sc.ch == '<') {
+				sc.SetState(SCE_C_STRING);
 			} else if (sc.ch == '\'') {
 				sc.SetState(SCE_C_CHARACTER);
 			} else if (sc.ch == '#' && visibleChars == 0) {
@@ -332,6 +348,8 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 				} while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
 				if (sc.atLineEnd) {
 					sc.SetState(SCE_C_DEFAULT);
+				} else if (sc.Match("include")) {
+					isIncludePreprocessor = true;
 				}
 			} else if (isoperator(static_cast<char>(sc.ch))) {
 				sc.SetState(SCE_C_OPERATOR);
@@ -359,10 +377,24 @@ static bool IsStreamCommentStyle(int style) {
 // and to make it possible to fiddle the current level for "} else {".
 static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
 					   WordList *[], Accessor &styler) {
+
+	// property fold.comment
+	//	This option enables folding multi-line comments and explicit fold points when using the C++ lexer. 
+	//	Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} 
+	//	at the end of a section that should fold. 
 	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+
+	// property fold.preprocessor
+	//	This option enables folding preprocessor directives when using the C++ lexer. 
+	//	Includes C#'s explicit #region and #endregion folding directives. 
 	bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+
 	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+
+	// property fold.at.else 
+	//	This option enables C++ folding on a "} else {" line of an if statement. 
 	bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
+
 	unsigned int endPos = startPos + length;
 	int visibleChars = 0;
 	int lineCurrent = styler.GetLine(startPos);
@@ -442,6 +474,10 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
 			lineCurrent++;
 			levelCurrent = levelNext;
 			levelMinCurrent = levelCurrent;
+			if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) {
+				// There is an empty line at end of file so give it same level and empty
+				styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
+			}
 			visibleChars = 0;
 		}
 	}
diff --git a/plugins/scintilla/scintilla/LexCaml.cxx b/plugins/scintilla/scintilla/LexCaml.cxx
index 539eee0..0d11622 100644
--- a/plugins/scintilla/scintilla/LexCaml.cxx
+++ b/plugins/scintilla/scintilla/LexCaml.cxx
@@ -2,7 +2,7 @@
 /** @file LexCaml.cxx
  ** Lexer for Objective Caml.
  **/
-// Copyright 2005 by Robert Roessler <robertr rftp com>
+// Copyright 2005-2009 by Robert Roessler <robertr rftp com>
 // The License.txt file describes the conditions under which this software may be distributed.
 /*	Release History
 	20050204 Initial release.
@@ -15,6 +15,7 @@
 	20051125 Added 2nd "optional" keywords class.
 	20051129 Support "magic" (read-only) comments for RCaml.
 	20051204 Swtich to using StyleContext infrastructure.
+	20090629 Add full Standard ML '97 support.
 */
 
 #include <stdlib.h>
@@ -26,6 +27,7 @@
 #include "Platform.h"
 
 #include "PropSet.h"
+#include "PropSetSimple.h"
 #include "Accessor.h"
 #include "StyleContext.h"
 #include "KeyWords.h"
@@ -35,7 +37,6 @@
 //	Since the Microsoft __iscsym[f] funcs are not ANSI...
 inline int  iscaml(int c) {return isalnum(c) || c == '_';}
 inline int iscamlf(int c) {return isalpha(c) || c == '_';}
-inline int iscamld(int c) {return isdigit(c) || c == '_';}
 
 static const int baseT[24] = {
 	0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* A - L */
@@ -143,7 +144,7 @@ static void InternalLexOrFold(int foldOrLex, unsigned int startPos, int length,
 	int initStyle, char *words[], WindowID window, char *props)
 {
 	// create and initialize a WindowAccessor (including contained PropSet)
-	PropSet ps;
+	PropSetSimple ps;
 	ps.SetMultiple(props);
 	WindowAccessor wa(window, ps);
 	// create and initialize WordList(s)
@@ -179,25 +180,27 @@ void ColouriseCamlDoc(
 {
 	// initialize styler
 	StyleContext sc(startPos, length, initStyle, styler);
-	// set up [initial] state info (terminating states that shouldn't "bleed")
-	int nesting = 0;
-	if (sc.state < SCE_CAML_STRING)
-		sc.state = SCE_CAML_DEFAULT;
-	if (sc.state >= SCE_CAML_COMMENT)
-		nesting = (sc.state & 0x0f) - SCE_CAML_COMMENT;
 
 	int chBase = 0, chToken = 0, chLit = 0;
 	WordList& keywords  = *keywordlists[0];
 	WordList& keywords2 = *keywordlists[1];
 	WordList& keywords3 = *keywordlists[2];
+	const bool isSML = keywords.InList("andalso");
 	const int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0);
 
+	// set up [initial] state info (terminating states that shouldn't "bleed")
+	const int state_ = sc.state & 0x0f;
+	if (state_ <= SCE_CAML_CHAR
+		|| (isSML && state_ == SCE_CAML_STRING))
+		sc.state = SCE_CAML_DEFAULT;
+	int nesting = (state_ >= SCE_CAML_COMMENT)? (state_ - SCE_CAML_COMMENT): 0;
+
 	// foreach char in range...
 	while (sc.More()) {
 		// set up [per-char] state info
-		int state2 = -1;		// (ASSUME no state change)
+		int state2 = -1;				// (ASSUME no state change)
 		int chColor = sc.currentPos - 1;// (ASSUME standard coloring range)
-		bool advance = true;	// (ASSUME scanner "eats" 1 char)
+		bool advance = true;			// (ASSUME scanner "eats" 1 char)
 
 		// step state machine
 		switch (sc.state & 0x0f) {
@@ -206,25 +209,38 @@ void ColouriseCamlDoc(
 			// it's wide open; what do we have?
 			if (iscamlf(sc.ch))
 				state2 = SCE_CAML_IDENTIFIER;
-			else if (sc.Match('`') && iscamlf(sc.chNext))
+			else if (!isSML && sc.Match('`') && iscamlf(sc.chNext))
 				state2 = SCE_CAML_TAGNAME;
-			else if (sc.Match('#') && isdigit(sc.chNext))
+			else if (!isSML && sc.Match('#') && isdigit(sc.chNext))
 				state2 = SCE_CAML_LINENUM;
 			else if (isdigit(sc.ch)) {
+				// it's a number, assume base 10
 				state2 = SCE_CAML_NUMBER, chBase = 10;
-				if (sc.Match('0') && strchr("bBoOxX", sc.chNext))
-					chBase = baseT[tolower(sc.chNext) - 'a'], sc.Forward();
-			} else if (sc.Match('\''))	/* (char literal?) */
+				if (sc.Match('0')) {
+					// there MAY be a base specified...
+					const char* baseC = "bBoOxX";
+					if (isSML) {
+						if (sc.chNext == 'w')
+							sc.Forward();	// (consume SML "word" indicator)
+						baseC = "x";
+					}
+					// ... change to specified base AS REQUIRED
+					if (strchr(baseC, sc.chNext))
+						chBase = baseT[tolower(sc.chNext) - 'a'], sc.Forward();
+				}
+			} else if (!isSML && sc.Match('\''))	// (Caml char literal?)
 				state2 = SCE_CAML_CHAR, chLit = 0;
-			else if (sc.Match('\"'))
+			else if (isSML && sc.Match('#', '"'))	// (SML char literal?)
+				state2 = SCE_CAML_CHAR, sc.Forward();
+			else if (sc.Match('"'))
 				state2 = SCE_CAML_STRING;
 			else if (sc.Match('(', '*'))
-				state2 = SCE_CAML_COMMENT,
-					sc.ch = ' ',	// (make SURE "(*)" isn't seen as a closed comment)
-					sc.Forward();
-			else if (strchr("!?~"		/* Caml "prefix-symbol" */
-					"=<>@^|&+-*/$%"		/* Caml "infix-symbol" */
-					"()[]{};,:.#", sc.ch))	/* Caml "bracket" or ;,:.# */
+				state2 = SCE_CAML_COMMENT, sc.Forward(), sc.ch = ' '; // (*)...
+			else if (strchr("!?~"			/* Caml "prefix-symbol" */
+					"=<>@^|&+-*/$%"			/* Caml "infix-symbol" */
+					"()[]{};,:.#", sc.ch)	// Caml "bracket" or ;,:.#
+											// SML "extra" ident chars
+				|| (isSML && (sc.Match('\\') || sc.Match('`'))))
 				state2 = SCE_CAML_OPERATOR;
 			break;
 
@@ -273,9 +289,12 @@ void ColouriseCamlDoc(
 		case SCE_CAML_OPERATOR: {
 			// [try to] interpret as [additional] operator char
 			const char* o = 0;
-			if (iscaml(sc.ch) || isspace(sc.ch)		   /* ident or whitespace */
-				|| (o = strchr(")]};,\'\"`#", sc.ch),o)/* "termination" chars */
-				|| !strchr("!$%&*+-./:<=>? ^|~", sc.ch)/* "operator" chars */) {
+			if (iscaml(sc.ch) || isspace(sc.ch)			// ident or whitespace
+				|| (o = strchr(")]};,\'\"#", sc.ch),o)	// "termination" chars
+				|| (!isSML && sc.Match('`'))			// Caml extra term char
+				|| (!strchr("!$%&*+-./:<=>? ^|~", sc.ch)// "operator" chars
+														// SML extra ident chars
+					&& !(isSML && (sc.Match('\\') || sc.Match('`'))))) {
 				// check for INCLUSIVE termination
 				if (o && strchr(")]};,", sc.ch)) {
 					if ((sc.Match(')') && sc.chPrev == '(')
@@ -292,24 +311,27 @@ void ColouriseCamlDoc(
 
 		case SCE_CAML_NUMBER:
 			// [try to] interpret as [additional] numeric literal char
-			// N.B. - improperly accepts "extra" digits in base 2 or 8 literals
-			if (iscamld(sc.ch) || IsADigit(sc.ch, chBase))
+			if ((!isSML && sc.Match('_')) || IsADigit(sc.ch, chBase))
 				break;
 			// how about an integer suffix?
-			if ((sc.Match('l') || sc.Match('L') || sc.Match('n'))
-				&& (iscamld(sc.chPrev) || IsADigit(sc.chPrev, chBase)))
+			if (!isSML && (sc.Match('l') || sc.Match('L') || sc.Match('n'))
+				&& (sc.chPrev == '_' || IsADigit(sc.chPrev, chBase)))
 				break;
 			// or a floating-point literal?
 			if (chBase == 10) {
 				// with a decimal point?
-				if (sc.Match('.') && iscamld(sc.chPrev))
+				if (sc.Match('.')
+					&& ((!isSML && sc.chPrev == '_')
+						|| IsADigit(sc.chPrev, chBase)))
 					break;
 				// with an exponent? (I)
 				if ((sc.Match('e') || sc.Match('E'))
-					&& (iscamld(sc.chPrev) || sc.chPrev == '.'))
+					&& ((!isSML && (sc.chPrev == '.' || sc.chPrev == '_'))
+						|| IsADigit(sc.chPrev, chBase)))
 					break;
 				// with an exponent? (II)
-				if ((sc.Match('+') || sc.Match('-'))
+				if (((!isSML && (sc.Match('+') || sc.Match('-')))
+						|| (isSML && sc.Match('~')))
 					&& (sc.chPrev == 'e' || sc.chPrev == 'E'))
 					break;
 			}
@@ -318,29 +340,56 @@ void ColouriseCamlDoc(
 			break;
 
 		case SCE_CAML_CHAR:
-			// [try to] interpret as [additional] char literal char
-			if (sc.Match('\\')) {
-				chLit = 1;	// (definitely IS a char literal)
-				if (sc.chPrev == '\\')
-					sc.ch = ' ';	// (so termination test isn't fooled)
+			if (!isSML) {
+				// [try to] interpret as [additional] char literal char
+				if (sc.Match('\\')) {
+					chLit = 1;	// (definitely IS a char literal)
+					if (sc.chPrev == '\\')
+						sc.ch = ' ';	// (...\\')
+				// should we be terminating - one way or another?
+				} else if ((sc.Match('\'') && sc.chPrev != '\\')
+					|| sc.atLineEnd) {
+					state2 = SCE_CAML_DEFAULT;
+					if (sc.Match('\''))
+						chColor++;
+					else
+						sc.ChangeState(SCE_CAML_IDENTIFIER);
+				// ... maybe a char literal, maybe not
+				} else if (chLit < 1 && sc.currentPos - chToken >= 2)
+					sc.ChangeState(SCE_CAML_IDENTIFIER), advance = false;
+				break;
+			}/* else
+				// fall through for SML char literal (handle like string) */
+
+		case SCE_CAML_STRING:
+			// [try to] interpret as [additional] [SML char/] string literal char
+			if (isSML && sc.Match('\\') && sc.chPrev != '\\' && isspace(sc.chNext))
+				state2 = SCE_CAML_WHITE;
+			else if (sc.Match('\\') && sc.chPrev == '\\')
+				sc.ch = ' ';	// (...\\")
 			// should we be terminating - one way or another?
-			} else if ((sc.Match('\'') && sc.chPrev != '\\') || sc.atLineEnd) {
+			else if ((sc.Match('"') && sc.chPrev != '\\')
+				|| (isSML && sc.atLineEnd)) {
 				state2 = SCE_CAML_DEFAULT;
-				if (sc.Match('\''))
+				if (sc.Match('"'))
 					chColor++;
-				else
-					sc.ChangeState(SCE_CAML_IDENTIFIER);
-			// ... maybe a char literal, maybe not
-			} else if (chLit < 1 && sc.currentPos - chToken >= 2)
-				sc.ChangeState(SCE_CAML_IDENTIFIER), advance = false;
+			}
 			break;
 
-		case SCE_CAML_STRING:
-			// [try to] interpret as [additional] string literal char
-			if (sc.Match('\\') && sc.chPrev == '\\')
-				sc.ch = ' ';	// (so '\\' doesn't cause us trouble)
-			else if (sc.Match('\"') && sc.chPrev != '\\')
-				state2 = SCE_CAML_DEFAULT, chColor++;
+		case SCE_CAML_WHITE:
+			// [try to] interpret as [additional] SML embedded whitespace char
+			if (sc.Match('\\')) {
+				// style this puppy NOW...
+				state2 = SCE_CAML_STRING, sc.ch = ' ' /* (...\") */, chColor++,
+					styler.ColourTo(chColor, SCE_CAML_WHITE), styler.Flush();
+				// ... then backtrack to determine original SML literal type
+				int p = chColor - 2;
+				for (; p >= 0 && styler.StyleAt(p) == SCE_CAML_WHITE; p--) ;
+				if (p >= 0)
+					state2 = static_cast<int>(styler.StyleAt(p));
+				// take care of state change NOW
+				sc.ChangeState(state2), state2 = -1;
+			}
 			break;
 
 		case SCE_CAML_COMMENT:
@@ -350,8 +399,7 @@ void ColouriseCamlDoc(
 			// we're IN a comment - does this start a NESTED comment?
 			if (sc.Match('(', '*'))
 				state2 = sc.state + 1, chToken = sc.currentPos,
-					sc.ch = ' ',	// (make SURE "(*)" isn't seen as a closed comment)
-					sc.Forward(), nesting++;
+					sc.Forward(), sc.ch = ' ' /* (*)... */, nesting++;
 			// [try to] interpret as [additional] comment char
 			else if (sc.Match(')') && sc.chPrev == '*') {
 				if (nesting)
@@ -366,7 +414,7 @@ void ColouriseCamlDoc(
 			break;
 		}
 
-		// handle state change and char coloring as required
+		// handle state change and char coloring AS REQUIRED
 		if (state2 >= 0)
 			styler.ColourTo(chColor, sc.state), sc.ChangeState(state2);
 		// move to next char UNLESS re-scanning current char
diff --git a/plugins/scintilla/scintilla/LexCmake.cxx b/plugins/scintilla/scintilla/LexCmake.cxx
index f63eb39..1f51f47 100644
--- a/plugins/scintilla/scintilla/LexCmake.cxx
+++ b/plugins/scintilla/scintilla/LexCmake.cxx
@@ -13,6 +13,7 @@
 
 #include "Platform.h"
 
+#include "CharClassify.h"
 #include "PropSet.h"
 #include "Accessor.h"
 #include "KeyWords.h"
diff --git a/plugins/scintilla/scintilla/LexD.cxx b/plugins/scintilla/scintilla/LexD.cxx
index 95be129..4c4bcb3 100644
--- a/plugins/scintilla/scintilla/LexD.cxx
+++ b/plugins/scintilla/scintilla/LexD.cxx
@@ -25,20 +25,20 @@
 using namespace Scintilla;
 #endif
 
-/*/ Nested comments require keeping the value of the nesting level for every
-    position in the document.  But since scintilla always styles line by line,
-    we only need to store one value per line. The non-negative number indicates
-    nesting level at the end of the line.
-/*/
+/* Nested comments require keeping the value of the nesting level for every
+   position in the document.  But since scintilla always styles line by line,
+   we only need to store one value per line. The non-negative number indicates
+   nesting level at the end of the line.
+*/
 
-// We use custom qualifiers since it is not clear what D allows.
+// Underscore, letter, digit and universal alphas from C99 Appendix D.
 
 static bool IsWordStart(int ch) {
-	return isascii(ch) && (isalpha(ch) || ch == '_');
+	return (isascii(ch) && (isalpha(ch) || ch == '_')) || !isascii(ch);
 }
 
 static bool IsWord(int ch) {
-	return isascii(ch) && (isalnum(ch) || ch == '_');
+	return (isascii(ch) && (isalnum(ch) || ch == '_')) || !isascii(ch);
 }
 
 static bool IsDoxygen(int ch) {
@@ -51,308 +51,349 @@ static bool IsDoxygen(int ch) {
 	return false;
 }
 
+static bool IsStringSuffix(int ch) {
+	return ch == 'c' || ch == 'w' || ch == 'd';
+}
 
-static void ColouriseDoc(unsigned int startPos, int length, int initStyle, 
-    WordList *keywordlists[], Accessor &styler, bool caseSensitive) {
 
-    WordList &keywords = *keywordlists[0];
-    WordList &keywords2 = *keywordlists[1];
-    WordList &keywords3 = *keywordlists[2];
-    WordList &keywords4 = *keywordlists[3];
+static void ColouriseDoc(unsigned int startPos, int length, int initStyle,
+	WordList *keywordlists[], Accessor &styler, bool caseSensitive) {
 
-    int styleBeforeDCKeyword = SCE_D_DEFAULT;
+	WordList &keywords  = *keywordlists[0];
+	WordList &keywords2 = *keywordlists[1];
+	WordList &keywords3 = *keywordlists[2]; //doxygen
+	WordList &keywords4 = *keywordlists[3];
+	WordList &keywords5 = *keywordlists[4];
+	WordList &keywords6 = *keywordlists[5];
+	WordList &keywords7 = *keywordlists[6];
 
-    StyleContext sc(startPos, length, initStyle, styler);
+	int styleBeforeDCKeyword = SCE_D_DEFAULT;
 
-    int curLine = styler.GetLine(startPos);
-    int curNcLevel = curLine > 0? styler.GetLineState(curLine-1): 0;
+	StyleContext sc(startPos, length, initStyle, styler);
 
-    for (; sc.More(); sc.Forward()) {
+	int curLine = styler.GetLine(startPos);
+	int curNcLevel = curLine > 0? styler.GetLineState(curLine-1): 0;
+	bool numFloat = false; // Float literals have '+' and '-' signs
+	bool numHex = false;
 
-        if (sc.atLineStart) {
-            if (sc.state == SCE_D_STRING) {
-                // Prevent SCE_D_STRINGEOL from leaking back to previous line which
-                // ends with a line continuation by locking in the state upto this position.
-                sc.SetState(SCE_D_STRING);
-            }
-            curLine = styler.GetLine(sc.currentPos);
-            styler.SetLineState(curLine, curNcLevel);
-        }
+	for (; sc.More(); sc.Forward()) {
 
-        // Handle line continuation generically.
-        if (sc.ch == '\\') {
-            if (sc.chNext == '\n' || sc.chNext == '\r') {
-                sc.Forward();
-                if (sc.ch == '\r' && sc.chNext == '\n') {
-                    sc.Forward();
-                }
-                continue;
-            }
-        }
+		if (sc.atLineStart) {
+			curLine = styler.GetLine(sc.currentPos);
+			styler.SetLineState(curLine, curNcLevel);
+		}
 
-        // Determine if the current state should terminate.
-        switch (sc.state) {
-            case SCE_D_OPERATOR:
-                sc.SetState(SCE_D_DEFAULT);
-                break;
-            case SCE_D_NUMBER:
-                // We accept almost anything because of hex. and number suffixes
-                if (!IsWord(sc.ch) && sc.ch != '.') {
-                    sc.SetState(SCE_D_DEFAULT);
-                }
-                break;
-            case SCE_D_IDENTIFIER:
-                if (!IsWord(sc.ch)) {
-                    char s[1000];
-                    if (caseSensitive) {
-                        sc.GetCurrent(s, sizeof(s));
-                    } else {
-                        sc.GetCurrentLowered(s, sizeof(s));
-                    }
-                    if (keywords.InList(s)) {
-                        sc.ChangeState(SCE_D_WORD);
-                    } else if (keywords2.InList(s)) {
-                        sc.ChangeState(SCE_D_WORD2);
-                    } else if (keywords4.InList(s)) {
-                        sc.ChangeState(SCE_D_TYPEDEF);
-                    }
-                    sc.SetState(SCE_D_DEFAULT);
-                }
-                break;
-            case SCE_D_COMMENT:
-                if (sc.Match('*', '/')) {
-                    sc.Forward();
-                    sc.ForwardSetState(SCE_D_DEFAULT);
-                }
-                break;
-            case SCE_D_COMMENTDOC:
-                if (sc.Match('*', '/')) {
-                    sc.Forward();
-                    sc.ForwardSetState(SCE_D_DEFAULT);
-                } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
-                    // Verify that we have the conditions to mark a comment-doc-keyword
-                    if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
-                        styleBeforeDCKeyword = SCE_D_COMMENTDOC;
-                        sc.SetState(SCE_D_COMMENTDOCKEYWORD);
-                    }
-                }
-                break;
-            case SCE_D_COMMENTLINE:
-                if (sc.atLineStart) {
-                    sc.SetState(SCE_D_DEFAULT);
-                }
-                break;
-            case SCE_D_COMMENTLINEDOC:
-                if (sc.atLineStart) {
-                    sc.SetState(SCE_D_DEFAULT);
-                } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
-                    // Verify that we have the conditions to mark a comment-doc-keyword
-                    if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
-                        styleBeforeDCKeyword = SCE_D_COMMENTLINEDOC;
-                        sc.SetState(SCE_D_COMMENTDOCKEYWORD);
-                    }
-                }
-                break;
-            case SCE_D_COMMENTDOCKEYWORD:
-                if ((styleBeforeDCKeyword == SCE_D_COMMENTDOC) && sc.Match('*', '/')) {
-                    sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
-                    sc.Forward();
-                    sc.ForwardSetState(SCE_D_DEFAULT);
-                } else if (!IsDoxygen(sc.ch)) {
-                    char s[100];
-                    if (caseSensitive) {
-                        sc.GetCurrent(s, sizeof(s));
-                    } else {
-                        sc.GetCurrentLowered(s, sizeof(s));
-                    }
-                    if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
-                        sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
-                    }
-                    sc.SetState(styleBeforeDCKeyword);
-                }
-                break;
-            case SCE_D_COMMENTNESTED:
-                if (sc.Match('+', '/')) {
-                    if (curNcLevel > 0)
-                        curNcLevel -= 1;
-                    curLine = styler.GetLine(sc.currentPos);
-                    styler.SetLineState(curLine, curNcLevel);
-                    sc.Forward();
-                    if (curNcLevel == 0) {
-                        sc.ForwardSetState(SCE_D_DEFAULT);
-		    }
-                }
-                else if (sc.Match('/','+')) {
-                    curNcLevel += 1;
-                    curLine = styler.GetLine(sc.currentPos);
-                    styler.SetLineState(curLine, curNcLevel);
-                    sc.Forward();
-                }
-                break;
-            case SCE_D_STRING:
-                if (sc.atLineEnd) {
-                    sc.ChangeState(SCE_D_STRINGEOL);
-                } else if (sc.ch == '\\') {
-                    if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
-                        sc.Forward();
-                    }
-                } else if (sc.ch == '\"') {
-                    sc.ForwardSetState(SCE_D_DEFAULT);
-                }
-                break;
-            case SCE_D_CHARACTER:
-                if (sc.atLineEnd) {
-                    sc.ChangeState(SCE_D_STRINGEOL);
-                } else if (sc.ch == '\\') {
-                    if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
-                        sc.Forward();
-                    }
-                } else if (sc.ch == '\'') {
-                    sc.ForwardSetState(SCE_D_DEFAULT);
-                }
-                break;
-            case SCE_D_STRINGEOL:
-                if (sc.atLineStart) {
-                    sc.SetState(SCE_D_DEFAULT);
-                }
-                break;
-        }
+		// Determine if the current state should terminate.
+		switch (sc.state) {
+			case SCE_D_OPERATOR:
+				sc.SetState(SCE_D_DEFAULT);
+				break;
+			case SCE_D_NUMBER:
+				// We accept almost anything because of hex. and number suffixes
+				if (isascii(sc.ch) && (isalnum(sc.ch) || sc.ch == '_')) {
+					continue;
+				} else if (sc.ch == '.' && sc.chNext != '.' && !numFloat) {
+					// Don't parse 0..2 as number.
+					numFloat=true;
+					continue;
+				} else if ( ( sc.ch == '-' || sc.ch == '+' ) && (		/*sign and*/
+					( !numHex && ( sc.chPrev == 'e' || sc.chPrev == 'E' ) ) || /*decimal or*/
+					( sc.chPrev == 'p' || sc.chPrev == 'P' ) ) ) {		/*hex*/
+					// Parse exponent sign in float literals: 2e+10 0x2e+10
+					continue;
+				} else {
+					sc.SetState(SCE_D_DEFAULT);
+				}
+				break;
+			case SCE_D_IDENTIFIER:
+				if (!IsWord(sc.ch)) {
+					char s[1000];
+					if (caseSensitive) {
+						sc.GetCurrent(s, sizeof(s));
+					} else {
+						sc.GetCurrentLowered(s, sizeof(s));
+					}
+					if (keywords.InList(s)) {
+						sc.ChangeState(SCE_D_WORD);
+					} else if (keywords2.InList(s)) {
+						sc.ChangeState(SCE_D_WORD2);
+					} else if (keywords4.InList(s)) {
+						sc.ChangeState(SCE_D_TYPEDEF);
+					} else if (keywords5.InList(s)) {
+						sc.ChangeState(SCE_D_WORD5);
+					} else if (keywords6.InList(s)) {
+						sc.ChangeState(SCE_D_WORD6);
+					} else if (keywords7.InList(s)) {
+						sc.ChangeState(SCE_D_WORD7);
+					}
+					sc.SetState(SCE_D_DEFAULT);
+				}
+				break;
+			case SCE_D_COMMENT:
+				if (sc.Match('*', '/')) {
+					sc.Forward();
+					sc.ForwardSetState(SCE_D_DEFAULT);
+				}
+				break;
+			case SCE_D_COMMENTDOC:
+				if (sc.Match('*', '/')) {
+					sc.Forward();
+					sc.ForwardSetState(SCE_D_DEFAULT);
+				} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+					// Verify that we have the conditions to mark a comment-doc-keyword
+					if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
+						styleBeforeDCKeyword = SCE_D_COMMENTDOC;
+						sc.SetState(SCE_D_COMMENTDOCKEYWORD);
+					}
+				}
+				break;
+			case SCE_D_COMMENTLINE:
+				if (sc.atLineStart) {
+					sc.SetState(SCE_D_DEFAULT);
+				}
+				break;
+			case SCE_D_COMMENTLINEDOC:
+				if (sc.atLineStart) {
+					sc.SetState(SCE_D_DEFAULT);
+				} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+					// Verify that we have the conditions to mark a comment-doc-keyword
+					if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
+						styleBeforeDCKeyword = SCE_D_COMMENTLINEDOC;
+						sc.SetState(SCE_D_COMMENTDOCKEYWORD);
+					}
+				}
+				break;
+			case SCE_D_COMMENTDOCKEYWORD:
+				if ((styleBeforeDCKeyword == SCE_D_COMMENTDOC) && sc.Match('*', '/')) {
+					sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
+					sc.Forward();
+					sc.ForwardSetState(SCE_D_DEFAULT);
+				} else if (!IsDoxygen(sc.ch)) {
+					char s[100];
+					if (caseSensitive) {
+						sc.GetCurrent(s, sizeof(s));
+					} else {
+						sc.GetCurrentLowered(s, sizeof(s));
+					}
+					if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
+						sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR);
+					}
+					sc.SetState(styleBeforeDCKeyword);
+				}
+				break;
+			case SCE_D_COMMENTNESTED:
+				if (sc.Match('+', '/')) {
+					if (curNcLevel > 0)
+						curNcLevel -= 1;
+					curLine = styler.GetLine(sc.currentPos);
+					styler.SetLineState(curLine, curNcLevel);
+					sc.Forward();
+					if (curNcLevel == 0) {
+						sc.ForwardSetState(SCE_D_DEFAULT);
+					}
+				} else if (sc.Match('/','+')) {
+					curNcLevel += 1;
+					curLine = styler.GetLine(sc.currentPos);
+					styler.SetLineState(curLine, curNcLevel);
+					sc.Forward();
+				}
+				break;
+			case SCE_D_STRING:
+				if (sc.ch == '\\') {
+					if (sc.chNext == '"' || sc.chNext == '\\') {
+						sc.Forward();
+					}
+				} else if (sc.ch == '"') {
+					if(IsStringSuffix(sc.chNext))
+						sc.Forward();
+					sc.ForwardSetState(SCE_D_DEFAULT);
+				}
+				break;
+			case SCE_D_CHARACTER:
+				if (sc.atLineEnd) {
+					sc.ChangeState(SCE_D_STRINGEOL);
+				} else if (sc.ch == '\\') {
+					if (sc.chNext == '\'' || sc.chNext == '\\') {
+						sc.Forward();
+					}
+				} else if (sc.ch == '\'') {
+					// Char has no suffixes
+					sc.ForwardSetState(SCE_D_DEFAULT);
+				}
+				break;
+			case SCE_D_STRINGEOL:
+				if (sc.atLineStart) {
+					sc.SetState(SCE_D_DEFAULT);
+				}
+				break;
+			case SCE_D_STRINGB:
+				if (sc.ch == '`') {
+					if(IsStringSuffix(sc.chNext))
+						sc.Forward();
+					sc.ForwardSetState(SCE_D_DEFAULT);
+				}
+				break;
+			case SCE_D_STRINGR:
+				if (sc.ch == '"') {
+					if(IsStringSuffix(sc.chNext))
+						sc.Forward();
+					sc.ForwardSetState(SCE_D_DEFAULT);
+				}
+				break;
+		}
 
-        // Determine if a new state should be entered.
-        if (sc.state == SCE_D_DEFAULT) {
-            if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
-                    sc.SetState(SCE_D_NUMBER);
-            } else if (IsWordStart(sc.ch)) {
-                    sc.SetState(SCE_D_IDENTIFIER);
-            } else if (sc.Match('/','+')) {
-                curNcLevel += 1;
-		curLine = styler.GetLine(sc.currentPos);
-                styler.SetLineState(curLine, curNcLevel);
-                sc.SetState(SCE_D_COMMENTNESTED);
-                sc.Forward();
-            } else if (sc.Match('/', '*')) {
-                if (sc.Match("/**") || sc.Match("/*!")) {   // Support of Qt/Doxygen doc. style
-                    sc.SetState(SCE_D_COMMENTDOC);
-                } else {
-                    sc.SetState(SCE_D_COMMENT);
-                }
-                sc.Forward();   // Eat the * so it isn't used for the end of the comment
-            } else if (sc.Match('/', '/')) {
-                if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
-                    // Support of Qt/Doxygen doc. style
-                    sc.SetState(SCE_D_COMMENTLINEDOC);
-                else
-                    sc.SetState(SCE_D_COMMENTLINE);
-            } else if (sc.ch == '\"') {
-                sc.SetState(SCE_D_STRING);
-            } else if (sc.ch == '\'') {
-                sc.SetState(SCE_D_CHARACTER);
-            } else if (isoperator(static_cast<char>(sc.ch))) {
-                sc.SetState(SCE_D_OPERATOR);
-            }
-        }
-    }
-    sc.Complete();
+		// Determine if a new state should be entered.
+		if (sc.state == SCE_D_DEFAULT) {
+			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+				sc.SetState(SCE_D_NUMBER);
+				numFloat = sc.ch == '.';
+				// Remember hex literal
+				numHex = sc.ch == '0' && ( sc.chNext == 'x' || sc.chNext == 'X' );
+			} else if ( (sc.ch == 'r' || sc.ch == 'x' || sc.ch == 'q')
+				&& sc.chNext == '"' ) {
+				// Limited support for hex and delimited strings: parse as r""
+				sc.SetState(SCE_D_STRINGR);
+				sc.Forward();
+			} else if (IsWordStart(sc.ch) || sc.ch == '$') {
+				sc.SetState(SCE_D_IDENTIFIER);
+			} else if (sc.Match('/','+')) {
+				curNcLevel += 1;
+				curLine = styler.GetLine(sc.currentPos);
+				styler.SetLineState(curLine, curNcLevel);
+				sc.SetState(SCE_D_COMMENTNESTED);
+				sc.Forward();
+			} else if (sc.Match('/', '*')) {
+				if (sc.Match("/**") || sc.Match("/*!")) {   // Support of Qt/Doxygen doc. style
+					sc.SetState(SCE_D_COMMENTDOC);
+				} else {
+					sc.SetState(SCE_D_COMMENT);
+				}
+				sc.Forward();   // Eat the * so it isn't used for the end of the comment
+			} else if (sc.Match('/', '/')) {
+				if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
+					// Support of Qt/Doxygen doc. style
+					sc.SetState(SCE_D_COMMENTLINEDOC);
+				else
+					sc.SetState(SCE_D_COMMENTLINE);
+			} else if (sc.ch == '"') {
+				sc.SetState(SCE_D_STRING);
+			} else if (sc.ch == '\'') {
+				sc.SetState(SCE_D_CHARACTER);
+			} else if (sc.ch == '`') {
+				sc.SetState(SCE_D_STRINGB);
+			} else if (isoperator(static_cast<char>(sc.ch))) {
+				sc.SetState(SCE_D_OPERATOR);
+				if (sc.ch == '.' && sc.chNext == '.') sc.Forward(); // Range operator
+			}
+		}
+	}
+	sc.Complete();
 }
 
 static bool IsStreamCommentStyle(int style) {
-    return style == SCE_D_COMMENT ||
-        style == SCE_D_COMMENTDOC ||
-        style == SCE_D_COMMENTDOCKEYWORD ||
-        style == SCE_D_COMMENTDOCKEYWORDERROR;
+	return style == SCE_D_COMMENT ||
+		style == SCE_D_COMMENTDOC ||
+		style == SCE_D_COMMENTDOCKEYWORD ||
+		style == SCE_D_COMMENTDOCKEYWORDERROR;
 }
 
 // Store both the current line's fold level and the next lines in the
 // level store to make it easy to pick up with each increment
 // and to make it possible to fiddle the current level for "} else {".
 static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &styler) {
-    bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
-    bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
-    bool foldAtElse = styler.GetPropertyInt("lexer.d.fold.at.else",
+	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+
+	// property lexer.d.fold.at.else
+	//  This option enables D folding on a "} else {" line of an if statement.
+	bool foldAtElse = styler.GetPropertyInt("lexer.d.fold.at.else",
 		styler.GetPropertyInt("fold.at.else", 0)) != 0;
-    unsigned int endPos = startPos + length;
-    int visibleChars = 0;
-    int lineCurrent = styler.GetLine(startPos);
-    int levelCurrent = SC_FOLDLEVELBASE;
-    if (lineCurrent > 0)
-        levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
-    int levelMinCurrent = levelCurrent;
-    int levelNext = levelCurrent;
-    char chNext = styler[startPos];
-    int styleNext = styler.StyleAt(startPos);
-    int style = initStyle;
-    for (unsigned int i = startPos; i < endPos; i++) {
-        char ch = chNext;
-        chNext = styler.SafeGetCharAt(i + 1);
-        int stylePrev = style;
-        style = styleNext;
-        styleNext = styler.StyleAt(i + 1);
-        bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-        if (foldComment && IsStreamCommentStyle(style)) {
-            if (!IsStreamCommentStyle(stylePrev)) {
-                levelNext++;
-            } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
-                // Comments don't end at end of line and the next character may be unstyled.
-                levelNext--;
-            }
-        }
-        if (style == SCE_D_OPERATOR) {
-            if (ch == '{') {
-                // Measure the minimum before a '{' to allow
-                // folding on "} else {"
-                if (levelMinCurrent > levelNext) {
-                    levelMinCurrent = levelNext;
-                }
-                levelNext++;
-            } else if (ch == '}') {
-                levelNext--;
-            }
-        }
-        if (atEOL) {
-            if (foldComment) {	// Handle nested comments
-		int nc;
-                nc =  styler.GetLineState(lineCurrent);
-                nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;
-                levelNext += nc;
-	    }
-            int levelUse = levelCurrent;
-            if (foldAtElse) {
-                levelUse = levelMinCurrent;
-            }
-            int lev = levelUse | levelNext << 16;
-            if (visibleChars == 0 && foldCompact)
-                lev |= SC_FOLDLEVELWHITEFLAG;
-            if (levelUse < levelNext)
-                lev |= SC_FOLDLEVELHEADERFLAG;
-            if (lev != styler.LevelAt(lineCurrent)) {
-                styler.SetLevel(lineCurrent, lev);
-            }
-            lineCurrent++;
-            levelCurrent = levelNext;
-            levelMinCurrent = levelCurrent;
-            visibleChars = 0;
-        }
-        if (!IsASpace(ch))
-            visibleChars++;
-    }
+	unsigned int endPos = startPos + length;
+	int visibleChars = 0;
+	int lineCurrent = styler.GetLine(startPos);
+	int levelCurrent = SC_FOLDLEVELBASE;
+	if (lineCurrent > 0)
+		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+	int levelMinCurrent = levelCurrent;
+	int levelNext = levelCurrent;
+	char chNext = styler[startPos];
+	int styleNext = styler.StyleAt(startPos);
+	int style = initStyle;
+	for (unsigned int i = startPos; i < endPos; i++) {
+		char ch = chNext;
+		chNext = styler.SafeGetCharAt(i + 1);
+		int stylePrev = style;
+		style = styleNext;
+		styleNext = styler.StyleAt(i + 1);
+		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+		if (foldComment && IsStreamCommentStyle(style)) {
+			if (!IsStreamCommentStyle(stylePrev)) {
+				levelNext++;
+			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+				// Comments don't end at end of line and the next character may be unstyled.
+				levelNext--;
+			}
+		}
+		if (style == SCE_D_OPERATOR) {
+			if (ch == '{') {
+				// Measure the minimum before a '{' to allow
+				// folding on "} else {"
+				if (levelMinCurrent > levelNext) {
+					levelMinCurrent = levelNext;
+				}
+				levelNext++;
+			} else if (ch == '}') {
+				levelNext--;
+			}
+		}
+		if (atEOL) {
+			if (foldComment) {  // Handle nested comments
+				int nc;
+				nc =  styler.GetLineState(lineCurrent);
+				nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;
+				levelNext += nc;
+			}
+			int levelUse = levelCurrent;
+			if (foldAtElse) {
+				levelUse = levelMinCurrent;
+			}
+			int lev = levelUse | levelNext << 16;
+			if (visibleChars == 0 && foldCompact)
+				lev |= SC_FOLDLEVELWHITEFLAG;
+			if (levelUse < levelNext)
+				lev |= SC_FOLDLEVELHEADERFLAG;
+			if (lev != styler.LevelAt(lineCurrent)) {
+				styler.SetLevel(lineCurrent, lev);
+			}
+			lineCurrent++;
+			levelCurrent = levelNext;
+			levelMinCurrent = levelCurrent;
+			visibleChars = 0;
+		}
+		if (!IsASpace(ch))
+			visibleChars++;
+	}
 }
 
 static void FoldDDoc(unsigned int startPos, int length, int initStyle,
-    WordList *[], Accessor &styler) {
-        FoldDoc(startPos, length, initStyle, styler);
+	WordList *[], Accessor &styler) {
+		FoldDoc(startPos, length, initStyle, styler);
 }
 
 static const char * const dWordLists[] = {
-            "Primary keywords and identifiers",
-            "Secondary keywords and identifiers",
-            "Documentation comment keywords",
-            "Type definitions and aliases",
-            0,
-        };
+			"Primary keywords and identifiers",
+			"Secondary keywords and identifiers",
+			"Documentation comment keywords",
+			"Type definitions and aliases",
+			"Keywords 5",
+			"Keywords 6",
+			"Keywords 7",
+			0,
+		};
 
-static void ColouriseDDoc(unsigned int startPos, int length, 
-    int initStyle, WordList *keywordlists[], Accessor &styler) {
-        ColouriseDoc(startPos, length, initStyle, keywordlists, styler, true);
+static void ColouriseDDoc(unsigned int startPos, int length,
+	int initStyle, WordList *keywordlists[], Accessor &styler) {
+		ColouriseDoc(startPos, length, initStyle, keywordlists, styler, true);
 }
 
 LexerModule lmD(SCLEX_D, ColouriseDDoc, "d", FoldDDoc, dWordLists);
diff --git a/plugins/scintilla/scintilla/LexForth.cxx b/plugins/scintilla/scintilla/LexForth.cxx
index f097b0e..e52543f 100644
--- a/plugins/scintilla/scintilla/LexForth.cxx
+++ b/plugins/scintilla/scintilla/LexForth.cxx
@@ -1,10 +1,8 @@
 // Scintilla source code edit control
-/** @file LexCrontab.cxx
- ** Lexer to use with extended crontab files used by a powerful
- ** Windows scheduler/event monitor/automation manager nnCron.
- ** (http://nemtsev.eserv.ru/)
+/** @file LexForth.cxx
+ ** Lexer for FORTH
  **/
-// Copyright 1998-2001 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
@@ -17,6 +15,7 @@
 
 #include "PropSet.h"
 #include "Accessor.h"
+#include "StyleContext.h"
 #include "KeyWords.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
@@ -25,100 +24,29 @@
 using namespace Scintilla;
 #endif
 
-bool is_whitespace(int ch){
-    return ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ';
+static inline bool IsAWordChar(int ch) {
+	return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
+		ch == '_' || ch == '?' || ch == '"' || ch == '@' ||
+		ch == '!' || ch == '[' || ch == ']' || ch == '/' ||
+		ch == '+' || ch == '-' || ch == '*' || ch == '<' ||
+		ch == '>' || ch == '=' || ch == ';' || ch == '(' ||
+		ch == ')' );
 }
 
-bool is_blank(int ch){
-    return ch == '\t' || ch == ' ';
+static inline bool IsAWordStart(int ch) {
+	return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
 }
-//#define FORTH_DEBUG
-#ifdef FORTH_DEBUG
-static FILE *f_debug;
-#define log(x)  fputs(f_debug,x);
-#else
-#define log(x)
-#endif
-
-#define STATE_LOCALE
-#define BL ' '
 
-static Accessor *st;
-static int cur_pos,pos1,pos2,pos0,lengthDoc;
-char *buffer;
-
-char getChar(bool is_bl){
-    char ch=st->SafeGetCharAt(cur_pos);
-    if(is_bl) if(is_whitespace(ch)) ch=BL;
-    return ch;
+static inline bool IsANumChar(int ch) {
+	return (ch < 0x80) && (isxdigit(ch) || ch == '.' || ch == 'e' || ch == 'E' );
 }
 
-char getCharBL(){
-    char ch=st->SafeGetCharAt(cur_pos);
-    return ch;
-}
-bool is_eol(char ch){
-    return ch=='\n' || ch=='\r';
-}
-
-int parse(char ch, bool skip_eol){
-// pos1 - start pos of word
-// pos2 - pos after of word
-// pos0 - start pos
-    char c=0;
-    int len;
-    bool is_bl=ch==BL;
-    pos0=pos1=pos2=cur_pos;
-    for(;cur_pos<lengthDoc && (c=getChar(is_bl))==ch; cur_pos++){
-        if(is_eol(c) && !skip_eol){
-            pos2=pos1;
-            return 0;
-        }
-    }
-    pos1=cur_pos;
-    pos2=pos1;
-    if(cur_pos==lengthDoc) return 0;
-    for(len=0;cur_pos<lengthDoc && (c=getChar(is_bl))!=ch; cur_pos++){
-        if(is_eol(c) && !skip_eol) break;
-        pos2++;
-        buffer[len++]=c;
-    }
-    if(c==ch) pos2--;
-    buffer[len]='\0';
-#ifdef FORTH_DEBUG
-    fprintf(f_debug,"parse: %c %s\n",ch,buffer);
-#endif
-    return len;
+static inline bool IsASpaceChar(int ch) {
+	return (ch < 0x80) && isspace(ch);
 }
 
-bool _is_number(char *s,int base){
-    for(;*s;s++){
-        int digit=((int)*s)-(int)'0';
-#ifdef FORTH_DEBUG
-    fprintf(f_debug,"digit: %c %d\n",*s,digit);
-#endif
-        if(digit>9 && base>10) digit-=7;
-        if(digit<0) return false;
-        if(digit>=base) return false;
-    }
-    return true;
-}
-
-bool is_number(char *s){
-    if(strncmp(s,"0x",2)==0) return _is_number(s+2,16);
-    return _is_number(s,10);
-}
-
-static void ColouriseForthDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
-{
-    st=&styler;
-    cur_pos=startPos;
-    lengthDoc = startPos + length;
-    buffer = new char[length];
-
-#ifdef FORTH_DEBUG
-    f_debug=fopen("c:\\sci.log","at");
-#endif
+static void ColouriseForthDoc(unsigned int startPos, int length, int initStyle, WordList *keywordLists[],
+                            Accessor &styler) {
 
     WordList &control = *keywordLists[0];
     WordList &keyword = *keywordLists[1];
@@ -127,226 +55,122 @@ static void ColouriseForthDoc(unsigned int startPos, int length, int, WordList *
     WordList &preword2 = *keywordLists[4];
     WordList &strings = *keywordLists[5];
 
-    // go through all provided text segment
-    // using the hand-written state machine shown below
-    styler.StartAt(startPos);
-    styler.StartSegment(startPos);
-    while(parse(BL,true)!=0){
-        if(pos0!=pos1){
-            styler.ColourTo(pos0,SCE_FORTH_DEFAULT);
-            styler.ColourTo(pos1-1,SCE_FORTH_DEFAULT);
-        }
-        if(strcmp("\\",buffer)==0){
-            styler.ColourTo(pos1,SCE_FORTH_COMMENT);
-            parse(1,false);
-            styler.ColourTo(pos2,SCE_FORTH_COMMENT);
-        }else if(strcmp("(",buffer)==0){
-            styler.ColourTo(pos1,SCE_FORTH_COMMENT);
-            parse(')',true);
-            if(cur_pos<lengthDoc) cur_pos++;
-            styler.ColourTo(cur_pos,SCE_FORTH_COMMENT);
-        }else if(strcmp("[",buffer)==0){
-            styler.ColourTo(pos1,SCE_FORTH_STRING);
-            parse(']',true);
-            if(cur_pos<lengthDoc) cur_pos++;
-            styler.ColourTo(cur_pos,SCE_FORTH_STRING);
-        }else if(strcmp("{",buffer)==0){
-            styler.ColourTo(pos1,SCE_FORTH_LOCALE);
-            parse('}',false);
-            if(cur_pos<lengthDoc) cur_pos++;
-            styler.ColourTo(cur_pos,SCE_FORTH_LOCALE);
-        }else if(strings.InList(buffer)) {
-            styler.ColourTo(pos1,SCE_FORTH_STRING);
-            parse('"',false);
-            if(cur_pos<lengthDoc) cur_pos++;
-            styler.ColourTo(cur_pos,SCE_FORTH_STRING);
-        }else if(control.InList(buffer)) {
-            styler.ColourTo(pos1,SCE_FORTH_CONTROL);
-            styler.ColourTo(pos2,SCE_FORTH_CONTROL);
-        }else if(keyword.InList(buffer)) {
-            styler.ColourTo(pos1,SCE_FORTH_KEYWORD);
-            styler.ColourTo(pos2,SCE_FORTH_KEYWORD);
-        }else if(defword.InList(buffer)) {
-            styler.ColourTo(pos1,SCE_FORTH_KEYWORD);
-            styler.ColourTo(pos2,SCE_FORTH_KEYWORD);
-            parse(BL,false);
-            styler.ColourTo(pos1-1,SCE_FORTH_DEFAULT);
-            styler.ColourTo(pos1,SCE_FORTH_DEFWORD);
-            styler.ColourTo(pos2,SCE_FORTH_DEFWORD);
-        }else if(preword1.InList(buffer)) {
-            styler.ColourTo(pos1,SCE_FORTH_PREWORD1);
-            parse(BL,false);
-            styler.ColourTo(pos2,SCE_FORTH_PREWORD1);
-        }else if(preword2.InList(buffer)) {
-            styler.ColourTo(pos1,SCE_FORTH_PREWORD2);
-            parse(BL,false);
-            styler.ColourTo(pos2,SCE_FORTH_PREWORD2);
-            parse(BL,false);
-            styler.ColourTo(pos1,SCE_FORTH_STRING);
-            styler.ColourTo(pos2,SCE_FORTH_STRING);
-        }else if(is_number(buffer)){
-            styler.ColourTo(pos1,SCE_FORTH_NUMBER);
-            styler.ColourTo(pos2,SCE_FORTH_NUMBER);
-        }
-    }
-#ifdef FORTH_DEBUG
-    fclose(f_debug);
-#endif
-    delete []buffer;
-    return;
-/*
-                        if(control.InList(buffer)) {
-                            styler.ColourTo(i,SCE_FORTH_CONTROL);
-                        } else if(keyword.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_KEYWORD );
-                        } else if(defword.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_DEFWORD );
-//                            prev_state=SCE_FORTH_DEFWORD
-                        } else if(preword1.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_PREWORD1 );
-//                            state=SCE_FORTH_PREWORD1;
-                        } else if(preword2.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_PREWORD2 );
-                         } else {
-                            styler.ColourTo(i-1,SCE_FORTH_DEFAULT);
-                        }
-*/
-/*
-    chPrev=' ';
-    for (int i = startPos; i < lengthDoc; i++) {
-        char ch = chNext;
-        chNext = styler.SafeGetCharAt(i + 1);
-        if(i!=startPos) chPrev=styler.SafeGetCharAt(i - 1);
-
-        if (styler.IsLeadByte(ch)) {
-            chNext = styler.SafeGetCharAt(i + 2);
-            i++;
-            continue;
-        }
-#ifdef FORTH_DEBUG
-        fprintf(f_debug,"%c %d ",ch,state);
-#endif
-        switch(state) {
-            case SCE_FORTH_DEFAULT:
-                if(is_whitespace(ch)) {
-                    // whitespace is simply ignored here...
-                    styler.ColourTo(i,SCE_FORTH_DEFAULT);
-                    break;
-                } else if( ch == '\\' && is_blank(chNext)) {
-                    // signals the start of an one line comment...
-                    state = SCE_FORTH_COMMENT;
-                    styler.ColourTo(i,SCE_FORTH_COMMENT);
-                } else if( is_whitespace(chPrev) &&  ch == '(' &&  is_whitespace(chNext)) {
-                    // signals the start of a plain comment...
-                    state = SCE_FORTH_COMMENT_ML;
-                    styler.ColourTo(i,SCE_FORTH_COMMENT_ML);
-                } else if( isdigit(ch) ) {
-                    // signals the start of a number
-                    bufferCount = 0;
-                    buffer[bufferCount++] = ch;
-                    state = SCE_FORTH_NUMBER;
-                } else if( !is_whitespace(ch)) {
-                    // signals the start of an identifier
-                    bufferCount = 0;
-                    buffer[bufferCount++] = ch;
-                    state = SCE_FORTH_IDENTIFIER;
-                } else {
-                    // style it the default style..
-                    styler.ColourTo(i,SCE_FORTH_DEFAULT);
-                }
-                break;
-
-            case SCE_FORTH_COMMENT:
-                // if we find a newline here,
-                // we simply go to default state
-                // else continue to work on it...
-                if( ch == '\n' || ch == '\r' ) {
-                    state = SCE_FORTH_DEFAULT;
-                } else {
-                    styler.ColourTo(i,SCE_FORTH_COMMENT);
-                }
-                break;
-
-            case SCE_FORTH_COMMENT_ML:
-                if( ch == ')') {
-                    state = SCE_FORTH_DEFAULT;
-                } else {
-                    styler.ColourTo(i+1,SCE_FORTH_COMMENT_ML);
-                }
-                break;
-
-            case SCE_FORTH_IDENTIFIER:
-                // stay  in CONF_IDENTIFIER state until we find a non-alphanumeric
-                if( !is_whitespace(ch) ) {
-                    buffer[bufferCount++] = ch;
-                } else {
-                    state = SCE_FORTH_DEFAULT;
-                    buffer[bufferCount] = '\0';
-#ifdef FORTH_DEBUG
-        fprintf(f_debug,"\nid %s\n",buffer);
-#endif
-
-                    // check if the buffer contains a keyword,
-                    // and highlight it if it is a keyword...
-//                    switch(prev_state)
-//                    case SCE_FORTH_DEFAULT:
-                        if(control.InList(buffer)) {
-                            styler.ColourTo(i,SCE_FORTH_CONTROL);
-                        } else if(keyword.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_KEYWORD );
-                        } else if(defword.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_DEFWORD );
-//                            prev_state=SCE_FORTH_DEFWORD
-                        } else if(preword1.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_PREWORD1 );
-//                            state=SCE_FORTH_PREWORD1;
-                        } else if(preword2.InList(buffer)) {
-                            styler.ColourTo(i-1,SCE_FORTH_PREWORD2 );
-                         } else {
-                            styler.ColourTo(i-1,SCE_FORTH_DEFAULT);
-                        }
-//                        break;
-//                    case
-
-                    // push back the faulty character
-                    chNext = styler[i--];
-                }
-                break;
-
-            case SCE_FORTH_NUMBER:
-                // stay  in CONF_NUMBER state until we find a non-numeric
-                if( isdigit(ch) ) {
-                    buffer[bufferCount++] = ch;
-                } else {
-                    state = SCE_FORTH_DEFAULT;
-                    buffer[bufferCount] = '\0';
-                    // Colourize here... (normal number)
-                    styler.ColourTo(i-1,SCE_FORTH_NUMBER);
-                    // push back a character
-                    chNext = styler[i--];
-                }
-                break;
-        }
-    }
-#ifdef FORTH_DEBUG
-    fclose(f_debug);
-#endif
-    delete []buffer;
-*/
+	StyleContext sc(startPos, length, initStyle, styler);
+
+	for (; sc.More(); sc.Forward())
+	{
+		// Determine if the current state should terminate.
+		if (sc.state == SCE_FORTH_COMMENT) {
+			if (sc.atLineEnd) {
+				sc.SetState(SCE_FORTH_DEFAULT);
+			}
+		}else if (sc.state == SCE_FORTH_COMMENT_ML) {
+			if (sc.ch == ')') {
+				sc.ForwardSetState(SCE_FORTH_DEFAULT);
+			}
+		}else if (sc.state == SCE_FORTH_IDENTIFIER || sc.state == SCE_FORTH_NUMBER) {
+			// handle numbers here too, because what we thought was a number might
+			// turn out to be a keyword e.g. 2DUP
+			if (IsASpaceChar(sc.ch) ) {
+				char s[100];
+				sc.GetCurrentLowered(s, sizeof(s));
+				int newState = sc.state == SCE_FORTH_NUMBER ? SCE_FORTH_NUMBER : SCE_FORTH_DEFAULT;
+				if (control.InList(s)) {
+					sc.ChangeState(SCE_FORTH_CONTROL);
+				} else if (keyword.InList(s)) {
+					sc.ChangeState(SCE_FORTH_KEYWORD);
+				} else if (defword.InList(s)) {
+					sc.ChangeState(SCE_FORTH_DEFWORD);
+				}  else if (preword1.InList(s)) {
+					sc.ChangeState(SCE_FORTH_PREWORD1);
+				} else if (preword2.InList(s)) {
+					sc.ChangeState(SCE_FORTH_PREWORD2);
+				} else if (strings.InList(s)) {
+					sc.ChangeState(SCE_FORTH_STRING);
+					newState = SCE_FORTH_STRING;
+				}
+				sc.SetState(newState);
+			}
+			if (sc.state == SCE_FORTH_NUMBER) {
+				if (IsASpaceChar(sc.ch)) {
+					sc.SetState(SCE_FORTH_DEFAULT);
+				} else if (!IsANumChar(sc.ch)) {
+					sc.ChangeState(SCE_FORTH_IDENTIFIER);
+				}
+			}
+		}else if (sc.state == SCE_FORTH_STRING) {
+			if (sc.ch == '\"') {
+				sc.ForwardSetState(SCE_FORTH_DEFAULT);
+			}
+		}else if (sc.state == SCE_FORTH_LOCALE) {
+			if (sc.ch == '}') {
+				sc.ForwardSetState(SCE_FORTH_DEFAULT);
+			}
+		}else if (sc.state == SCE_FORTH_DEFWORD) {
+			if (IsASpaceChar(sc.ch)) {
+				sc.SetState(SCE_FORTH_DEFAULT);
+			}
+		}
+
+		// Determine if a new state should be entered.
+		if (sc.state == SCE_FORTH_DEFAULT) {
+			if (sc.ch == '\\'){
+				sc.SetState(SCE_FORTH_COMMENT);
+			} else if (sc.ch == '(' &&
+					(sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
+					(sc.atLineEnd   || IsASpaceChar(sc.chNext))) {
+				sc.SetState(SCE_FORTH_COMMENT_ML);
+			} else if (	(sc.ch == '$' && (isascii(sc.chNext) && isxdigit(sc.chNext))) ) {
+				// number starting with $ is a hex number
+				sc.SetState(SCE_FORTH_NUMBER);
+				while(sc.More() && isascii(sc.chNext) && isxdigit(sc.chNext))
+					sc.Forward();
+			} else if ( (sc.ch == '%' && (isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))) ) {
+				// number starting with % is binary
+				sc.SetState(SCE_FORTH_NUMBER);
+				while(sc.More() && isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))
+					sc.Forward();
+			} else if (	isascii(sc.ch) && 
+						(isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && isascii(sc.chNext) && isxdigit(sc.chNext)) )
+					){
+				sc.SetState(SCE_FORTH_NUMBER);
+			} else if (IsAWordStart(sc.ch)) {
+				sc.SetState(SCE_FORTH_IDENTIFIER);
+			} else if (sc.ch == '{') {
+				sc.SetState(SCE_FORTH_LOCALE);
+			} else if (sc.ch == ':' && isascii(sc.chNext) && isspace(sc.chNext)) {
+				// highlight word definitions e.g.  : GCD ( n n -- n ) ..... ;
+				//                                  ^ ^^^
+				sc.SetState(SCE_FORTH_DEFWORD);
+				while(sc.More() && isascii(sc.chNext) && isspace(sc.chNext))
+					sc.Forward();
+			} else if (sc.ch == ';' &&
+					(sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
+					(sc.atLineEnd   || IsASpaceChar(sc.chNext))	) {
+				// mark the ';' that ends a word
+				sc.SetState(SCE_FORTH_DEFWORD);
+				sc.ForwardSetState(SCE_FORTH_DEFAULT);
+			}
+		}
+
+	}
+	sc.Complete();
 }
 
 static void FoldForthDoc(unsigned int, int, int, WordList *[],
-                       Accessor &) {
+						Accessor &) {
 }
 
 static const char * const forthWordLists[] = {
-            "control keywords",
-            "keywords",
-            "definition words",
-            "prewords with one argument",
-            "prewords with two arguments",
-            "string definition keywords",
-            0,
-        };
-
-LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth",FoldForthDoc,forthWordLists);
+			"control keywords",
+			"keywords",
+			"definition words",
+			"prewords with one argument",
+			"prewords with two arguments",
+			"string definition keywords",
+			0,
+		};
+
+LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth", FoldForthDoc, forthWordLists);
+
+ 	  	 
diff --git a/plugins/scintilla/scintilla/LexFortran.cxx b/plugins/scintilla/scintilla/LexFortran.cxx
index e66b37e..0b3f277 100644
--- a/plugins/scintilla/scintilla/LexFortran.cxx
+++ b/plugins/scintilla/scintilla/LexFortran.cxx
@@ -83,7 +83,7 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
 		// Handle the fix format generically
 		int toLineStart = sc.currentPos - posLineStart;
 		if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) {
-			if (toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*') || sc.ch == '!') {
+			if ((toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*')) || sc.ch == '!') {
                 if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") || sc.MatchIgnoreCase("!dec$") ||
                     sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") || sc.MatchIgnoreCase("!dir$") ||
                     sc.MatchIgnoreCase("cms$")  || sc.MatchIgnoreCase("*ms$")  || sc.MatchIgnoreCase("!ms$")  ||
@@ -252,7 +252,7 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
 				lev = 0;
 			else
 				lev = 1;
-	} else if (strcmp(s, "end") == 0 && chNextNonBlank != '='
+	} else if ((strcmp(s, "end") == 0 && chNextNonBlank != '=')
 		|| strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
 		|| strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
 		|| strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0
diff --git a/plugins/scintilla/scintilla/LexHTML.cxx b/plugins/scintilla/scintilla/LexHTML.cxx
index 6d16c53..a8d7e27 100644
--- a/plugins/scintilla/scintilla/LexHTML.cxx
+++ b/plugins/scintilla/scintilla/LexHTML.cxx
@@ -274,17 +274,30 @@ static int classifyTagHTML(unsigned int start, unsigned int end,
 	s[i] = '\0';
 
 	// No keywords -> all are known
-	// Name of a closing tag starts at s + 1
 	char chAttr = SCE_H_TAGUNKNOWN;
 	if (s[0] == '!') {
 		chAttr = SCE_H_SGML_DEFAULT;
-	} else if (!keywords || keywords.InList(s[0] == '/' ? s + 1 : s)) {
+	} else if (!keywords || keywords.InList(s)) {
 		chAttr = SCE_H_TAG;
 	}
 	styler.ColourTo(end, chAttr);
 	if (chAttr == SCE_H_TAG) {
 		if (allowScripts && 0 == strcmp(s, "script")) {
-			chAttr = SCE_H_SCRIPT;
+			// check to see if this is a self-closing tag by sniffing ahead
+			bool isSelfClose = false;
+			for (unsigned int cPos = end; cPos <= end + 100; cPos++) {
+				char ch = styler.SafeGetCharAt(cPos, '\0');
+				if (ch == '\0' || ch == '>')
+					break;
+				else if (ch == '/' && styler.SafeGetCharAt(cPos + 1, '\0') == '>') {
+					isSelfClose = true;
+					break;
+				}
+			}
+
+			// do not enter a script state if the tag self-closed
+			if (!isSelfClose)
+				chAttr = SCE_H_SCRIPT;
 		} else if (!isXml && 0 == strcmp(s, "comment")) {
 			chAttr = SCE_H_COMMENT;
 		}
@@ -561,6 +574,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 	} else {
 		// Default client and ASP scripting language is JavaScript
 		lineState = eScriptJS << 8;
+
+		// property asp.default.language 
+		//	Script in ASP code is initially assumed to be in JavaScript. 
+		//	To change this to VBScript set asp.default.language to 2. Python is 3.
 		lineState |= styler.GetPropertyInt("asp.default.language", eScriptJS) << 4;
 	}
 	script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode
@@ -577,13 +594,37 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 		scriptLanguage = eScriptComment;
 	}
 
+	// property fold.html 
+	//	Folding is turned on or off for HTML and XML files with this option. 
+	//	The fold option must also be on for folding to occur.
 	const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0;
+
 	const bool fold = foldHTML && styler.GetPropertyInt("fold", 0);
+
+	// property fold.html.preprocessor 
+	//	Folding is turned on or off for scripts embedded in HTML files with this option. 
+	//	The default is on.
 	const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1);
+
 	const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+
+	// property fold.hypertext.comment 
+	//	Allow folding for comments in scripts embedded in HTML. 
+	//	The default is off. 
 	const bool foldComment = fold && styler.GetPropertyInt("fold.hypertext.comment", 0) != 0;
+
+	// property fold.hypertext.heredoc 
+	//	Allow folding for heredocs in scripts embedded in HTML. 
+	//	The default is off.  
 	const bool foldHeredoc = fold && styler.GetPropertyInt("fold.hypertext.heredoc", 0) != 0;
+
+	// property html.tags.case.sensitive 
+	//	For XML and HTML, setting this property to 1 will make tags match in a case 
+	//	sensitive way which is the expected behaviour for XML and XHTML. 
 	const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
+
+	// property lexer.xml.allow.scripts 
+	//	Set to 0 to disable scripts in XML.  
 	const bool allowScripts = styler.GetPropertyInt("lexer.xml.allow.scripts", 1) != 0;
 
 	const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true);
@@ -855,7 +896,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 				state = SCE_H_SGML_COMMAND; // wait for a pending command
 			}
 			// fold whole tag (-- when closing the tag)
-			if (foldHTMLPreprocessor)
+			if (foldHTMLPreprocessor || (state == SCE_H_COMMENT))
 				levelCurrent++;
 			continue;
 		}
@@ -1091,7 +1132,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 			}
 			if (ch != '#' && !(isascii(ch) && isalnum(ch))	// Should check that '#' follows '&', but it is unlikely anyway...
 				&& ch != '.' && ch != '-' && ch != '_' && ch != ':') { // valid in XML
-				styler.ColourTo(i, SCE_H_TAGUNKNOWN);
+				if (!isascii(ch))	// Possibly start of a multibyte character so don't allow this byte to be in entity style
+					styler.ColourTo(i-1, SCE_H_TAGUNKNOWN);
+				else
+					styler.ColourTo(i, SCE_H_TAGUNKNOWN);
 				state = SCE_H_DEFAULT;
 			}
 			break;
@@ -1856,299 +1900,6 @@ static void ColouriseHTMLDoc(unsigned int startPos, int length, int initStyle, W
 	ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, false);
 }
 
-static bool isASPScript(int state) {
-	return
-		(state >= SCE_HJA_START && state <= SCE_HJA_REGEX) ||
-		(state >= SCE_HBA_START && state <= SCE_HBA_STRINGEOL) ||
-		(state >= SCE_HPA_DEFAULT && state <= SCE_HPA_IDENTIFIER);
-}
-
-static void ColouriseHBAPiece(StyleContext &sc, WordList *keywordlists[]) {
-	WordList &keywordsVBS = *keywordlists[2];
-	if (sc.state == SCE_HBA_WORD) {
-		if (!IsAWordChar(sc.ch)) {
-			char s[100];
-			sc.GetCurrentLowered(s, sizeof(s));
-			if (keywordsVBS.InList(s)) {
-				if (strcmp(s, "rem") == 0) {
-					sc.ChangeState(SCE_HBA_COMMENTLINE);
-					if (sc.atLineEnd) {
-						sc.SetState(SCE_HBA_DEFAULT);
-					}
-				} else {
-					sc.SetState(SCE_HBA_DEFAULT);
-				}
-			} else {
-				sc.ChangeState(SCE_HBA_IDENTIFIER);
-				sc.SetState(SCE_HBA_DEFAULT);
-			}
-		}
-	} else if (sc.state == SCE_HBA_NUMBER) {
-		if (!IsAWordChar(sc.ch)) {
-			sc.SetState(SCE_HBA_DEFAULT);
-		}
-	} else if (sc.state == SCE_HBA_STRING) {
-		if (sc.ch == '\"') {
-			sc.ForwardSetState(SCE_HBA_DEFAULT);
-		} else if (sc.ch == '\r' || sc.ch == '\n') {
-			sc.ChangeState(SCE_HBA_STRINGEOL);
-			sc.ForwardSetState(SCE_HBA_DEFAULT);
-		}
-	} else if (sc.state == SCE_HBA_COMMENTLINE) {
-		if (sc.ch == '\r' || sc.ch == '\n') {
-			sc.SetState(SCE_HBA_DEFAULT);
-		}
-	}
-
-	if (sc.state == SCE_HBA_DEFAULT) {
-		if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
-			sc.SetState(SCE_HBA_NUMBER);
-		} else if (IsAWordStart(sc.ch)) {
-			sc.SetState(SCE_HBA_WORD);
-		} else if (sc.ch == '\'') {
-			sc.SetState(SCE_HBA_COMMENTLINE);
-		} else if (sc.ch == '\"') {
-			sc.SetState(SCE_HBA_STRING);
-		}
-	}
-}
-
-static void ColouriseHTMLPiece(StyleContext &sc, WordList *keywordlists[]) {
-	WordList &keywordsTags = *keywordlists[0];
-	if (sc.state == SCE_H_COMMENT) {
-		if (sc.Match("-->")) {
-			sc.Forward();
-			sc.Forward();
-			sc.ForwardSetState(SCE_H_DEFAULT);
-		}
-	} else if (sc.state == SCE_H_ENTITY) {
-		if (sc.ch == ';') {
-			sc.ForwardSetState(SCE_H_DEFAULT);
-		} else if (sc.ch != '#' && (sc.ch < 0x80) && !isalnum(sc.ch)	// Should check that '#' follows '&', but it is unlikely anyway...
-			&& sc.ch != '.' && sc.ch != '-' && sc.ch != '_' && sc.ch != ':') { // valid in XML
-			sc.ChangeState(SCE_H_TAGUNKNOWN);
-			sc.SetState(SCE_H_DEFAULT);
-		}
-	} else if (sc.state == SCE_H_TAGUNKNOWN) {
-		if (!ishtmlwordchar(sc.ch) && !((sc.ch == '/') && (sc.chPrev == '<')) && sc.ch != '[') {
-			char s[100];
-			sc.GetCurrentLowered(s, sizeof(s));
-			if (s[1] == '/') {
-				if (keywordsTags.InList(s + 2)) {
-					sc.ChangeState(SCE_H_TAG);
-				}
-			} else {
-				if (keywordsTags.InList(s + 1)) {
-					sc.ChangeState(SCE_H_TAG);
-				}
-			}
-			if (sc.ch == '>') {
-				sc.ForwardSetState(SCE_H_DEFAULT);
-			} else if (sc.Match('/', '>')) {
-				sc.SetState(SCE_H_TAGEND);
-				sc.Forward();
-				sc.ForwardSetState(SCE_H_DEFAULT);
-			} else {
-				sc.SetState(SCE_H_OTHER);
-			}
-		}
-	} else if (sc.state == SCE_H_ATTRIBUTE) {
-		if (!ishtmlwordchar(sc.ch)) {
-			char s[100];
-			sc.GetCurrentLowered(s, sizeof(s));
-			if (!keywordsTags.InList(s)) {
-				sc.ChangeState(SCE_H_ATTRIBUTEUNKNOWN);
-			}
-			sc.SetState(SCE_H_OTHER);
-		}
-	} else if (sc.state == SCE_H_OTHER) {
-		if (sc.ch == '>') {
-			sc.SetState(SCE_H_TAG);
-			sc.ForwardSetState(SCE_H_DEFAULT);
-		} else if (sc.Match('/', '>')) {
-			sc.SetState(SCE_H_TAG);
-			sc.Forward();
-			sc.ForwardSetState(SCE_H_DEFAULT);
-		} else if (sc.chPrev == '=') {
-			sc.SetState(SCE_H_VALUE);
-		}
-	} else if (sc.state == SCE_H_DOUBLESTRING) {
-		if (sc.ch == '\"') {
-			sc.ForwardSetState(SCE_H_OTHER);
-		}
-	} else if (sc.state == SCE_H_SINGLESTRING) {
-		if (sc.ch == '\'') {
-			sc.ForwardSetState(SCE_H_OTHER);
-		}
-	} else if (sc.state == SCE_H_NUMBER) {
-		if (!IsADigit(sc.ch)) {
-			sc.SetState(SCE_H_OTHER);
-		}
-	}
-
-	if (sc.state == SCE_H_DEFAULT) {
-		if (sc.ch == '<') {
-			if (sc.Match("<!--"))
-				sc.SetState(SCE_H_COMMENT);
-			else
-				sc.SetState(SCE_H_TAGUNKNOWN);
-		} else if (sc.ch == '&') {
-			sc.SetState(SCE_H_ENTITY);
-		}
-	} else if ((sc.state == SCE_H_OTHER) || (sc.state == SCE_H_VALUE)) {
-		if (sc.ch == '\"' && sc.chPrev == '=') {
-			sc.SetState(SCE_H_DOUBLESTRING);
-		} else if (sc.ch == '\'' && sc.chPrev == '=') {
-			sc.SetState(SCE_H_SINGLESTRING);
-		} else if (IsADigit(sc.ch)) {
-			sc.SetState(SCE_H_NUMBER);
-		} else if (sc.ch == '>') {
-			sc.SetState(SCE_H_TAG);
-			sc.ForwardSetState(SCE_H_DEFAULT);
-		} else if (ishtmlwordchar(sc.ch)) {
-			sc.SetState(SCE_H_ATTRIBUTE);
-		}
-	}
-}
-
-static void ColouriseASPPiece(StyleContext &sc, WordList *keywordlists[]) {
-	// Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
-	if ((sc.state == SCE_H_ASPAT || isASPScript(sc.state)) && sc.Match('%', '>')) {
-		sc.SetState(SCE_H_ASP);
-		sc.Forward();
-		sc.ForwardSetState(SCE_H_DEFAULT);
-	}
-
-	// Handle some ASP script
-	if (sc.state >= SCE_HBA_START && sc.state <= SCE_HBA_STRINGEOL) {
-		ColouriseHBAPiece(sc, keywordlists);
-	} else if (sc.state >= SCE_H_DEFAULT && sc.state <= SCE_H_SGML_BLOCK_DEFAULT) {
-		ColouriseHTMLPiece(sc, keywordlists);
-	}
-
-	// Enter new sc.state
-	if ((sc.state == SCE_H_DEFAULT) || (sc.state == SCE_H_TAGUNKNOWN)) {
-		if (sc.Match('<', '%')) {
-			if (sc.state == SCE_H_TAGUNKNOWN)
-				sc.ChangeState(SCE_H_ASP);
-			else
-				sc.SetState(SCE_H_ASP);
-			sc.Forward();
-			sc.Forward();
-			if (sc.ch == '@') {
-				sc.ForwardSetState(SCE_H_ASPAT);
-			} else {
-				if (sc.ch == '=') {
-					sc.Forward();
-				}
-				sc.SetState(SCE_HBA_DEFAULT);
-			}
-		}
-	}
-}
-
-static void ColouriseASPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                                  Accessor &styler) {
-	// Lexer for HTML requires more lexical states (8 bits worth) than most lexers
-	StyleContext sc(startPos, length, initStyle, styler, static_cast<char>(STYLE_MAX));
-	for (; sc.More(); sc.Forward()) {
-		ColouriseASPPiece(sc, keywordlists);
-	}
-	sc.Complete();
-}
-
-static void ColourisePHPPiece(StyleContext &sc, WordList *keywordlists[]) {
-	// Possibly exit current state to either SCE_H_DEFAULT or SCE_HBA_DEFAULT
-	if (sc.state >= SCE_HPHP_DEFAULT && sc.state <= SCE_HPHP_OPERATOR) {
-		if (!isPHPStringState(sc.state) &&
-			(sc.state != SCE_HPHP_COMMENT) &&
-			(sc.Match('?', '>'))) {
-			sc.SetState(SCE_H_QUESTION);
-			sc.Forward();
-			sc.ForwardSetState(SCE_H_DEFAULT);
-		}
-	}
-
-	if (sc.state >= SCE_H_DEFAULT && sc.state <= SCE_H_SGML_BLOCK_DEFAULT) {
-		ColouriseHTMLPiece(sc, keywordlists);
-	}
-
-	// Handle some PHP script
-	if (sc.state == SCE_HPHP_WORD) {
-		if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
-			sc.SetState(SCE_HPHP_DEFAULT);
-		}
-	} else if (sc.state == SCE_HPHP_COMMENTLINE) {
-		if (sc.ch == '\r' || sc.ch == '\n') {
-			sc.SetState(SCE_HPHP_DEFAULT);
-		}
-	} else if (sc.state == SCE_HPHP_COMMENT) {
-		if (sc.Match('*', '/')) {
-			sc.Forward();
-			sc.Forward();
-			sc.SetState(SCE_HPHP_DEFAULT);
-		}
-	} else if (sc.state == SCE_HPHP_HSTRING) {
-		if (sc.ch == '\"') {
-			sc.ForwardSetState(SCE_HPHP_DEFAULT);
-		}
-	} else if (sc.state == SCE_HPHP_SIMPLESTRING) {
-		if (sc.ch == '\'') {
-			sc.ForwardSetState(SCE_HPHP_DEFAULT);
-		}
-	} else if (sc.state == SCE_HPHP_VARIABLE) {
-		if (!IsPhpWordChar(static_cast<char>(sc.ch))) {
-			sc.SetState(SCE_HPHP_DEFAULT);
-		}
-	} else if (sc.state == SCE_HPHP_OPERATOR) {
-		sc.SetState(SCE_HPHP_DEFAULT);
-	}
-
-	// Enter new sc.state
-	if ((sc.state == SCE_H_DEFAULT) || (sc.state == SCE_H_TAGUNKNOWN)) {
-		if (sc.Match("<?php")) {
-			sc.SetState(SCE_H_QUESTION);
-			sc.Forward();
-			sc.Forward();
-			sc.Forward();
-			sc.Forward();
-			sc.Forward();
-			sc.SetState(SCE_HPHP_DEFAULT);
-		}
-	}
-	if (sc.state == SCE_HPHP_DEFAULT) {
-		if (IsPhpWordStart(static_cast<char>(sc.ch))) {
-			sc.SetState(SCE_HPHP_WORD);
-		} else if (sc.ch == '#') {
-			sc.SetState(SCE_HPHP_COMMENTLINE);
-		} else if (sc.Match("<!--")) {
-			sc.SetState(SCE_HPHP_COMMENTLINE);
-		} else if (sc.Match('/', '/')) {
-			sc.SetState(SCE_HPHP_COMMENTLINE);
-		} else if (sc.Match('/', '*')) {
-			sc.SetState(SCE_HPHP_COMMENT);
-		} else if (sc.ch == '\"') {
-			sc.SetState(SCE_HPHP_HSTRING);
-		} else if (sc.ch == '\'') {
-			sc.SetState(SCE_HPHP_SIMPLESTRING);
-		} else if (sc.ch == '$' && IsPhpWordStart(static_cast<char>(sc.chNext))) {
-			sc.SetState(SCE_HPHP_VARIABLE);
-		} else if (IsOperator(static_cast<char>(sc.ch))) {
-			sc.SetState(SCE_HPHP_OPERATOR);
-		}
-	}
-}
-
-static void ColourisePHPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                                  Accessor &styler) {
-	// Lexer for HTML requires more lexical states (8 bits worth) than most lexers
-	StyleContext sc(startPos, length, initStyle, styler, static_cast<char>(STYLE_MAX));
-	for (; sc.More(); sc.Forward()) {
-		ColourisePHPPiece(sc, keywordlists);
-	}
-	sc.Complete();
-}
-
 static void ColourisePHPScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
         Accessor &styler) {
 	if (startPos == 0)
@@ -2178,7 +1929,4 @@ static const char * const phpscriptWordListDesc[] = {
 
 LexerModule lmHTML(SCLEX_HTML, ColouriseHTMLDoc, "hypertext", 0, htmlWordListDesc, 8);
 LexerModule lmXML(SCLEX_XML, ColouriseXMLDoc, "xml", 0, htmlWordListDesc, 8);
-// SCLEX_ASP and SCLEX_PHP should not be used in new code: use SCLEX_HTML instead.
-LexerModule lmASP(SCLEX_ASP, ColouriseASPDoc, "asp", 0, htmlWordListDesc, 8);
-LexerModule lmPHP(SCLEX_PHP, ColourisePHPDoc, "php", 0, htmlWordListDesc, 8);
 LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc, 8);
diff --git a/plugins/scintilla/scintilla/LexHaskell.cxx b/plugins/scintilla/scintilla/LexHaskell.cxx
index 3213bd5..b528f3f 100644
--- a/plugins/scintilla/scintilla/LexHaskell.cxx
+++ b/plugins/scintilla/scintilla/LexHaskell.cxx
@@ -25,6 +25,7 @@
 #include "Platform.h"
 
 #include "PropSet.h"
+#include "PropSetSimple.h"
 #include "Accessor.h"
 #include "StyleContext.h"
 #include "KeyWords.h"
@@ -225,7 +226,7 @@ static const char* LexerName = "haskell";
 void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length, int initStyle,
                         char *words[], WindowID window, char *props)
 {
-   PropSet ps;
+   PropSetSimple ps;
    ps.SetMultiple(props);
    WindowAccessor wa(window, ps);
 
diff --git a/plugins/scintilla/scintilla/LexInno.cxx b/plugins/scintilla/scintilla/LexInno.cxx
index 3af9b2f..6d1102c 100644
--- a/plugins/scintilla/scintilla/LexInno.cxx
+++ b/plugins/scintilla/scintilla/LexInno.cxx
@@ -13,6 +13,7 @@
 
 #include "Platform.h"
 
+#include "CharClassify.h"
 #include "PropSet.h"
 #include "Accessor.h"
 #include "StyleContext.h"
@@ -33,6 +34,8 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
 	char *buffer = new char[length];
 	int bufferCount = 0;
 	bool isBOL, isEOL, isWS, isBOLWS = 0;
+	bool isCode = false;
+	bool isCStyleComment = false;
 
 	WordList &sectionKeywords = *keywordLists[0];
 	WordList &standardKeywords = *keywordLists[1];
@@ -63,7 +66,7 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
 
 		switch(state) {
 			case SCE_INNO_DEFAULT:
-				if (ch == ';' && isBOLWS) {
+				if (!isCode && ch == ';' && isBOLWS) {
 					// Start of a comment
 					state = SCE_INNO_COMMENT;
 				} else if (ch == '[' && isBOLWS) {
@@ -73,13 +76,17 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
 				} else if (ch == '#' && isBOLWS) {
 					// Start of a preprocessor directive
 					state = SCE_INNO_PREPROC;
-				} else if (ch == '{' && chNext == '#') {
-					// Start of a preprocessor inline directive
-					state = SCE_INNO_PREPROC_INLINE;
-				} else if ((ch == '{' && (chNext == ' ' || chNext == '\t'))
-					   || (ch == '(' && chNext == '*')) {
+				} else if (!isCode && ch == '{' && chNext != '{' && chPrev != '{') {
+					// Start of an inline expansion
+					state = SCE_INNO_INLINE_EXPANSION;
+				} else if (isCode && (ch == '{' || (ch == '(' && chNext == '*'))) {
 					// Start of a Pascal comment
 					state = SCE_INNO_COMMENT_PASCAL;
+					isCStyleComment = false;
+				} else if (isCode && ch == '/' && chNext == '/') {
+					// Apparently, C-style comments are legal, too
+					state = SCE_INNO_COMMENT_PASCAL;
+					isCStyleComment = true;
 				} else if (ch == '"') {
 					// Start of a double-quote string
 					state = SCE_INNO_STRING_DOUBLE;
@@ -112,13 +119,13 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
 					buffer[bufferCount] = '\0';
 
 					// Check if the buffer contains a keyword
-					if (standardKeywords.InList(buffer)) {
+					if (!isCode && standardKeywords.InList(buffer)) {
 						styler.ColourTo(i-1,SCE_INNO_KEYWORD);
-					} else if (parameterKeywords.InList(buffer)) {
+					} else if (!isCode && parameterKeywords.InList(buffer)) {
 						styler.ColourTo(i-1,SCE_INNO_PARAMETER);
-					} else if (pascalKeywords.InList(buffer)) {
+					} else if (isCode && pascalKeywords.InList(buffer)) {
 						styler.ColourTo(i-1,SCE_INNO_KEYWORD_PASCAL);
-					} else if (userKeywords.InList(buffer)) {
+					} else if (!isCode && userKeywords.InList(buffer)) {
 						styler.ColourTo(i-1,SCE_INNO_KEYWORD_USER);
 					} else {
 						styler.ColourTo(i-1,SCE_INNO_DEFAULT);
@@ -138,6 +145,7 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
 					// Check if the buffer contains a section name
 					if (sectionKeywords.InList(buffer)) {
 						styler.ColourTo(i,SCE_INNO_SECTION);
+						isCode = !CompareCaseInsensitive(buffer, "code");
 					} else {
 						styler.ColourTo(i,SCE_INNO_DEFAULT);
 					}
@@ -187,10 +195,10 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
 				}
 				break;
 
-			case SCE_INNO_PREPROC_INLINE:
+			case SCE_INNO_INLINE_EXPANSION:
 				if (ch == '}') {
 					state = SCE_INNO_DEFAULT;
-					styler.ColourTo(i,SCE_INNO_PREPROC_INLINE);
+					styler.ColourTo(i,SCE_INNO_INLINE_EXPANSION);
 				} else if (isEOL) {
 					state = SCE_INNO_DEFAULT;
 					styler.ColourTo(i,SCE_INNO_DEFAULT);
@@ -198,12 +206,19 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
 				break;
 
 			case SCE_INNO_COMMENT_PASCAL:
-				if (ch == '}' || (ch == ')' && chPrev == '*')) {
-					state = SCE_INNO_DEFAULT;
-					styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
-				} else if (isEOL) {
-					state = SCE_INNO_DEFAULT;
-					styler.ColourTo(i,SCE_INNO_DEFAULT);
+				if (isCStyleComment) {
+					if (isEOL) {
+						state = SCE_INNO_DEFAULT;
+						styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
+					}
+				} else {
+					if (ch == '}' || (ch == ')' && chPrev == '*')) {
+						state = SCE_INNO_DEFAULT;
+						styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);
+					} else if (isEOL) {
+						state = SCE_INNO_DEFAULT;
+						styler.ColourTo(i,SCE_INNO_DEFAULT);
+					}
 				}
 				break;
 
diff --git a/plugins/scintilla/scintilla/LexLisp.cxx b/plugins/scintilla/scintilla/LexLisp.cxx
index 1072e13..e1d06cb 100755
--- a/plugins/scintilla/scintilla/LexLisp.cxx
+++ b/plugins/scintilla/scintilla/LexLisp.cxx
@@ -32,7 +32,7 @@ using namespace Scintilla;
 static inline bool isLispoperator(char ch) {
 	if (isascii(ch) && isalnum(ch))
 		return false;
-	if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' )
+	if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '{' || ch == '}')
 		return true;
 	return false;
 }
@@ -100,6 +100,9 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W
 				styler.ColourTo(i - 1, state);
 				radix = -1;
 				state = SCE_LISP_MACRO_DISPATCH;
+			} else if (ch == ':' && isLispwordstart(chNext)) {
+				styler.ColourTo(i - 1, state);
+				state = SCE_LISP_SYMBOL;
 			} else if (isLispwordstart(ch)) {
 				styler.ColourTo(i - 1, state);
 				state = SCE_LISP_IDENTIFIER;
@@ -243,9 +246,9 @@ static void FoldLispDoc(unsigned int startPos, int length, int /* initStyle */,
 		styleNext = styler.StyleAt(i + 1);
 		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 		if (style == SCE_LISP_OPERATOR) {
-			if (ch == '(') {
+			if (ch == '(' || ch == '[' || ch == '{') {
 				levelCurrent++;
-			} else if (ch == ')') {
+			} else if (ch == ')' || ch == ']' || ch == '}') {
 				levelCurrent--;
 			}
 		}
diff --git a/plugins/scintilla/scintilla/LexMPT.cxx b/plugins/scintilla/scintilla/LexMPT.cxx
index 93b8cab..b0099ff 100644
--- a/plugins/scintilla/scintilla/LexMPT.cxx
+++ b/plugins/scintilla/scintilla/LexMPT.cxx
@@ -11,6 +11,9 @@
 #include <stdio.h>
 #include <ctype.h>
 #include <stdlib.h>
+
+#include <string>
+
 #include "Platform.h"
 
 #include "PropSet.h"
@@ -18,13 +21,12 @@
 #include "KeyWords.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
-#include "SString.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-static int GetLotLineState(SString &line) {
+static int GetLotLineState(std::string &line) {
 	if (line.length()) {
 		// Most of the time the first non-blank character in line determines that line's type
 		// Now finds the first non-blank character
@@ -54,13 +56,13 @@ static int GetLotLineState(SString &line) {
 
 		default:  // Any other line
 			// Checks for message at the end of lot file
-			if (line.contains("PASSED")) {
+			if (line.find("PASSED") != std::string::npos) {
 				return SCE_LOT_PASS;
 			}
-			else if (line.contains("FAILED")) {
+			else if (line.find("FAILED") != std::string::npos) {
 				return SCE_LOT_FAIL;
 			}
-			else if (line.contains("ABORTED")) {
+			else if (line.find("ABORTED") != std::string::npos) {
 				return SCE_LOT_ABORT;
 			}
 			else {
@@ -78,8 +80,8 @@ static void ColourizeLotDoc(unsigned int startPos, int length, int, WordList *[]
 	styler.StartSegment(startPos);
 	bool atLineStart = true;// Arms the 'at line start' flag
 	char chNext = styler.SafeGetCharAt(startPos);
-	SString line("");
-	line.setsizegrowth(256);	// Lot lines are less than 256 chars long most of the time. This should avoid reallocations
+	std::string line("");
+	line.reserve(256);	// Lot lines are less than 256 chars long most of the time. This should avoid reallocations
 
 	// Styles LOT document
 	unsigned int i;			// Declared here because it's used after the for loop
diff --git a/plugins/scintilla/scintilla/LexMagik.cxx b/plugins/scintilla/scintilla/LexMagik.cxx
index 8ab4d08..c6f6585 100644
--- a/plugins/scintilla/scintilla/LexMagik.cxx
+++ b/plugins/scintilla/scintilla/LexMagik.cxx
@@ -62,7 +62,7 @@ static inline bool IsAlphaSym(int ch) {
  * \return True if ch is a character, False otherwise
  */
 static inline bool IsAlNum(int ch) {
-    return ((ch > '0' && ch < '9') || IsAlpha(ch));
+    return ((ch >= '0' && ch <= '9') || IsAlpha(ch));
 }
 
 /**
diff --git a/plugins/scintilla/scintilla/LexMySQL.cxx b/plugins/scintilla/scintilla/LexMySQL.cxx
index 742ff43..f29a183 100644
--- a/plugins/scintilla/scintilla/LexMySQL.cxx
+++ b/plugins/scintilla/scintilla/LexMySQL.cxx
@@ -1,11 +1,14 @@
-// Scintilla source code edit control
-/** @file LexMySQL.cxx
- ** Lexer for MySQL
- **/
-// Adopted from LexSQL.cxx by Anders Karlsson <anders mysql com>
-// Original work by Neil Hodgson <neilh scintilla org>
-// Copyright 1998-2005 by Neil Hodgson <neilh scintilla org>
-// The License.txt file describes the conditions under which this software may be distributed.
+/**
+ * Scintilla source code edit control
+ * @file LexMySQL.cxx
+ * Lexer for MySQL
+ *
+ * Improved by Mike Lischke <mike lischke sun com>
+ * Adopted from LexSQL.cxx by Anders Karlsson <anders mysql com>
+ * Original work by Neil Hodgson <neilh scintilla org>
+ * Copyright 1998-2005 by Neil Hodgson <neilh scintilla org>
+ * The License.txt file describes the conditions under which this software may be distributed.
+ */
 
 #include <stdlib.h>
 #include <string.h>
@@ -49,287 +52,432 @@ static inline bool IsANumberChar(int ch) {
              ch == '.' || ch == '-' || ch == '+');
 }
 
-static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                            Accessor &styler) {
+//--------------------------------------------------------------------------------------------------
+
+/**
+ * Check if the current content context represent a keyword and set the context state if so.
+ */
+static void CheckForKeyword(StyleContext& sc, WordList* keywordlists[])
+{
+  int length = sc.LengthCurrent() + 1; // +1 for the next char
+  char* s = new char[length];
+  sc.GetCurrentLowered(s, length);
+  if (keywordlists[0]->InList(s))
+    sc.ChangeState(SCE_MYSQL_MAJORKEYWORD);
+  else
+    if (keywordlists[1]->InList(s))
+      sc.ChangeState(SCE_MYSQL_KEYWORD);
+    else
+      if (keywordlists[2]->InList(s))
+        sc.ChangeState(SCE_MYSQL_DATABASEOBJECT);
+      else
+        if (keywordlists[3]->InList(s))
+          sc.ChangeState(SCE_MYSQL_FUNCTION);
+        else
+          if (keywordlists[5]->InList(s))
+            sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD);
+          else
+            if (keywordlists[6]->InList(s))
+              sc.ChangeState(SCE_MYSQL_USER1);
+            else
+              if (keywordlists[7]->InList(s))
+                sc.ChangeState(SCE_MYSQL_USER2);
+              else
+                if (keywordlists[8]->InList(s))
+                  sc.ChangeState(SCE_MYSQL_USER3);
+  delete [] s;
+}
 
-	WordList &major_keywords = *keywordlists[0];
-	WordList &keywords = *keywordlists[1];
-	WordList &database_objects = *keywordlists[2];
-	WordList &functions = *keywordlists[3];
-	WordList &system_variables = *keywordlists[4];
-	WordList &procedure_keywords = *keywordlists[5];
-	WordList &kw_user1 = *keywordlists[6];
-	WordList &kw_user2 = *keywordlists[7];
-	WordList &kw_user3 = *keywordlists[8];
+//--------------------------------------------------------------------------------------------------
 
+static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler)
+{
 	StyleContext sc(startPos, length, initStyle, styler);
 
-	for (; sc.More(); sc.Forward()) {
+	for (; sc.More(); sc.Forward())
+  {
 		// Determine if the current state should terminate.
-		switch (sc.state) {
-		case SCE_MYSQL_OPERATOR:
-			sc.SetState(SCE_MYSQL_DEFAULT);
-			break;
-		case SCE_MYSQL_NUMBER:
-			// We stop the number definition on non-numerical non-dot non-eE non-sign char
-			if (!IsANumberChar(sc.ch)) {
-				sc.SetState(SCE_MYSQL_DEFAULT);
-			}
-			break;
-		case SCE_MYSQL_IDENTIFIER:
-			if (!IsAWordChar(sc.ch)) {
-				int nextState = SCE_MYSQL_DEFAULT;
-				char s[1000];
-				sc.GetCurrentLowered(s, sizeof(s));
-				if (major_keywords.InList(s)) {
-					sc.ChangeState(SCE_MYSQL_MAJORKEYWORD);
-				} else if (keywords.InList(s)) {
-					sc.ChangeState(SCE_MYSQL_KEYWORD);
-				} else if (database_objects.InList(s)) {
-					sc.ChangeState(SCE_MYSQL_DATABASEOBJECT);
-				} else if (functions.InList(s)) {
-					sc.ChangeState(SCE_MYSQL_FUNCTION);
-				} else if (procedure_keywords.InList(s)) {
-					sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD);
-				} else if (kw_user1.InList(s)) {
-					sc.ChangeState(SCE_MYSQL_USER1);
-				} else if (kw_user2.InList(s)) {
-					sc.ChangeState(SCE_MYSQL_USER2);
-				} else if (kw_user3.InList(s)) {
-					sc.ChangeState(SCE_MYSQL_USER3);
-				}
-				sc.SetState(nextState);
-			}
-			break;
-		case SCE_MYSQL_VARIABLE:
-			if (!IsAWordChar(sc.ch)) {
-				sc.SetState(SCE_MYSQL_DEFAULT);
-			}
-			break;
-		case SCE_MYSQL_SYSTEMVARIABLE:
-			if (!IsAWordChar(sc.ch)) {
-				char s[1000];
-				sc.GetCurrentLowered(s, sizeof(s));
-// Check for known system variables here.
-				if (system_variables.InList(&s[2])) {
-					sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE);
-				}
-				sc.SetState(SCE_MYSQL_DEFAULT);
-			}
-			break;
-		case SCE_MYSQL_QUOTEDIDENTIFIER:
-			if (sc.ch == 0x60) {
-				if (sc.chNext == 0x60) {
-					sc.Forward();	// Ignore it
-				} else {
-					sc.ForwardSetState(SCE_MYSQL_DEFAULT);
-				}
-			}
-			break;
-		case SCE_MYSQL_COMMENT:
-			if (sc.Match('*', '/')) {
-				sc.Forward();
-				sc.ForwardSetState(SCE_MYSQL_DEFAULT);
-			}
-			break;
-		case SCE_MYSQL_COMMENTLINE:
-			if (sc.atLineStart) {
-				sc.SetState(SCE_MYSQL_DEFAULT);
-			}
-			break;
-		case SCE_MYSQL_SQSTRING:
-			if (sc.ch == '\\') {
-				// Escape sequence
-				sc.Forward();
-			} else if (sc.ch == '\'') {
-				if (sc.chNext == '\'') {
-					sc.Forward();
-				} else {
-					sc.ChangeState(SCE_MYSQL_STRING);
-					sc.ForwardSetState(SCE_MYSQL_DEFAULT);
-				}
-			}
-			break;
-		case SCE_MYSQL_DQSTRING:
-			if (sc.ch == '\\') {
-				// Escape sequence
-				sc.Forward();
-			} else if (sc.ch == '\"') {
-				if (sc.chNext == '\"') {
-					sc.Forward();
-				} else {
-					sc.ChangeState(SCE_MYSQL_STRING);
-					sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+		switch (sc.state)
+    {
+      case SCE_MYSQL_OPERATOR:
+        sc.SetState(SCE_MYSQL_DEFAULT);
+        break;
+      case SCE_MYSQL_NUMBER:
+        // We stop the number definition on non-numerical non-dot non-eE non-sign char.
+        if (!IsANumberChar(sc.ch))
+          sc.SetState(SCE_MYSQL_DEFAULT);
+        break;
+      case SCE_MYSQL_IDENTIFIER:
+        // Switch from identifier to keyword state and open a new state for the new char.
+        if (!IsAWordChar(sc.ch))
+        {
+          CheckForKeyword(sc, keywordlists);
+          
+          // Additional check for function keywords needed.
+          // A function name must be followed by an opening parenthesis.
+          if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
+            sc.ChangeState(SCE_MYSQL_DEFAULT);
+            
+          sc.SetState(SCE_MYSQL_DEFAULT);
+        }
+        break;
+      case SCE_MYSQL_VARIABLE:
+        if (!IsAWordChar(sc.ch))
+          sc.SetState(SCE_MYSQL_DEFAULT);
+        break;
+      case SCE_MYSQL_SYSTEMVARIABLE:
+        if (!IsAWordChar(sc.ch))
+        {
+          int length = sc.LengthCurrent() + 1;
+          char* s = new char[length];
+          sc.GetCurrentLowered(s, length);
+
+          // Check for known system variables here.
+          if (keywordlists[4]->InList(&s[2]))
+            sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE);
+          delete [] s;
+          
+          sc.SetState(SCE_MYSQL_DEFAULT);
+        }
+        break;
+      case SCE_MYSQL_QUOTEDIDENTIFIER:
+        if (sc.ch == '`')
+        {
+          if (sc.chNext == '`')
+            sc.Forward();	// Ignore it
+          else
+            sc.ForwardSetState(SCE_MYSQL_DEFAULT);
 				}
-			}
-			break;
-		}
+  			break;
+      case SCE_MYSQL_COMMENT:
+      case SCE_MYSQL_HIDDENCOMMAND:
+        if (sc.Match('*', '/'))
+        {
+          sc.Forward();
+          sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+        }
+        break;
+      case SCE_MYSQL_COMMENTLINE:
+        if (sc.atLineStart)
+          sc.SetState(SCE_MYSQL_DEFAULT);
+        break;
+      case SCE_MYSQL_SQSTRING:
+        if (sc.ch == '\\')
+          sc.Forward(); // Escape sequence
+        else
+          if (sc.ch == '\'')
+          {
+            // End of single quoted string reached?
+            if (sc.chNext == '\'')
+              sc.Forward();
+            else
+              sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+          }
+        break;
+      case SCE_MYSQL_DQSTRING:
+        if (sc.ch == '\\')
+          sc.Forward(); // Escape sequence
+        else
+          if (sc.ch == '\"')
+          {
+            // End of single quoted string reached?
+            if (sc.chNext == '\"')
+              sc.Forward();
+            else
+              sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+          }
+        break;
+    }
 
-		// Determine if a new state should be entered.
-		if (sc.state == SCE_MYSQL_DEFAULT) {
-			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
-				sc.SetState(SCE_MYSQL_NUMBER);
-			} else if (IsAWordStart(sc.ch)) {
-				sc.SetState(SCE_MYSQL_IDENTIFIER);
-// Note that the order of SYSTEMVARIABLE and VARIABLE is important here.
-			} else if (sc.ch == 0x40 && sc.chNext == 0x40) {
-				sc.SetState(SCE_MYSQL_SYSTEMVARIABLE);
-				sc.Forward(); // Skip past the second at-sign.
-			} else if (sc.ch == 0x40) {
-				sc.SetState(SCE_MYSQL_VARIABLE);
-			} else if (sc.ch == 0x60) {
-				sc.SetState(SCE_MYSQL_QUOTEDIDENTIFIER);
-			} else if (sc.Match('/', '*')) {
-				sc.SetState(SCE_MYSQL_COMMENT);
-				sc.Forward();	// Eat the * so it isn't used for the end of the comment
-			} else if (sc.Match('-', '-') || sc.Match('#')) {
-				sc.SetState(SCE_MYSQL_COMMENTLINE);
-			} else if (sc.ch == '\'') {
-				sc.SetState(SCE_MYSQL_SQSTRING);
-			} else if (sc.ch == '\"') {
-				sc.SetState(SCE_MYSQL_DQSTRING);
-			} else if (isoperator(static_cast<char>(sc.ch))) {
-				sc.SetState(SCE_MYSQL_OPERATOR);
-			}
-		}
-	}
-	sc.Complete();
+    // Determine if a new state should be entered.
+    if (sc.state == SCE_MYSQL_DEFAULT)
+    {
+      switch (sc.ch)
+      {
+        case '@':
+          if (sc.chNext == '@')
+          {
+            sc.SetState(SCE_MYSQL_SYSTEMVARIABLE);
+            sc.Forward(2); // Skip past @@.
+          }
+          else
+            if (IsAWordStart(sc.ch))
+            {
+              sc.SetState(SCE_MYSQL_VARIABLE);
+              sc.Forward(); // Skip past @.
+            }
+            else
+              sc.SetState(SCE_MYSQL_OPERATOR);
+          break;
+        case '`':
+          sc.SetState(SCE_MYSQL_QUOTEDIDENTIFIER);
+          break;
+        case '#':
+          sc.SetState(SCE_MYSQL_COMMENTLINE);
+          break;
+        case '\'':
+          sc.SetState(SCE_MYSQL_SQSTRING);
+          break;
+        case '\"':
+          sc.SetState(SCE_MYSQL_DQSTRING);
+          break;
+        default:
+          if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
+            sc.SetState(SCE_MYSQL_NUMBER);
+          else
+            if (IsAWordStart(sc.ch))
+              sc.SetState(SCE_MYSQL_IDENTIFIER);
+            else
+              if (sc.Match('/', '*'))
+              {
+                sc.SetState(SCE_MYSQL_COMMENT);
+                
+                // Skip comment introducer and check for hidden command.
+                sc.Forward(2);
+                if (sc.ch == '!')
+                {
+                  sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND);
+                  sc.Forward();
+                }
+              }
+              else
+                if (sc.Match("--"))
+                {
+                  // Special MySQL single line comment.
+                  sc.SetState(SCE_MYSQL_COMMENTLINE);
+                  sc.Forward(2);
+                  
+                  // Check the third character too. It must be a space or EOL.
+                  if (sc.ch != ' ' && sc.ch != '\n' && sc.ch != '\r')
+                    sc.ChangeState(SCE_MYSQL_OPERATOR);
+                }
+                else
+                  if (isoperator(static_cast<char>(sc.ch)))
+                    sc.SetState(SCE_MYSQL_OPERATOR);
+      }
+    }
+  }
+  
+  // Do a final check for keywords if we currently have an identifier, to highlight them
+  // also at the end of a line.
+  if (sc.state == SCE_MYSQL_IDENTIFIER)
+  {
+    CheckForKeyword(sc, keywordlists);
+
+    // Additional check for function keywords needed.
+    // A function name must be followed by an opening parenthesis.
+    if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
+      sc.ChangeState(SCE_MYSQL_DEFAULT);
+  }
+	
+  sc.Complete();
 }
 
-static bool IsStreamCommentStyle(int style) {
+//--------------------------------------------------------------------------------------------------
+
+/**
+ * Helper function to determine if we have a foldable comment currently.
+ */
+static bool IsStreamCommentStyle(int style)
+{
 	return style == SCE_MYSQL_COMMENT;
 }
 
+//--------------------------------------------------------------------------------------------------
+
+/**
+ * Code copied from StyleContext and modified to work here. Should go into Accessor as a
+ * companion to Match()...
+ */
+bool MatchIgnoreCase(Accessor &styler, int currentPos, const char *s)
+{
+  for (int n = 0; *s; n++)
+  {
+    if (*s != tolower(styler.SafeGetCharAt(currentPos + n)))
+      return false;
+    s++;
+  }
+  return true;
+}
+
+//--------------------------------------------------------------------------------------------------
+
 // Store both the current line's fold level and the next lines in the
 // level store to make it easy to pick up with each increment.
-static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle,
-                            WordList *[], Accessor &styler) {
+static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler)
+{
 	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 	bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0;
 
-	unsigned int endPos = startPos + length;
 	int visibleChars = 0;
 	int lineCurrent = styler.GetLine(startPos);
 	int levelCurrent = SC_FOLDLEVELBASE;
-	if (lineCurrent > 0) {
+	if (lineCurrent > 0)
 		levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
-	}
 	int levelNext = levelCurrent;
-	char chNext = styler[startPos];
+
 	int styleNext = styler.StyleAt(startPos);
 	int style = initStyle;
-	bool endFound = false;
+	
+  bool endFound = false;
 	bool whenFound = false;
 	bool elseFound = false;
-	for (unsigned int i = startPos; i < endPos; i++) {
-		char ch = chNext;
-		chNext = styler.SafeGetCharAt(i + 1);
+
+  char nextChar = styler.SafeGetCharAt(startPos);
+  for (unsigned int i = startPos; length > 0; i++, length--)
+  {
 		int stylePrev = style;
 		style = styleNext;
 		styleNext = styler.StyleAt(i + 1);
-		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-		if (foldComment && IsStreamCommentStyle(style)) {
-			if (!IsStreamCommentStyle(stylePrev)) {
-				levelNext++;
-			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
-				// Comments don't end at end of line and the next character may be unstyled.
-				levelNext--;
-			}
-		}
-		if (foldComment && (style == SCE_MYSQL_COMMENTLINE)) {
-			// MySQL needs -- comments to be followed by space or control char
-			if ((ch == '-') && (chNext == '-')) {
-				char chNext2 = styler.SafeGetCharAt(i + 2);
-				char chNext3 = styler.SafeGetCharAt(i + 3);
-				if (chNext2 == '{' || chNext3 == '{') {
-					levelNext++;
-				} else if (chNext2 == '}' || chNext3 == '}') {
-					levelNext--;
-				}
-			}
-		}
-		if (style == SCE_MYSQL_OPERATOR) {
-			if (ch == '(') {
-				levelNext++;
-			} else if (ch == ')') {
-				levelNext--;
-			}
-		}
-
-// Style new keywords here.
-		if ((style == SCE_MYSQL_MAJORKEYWORD && stylePrev != SCE_MYSQL_MAJORKEYWORD)
-		  || (style == SCE_MYSQL_KEYWORD && stylePrev != SCE_MYSQL_KEYWORD)
-		  || (style == SCE_MYSQL_PROCEDUREKEYWORD && stylePrev != SCE_MYSQL_PROCEDUREKEYWORD)) {
-			const int MAX_KW_LEN = 6;	// Maximum length of folding keywords
-			char s[MAX_KW_LEN + 2];
-			unsigned int j = 0;
-			for (; j < MAX_KW_LEN + 1; j++) {
-				if (!iswordchar(styler[i + j])) {
-					break;
-				}
-				s[j] = static_cast<char>(tolower(styler[i + j]));
-			}
-			if (j == MAX_KW_LEN + 1) {
-				// Keyword too long, don't test it
-				s[0] = '\0';
-			} else {
-				s[j] = '\0';
-			}
-			if (!foldOnlyBegin && endFound && (strcmp(s, "if") == 0 || strcmp(s, "while") == 0 || strcmp(s, "loop") == 0)) {
-				endFound = false;
-				levelNext--;
-				if (levelNext < SC_FOLDLEVELBASE) {
-					levelNext = SC_FOLDLEVELBASE;
-				}
-// Note that else is special here. It may or may be followed by an if then, but in aly case the level stays the
-// same. When followed by a if .. then, the level will be increased later, if not, at eol.
-			} else if (!foldOnlyBegin && strcmp(s, "else") == 0) {
-				levelNext--;
-				elseFound = true;
-			} else if (!foldOnlyBegin && strcmp(s, "then") == 0) {
-				if(whenFound) {
-					whenFound = false;
-				} else {
-					levelNext++;
-				}
-			} else if (strcmp(s, "if") == 0) {
-				elseFound = false;
-			} else if (strcmp(s, "when") == 0) {
-				whenFound = true;
-			} else if (strcmp(s, "begin") == 0) {
-				levelNext++;
-			} else if (!foldOnlyBegin && (strcmp(s, "loop") == 0 || strcmp(s, "repeat") == 0
-			  || strcmp(s, "while") == 0)) {
-				if(endFound) {
-					endFound = false;
-				} else {
-					levelNext++;
-				}
-			} else if (strcmp(s, "end") == 0) {
-// Multiple END in a row are counted multiple times!
-				if (endFound) {
-					levelNext--;
-					if (levelNext < SC_FOLDLEVELBASE) {
-						levelNext = SC_FOLDLEVELBASE;
-					}
-				}
-				endFound = true;
-				whenFound = false;
-			}
-		}
-// Handle this for a trailing end withiut an if / while etc, as in the case of a begin.
-		if (endFound) {
+    
+    char currentChar = nextChar;
+    nextChar = styler.SafeGetCharAt(i + 1);
+		bool atEOL = (currentChar == '\r' && nextChar != '\n') || (currentChar == '\n');
+	
+    switch (style)
+    {
+      case SCE_MYSQL_COMMENT:
+        if (foldComment)
+        {
+          // Multiline comment style /* .. */.
+          if (IsStreamCommentStyle(style))
+          {
+            // Increase level if we just start a foldable comment.
+            if (!IsStreamCommentStyle(stylePrev))
+              levelNext++;
+            else
+              // If we are in the middle of a foldable comment check if it ends now.
+              // Don't end at the line end, though.
+              if (!IsStreamCommentStyle(styleNext) && !atEOL)
+                levelNext--;
+          }
+        }
+        break;
+      case SCE_MYSQL_COMMENTLINE:
+        if (foldComment)
+        { 
+          // Not really a standard, but we add support for single line comments
+          // with special curly braces syntax as foldable comments too.
+          // MySQL needs -- comments to be followed by space or control char
+          if (styler.Match(startPos, "--"))
+          {
+            char chNext2 = styler.SafeGetCharAt(i + 2);
+            char chNext3 = styler.SafeGetCharAt(i + 3);
+            if (chNext2 == '{' || chNext3 == '{')
+              levelNext++;
+            else
+              if (chNext2 == '}' || chNext3 == '}')
+                levelNext--;
+          }
+        }
+        break;
+      case SCE_MYSQL_HIDDENCOMMAND:
+        if (style != stylePrev)
+          levelNext++;
+        else
+          if (style != styleNext)
+            levelNext--;
+        break;
+      case SCE_MYSQL_OPERATOR:
+        if (currentChar == '(')
+          levelNext++;
+        else
+          if (currentChar == ')')
+            levelNext--;
+        break;
+      case SCE_MYSQL_MAJORKEYWORD:
+      case SCE_MYSQL_KEYWORD:
+      case SCE_MYSQL_FUNCTION:
+      case SCE_MYSQL_PROCEDUREKEYWORD:
+        // Reserved and other keywords.
+        if (style != stylePrev)
+        {
+          bool beginFound = MatchIgnoreCase(styler, startPos, "begin");
+          bool ifFound = MatchIgnoreCase(styler, startPos, "if");
+          bool thenFound = MatchIgnoreCase(styler, startPos, "then");
+          bool whileFound = MatchIgnoreCase(styler, startPos, "while");
+          bool loopFound = MatchIgnoreCase(styler, startPos, "loop");
+          bool repeatFound = MatchIgnoreCase(styler, startPos, "repeat");
+          
+          if (!foldOnlyBegin && endFound && (ifFound || whileFound || loopFound))
+          {
+            endFound = false;
+            levelNext--;
+            if (levelNext < SC_FOLDLEVELBASE)
+              levelNext = SC_FOLDLEVELBASE;
+            
+            // Note that "else" is special here. It may or may not be followed by an "if .. then",
+            // but in any case the level stays the same. When followed by an "if .. then" the level
+            // will be increased later, if not, then at eol.
+          }
+          else
+            if (!foldOnlyBegin && MatchIgnoreCase(styler, startPos, "else"))
+            {
+              levelNext--;
+              elseFound = true;
+            }
+            else
+              if (!foldOnlyBegin && thenFound)
+              {
+                if (whenFound)
+                  whenFound = false;
+                else
+                  levelNext++;
+              }
+              else
+                if (ifFound)
+                  elseFound = false;
+                else
+                  if (MatchIgnoreCase(styler, startPos, "when"))
+                    whenFound = true;
+                  else
+                  {
+                    if (beginFound)
+                      levelNext++;
+                    else
+                      if (!foldOnlyBegin && (loopFound || repeatFound || whileFound))
+                      {
+                        if (endFound)
+                          endFound = false;
+                        else
+                          levelNext++;
+                      }
+                      else
+                        if (MatchIgnoreCase(styler, startPos, "end"))
+                        {
+                          // Multiple "end" in a row are counted multiple times!
+                          if (endFound)
+                          {
+                            levelNext--;
+                            if (levelNext < SC_FOLDLEVELBASE)
+                              levelNext = SC_FOLDLEVELBASE;
+                          }
+                          endFound = true;
+                          whenFound = false;
+                        }
+                  }
+        }
+        break;
+    }
+    
+    // Handle the case of a trailing end without an if / while etc, as in the case of a begin.
+		if (endFound)
+    {
 			endFound = false;
 			levelNext--;
-			if (levelNext < SC_FOLDLEVELBASE) {
-				levelNext = SC_FOLDLEVELBASE;
-			}
+			if (levelNext < SC_FOLDLEVELBASE)
+        levelNext = SC_FOLDLEVELBASE;
 		}
-		if (atEOL) {
-			if(elseFound)
+    
+		if (atEOL)
+    {
+			if (elseFound)
+      {
 				levelNext++;
-			elseFound = false;
+        elseFound = false;
+      }
 
 			int levelUse = levelCurrent;
 			int lev = levelUse | levelNext << 16;
@@ -337,21 +485,23 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle,
 				lev |= SC_FOLDLEVELWHITEFLAG;
 			if (levelUse < levelNext)
 				lev |= SC_FOLDLEVELHEADERFLAG;
-			if (lev != styler.LevelAt(lineCurrent)) {
+			if (lev != styler.LevelAt(lineCurrent))
 				styler.SetLevel(lineCurrent, lev);
-			}
+      
 			lineCurrent++;
 			levelCurrent = levelNext;
 			visibleChars = 0;
 			endFound = false;
 			whenFound = false;
 		}
-		if (!isspacechar(ch)) {
+    
+		if (!isspacechar(currentChar))
 			visibleChars++;
-		}
 	}
 }
 
+//--------------------------------------------------------------------------------------------------
+
 static const char * const mysqlWordListDesc[] = {
 	"Major Keywords",
 	"Keywords",
@@ -361,7 +511,8 @@ static const char * const mysqlWordListDesc[] = {
 	"Procedure keywords",
 	"User Keywords 1",
 	"User Keywords 2",
-	"User Keywords 3"
+	"User Keywords 3",
+	0
 };
 
 LexerModule lmMySQL(SCLEX_MYSQL, ColouriseMySQLDoc, "mysql", FoldMySQLDoc, mysqlWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexNimrod.cxx b/plugins/scintilla/scintilla/LexNimrod.cxx
new file mode 100644
index 0000000..8c4d043
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexNimrod.cxx
@@ -0,0 +1,430 @@
+// Scintilla source code edit control
+// Nimrod lexer
+// (c) 2009 Andreas Rumpf
+/** @file LexNimrod.cxx
+ ** Lexer for Nimrod.
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static inline bool IsAWordChar(int ch) {
+	return (ch >= 0x80) || isalnum(ch) || ch == '_';
+}
+
+static int tillEndOfTripleQuote(Accessor &styler, int pos, int max) {
+  /* search for """ */
+  for (;;) {
+    if (styler.SafeGetCharAt(pos, '\0') == '\0') return pos;
+    if (pos >= max) return pos;
+    if (styler.Match(pos, "\"\"\"")) {
+      return pos + 2;
+    }
+    pos++;
+  }
+}
+
+#define CR 13 /* use both because Scite allows changing the line ending */
+#define LF 10
+
+static bool inline isNewLine(int ch) {
+  return ch == CR || ch == LF;
+}
+
+static int scanString(Accessor &styler, int pos, int max, bool rawMode) {
+  for (;;) {
+    if (pos >= max) return pos;
+    char ch = styler.SafeGetCharAt(pos, '\0');
+    if (ch == CR || ch == LF || ch == '\0') return pos;
+    if (ch == '"') return pos;
+    if (ch == '\\' && !rawMode) {
+      pos += 2;
+    } else {
+      pos++;
+    }
+  }
+}
+
+static int scanChar(Accessor &styler, int pos, int max) {
+  for (;;) {
+    if (pos >= max) return pos;
+    char ch = styler.SafeGetCharAt(pos, '\0');
+    if (ch == CR || ch == LF || ch == '\0') return pos;
+    if (ch == '\'' && !isalnum(styler.SafeGetCharAt(pos+1, '\0')) )
+      return pos;
+    if (ch == '\\') {
+      pos += 2;
+    } else {
+      pos++;
+    }
+  }
+}
+
+static int scanIdent(Accessor &styler, int pos, WordList &keywords) {
+  char buf[100]; /* copy to lowercase and ignore underscores */
+  int i = 0;
+
+  for (;;) {
+    char ch = styler.SafeGetCharAt(pos, '\0');
+    if (!IsAWordChar(ch)) break;
+    if (ch != '_' && i < ((int)sizeof(buf))-1) {
+      buf[i] = static_cast<char>(tolower(ch));
+      i++;
+    }
+    pos++;
+  }
+  buf[i] = '\0';
+  /* look for keyword */
+  if (keywords.InList(buf)) {
+    styler.ColourTo(pos-1, SCE_P_WORD);
+  } else {
+    styler.ColourTo(pos-1, SCE_P_IDENTIFIER);
+  }
+  return pos;
+}
+
+static int scanNumber(Accessor &styler, int pos) {
+  char ch, ch2;
+  ch = styler.SafeGetCharAt(pos, '\0');
+  ch2 = styler.SafeGetCharAt(pos+1, '\0');
+  if (ch == '0' && (ch2 == 'b' || ch2 == 'B')) {
+    /* binary number: */
+    pos += 2;
+    for (;;) {
+      ch = styler.SafeGetCharAt(pos, '\0');
+      if (ch == '_' || (ch >= '0' && ch <= '1')) ++pos;
+      else break;
+    }
+  } else if (ch == '0' && 
+            (ch2 == 'o' || ch2 == 'O' || ch2 == 'c' || ch2 == 'C')) {
+    /* octal number: */
+    pos += 2;
+    for (;;) {
+      ch = styler.SafeGetCharAt(pos, '\0');
+      if (ch == '_' || (ch >= '0' && ch <= '7')) ++pos;
+      else break;
+    }
+  } else if (ch == '0' && (ch2 == 'x' || ch2 == 'X')) {
+    /* hexadecimal number: */
+    pos += 2;
+    for (;;) {
+      ch = styler.SafeGetCharAt(pos, '\0');
+      if (ch == '_' || (ch >= '0' && ch <= '9')
+          || (ch >= 'a' && ch <= 'f')
+          || (ch >= 'A' && ch <= 'F')) ++pos;
+      else break;
+    }
+  } else {
+    // skip decimal part:
+    for (;;) {
+      ch = styler.SafeGetCharAt(pos, '\0');
+      if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
+      else break;
+    }
+    ch2 = styler.SafeGetCharAt(pos+1, '\0');
+    if (ch == '.' && ch2 >= '0' && ch2 <= '9') {
+      ++pos; // skip '.'
+      for (;;) {
+        ch = styler.SafeGetCharAt(pos, '\0');
+        if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
+        else break;
+      }
+    }
+    if (ch == 'e' || ch == 'E') {
+      ++pos;
+      ch = styler.SafeGetCharAt(pos, '\0');
+      if (ch == '-' || ch == '+') ++pos;
+      for (;;) {
+        ch = styler.SafeGetCharAt(pos, '\0');
+        if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos;
+        else break;
+      }
+    }
+  }
+  if (ch == '\'') {
+    /* a type suffix: */
+    pos++;
+    for (;;) {
+      ch = styler.SafeGetCharAt(pos);
+      if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z')
+         || (ch >= 'a' && ch <= 'z') || ch == '_') ++pos;
+      else break;
+    }
+  }
+  styler.ColourTo(pos-1, SCE_P_NUMBER);
+  return pos;
+}
+
+/* rewritten from scratch, because I couldn't get rid of the bugs...
+   (A character based approach sucks!)
+*/
+static void ColouriseNimrodDoc(unsigned int startPos, int length, int initStyle,
+                                WordList *keywordlists[], Accessor &styler) {
+  int pos = startPos;
+  int max = startPos + length;
+  char ch;
+  WordList &keywords = *keywordlists[0];
+
+  styler.StartAt(startPos);
+  styler.StartSegment(startPos);
+
+  switch (initStyle) {
+    /* check where we are: */
+    case SCE_P_TRIPLEDOUBLE:
+      pos = tillEndOfTripleQuote(styler, pos, max);
+      styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE);
+      pos++;
+    break;
+    default: /* nothing to do: */
+    break;
+  }
+  while (pos < max) {
+    ch = styler.SafeGetCharAt(pos, '\0');
+    switch (ch) {
+      case '\0': return;
+      case '#': {
+        bool doccomment = (styler.SafeGetCharAt(pos+1) == '#');
+        while (pos < max && !isNewLine(styler.SafeGetCharAt(pos, LF))) pos++;
+        if (doccomment) 
+          styler.ColourTo(pos, SCE_C_COMMENTLINEDOC);
+        else
+          styler.ColourTo(pos, SCE_P_COMMENTLINE);
+      } break;
+      case 'r': case 'R': {
+        if (styler.SafeGetCharAt(pos+1) == '"') {
+          pos = scanString(styler, pos+2, max, true);
+          styler.ColourTo(pos, SCE_P_STRING);
+          pos++;
+        } else {
+          pos = scanIdent(styler, pos, keywords);
+        }
+      } break;
+      case '"':
+        if (styler.Match(pos+1, "\"\"")) {
+          pos = tillEndOfTripleQuote(styler, pos+3, max);
+          styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE);
+        } else {
+          pos = scanString(styler, pos+1, max, false);
+          styler.ColourTo(pos, SCE_P_STRING);
+        }
+        pos++;
+      break;
+      case '\'':
+        pos = scanChar(styler, pos+1, max);
+        styler.ColourTo(pos, SCE_P_CHARACTER);
+        pos++;
+      break;
+      default: // identifers, numbers, operators, whitespace
+        if (ch >= '0' && ch <= '9') {
+          pos = scanNumber(styler, pos);
+        } else if (IsAWordChar(ch)) {
+          pos = scanIdent(styler, pos, keywords);
+        } else if (ch == '`') {
+          pos++;
+          while (pos < max) {
+            ch = styler.SafeGetCharAt(pos, LF);
+            if (ch == '`') {
+              ++pos;
+              break;
+            }
+            if (ch == CR || ch == LF) break;
+            ++pos;
+          }
+          styler.ColourTo(pos, SCE_P_IDENTIFIER);
+        } else if (strchr("()[]{}:=;-\\/&%$!+<>|^?,.*~@", ch)) {
+          styler.ColourTo(pos, SCE_P_OPERATOR);
+          pos++;
+        } else {
+          styler.ColourTo(pos, SCE_P_DEFAULT);
+          pos++;
+        }
+      break;
+    }
+  }
+}
+
+static bool IsCommentLine(int line, Accessor &styler) {
+	int pos = styler.LineStart(line);
+	int eol_pos = styler.LineStart(line + 1) - 1;
+	for (int i = pos; i < eol_pos; i++) {
+		char ch = styler[i];
+		if (ch == '#')
+			return true;
+		else if (ch != ' ' && ch != '\t')
+			return false;
+	}
+	return false;
+}
+
+static bool IsQuoteLine(int line, Accessor &styler) {
+	int style = styler.StyleAt(styler.LineStart(line)) & 31;
+	return ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
+}
+
+
+static void FoldNimrodDoc(unsigned int startPos, int length, 
+                          int /*initStyle - unused*/,
+                          WordList *[], Accessor &styler) {
+	const int maxPos = startPos + length;
+	const int maxLines = styler.GetLine(maxPos - 1); // Requested last line
+	const int docLines = styler.GetLine(styler.Length() - 1); // Available last line
+	const bool foldComment = styler.GetPropertyInt("fold.comment.nimrod") != 0;
+	const bool foldQuotes = styler.GetPropertyInt("fold.quotes.nimrod") != 0;
+
+	// Backtrack to previous non-blank line so we can determine indent level
+	// for any white space lines (needed esp. within triple quoted strings)
+	// and so we can fix any preceding fold level (which is why we go back
+	// at least one line in all cases)
+	int spaceFlags = 0;
+	int lineCurrent = styler.GetLine(startPos);
+	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
+	while (lineCurrent > 0) {
+		lineCurrent--;
+		indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
+		if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) &&
+		        (!IsCommentLine(lineCurrent, styler)) &&
+		        (!IsQuoteLine(lineCurrent, styler)))
+			break;
+	}
+	int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
+
+	// Set up initial loop state
+	startPos = styler.LineStart(lineCurrent);
+	int prev_state = SCE_P_DEFAULT & 31;
+	if (lineCurrent >= 1)
+		prev_state = styler.StyleAt(startPos - 1) & 31;
+	int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) || 
+	                               (prev_state == SCE_P_TRIPLEDOUBLE));
+	int prevComment = 0;
+	if (lineCurrent >= 1)
+		prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);
+
+	// Process all characters to end of requested range or end of any triple quote
+	// or comment that hangs over the end of the range.  Cap processing in all cases
+	// to end of document (in case of unclosed quote or comment at end).
+	while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || 
+	                                      prevQuote || prevComment)) {
+
+		// Gather info
+		int lev = indentCurrent;
+		int lineNext = lineCurrent + 1;
+		int indentNext = indentCurrent;
+		int quote = false;
+		if (lineNext <= docLines) {
+			// Information about next line is only available if not at end of document
+			indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
+			int style = styler.StyleAt(styler.LineStart(lineNext)) & 31;
+			quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
+		}
+		const int quote_start = (quote && !prevQuote);
+		const int quote_continue = (quote && prevQuote);
+		const int comment = foldComment && IsCommentLine(lineCurrent, styler);
+		const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
+		                           IsCommentLine(lineNext, styler) && 
+		                           (lev > SC_FOLDLEVELBASE));
+		const int comment_continue = (comment && prevComment);
+		if ((!quote || !prevQuote) && !comment)
+			indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
+		if (quote)
+			indentNext = indentCurrentLevel;
+		if (indentNext & SC_FOLDLEVELWHITEFLAG)
+			indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
+
+		if (quote_start) {
+			// Place fold point at start of triple quoted string
+			lev |= SC_FOLDLEVELHEADERFLAG;
+		} else if (quote_continue || prevQuote) {
+			// Add level to rest of lines in the string
+			lev = lev + 1;
+		} else if (comment_start) {
+			// Place fold point at start of a block of comments
+			lev |= SC_FOLDLEVELHEADERFLAG;
+		} else if (comment_continue) {
+			// Add level to rest of lines in the block
+			lev = lev + 1;
+		}
+
+		// Skip past any blank lines for next indent level info; we skip also
+		// comments (all comments, not just those starting in column 0)
+		// which effectively folds them into surrounding code rather
+		// than screwing up folding.
+
+		while (!quote &&
+		        (lineNext < docLines) &&
+		        ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
+		         (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {
+
+			lineNext++;
+			indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
+		}
+
+		const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
+		const int levelBeforeComments = 
+		    Platform::Maximum(indentCurrentLevel,levelAfterComments);
+
+		// Now set all the indent levels on the lines we skipped
+		// Do this from end to start.  Once we encounter one line
+		// which is indented more than the line after the end of
+		// the comment-block, use the level of the block before
+
+		int skipLine = lineNext;
+		int skipLevel = levelAfterComments;
+
+		while (--skipLine > lineCurrent) {
+			int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
+
+			if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
+				skipLevel = levelBeforeComments;
+
+			int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
+
+			styler.SetLevel(skipLine, skipLevel | whiteFlag);
+		}
+
+		// Set fold header on non-quote/non-comment line
+		if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
+			if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < 
+			     (indentNext & SC_FOLDLEVELNUMBERMASK))
+				lev |= SC_FOLDLEVELHEADERFLAG;
+		}
+
+		// Keep track of triple quote and block comment state of previous line
+		prevQuote = quote;
+		prevComment = comment_start || comment_continue;
+
+		// Set fold level for this line and move to next line
+		styler.SetLevel(lineCurrent, lev);
+		indentCurrent = indentNext;
+		lineCurrent = lineNext;
+	}
+
+	// NOTE: Cannot set level of last line here because indentCurrent doesn't have
+	// header flag set; the loop above is crafted to take care of this case!
+	//styler.SetLevel(lineCurrent, indentCurrent);
+}
+
+static const char * const nimrodWordListDesc[] = {
+	"Keywords",
+	0
+};
+
+LexerModule lmNimrod(SCLEX_NIMROD, ColouriseNimrodDoc, "nimrod", FoldNimrodDoc,
+				     nimrodWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexNsis.cxx b/plugins/scintilla/scintilla/LexNsis.cxx
index ab6304c..b16cc9b 100644
--- a/plugins/scintilla/scintilla/LexNsis.cxx
+++ b/plugins/scintilla/scintilla/LexNsis.cxx
@@ -13,6 +13,7 @@
 
 #include "Platform.h"
 
+#include "CharClassify.h"
 #include "PropSet.h"
 #include "Accessor.h"
 #include "KeyWords.h"
diff --git a/plugins/scintilla/scintilla/LexOthers.cxx b/plugins/scintilla/scintilla/LexOthers.cxx
index 24eee96..75458f6 100644
--- a/plugins/scintilla/scintilla/LexOthers.cxx
+++ b/plugins/scintilla/scintilla/LexOthers.cxx
@@ -14,6 +14,7 @@
 
 #include "Platform.h"
 
+#include "CharClassify.h"
 #include "PropSet.h"
 #include "Accessor.h"
 #include "KeyWords.h"
@@ -213,6 +214,7 @@ static void ColouriseBatchLine(
 			// No need to Reset Offset
 		// Check for Special Keyword in list, External Command / Program, or Default Text
 		} else if ((wordBuffer[0] != '%') &&
+				   (wordBuffer[0] != '!') &&
 			(!IsBOperator(wordBuffer[0])) &&
 			(continueProcessing)) {
 			// Check for Special Keyword
@@ -249,6 +251,7 @@ static void ColouriseBatchLine(
 					// Read up to %, Operator or Separator
 					while ((wbo < wbl) &&
 						(wordBuffer[wbo] != '%') &&
+						(wordBuffer[wbo] != '!') &&
 						(!IsBOperator(wordBuffer[wbo])) &&
 						(!IsBSeparator(wordBuffer[wbo]))) {
 						wbo++;
@@ -298,6 +301,7 @@ static void ColouriseBatchLine(
 					// Read up to %, Operator or Separator
 					while ((wbo < wbl) &&
 						(wordBuffer[wbo] != '%') &&
+						(wordBuffer[wbo] != '!') &&
 						(!IsBOperator(wordBuffer[wbo])) &&
 						(!IsBSeparator(wordBuffer[wbo]))) {
 						wbo++;
@@ -370,6 +374,29 @@ static void ColouriseBatchLine(
 				// Reset Offset to re-process remainder of word
 				offset -= (wbl - 3);
 			}
+		// Check for Environment Variable (!x...!)
+		} else if (wordBuffer[0] == '!') {
+			// Colorize Default Text
+			styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT);
+			wbo++;
+			// Search to end of word for second ! (can be a long path)
+			while ((wbo < wbl) &&
+				(wordBuffer[wbo] != '!') &&
+				(!IsBOperator(wordBuffer[wbo])) &&
+				(!IsBSeparator(wordBuffer[wbo]))) {
+				wbo++;
+			}
+			if (wordBuffer[wbo] == '!') {
+				wbo++;
+				// Check for External Command / Program
+				if (cmdLoc == offset - wbl) {
+					cmdLoc = offset - (wbl - wbo);
+				}
+				// Colorize Environment Variable
+				styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER);
+				// Reset Offset to re-process remainder of word
+				offset -= (wbl - wbo);
+			}
 		// Check for Operator
 		} else if (IsBOperator(wordBuffer[0])) {
 			// Colorize Default Text
@@ -417,6 +444,7 @@ static void ColouriseBatchLine(
 			// Read up to %, Operator or Separator
 			while ((wbo < wbl) &&
 				(wordBuffer[wbo] != '%') &&
+				(wordBuffer[wbo] != '!') &&
 				(!IsBOperator(wordBuffer[wbo])) &&
 				(!IsBSeparator(wordBuffer[wbo]))) {
 				wbo++;
@@ -640,17 +668,27 @@ static void ColourisePoDoc(unsigned int startPos, int length, int, WordList *[],
 	}
 }
 
+static inline bool isassignchar(unsigned char ch) {
+	return (ch == '=') || (ch == ':');
+}
 
 static void ColourisePropsLine(
     char *lineBuffer,
     unsigned int lengthLine,
     unsigned int startLine,
     unsigned int endPos,
-    Accessor &styler) {
+    Accessor &styler,
+    bool allowInitialSpaces) {
 
 	unsigned int i = 0;
-	while ((i < lengthLine) && isspacechar(lineBuffer[i]))	// Skip initial spaces
-		i++;
+	if (allowInitialSpaces) {
+		while ((i < lengthLine) && isspacechar(lineBuffer[i]))	// Skip initial spaces
+			i++;
+	} else {
+		if (isspacechar(lineBuffer[i])) // don't allow initial spaces
+			i = lengthLine;
+	}
+
 	if (i < lengthLine) {
 		if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') {
 			styler.ColourTo(endPos, SCE_PROPS_COMMENT);
@@ -658,14 +696,14 @@ static void ColourisePropsLine(
 			styler.ColourTo(endPos, SCE_PROPS_SECTION);
 		} else if (lineBuffer[i] == '@') {
 			styler.ColourTo(startLine + i, SCE_PROPS_DEFVAL);
-			if (lineBuffer[++i] == '=')
+			if (isassignchar(lineBuffer[i++]))
 				styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);
 			styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
 		} else {
 			// Search for the '=' character
-			while ((i < lengthLine) && (lineBuffer[i] != '='))
+			while ((i < lengthLine) && !isassignchar(lineBuffer[i]))
 				i++;
-			if ((i < lengthLine) && (lineBuffer[i] == '=')) {
+			if ((i < lengthLine) && isassignchar(lineBuffer[i])) {
 				styler.ColourTo(startLine + i - 1, SCE_PROPS_KEY);
 				styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);
 				styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
@@ -684,18 +722,25 @@ static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *
 	styler.StartSegment(startPos);
 	unsigned int linePos = 0;
 	unsigned int startLine = startPos;
+
+	// property lexer.props.allow.initial.spaces 
+	//	For properties files, set to 0 to style all lines that start with whitespace in the default style. 
+	//	This is not suitable for SciTE .properties files which use indentation for flow control but 
+	//	can be used for RFC2822 text where indentation is used for continuation lines. 
+	bool allowInitialSpaces = styler.GetPropertyInt("lexer.props.allow.initial.spaces", 1) != 0;
+
 	for (unsigned int i = startPos; i < startPos + length; i++) {
 		lineBuffer[linePos++] = styler[i];
 		if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
 			// End of line (or of line buffer) met, colourise it
 			lineBuffer[linePos] = '\0';
-			ColourisePropsLine(lineBuffer, linePos, startLine, i, styler);
+			ColourisePropsLine(lineBuffer, linePos, startLine, i, styler, allowInitialSpaces);
 			linePos = 0;
 			startLine = i + 1;
 		}
 	}
 	if (linePos > 0) {	// Last line does not have ending characters
-		ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
+		ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler, allowInitialSpaces);
 	}
 }
 
@@ -770,7 +815,7 @@ static void FoldPropsDoc(unsigned int startPos, int length, int, WordList *[], A
 		lev = SC_FOLDLEVELBASE;
 	}
 	int flagsNext = styler.LevelAt(lineCurrent);
-	styler.SetLevel(lineCurrent, lev | flagsNext & ~SC_FOLDLEVELNUMBERMASK);
+	styler.SetLevel(lineCurrent, lev | (flagsNext & ~SC_FOLDLEVELNUMBERMASK));
 }
 
 static void ColouriseMakeLine(
@@ -1085,6 +1130,12 @@ static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordLi
 	styler.StartAt(startPos);
 	styler.StartSegment(startPos);
 	unsigned int linePos = 0;
+
+	// property lexer.errorlist.value.separate 
+	//	For lines in the output pane that are matches from Find in Files or GCC-style 
+	//	diagnostics, style the path and line number separately from the rest of the 
+	//	line with style 21 used for the rest of the line. 
+	//	This allows matched text to be more easily distinguished from its location. 
 	bool valueSeparate = styler.GetPropertyInt("lexer.errorlist.value.separate", 0) != 0;
 	for (unsigned int i = startPos; i < startPos + length; i++) {
 		lineBuffer[linePos++] = styler[i];
diff --git a/plugins/scintilla/scintilla/LexPascal.cxx b/plugins/scintilla/scintilla/LexPascal.cxx
index 0e45760..3dcf35a 100644
--- a/plugins/scintilla/scintilla/LexPascal.cxx
+++ b/plugins/scintilla/scintilla/LexPascal.cxx
@@ -4,8 +4,109 @@
  ** Written by Laurent le Tynevez
  ** Updated by Simon Steele <s steele pnotepad org> September 2002
  ** Updated by Mathias Rauen <scite madshi net> May 2003 (Delphi adjustments)
+ ** Completely rewritten by Marko Njezic <sf maxempire com> October 2008
  **/
 
+/*
+
+A few words about features of the new completely rewritten LexPascal...
+
+Generally speaking LexPascal tries to support all available Delphi features (up 
+to Delphi 2009 at this time), including .NET specific features.
+
+~ HIGHLIGHTING:
+
+If you enable "lexer.pascal.smart.highlighting" property, some keywords will 
+only be highlighted in appropriate context. As implemented those are keywords 
+related to property and DLL exports declarations (similar to how Delphi IDE 
+works). 
+
+For example, keywords "read" and "write" will only be highlighted if they are in 
+property declaration:
+
+property MyProperty: boolean read FMyProperty write FMyProperty; 
+
+~ FOLDING:
+
+Folding is supported in the following cases:
+
+- Folding of stream-like comments
+- Folding of groups of consecutive line comments
+- Folding of preprocessor blocks (the following preprocessor blocks are 
+supported: IF / IFEND; IFDEF, IFNDEF, IFOPT / ENDIF and REGION / ENDREGION 
+blocks), including nesting of preprocessor blocks up to 255 levels
+- Folding of code blocks on appropriate keywords (the following code blocks are 
+supported: "begin, asm, record, try, case / end" blocks, class & object 
+declarations and interface declarations)
+
+Remarks:
+
+- Folding of code blocks tries to handle all special cases in which folding 
+should not occur. As implemented those are:
+
+1. Structure "record case / end" (there's only one "end" statement and "case" is 
+ignored as fold point)
+2. Forward class declarations ("type TMyClass = class;") and object method 
+declarations ("TNotifyEvent = procedure(Sender: TObject) of object;") are 
+ignored as fold points
+3. Simplified complete class declarations ("type TMyClass = class(TObject);") 
+are ignored as fold points
+4. Every other situation when class keyword doesn't actually start class 
+declaration ("class procedure", "class function", "class of", "class var", 
+"class property" and "class operator")
+
+- Folding of code blocks inside preprocessor blocks is disabled (any comments 
+inside them will be folded fine) because there is no guarantee that complete 
+code block will be contained inside folded preprocessor block in which case 
+folded code block could end prematurely at the end of preprocessor block if 
+there is no closing statement inside. This was done in order to properly process 
+document that may contain something like this:
+
+type
+{$IFDEF UNICODE}
+  TMyClass = class(UnicodeAncestor)
+{$ELSE}
+  TMyClass = class(AnsiAncestor)
+{$ENDIF}
+  private
+  ...
+  public
+  ...
+  published
+  ...
+end;
+
+If class declarations were folded, then the second class declaration would end 
+at "$ENDIF" statement, first class statement would end at "end;" statement and 
+preprocessor "$IFDEF" block would go all the way to the end of document. 
+However, having in mind all this, if you want to enable folding of code blocks 
+inside preprocessor blocks, you can disable folding of preprocessor blocks by 
+changing "fold.preprocessor" property, in which case everything inside them 
+would be folded.
+
+~ KEYWORDS:
+
+The list of keywords that can be used in pascal.properties file (up to Delphi 
+2009):
+
+- Keywords: absolute abstract and array as asm assembler automated begin case 
+cdecl class const constructor deprecated destructor dispid dispinterface div do 
+downto dynamic else end except export exports external far file final 
+finalization finally for forward function goto if implementation in inherited 
+initialization inline interface is label library message mod near nil not object 
+of on or out overload override packed pascal platform private procedure program 
+property protected public published raise record register reintroduce repeat 
+resourcestring safecall sealed set shl shr static stdcall strict string then 
+threadvar to try type unit unsafe until uses var varargs virtual while with xor
+
+- Keywords related to the "smart highlithing" feature: add default implements 
+index name nodefault read readonly remove stored write writeonly
+
+- Keywords related to Delphi packages (in addition to all above): package 
+contains requires
+
+*/
+
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
@@ -20,12 +121,13 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 #include "StyleContext.h"
+#include "CharacterSet.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-static void getRange(unsigned int start,
+static void GetRangeLowered(unsigned int start,
 		unsigned int end,
 		Accessor &styler,
 		char *s,
@@ -38,239 +140,361 @@ static void getRange(unsigned int start,
 	s[i] = '\0';
 }
 
-static bool IsStreamCommentStyle(int style) {
-	return style == SCE_C_COMMENT ||
-		style == SCE_C_COMMENTDOC ||
-		style == SCE_C_COMMENTDOCKEYWORD ||
-		style == SCE_C_COMMENTDOCKEYWORDERROR;
-}
+static void GetForwardRangeLowered(unsigned int start,
+		CharacterSet &charSet,
+		Accessor &styler,
+		char *s,
+		unsigned int len) {
+	unsigned int i = 0;
+	while ((i < len-1) && charSet.Contains(styler.SafeGetCharAt(start + i))) {
+		s[i] = static_cast<char>(tolower(styler.SafeGetCharAt(start + i)));
+		i++;
+	}
+	s[i] = '\0';
 
-static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
-	if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
-		styler.ColourTo(end, SCE_C_REGEX);
-	} else
-		styler.ColourTo(end, attr);
 }
 
-// returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
-static int classifyWordPascal(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInClass, bool bInAsm) {
-	int ret = 0;
+enum {
+	stateInAsm = 0x1000, 
+	stateInProperty = 0x2000, 
+	stateInExport = 0x4000, 
+	stateFoldInPreprocessor = 0x0100, 
+	stateFoldInRecord = 0x0200, 
+	stateFoldInPreprocessorLevelMask = 0x00FF, 
+	stateFoldMaskAll = 0x0FFF
+};
 
+static void ClassifyPascalWord(WordList *keywordlists[], StyleContext &sc, int &curLineState, bool bSmartHighlighting) {
 	WordList& keywords = *keywordlists[0];
-	WordList& classwords = *keywordlists[1];
 
 	char s[100];
-	getRange(start, end, styler, s, sizeof(s));
-
-	char chAttr = SCE_C_IDENTIFIER;
-	if (isdigit(s[0]) || (s[0] == '.') ||(s[0] == '$')) {
-		chAttr = SCE_C_NUMBER;
+	sc.GetCurrentLowered(s, sizeof(s));
+	if (keywords.InList(s)) {
+		if (curLineState & stateInAsm) {
+			if (strcmp(s, "end") == 0 && sc.GetRelative(-4) != '@') {
+				curLineState &= ~stateInAsm;
+				sc.ChangeState(SCE_PAS_WORD);
+			} else {
+				sc.ChangeState(SCE_PAS_ASM);
+			}
+		} else {
+			bool ignoreKeyword = false;
+			if (strcmp(s, "asm") == 0) {
+				curLineState |= stateInAsm;
+			} else if (bSmartHighlighting) {
+				if (strcmp(s, "property") == 0) {
+					curLineState |= stateInProperty;
+				} else if (strcmp(s, "exports") == 0) {
+					curLineState |= stateInExport;
+				} else if (!(curLineState & (stateInProperty | stateInExport)) && strcmp(s, "index") == 0) {
+					ignoreKeyword = true;
+				} else if (!(curLineState & stateInExport) && strcmp(s, "name") == 0) {
+					ignoreKeyword = true;
+				} else if (!(curLineState & stateInProperty) && 
+					(strcmp(s, "read") == 0 || strcmp(s, "write") == 0 || 
+					 strcmp(s, "default") == 0 || strcmp(s, "nodefault") == 0 || 
+					 strcmp(s, "stored") == 0 || strcmp(s, "implements") == 0 || 
+					 strcmp(s, "readonly") == 0 || strcmp(s, "writeonly") == 0 || 
+					 strcmp(s, "add") == 0 || strcmp(s, "remove") == 0)) {
+					ignoreKeyword = true;
+				}
+			}
+			if (!ignoreKeyword) {
+				sc.ChangeState(SCE_PAS_WORD);
+			}
+		}
+	} else if (curLineState & stateInAsm) {
+		sc.ChangeState(SCE_PAS_ASM);
 	}
-	else {
-		if (s[0] == '#') {
-			chAttr = SCE_C_CHARACTER;
+	sc.SetState(SCE_PAS_DEFAULT);
+}
+
+static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+		Accessor &styler) {
+	bool bSmartHighlighting = styler.GetPropertyInt("lexer.pascal.smart.highlighting", 1) != 0;
+
+	CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
+	CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
+	CharacterSet setNumber(CharacterSet::setDigits, ".-+eE");
+	CharacterSet setHexNumber(CharacterSet::setDigits, "abcdefABCDEF");
+	CharacterSet setOperator(CharacterSet::setNone, "#$&'()*+,-./:;<=>@[]^{}");
+
+	int curLine = styler.GetLine(startPos);
+	int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
+
+	StyleContext sc(startPos, length, initStyle, styler);
+
+	for (; sc.More(); sc.Forward()) {
+		if (sc.atLineEnd) {
+			// Update the line state, so it can be seen by next line
+			curLine = styler.GetLine(sc.currentPos);
+			styler.SetLineState(curLine, curLineState);
 		}
-		else {
-			if (keywords.InList(s)) {
-				chAttr = SCE_C_WORD;
 
-				if(strcmp(s, "class") == 0) {
-					ret = 1;
+		// Determine if the current state should terminate.
+		switch (sc.state) {
+			case SCE_PAS_NUMBER:
+				if (!setNumber.Contains(sc.ch) || (sc.ch == '.' && sc.chNext == '.')) {
+					sc.SetState(SCE_PAS_DEFAULT);
+				} else if (sc.ch == '-' || sc.ch == '+') {
+					if (sc.chPrev != 'E' && sc.chPrev != 'e') {
+						sc.SetState(SCE_PAS_DEFAULT);
+					}
 				}
-				else if (strcmp(s, "asm") == 0) {
-					ret = 2;
+				break;
+			case SCE_PAS_IDENTIFIER:
+				if (!setWord.Contains(sc.ch)) {
+					ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting);
 				}
-				else if (strcmp(s, "end") == 0) {
-					ret = -1;
+				break;
+			case SCE_PAS_HEXNUMBER:
+				if (!setHexNumber.Contains(sc.ch)) {
+					sc.SetState(SCE_PAS_DEFAULT);
 				}
-			} else if (bInClass) {
-				if (classwords.InList(s)) {
-					chAttr = SCE_C_WORD;
+				break;
+			case SCE_PAS_COMMENT:
+			case SCE_PAS_PREPROCESSOR:
+				if (sc.ch == '}') {
+					sc.ForwardSetState(SCE_PAS_DEFAULT);
 				}
-			}
+				break;
+			case SCE_PAS_COMMENT2:
+			case SCE_PAS_PREPROCESSOR2:
+				if (sc.Match('*', ')')) {
+					sc.Forward();
+					sc.ForwardSetState(SCE_PAS_DEFAULT);
+				}
+				break;
+			case SCE_PAS_COMMENTLINE:
+				if (sc.atLineStart) {
+					sc.SetState(SCE_PAS_DEFAULT);
+				}
+				break;
+			case SCE_PAS_STRING:
+				if (sc.atLineEnd) {
+					sc.ChangeState(SCE_PAS_STRINGEOL);
+				} else if (sc.ch == '\'' && sc.chNext == '\'') {
+					sc.Forward();
+				} else if (sc.ch == '\'') {
+					sc.ForwardSetState(SCE_PAS_DEFAULT);
+				}
+				break;
+			case SCE_PAS_STRINGEOL:
+				if (sc.atLineStart) {
+					sc.SetState(SCE_PAS_DEFAULT);
+				}
+				break;
+			case SCE_PAS_CHARACTER:
+				if (!setHexNumber.Contains(sc.ch) && sc.ch != '$') {
+					sc.SetState(SCE_PAS_DEFAULT);
+				}
+				break;
+			case SCE_PAS_OPERATOR:
+				if (bSmartHighlighting && sc.chPrev == ';') {
+					curLineState &= ~(stateInProperty | stateInExport);
+				}
+				sc.SetState(SCE_PAS_DEFAULT);
+				break;
+			case SCE_PAS_ASM:
+				sc.SetState(SCE_PAS_DEFAULT);
+				break;
 		}
-	}
-	ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
-	return ret;
-}
 
-static int classifyFoldPointPascal(const char* s) {
-	int lev = 0;
-	if (!(isdigit(s[0]) || (s[0] == '.'))) {
-		if (strcmp(s, "begin") == 0 ||
-			strcmp(s, "object") == 0 ||
-			strcmp(s, "case") == 0 ||
-			strcmp(s, "class") == 0 ||
-			strcmp(s, "record") == 0 ||
-			strcmp(s, "try") == 0) {
-			lev=1;
-		} else if (strcmp(s, "end") == 0) {
-			lev=-1;
+		// Determine if a new state should be entered.
+		if (sc.state == SCE_PAS_DEFAULT) {
+			if (IsADigit(sc.ch) && !(curLineState & stateInAsm)) {
+				sc.SetState(SCE_PAS_NUMBER);
+			} else if (setWordStart.Contains(sc.ch)) {
+				sc.SetState(SCE_PAS_IDENTIFIER);
+			} else if (sc.ch == '$' && !(curLineState & stateInAsm)) {
+				sc.SetState(SCE_PAS_HEXNUMBER);
+			} else if (sc.Match('{', '$')) {
+				sc.SetState(SCE_PAS_PREPROCESSOR);
+			} else if (sc.ch == '{') {
+				sc.SetState(SCE_PAS_COMMENT);
+			} else if (sc.Match("(*$")) {
+				sc.SetState(SCE_PAS_PREPROCESSOR2);
+			} else if (sc.Match('(', '*')) {
+				sc.SetState(SCE_PAS_COMMENT2);
+				sc.Forward();	// Eat the * so it isn't used for the end of the comment
+			} else if (sc.Match('/', '/')) {
+				sc.SetState(SCE_PAS_COMMENTLINE);
+			} else if (sc.ch == '\'') {
+				sc.SetState(SCE_PAS_STRING);
+			} else if (sc.ch == '#') {
+				sc.SetState(SCE_PAS_CHARACTER);
+			} else if (setOperator.Contains(sc.ch) && !(curLineState & stateInAsm)) {
+				sc.SetState(SCE_PAS_OPERATOR);
+			} else if (curLineState & stateInAsm) {
+				sc.SetState(SCE_PAS_ASM);
+			}
 		}
 	}
-	return lev;
-}
 
-static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-	Accessor &styler) {
-
-	styler.StartAt(startPos);
+	if (sc.state == SCE_PAS_IDENTIFIER && setWord.Contains(sc.chPrev)) {
+		ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting);
+	}
 
-	int state = initStyle;
-	if (state == SCE_C_CHARACTER)	// Does not leak onto next line
-		state = SCE_C_DEFAULT;
-	char chPrev = ' ';
-	char chNext = styler[startPos];
-	unsigned int lengthDoc = startPos + length;
+	sc.Complete();
+}
 
-	bool bInClassDefinition;
+static bool IsStreamCommentStyle(int style) {
+	return style == SCE_PAS_COMMENT || style == SCE_PAS_COMMENT2;
+}
 
-	int currentLine = styler.GetLine(startPos);
-	if (currentLine > 0) {
-		styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
-		bInClassDefinition = (styler.GetLineState(currentLine) == 1);
-	} else {
-		styler.SetLineState(currentLine, 0);
-		bInClassDefinition = false;
+static bool IsCommentLine(int line, Accessor &styler) {
+	int pos = styler.LineStart(line);
+	int eolPos = styler.LineStart(line + 1) - 1;
+	for (int i = pos; i < eolPos; i++) {
+		char ch = styler[i];
+		char chNext = styler.SafeGetCharAt(i + 1);
+		int style = styler.StyleAt(i);
+		if (ch == '/' && chNext == '/' && style == SCE_PAS_COMMENTLINE) {
+			return true;
+		} else if (!IsASpaceOrTab(ch)) {
+			return false;
+		}
 	}
+	return false;
+}
 
-	bool bInAsm = (state == SCE_C_REGEX);
-	if (bInAsm)
-		state = SCE_C_DEFAULT;
-
-	styler.StartSegment(startPos);
-	for (unsigned int i = startPos; i < lengthDoc; i++) {
-		char ch = chNext;
+static unsigned int GetFoldInPreprocessorLevelFlag(int lineFoldStateCurrent) {
+	return lineFoldStateCurrent & stateFoldInPreprocessorLevelMask;
+}
 
-		chNext = styler.SafeGetCharAt(i + 1);
+static void SetFoldInPreprocessorLevelFlag(int &lineFoldStateCurrent, unsigned int nestLevel) {
+	lineFoldStateCurrent &= ~stateFoldInPreprocessorLevelMask;
+	lineFoldStateCurrent |= nestLevel & stateFoldInPreprocessorLevelMask;
+}
 
-		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
-			// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
-			// Avoid triggering two times on Dos/Win
-			// End of line
-			if (state == SCE_C_CHARACTER) {
-				ColourTo(styler, i, state, bInAsm);
-				state = SCE_C_DEFAULT;
-			}
-			currentLine++;
-			styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
+static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent, 
+		unsigned int startPos, Accessor &styler) {
+	CharacterSet setWord(CharacterSet::setAlpha);
+
+	char s[11];	// Size of the longest possible keyword + one additional character + null
+	GetForwardRangeLowered(startPos, setWord, styler, s, sizeof(s));
+
+	unsigned int nestLevel = GetFoldInPreprocessorLevelFlag(lineFoldStateCurrent);
+
+	if (strcmp(s, "if") == 0 || 
+		strcmp(s, "ifdef") == 0 || 
+		strcmp(s, "ifndef") == 0 || 
+		strcmp(s, "ifopt") == 0 || 
+		strcmp(s, "region") == 0) {
+		nestLevel++;
+		SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
+		lineFoldStateCurrent |= stateFoldInPreprocessor;
+		levelCurrent++;
+	} else if (strcmp(s, "endif") == 0 || 
+		strcmp(s, "ifend") == 0 || 
+		strcmp(s, "endregion") == 0) {
+		nestLevel--;
+		SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
+		if (nestLevel == 0) {
+			lineFoldStateCurrent &= ~stateFoldInPreprocessor;
 		}
-
-		if (styler.IsLeadByte(ch)) {
-			chNext = styler.SafeGetCharAt(i + 2);
-			chPrev = ' ';
-			i += 1;
-			continue;
+		levelCurrent--;
+		if (levelCurrent < SC_FOLDLEVELBASE) {
+			levelCurrent = SC_FOLDLEVELBASE;
 		}
+	}
+}
 
-		if (state == SCE_C_DEFAULT) {
-			if (iswordstart(ch) || ch == '#' || ch == '$' || (ch == '@' && bInAsm)) {
-				ColourTo(styler, i-1, state, bInAsm);
-				state = SCE_C_IDENTIFIER;
-			} else if (ch == '{' && chNext != '$' && chNext != '&') {
-				ColourTo(styler, i-1, state, bInAsm);
-				state = SCE_C_COMMENT;
-			} else if (ch == '(' && chNext == '*'
-						&& styler.SafeGetCharAt(i + 2) != '$'
-						&& styler.SafeGetCharAt(i + 2) != '&') {
-				ColourTo(styler, i-1, state, bInAsm);
-				state = SCE_C_COMMENTDOC;
-			} else if (ch == '/' && chNext == '/') {
-				ColourTo(styler, i-1, state, bInAsm);
-				state = SCE_C_COMMENTLINE;
-			} else if (ch == '\'') {
-				ColourTo(styler, i-1, state, bInAsm);
-				state = SCE_C_CHARACTER;
-			} else if (ch == '{' && (chNext == '$' || chNext=='&')) {
-				ColourTo(styler, i-1, state, bInAsm);
-				state = SCE_C_PREPROCESSOR;
-			} else if (isoperator(ch)) {
-				ColourTo(styler, i-1, state, bInAsm);
-				ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
-
-			}
-		} else if (state == SCE_C_IDENTIFIER) {
-			bool bDoublePoint = ((ch == '.') && (chPrev == '.'));
-			if ((!iswordchar(ch) && ch != '$' && ch != '#' && (ch != '@' || !bInAsm)) || bDoublePoint) {
-				if (bDoublePoint) i--;
-				int lStateChange = classifyWordPascal(styler.GetStartSegment(), i - 1, keywordlists, styler, bInClassDefinition, bInAsm);
-
-				if(lStateChange == 1) {
-					styler.SetLineState(currentLine, 1);
-					bInClassDefinition = true;
-				} else if(lStateChange == 2) {
-					bInAsm = true;
-				} else if(lStateChange == -1) {
-					styler.SetLineState(currentLine, 0);
-					bInClassDefinition = false;
-					bInAsm = false;
-				}
-				if (bDoublePoint) {
-					i++;
-					ColourTo(styler, i-1, SCE_C_DEFAULT, bInAsm);
-				}
+static unsigned int SkipWhiteSpace(unsigned int currentPos, unsigned int endPos, 
+		Accessor &styler, bool includeChars = false) {
+	CharacterSet setWord(CharacterSet::setAlphaNum, "_");
+	unsigned int j = currentPos + 1;
+	char ch = styler.SafeGetCharAt(j);
+	while ((j < endPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' || 
+		IsStreamCommentStyle(styler.StyleAt(j)) || (includeChars && setWord.Contains(ch)))) {
+		j++;
+		ch = styler.SafeGetCharAt(j);
+	}
+	return j;
+}
 
-				state = SCE_C_DEFAULT;
-				chNext = styler.SafeGetCharAt(i + 1);
-				if (ch == '{' && chNext != '$' && chNext != '&') {
-					state = SCE_C_COMMENT;
-				} else if (ch == '(' && chNext == '*'
-						&& styler.SafeGetCharAt(i + 2) != '$'
-						&& styler.SafeGetCharAt(i + 2) != '&') {
-					ColourTo(styler, i-1, state, bInAsm);
-					state = SCE_C_COMMENTDOC;
-				} else if (ch == '/' && chNext == '/') {
-					state = SCE_C_COMMENTLINE;
-				} else if (ch == '\'') {
-					state = SCE_C_CHARACTER;
-				} else if (isoperator(ch)) {
-					ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
-				}
-			}
-		} else {
-			if (state == SCE_C_PREPROCESSOR) {
-				if (ch=='}'){
-					ColourTo(styler, i, state, bInAsm);
-					state = SCE_C_DEFAULT;
-				} else {
-					if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
-						ColourTo(styler, i-1, state, bInAsm);
-						state = SCE_C_DEFAULT;
+static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCurrent, 
+		int startPos, unsigned int endPos, 
+		unsigned int lastStart, unsigned int currentPos, Accessor &styler) {
+	char s[100];
+	GetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));
+
+	if (strcmp(s, "record") == 0) {
+		lineFoldStateCurrent |= stateFoldInRecord;
+		levelCurrent++;
+	} else if (strcmp(s, "begin") == 0 || 
+		strcmp(s, "asm") == 0 || 
+		strcmp(s, "try") == 0 || 
+		(strcmp(s, "case") == 0 && !(lineFoldStateCurrent & stateFoldInRecord))) {
+		levelCurrent++;
+	} else if (strcmp(s, "class") == 0 || strcmp(s, "object") == 0) {
+		// "class" & "object" keywords require special handling...
+		bool ignoreKeyword = false;
+		unsigned int j = SkipWhiteSpace(currentPos, endPos, styler);
+		if (j < endPos) {
+			CharacterSet setWordStart(CharacterSet::setAlpha, "_");
+			CharacterSet setWord(CharacterSet::setAlphaNum, "_");
+
+			if (styler.SafeGetCharAt(j) == ';') {
+				// Handle forward class declarations ("type TMyClass = class;") 
+				// and object method declarations ("TNotifyEvent = procedure(Sender: TObject) of object;")
+				ignoreKeyword = true;
+			} else if (strcmp(s, "class") == 0) {
+				// "class" keyword has a few more special cases...
+				if (styler.SafeGetCharAt(j) == '(') {
+					// Handle simplified complete class declarations ("type TMyClass = class(TObject);") 
+					j = SkipWhiteSpace(j, endPos, styler, true);
+					if (j < endPos && styler.SafeGetCharAt(j) == ')') {
+						j = SkipWhiteSpace(j, endPos, styler);
+						if (j < endPos && styler.SafeGetCharAt(j) == ';') {
+							ignoreKeyword = true;
+						}
 					}
-				}
-			} else if (state == SCE_C_COMMENT) {
-				if (ch == '}' ) {
-					ColourTo(styler, i, state, bInAsm);
-					state = SCE_C_DEFAULT;
-				}
-			} else if (state == SCE_C_COMMENTDOC) {
-				if (ch == ')' && chPrev == '*') {
-					if (((i > styler.GetStartSegment() + 2) || (
-						(initStyle == SCE_C_COMMENTDOC) &&
-						(styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
-							ColourTo(styler, i, state, bInAsm);
-							state = SCE_C_DEFAULT;
+				} else if (setWordStart.Contains(styler.SafeGetCharAt(j))) {
+					char s2[11];	// Size of the longest possible keyword + one additional character + null
+					GetForwardRangeLowered(j, setWord, styler, s2, sizeof(s2));
+
+					if (strcmp(s2, "procedure") == 0 || 
+						strcmp(s2, "function") == 0 || 
+						strcmp(s2, "of") == 0 || 
+						strcmp(s2, "var") == 0 || 
+						strcmp(s2, "property") == 0 || 
+						strcmp(s2, "operator") == 0) {
+						ignoreKeyword = true;
 					}
 				}
-			} else if (state == SCE_C_COMMENTLINE) {
-				if (ch == '\r' || ch == '\n') {
-					ColourTo(styler, i-1, state, bInAsm);
-					state = SCE_C_DEFAULT;
-				}
-			} else if (state == SCE_C_CHARACTER) {
-				if (ch == '\'') {
-					ColourTo(styler, i, state, bInAsm);
-					state = SCE_C_DEFAULT;
-				}
 			}
 		}
-		chPrev = ch;
+		if (!ignoreKeyword) {
+			levelCurrent++;
+		}
+	} else if (strcmp(s, "interface") == 0) {
+		// "interface" keyword requires special handling...
+		bool ignoreKeyword = true;
+		int j = lastStart - 1;
+		char ch = styler.SafeGetCharAt(j);
+		while ((j >= startPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' || 
+			IsStreamCommentStyle(styler.StyleAt(j)))) {
+			j--;
+			ch = styler.SafeGetCharAt(j);
+		}
+		if (j >= startPos && styler.SafeGetCharAt(j) == '=') {
+			ignoreKeyword = false;
+		}
+		if (!ignoreKeyword) {
+			levelCurrent++;
+		}
+	} else if (strcmp(s, "end") == 0) {
+		lineFoldStateCurrent &= ~stateFoldInRecord;
+		levelCurrent--;
+		if (levelCurrent < SC_FOLDLEVELBASE) {
+			levelCurrent = SC_FOLDLEVELBASE;
+		}
 	}
-	ColourTo(styler, lengthDoc - 1, state, bInAsm);
 }
 
 static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, WordList *[],
-                            Accessor &styler) {
+		Accessor &styler) {
 	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 	bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
 	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
@@ -279,11 +503,13 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word
 	int lineCurrent = styler.GetLine(startPos);
 	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 	int levelCurrent = levelPrev;
+	int lineFoldStateCurrent = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) & stateFoldMaskAll : 0;
 	char chNext = styler[startPos];
 	int styleNext = styler.StyleAt(startPos);
 	int style = initStyle;
 
 	int lastStart = 0;
+	CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
 
 	for (unsigned int i = startPos; i < endPos; i++) {
 		char ch = chNext;
@@ -293,53 +519,45 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word
 		styleNext = styler.StyleAt(i + 1);
 		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 
-		if (stylePrev != SCE_C_WORD && style == SCE_C_WORD)
+		if (foldComment && IsStreamCommentStyle(style)) {
+			if (!IsStreamCommentStyle(stylePrev)) {
+				levelCurrent++;
+			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+				// Comments don't end at end of line and the next character may be unstyled.
+				levelCurrent--;
+			}
+		}
+		if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
 		{
-			// Store last word start point.
-			lastStart = i;
+			if (!IsCommentLine(lineCurrent - 1, styler)
+			    && IsCommentLine(lineCurrent + 1, styler))
+				levelCurrent++;
+			else if (IsCommentLine(lineCurrent - 1, styler)
+			         && !IsCommentLine(lineCurrent+1, styler))
+				levelCurrent--;
 		}
-
-		if (stylePrev == SCE_C_WORD) {
-			if(iswordchar(ch) && !iswordchar(chNext)) {
-				char s[100];
-				getRange(lastStart, i, styler, s, sizeof(s));
-				levelCurrent += classifyFoldPointPascal(s);
+		if (foldPreprocessor) {
+			if (style == SCE_PAS_PREPROCESSOR && ch == '{' && chNext == '$') {
+				ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 2, styler);
+			} else if (style == SCE_PAS_PREPROCESSOR2 && ch == '(' && chNext == '*' 
+			           && styler.SafeGetCharAt(i + 2) == '$') {
+				ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler);
 			}
 		}
 
-		if (foldComment && (style == SCE_C_COMMENTLINE)) {
-			if ((ch == '/') && (chNext == '/')) {
-				char chNext2 = styler.SafeGetCharAt(i + 2);
-				if (chNext2 == '{') {
-					levelCurrent++;
-				} else if (chNext2 == '}') {
-					levelCurrent--;
-				}
-			}
+		if (stylePrev != SCE_PAS_WORD && style == SCE_PAS_WORD)
+		{
+			// Store last word start point.
+			lastStart = i;
 		}
-
-		if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
-			if (ch == '{' && chNext == '$') {
-				unsigned int j=i+2; // skip {$
-				while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
-					j++;
-				}
-				if (styler.Match(j, "region") || styler.Match(j, "if")) {
-					levelCurrent++;
-				} else if (styler.Match(j, "end")) {
-					levelCurrent--;
-				}
+		if (stylePrev == SCE_PAS_WORD && !(lineFoldStateCurrent & stateFoldInPreprocessor)) {
+			if(setWord.Contains(ch) && !setWord.Contains(chNext)) {
+				ClassifyPascalWordFoldPoint(levelCurrent, lineFoldStateCurrent, startPos, endPos, lastStart, i, styler);
 			}
 		}
 
-		if (foldComment && IsStreamCommentStyle(style)) {
-			if (!IsStreamCommentStyle(stylePrev)) {
-				levelCurrent++;
-			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
-				// Comments don't end at end of line and the next character may be unstyled.
-				levelCurrent--;
-			}
-		}
+		if (!IsASpace(ch))
+			visibleChars++;
 
 		if (atEOL) {
 			int lev = levelPrev;
@@ -350,23 +568,24 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word
 			if (lev != styler.LevelAt(lineCurrent)) {
 				styler.SetLevel(lineCurrent, lev);
 			}
+			int newLineState = (styler.GetLineState(lineCurrent) & ~stateFoldMaskAll) | lineFoldStateCurrent;
+			styler.SetLineState(lineCurrent, newLineState);
 			lineCurrent++;
 			levelPrev = levelCurrent;
 			visibleChars = 0;
 		}
-
-		if (!isspacechar(ch))
-			visibleChars++;
 	}
 
-	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
-	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
-	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+	// If we didn't reach the EOL in previous loop, store line level and whitespace information.
+	// The rest will be filled in later...
+	int lev = levelPrev;
+	if (visibleChars == 0 && foldCompact)
+		lev |= SC_FOLDLEVELWHITEFLAG;
+	styler.SetLevel(lineCurrent, lev);
 }
 
 static const char * const pascalWordListDesc[] = {
 	"Keywords",
-	"Classwords",
 	0
 };
 
diff --git a/plugins/scintilla/scintilla/LexPerl.cxx b/plugins/scintilla/scintilla/LexPerl.cxx
index f57f73c..0c66036 100644
--- a/plugins/scintilla/scintilla/LexPerl.cxx
+++ b/plugins/scintilla/scintilla/LexPerl.cxx
@@ -247,8 +247,9 @@ static bool styleCheckSubPrototype(Accessor &styler, unsigned int bk)
 static bool isMatch(const char *sref, char *s)
 {
 	// match per-line delimiter - must kill trailing CR if CRLF
-	if (s[strlen(s) - 1] == '\r')
-		s[strlen(s) - 1] = '\0';
+	int i = strlen(s);
+	if (i != 0 && s[i - 1] == '\r')
+		s[i - 1] = '\0';
 	return (strcmp(sref, s) == 0);
 }
 
@@ -569,7 +570,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 						sc.Forward(ws_skip + 1);
 						HereDoc.Quote = delim_ch;
 						HereDoc.Quoted = true;
-					} else if (ws_skip == 0 && setNonHereDoc.Contains(sc.chNext)
+					} else if ((ws_skip == 0 && setNonHereDoc.Contains(sc.chNext))
 							   || ws_skip > 0) {
 						// left shift << or <<= operator cases
 						// restore position if operator
@@ -962,6 +963,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 				bool hereDocSpace = false;		// for: SCALAR [whitespace] '<<'
 				unsigned int bk = (sc.currentPos > 0) ? sc.currentPos - 1: 0;
 				unsigned int bkend;
+				sc.Complete();
 				styler.Flush();
 				if (styler.StyleAt(bk) == SCE_PL_DEFAULT)
 					hereDocSpace = true;
@@ -1141,6 +1143,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 				}
 				backFlag = BACK_NONE;
 			} else if (sc.ch == '(' && sc.currentPos > 0) {	// '(' or subroutine prototype
+				sc.Complete();
 				if (styleCheckSubPrototype(styler, sc.currentPos - 1)) {
 					sc.SetState(SCE_PL_SUB_PROTOTYPE);
 					backFlag = BACK_NONE;
@@ -1183,8 +1186,15 @@ static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
 	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 	// Custom folding of POD and packages
+
+	// property fold.perl.pod 
+	//	Enable folding Pod blocks when using the Perl lexer. 
 	bool foldPOD = styler.GetPropertyInt("fold.perl.pod", 1) != 0;
+
+	// property fold.perl.package 
+	//	Enable folding packages when using the Perl lexer. 
 	bool foldPackage = styler.GetPropertyInt("fold.perl.package", 1) != 0;
+
 	unsigned int endPos = startPos + length;
 	int visibleChars = 0;
 	int lineCurrent = styler.GetLine(startPos);
diff --git a/plugins/scintilla/scintilla/LexPowerPro.cxx b/plugins/scintilla/scintilla/LexPowerPro.cxx
new file mode 100644
index 0000000..9320baf
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexPowerPro.cxx
@@ -0,0 +1,600 @@
+// Scintilla source code edit control
+// @file LexPowerPro.cxx
+// PowerPro utility, written by Bruce Switzer, is available from http://powerpro.webeddie.com
+// PowerPro lexer is written by Christopher Bean (cbean cb-software net)
+//
+// Lexer code heavily borrowed from: 
+//	LexAU3.cxx by Jos van der Zande
+//	LexCPP.cxx by Neil Hodgson
+//	LexVB.cxx by Neil Hodgson
+//
+// Changes:
+// 	2008-10-25 - Initial release
+//	2008-10-26 - Changed how <name> is hilighted in  'function <name>' so that 
+//				 local isFunction = "" and local functions = "" don't get falsely highlighted
+//	2008-12-14 - Added bounds checking for szKeyword and szDo
+//			   - Replaced SetOfCharacters with CharacterSet
+//			   - Made sure that CharacterSet::Contains is passed only positive values
+//			   - Made sure that the return value of Accessor::SafeGetCharAt is positive before 
+//				 passsing to functions that require positive values like isspacechar()
+//			   - Removed unused visibleChars processing from ColourisePowerProDoc()
+//			   - Fixed bug with folding logic where line continuations didn't end where 
+//				 they were supposed to
+//			   - Moved all helper functions to the top of the file
+//
+// Copyright 1998-2005 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Platform.h"
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+#include "CharacterSet.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static inline bool IsStreamCommentStyle(int style) {
+	return style == SCE_POWERPRO_COMMENTBLOCK;
+}
+
+static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
+{
+	int nsPos = styler.LineStart(szLine);
+	int nePos = styler.LineStart(szLine + 1) - 2;
+	while (nsPos < nePos)
+	{
+		int stylech = styler.StyleAt(nsPos);
+		if (!(stylech == SCE_POWERPRO_COMMENTBLOCK)) {
+			char ch = styler.SafeGetCharAt(nePos);
+			char chPrev = styler.SafeGetCharAt(nePos-1);
+			char chPrevPrev = styler.SafeGetCharAt(nePos-2);
+			if (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) ) {
+				if (chPrevPrev == ';' && chPrev == ';' && ch == '+')
+					return true;
+				else
+					return false;
+			}
+		}
+		nePos--; // skip to next char
+	}
+	return false;
+}
+
+// Routine to find first none space on the current line and return its Style
+// needed for comment lines not starting on pos 1 
+static int GetStyleFirstWord(unsigned int szLine, Accessor &styler)
+{
+	int nsPos = styler.LineStart(szLine);
+	int nePos = styler.LineStart(szLine+1) - 1;
+	char ch = styler.SafeGetCharAt(nsPos);
+	
+	while (ch > 0 && isspacechar(ch) && nsPos < nePos)
+	{
+		nsPos++; // skip to next char
+		ch = styler.SafeGetCharAt(nsPos);
+
+	}
+	return styler.StyleAt(nsPos);
+}
+
+//returns true if there is a function to highlight
+//used to highlight <name> in 'function <name>'
+static bool HasFunction(Accessor &styler, unsigned int currentPos) {
+	
+	//check for presence of 'function '
+	return 	(styler.SafeGetCharAt(currentPos) == ' ' 	
+	&& tolower(styler.SafeGetCharAt(currentPos-1)) == 'n' 
+	&& tolower(styler.SafeGetCharAt(currentPos-2)) == 'o'
+	&& tolower(styler.SafeGetCharAt(currentPos-3)) == 'i'
+	&& tolower(styler.SafeGetCharAt(currentPos-4)) == 't'
+	&& tolower(styler.SafeGetCharAt(currentPos-5)) == 'c'
+	&& tolower(styler.SafeGetCharAt(currentPos-6)) == 'n'
+	&& tolower(styler.SafeGetCharAt(currentPos-7)) == 'u'
+	&& tolower(styler.SafeGetCharAt(currentPos-8)) == 'f'
+	//only allow 'function ' to appear at the beginning of a line
+	&& (styler.SafeGetCharAt(currentPos-9) == '\n'   		
+		|| styler.SafeGetCharAt(currentPos-9) == '\r'
+		|| (styler.SafeGetCharAt(currentPos -9, '\0')) == '\0') //is the first line
+	);
+}
+
+static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                            Accessor &styler, bool caseSensitive) {
+
+	WordList &keywords  = *keywordlists[0];
+	WordList &keywords2 = *keywordlists[1];
+	WordList &keywords3 = *keywordlists[2];
+	WordList &keywords4 = *keywordlists[3];
+	
+	//define the character sets 
+	CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true);
+	CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
+
+	StyleContext sc(startPos, length, initStyle, styler);
+	char s_save[100]; //for last line highlighting
+	
+	for (; sc.More(); sc.Forward()) {
+			
+		// **********************************************
+		// save the total current word for eof processing
+		char s[100];
+		sc.GetCurrentLowered(s, sizeof(s));
+		 
+		if ((sc.ch > 0) && setWord.Contains(sc.ch)) 
+		{
+			strcpy(s_save,s);
+			int tp = strlen(s_save);
+			if (tp < 99) {
+				s_save[tp] = static_cast<char>(tolower(sc.ch));
+				s_save[tp+1] = '\0';
+			}
+		}
+		// **********************************************
+		//
+
+		if (sc.atLineStart) {
+			if (sc.state == SCE_POWERPRO_DOUBLEQUOTEDSTRING) {
+				// Prevent SCE_POWERPRO_STRINGEOL from leaking back to previous line which
+				// ends with a line continuation by locking in the state upto this position.
+				sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING);
+			}
+		}
+
+		// Determine if the current state should terminate.
+		switch (sc.state) {
+			case SCE_POWERPRO_OPERATOR:
+				sc.SetState(SCE_POWERPRO_DEFAULT);
+				break;
+			
+			case SCE_POWERPRO_NUMBER:
+
+				if (!IsADigit(sc.ch))
+					sc.SetState(SCE_POWERPRO_DEFAULT);
+				
+				break;
+
+			case SCE_POWERPRO_IDENTIFIER:
+				//if ((sc.ch > 0) && !setWord.Contains(sc.ch) || (sc.ch == '.')) { // use this line if don't want to match keywords with . in them. ie: win.debug will match both win and debug so win debug will also be colorized
+				if ((sc.ch > 0) && !setWord.Contains(sc.ch)){  // || (sc.ch == '.')) { // use this line if you want to match keywords with a . ie: win.debug will only match win.debug neither win nor debug will be colorized separately
+					char s[1000];
+					if (caseSensitive) {
+						sc.GetCurrent(s, sizeof(s));
+					} else {
+						sc.GetCurrentLowered(s, sizeof(s));
+					}
+					if (keywords.InList(s)) {
+						sc.ChangeState(SCE_POWERPRO_WORD);
+					} else if (keywords2.InList(s)) {
+						sc.ChangeState(SCE_POWERPRO_WORD2);
+					} else if (keywords3.InList(s)) {
+						sc.ChangeState(SCE_POWERPRO_WORD3);
+					} else if (keywords4.InList(s)) {
+						sc.ChangeState(SCE_POWERPRO_WORD4);
+					}
+					sc.SetState(SCE_POWERPRO_DEFAULT);
+				}
+				break;
+
+			case SCE_POWERPRO_LINECONTINUE:
+				if (sc.atLineStart) {
+					sc.SetState(SCE_POWERPRO_DEFAULT);
+				} else if (sc.Match('/', '*') || sc.Match('/', '/')) {
+					sc.SetState(SCE_POWERPRO_DEFAULT);
+				}
+				break;
+
+			case SCE_POWERPRO_COMMENTBLOCK:
+				if (sc.Match('*', '/')) {
+					sc.Forward();
+					sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+				}
+				break;
+
+			case SCE_POWERPRO_COMMENTLINE:
+				if (sc.atLineStart) {
+					sc.SetState(SCE_POWERPRO_DEFAULT);
+				}
+				break;
+
+			case SCE_POWERPRO_DOUBLEQUOTEDSTRING:
+				if (sc.atLineEnd) {
+					sc.ChangeState(SCE_POWERPRO_STRINGEOL);
+				} else if (sc.ch == '\\') {
+					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+						sc.Forward();
+					}
+				} else if (sc.ch == '\"') {
+					sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+				}
+				break;
+
+			case SCE_POWERPRO_SINGLEQUOTEDSTRING:
+				if (sc.atLineEnd) {
+					sc.ChangeState(SCE_POWERPRO_STRINGEOL);
+				} else if (sc.ch == '\\') {
+					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
+						sc.Forward();
+					}
+				} else if (sc.ch == '\'') {
+					sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+				}
+				break;
+
+			case SCE_POWERPRO_STRINGEOL:
+				if (sc.atLineStart) {
+					sc.SetState(SCE_POWERPRO_DEFAULT);
+				}
+				break;
+
+			case SCE_POWERPRO_VERBATIM:
+				if (sc.ch == '\"') {
+					if (sc.chNext == '\"') {
+						sc.Forward();
+					} else {
+						sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+					}
+				}
+				break;
+
+			case SCE_POWERPRO_ALTQUOTE:
+				if (sc.ch == '#') {
+					if (sc.chNext == '#') {
+						sc.Forward();
+					} else {
+						sc.ForwardSetState(SCE_POWERPRO_DEFAULT);
+					}
+				}
+				break;
+				
+			case SCE_POWERPRO_FUNCTION:
+				if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ' ' || sc.ch == '(') {
+					sc.SetState(SCE_POWERPRO_DEFAULT);
+				}
+			break;
+		}
+
+		// Determine if a new state should be entered.
+		if (sc.state == SCE_POWERPRO_DEFAULT) {
+			if (sc.Match('?', '\"')) {
+				sc.SetState(SCE_POWERPRO_VERBATIM);
+				sc.Forward();
+			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+				sc.SetState(SCE_POWERPRO_NUMBER);
+			}else if (sc.Match('?','#')) {
+				if (sc.ch == '?' && sc.chNext == '#') {
+					sc.SetState(SCE_POWERPRO_ALTQUOTE);
+					sc.Forward();
+				}
+			} else if (HasFunction(styler, sc.currentPos)) {	//highlight <name> in 'function <name>'
+				sc.SetState(SCE_POWERPRO_FUNCTION); 
+			} else if (sc.ch == '@' && sc.atLineStart) { 		//alternate function definition [label]
+				sc.SetState(SCE_POWERPRO_FUNCTION);
+			} else if ((sc.ch > 0) && (setWordStart.Contains(sc.ch) || (sc.ch == '?'))) {
+				sc.SetState(SCE_POWERPRO_IDENTIFIER);
+			} else if (sc.Match(";;+")) { 
+				sc.SetState(SCE_POWERPRO_LINECONTINUE);
+			} else if (sc.Match('/', '*')) {
+				sc.SetState(SCE_POWERPRO_COMMENTBLOCK);
+				sc.Forward();	// Eat the * so it isn't used for the end of the comment
+			} else if (sc.Match('/', '/')) {
+				sc.SetState(SCE_POWERPRO_COMMENTLINE);
+			} else if (sc.atLineStart && sc.ch == ';') {		//legacy comment that can only appear at the beginning of a line
+				sc.SetState(SCE_POWERPRO_COMMENTLINE);
+			} else if (sc.Match(";;")) {
+				sc.SetState(SCE_POWERPRO_COMMENTLINE);
+			} else if (sc.ch == '\"') {
+				sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING);
+			} else if (sc.ch == '\'') {
+				sc.SetState(SCE_POWERPRO_SINGLEQUOTEDSTRING);
+			} else if (isoperator(static_cast<char>(sc.ch))) {
+				sc.SetState(SCE_POWERPRO_OPERATOR);
+			}
+		}
+	}
+
+	//*************************************
+	// Colourize the last word correctly 
+	//*************************************
+	if (sc.state == SCE_POWERPRO_IDENTIFIER)
+	{
+		if (keywords.InList(s_save)) {
+			sc.ChangeState(SCE_POWERPRO_WORD);
+			sc.SetState(SCE_POWERPRO_DEFAULT);
+		}
+		else if (keywords2.InList(s_save)) {
+			sc.ChangeState(SCE_POWERPRO_WORD2);
+			sc.SetState(SCE_POWERPRO_DEFAULT);
+		}
+		else if (keywords3.InList(s_save)) {
+			sc.ChangeState(SCE_POWERPRO_WORD3);
+			sc.SetState(SCE_POWERPRO_DEFAULT);
+		}
+		else if (keywords4.InList(s_save)) {
+			sc.ChangeState(SCE_POWERPRO_WORD4);
+			sc.SetState(SCE_POWERPRO_DEFAULT);
+		}
+		else {
+			sc.SetState(SCE_POWERPRO_DEFAULT);
+		}
+	}
+	sc.Complete();
+}
+
+static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
+{
+	//define the character sets
+	CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true);
+	CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
+
+	bool isFoldingAll = true; //used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function)
+	int endPos = startPos + length;
+	int lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly
+
+	// get settings from the config files for folding comments and preprocessor lines
+	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+	bool foldInComment = styler.GetPropertyInt("fold.comment") == 2;
+	bool foldCompact = true;
+	
+	// Backtrack to previous line in case need to fix its fold status
+	int lineCurrent = styler.GetLine(startPos);
+	if (startPos > 0) {
+		isFoldingAll = false;
+		if (lineCurrent > 0) {
+			lineCurrent--;
+			startPos = styler.LineStart(lineCurrent);
+		}
+	}
+	// vars for style of previous/current/next lines 
+	int style = GetStyleFirstWord(lineCurrent,styler);
+	int stylePrev = 0;
+	
+	// find the first previous line without continuation character at the end
+	while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
+	       (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
+		lineCurrent--;
+		startPos = styler.LineStart(lineCurrent);
+	}
+	if (lineCurrent > 0) {
+		stylePrev = GetStyleFirstWord(lineCurrent-1,styler);
+	}
+	// vars for getting first word to check for keywords
+	bool FirstWordStart = false;
+	bool FirstWordEnd = false;
+		
+	const unsigned int KEYWORD_MAX = 10;
+	char szKeyword[KEYWORD_MAX]="";
+	unsigned int	 szKeywordlen = 0;
+	
+	char szDo[3]="";
+	int	 szDolen = 0;
+	bool DoFoundLast = false;
+	
+	// var for indentlevel
+	int levelCurrent = SC_FOLDLEVELBASE;
+	if (lineCurrent > 0) {
+		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+	}
+	int levelNext = levelCurrent;
+	
+	int	visibleChars = 0;
+	int functionCount = 0;
+	
+	char chNext = styler.SafeGetCharAt(startPos);
+	char chPrev = '\0';
+	char chPrevPrev = '\0';
+	char chPrevPrevPrev = '\0';
+	
+	for (int i = startPos; i < endPos; i++) {
+
+		char ch = chNext;
+		chNext = styler.SafeGetCharAt(i + 1);
+		
+		if ((ch > 0) && setWord.Contains(ch)) {
+			visibleChars++;
+		}
+		
+		// get the syle for the current character neede to check in comment
+		int stylech = styler.StyleAt(i);
+		
+		// get first word for the line for indent check max 9 characters
+		if (FirstWordStart && (!(FirstWordEnd))) {
+			if ((ch > 0) && !setWord.Contains(ch)) {
+				FirstWordEnd = true;
+			}
+			else if (szKeywordlen < KEYWORD_MAX - 1) {
+				szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
+				szKeyword[szKeywordlen] = '\0';
+			}
+		}
+		
+		// start the capture of the first word 
+		if (!(FirstWordStart)) {
+			if ((ch > 0) && (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/')) {
+				FirstWordStart = true;
+				if (szKeywordlen < KEYWORD_MAX - 1) {
+					szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
+					szKeyword[szKeywordlen] = '\0';
+				}
+			}
+		}
+		// only process this logic when not in comment section
+		if (stylech != SCE_POWERPRO_COMMENTLINE) {
+			if (DoFoundLast) {
+				if (DoFoundLast && (ch > 0) && setWord.Contains(ch)) {
+					DoFoundLast = false;
+				}		
+			}
+			// find out if the word "do" is the last on a "if" line
+			if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
+				if (szDolen == 2) {
+					szDo[0] = szDo[1];
+					szDo[1] = static_cast<char>(tolower(ch));
+					szDo[2] = '\0';
+					if (strcmp(szDo,"do") == 0 ) {
+						DoFoundLast = true;
+					}
+				}
+				else if (szDolen < 2) {
+					szDo[szDolen++] = static_cast<char>(tolower(ch));
+					szDo[szDolen] = '\0';
+				}
+			}
+		}
+
+		// End of Line found so process the information 
+		 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
+		 
+			// **************************
+			// Folding logic for Keywords
+			// **************************
+			
+			// if a keyword is found on the current line and the line doesn't end with ;;+ (continuation)
+			//    and we are not inside a commentblock.
+			if (szKeywordlen > 0 && 
+				(!(chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev ==';')) && 
+				((!(IsStreamCommentStyle(style)) || foldInComment)) ) {
+			
+				// only fold "if" last keyword is "then"  (else its a one line if)
+				if (strcmp(szKeyword,"if") == 0  && DoFoundLast) {
+						levelNext++;
+				}
+				// create new fold for these words 
+				if (strcmp(szKeyword,"for") == 0) {
+					levelNext++;
+				}
+				
+				//handle folding for functions/labels
+				//Note: Functions and labels don't have an explicit end like [end function]
+				//	1. functions/labels end at the start of another function
+				//	2. functions/labels end at the end of the file
+				if ((strcmp(szKeyword,"function") == 0) || (szKeywordlen > 0 && szKeyword[0] == '@')) {
+					if (isFoldingAll) { //if we're folding the whole document (recursivly by lua script)
+						
+						if (functionCount > 0) {
+							levelCurrent--;
+						} else {
+							levelNext++;
+						}
+						functionCount++;	
+						
+					} else { //if just folding a small piece (by clicking on the minus sign next to the word)
+						levelCurrent--;
+					}
+				}
+												
+				// end the fold for these words before the current line
+				if (strcmp(szKeyword,"endif") == 0 || strcmp(szKeyword,"endfor") == 0) {
+						levelNext--;
+						levelCurrent--;
+				}
+				// end the fold for these words before the current line and Start new fold 
+				if (strcmp(szKeyword,"else") == 0 || strcmp(szKeyword,"elseif") == 0 ) {
+						levelCurrent--;
+				}
+			}
+			// Preprocessor and Comment folding
+			int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
+
+			// *********************************
+			// Folding logic for Comment blocks
+			// *********************************
+			if (foldComment && IsStreamCommentStyle(style)) {
+				// Start of a comment block
+				if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
+				    levelNext++;
+				} 
+				// fold till the last line for normal comment lines
+				else if (IsStreamCommentStyle(stylePrev) 
+						&& !(styleNext == SCE_POWERPRO_COMMENTLINE)
+						&& stylePrev == SCE_POWERPRO_COMMENTLINE 
+						&& style == SCE_POWERPRO_COMMENTLINE) {
+					levelNext--;
+				}
+				// fold till the one but last line for Blockcomment lines
+				else if (IsStreamCommentStyle(stylePrev) 
+						&& !(styleNext == SCE_POWERPRO_COMMENTBLOCK)
+						&& style == SCE_POWERPRO_COMMENTBLOCK) {
+					levelNext--;
+					levelCurrent--;
+				}
+			}
+
+			int levelUse = levelCurrent;
+			int lev = levelUse | levelNext << 16;
+			if (visibleChars == 0 && foldCompact)
+				lev |= SC_FOLDLEVELWHITEFLAG;
+			if (levelUse < levelNext) {
+				lev |= SC_FOLDLEVELHEADERFLAG;
+			}
+			if (lev != styler.LevelAt(lineCurrent)) {
+				styler.SetLevel(lineCurrent, lev);
+			}
+
+			// reset values for the next line
+			lineCurrent++;
+			stylePrev = style;
+			style = styleNext;
+			levelCurrent = levelNext;
+			visibleChars = 0;
+			
+			// if the last characters are ;;+ then don't reset since the line continues on the next line.
+			if (chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev == ';') {
+				//do nothing
+			} else {
+				szKeywordlen = 0;
+				szDolen = 0;
+				FirstWordStart = false;
+				FirstWordEnd = false;
+				DoFoundLast = false;
+				//blank out keyword
+				for (unsigned int i = 0; i < KEYWORD_MAX; i++) {
+					szKeyword[i] = '\0';
+				}
+			}
+		}
+
+		// save the last processed characters
+		if ((ch > 0) && !isspacechar(ch)) {
+			chPrevPrevPrev = chPrevPrev;
+			chPrevPrev = chPrev;
+			chPrev = ch;
+			visibleChars++;
+		}
+	}
+
+	//close folds on the last line - without this a 'phantom' 
+	//fold can appear when an open fold is on the last line
+	//this can occur because functions and labels don't have an explicit end
+	if (lineCurrent >= lastLine) {
+		int lev = 0;
+		lev |= SC_FOLDLEVELWHITEFLAG;
+		styler.SetLevel(lineCurrent, lev);
+	}
+
+}
+
+static const char * const powerProWordLists[] = {
+            "Keyword list 1",
+            "Keyword list 2",
+            "Keyword list 3",
+            "Keyword list 4",
+            0,
+        };
+
+static void ColourisePowerProDocWrapper(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                                       Accessor &styler) {
+	ColourisePowerProDoc(startPos, length, initStyle, keywordlists, styler, false);
+}
+
+LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, "powerpro", FoldPowerProDoc, powerProWordLists);
diff --git a/plugins/scintilla/scintilla/LexProgress.cxx b/plugins/scintilla/scintilla/LexProgress.cxx
index c213569..d5217be 100644
--- a/plugins/scintilla/scintilla/LexProgress.cxx
+++ b/plugins/scintilla/scintilla/LexProgress.cxx
@@ -39,19 +39,19 @@ static inline bool IsAWordStart(int ch) {
 	return (ch < 0x80) && (isalpha(ch) || ch == '_');
 }
 
-enum SentenceStart { SetSentenceStart = 0xf, ResetSentenceStart = 0x10}; // true -> bit = 0
+enum SentenceStart { SetSentenceStart = 0xf, ResetSentenceStart = 0x10}; // true -> bit5 = 0
 
 static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                             Accessor &styler) {
 
-    WordList &keywords1 = *keywordlists[0];
-    WordList &keywords2 = *keywordlists[1];
-    WordList &keywords3 = *keywordlists[2];
-    //WordList &keywords4 = *keywordlists[3];
-    //WordList &keywords5 = *keywordlists[4];
+    WordList &keywords1 = *keywordlists[0];   // regular keywords
+    WordList &keywords2 = *keywordlists[1];   // block opening keywords, only when SentenceStart
+    WordList &keywords3 = *keywordlists[2];   // block opening keywords
+    //WordList &keywords4 = *keywordlists[3]; // preprocessor keywords. Not implemented
+    
 
 	int visibleChars = 0;
-	int mask;
+	int sentenceStartState; // true -> bit5 = 0
 
 	StyleContext sc(startPos, length, initStyle, styler);
 
@@ -86,21 +86,21 @@ static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, Wo
 			}
 		}
 		// Determine if a new state should be terminated.
-		mask = sc.state & 0x10;
+		sentenceStartState = sc.state & 0x10;
 		switch (sc.state & 0xf) {
 			case SCE_4GL_OPERATOR:
-				sc.SetState(SCE_4GL_DEFAULT | mask);
+				sc.SetState(SCE_4GL_DEFAULT | sentenceStartState);
 				break;
 			case SCE_4GL_NUMBER:
 				if (!(IsADigit(sc.ch))) {
-					sc.SetState(SCE_4GL_DEFAULT | mask);
+					sc.SetState(SCE_4GL_DEFAULT | sentenceStartState);
 				}
 				break;
 			case SCE_4GL_IDENTIFIER:
 				if (!IsAWordChar(sc.ch) && sc.ch != '-') {
 					char s[1000];
 					sc.GetCurrentLowered(s, sizeof(s));
-					if (((sc.state & 0x10) == 0) && keywords2.InList(s) || keywords3.InList(s)) {
+					if (((sentenceStartState == 0) && keywords2.InList(s)) || keywords3.InList(s)) { 
 						sc.ChangeState(SCE_4GL_BLOCK | ResetSentenceStart);
 					}
 					else if (keywords1.InList(s)) {
@@ -123,17 +123,17 @@ static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, Wo
 				if (sc.atLineStart) {
 					sc.SetState(SCE_4GL_DEFAULT & SetSentenceStart);
 				} else if (sc.ch == '*' && sc.chNext == '/') {
-					sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
+					sc.ForwardSetState(SCE_4GL_DEFAULT | sentenceStartState);
 				}
 				break;
 			case SCE_4GL_STRING:
 				if (sc.ch == '\"') {
-					sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
+					sc.ForwardSetState(SCE_4GL_DEFAULT | sentenceStartState);
 				}
 				break;
 			case SCE_4GL_CHARACTER:
 				if (sc.ch == '\'') {
-					sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
+					sc.ForwardSetState(SCE_4GL_DEFAULT | sentenceStartState);
 				}
 				break;
 			default:
@@ -141,7 +141,7 @@ static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, Wo
 					if (sc.ch == '*' && sc.chNext == '/') {
 						sc.Forward();
 						if ((sc.state & 0xf) == SCE_4GL_COMMENT1) {
-							sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
+							sc.ForwardSetState(SCE_4GL_DEFAULT | sentenceStartState);
 						}
 						else
 							sc.SetState((sc.state & 0x1f) - 1);
@@ -153,14 +153,14 @@ static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, Wo
 		}
 
 		// Determine if a new state should be entered.
-		mask = sc.state & 0x10;
+		sentenceStartState = sc.state & 0x10;
 		if ((sc.state & 0xf) == SCE_4GL_DEFAULT) {
 			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 				sc.SetState(SCE_4GL_NUMBER | ResetSentenceStart);
-			} else if (IsAWordStart(sc.ch) || (sc.ch == '@')) {
-				sc.SetState(SCE_4GL_IDENTIFIER | mask);
+			} else if (IsAWordStart(sc.ch) || sc.ch == '@') {
+				sc.SetState(SCE_4GL_IDENTIFIER | sentenceStartState);
 			} else if (sc.ch == '/' && sc.chNext == '*') {
-				sc.SetState(SCE_4GL_COMMENT1 | mask);
+				sc.SetState(SCE_4GL_COMMENT1 | sentenceStartState);
 				sc.Forward();
 			} else if (sc.ch == '\"') {
 				sc.SetState(SCE_4GL_STRING | ResetSentenceStart);
@@ -176,9 +176,12 @@ static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, Wo
 			} else if ((sc.ch == '.' || sc.ch == ':' || sc.ch == '}') && (sc.chNext == ' ' || sc.chNext == '\t' || sc.chNext == '\n' || sc.chNext == '\r')) {
 				sc.SetState(sc.state & SetSentenceStart);
 			} else if (isoperator(static_cast<char>(sc.ch))) {
+		/* 	This code allows highlight of handles. Alas, it would cause the frase "last-event:function"
+			to be recognized as a BlockBegin
+			
 				if (sc.ch == ':')
 					sc.SetState(SCE_4GL_OPERATOR & SetSentenceStart);
-				else
+				else */
 					sc.SetState(SCE_4GL_OPERATOR | ResetSentenceStart);
 			}
 		}
@@ -271,6 +274,4 @@ static const char * const FglWordLists[] = {
             0,
         };
 
-LexerModule lmProgress(SCLEX_PS, Colourise4glDoc, "progress", Fold4glDoc, FglWordLists);
-
-
+LexerModule lmProgress(SCLEX_PROGRESS, Colourise4glDoc, "progress", Fold4glDoc, FglWordLists);
diff --git a/plugins/scintilla/scintilla/LexPython.cxx b/plugins/scintilla/scintilla/LexPython.cxx
index 01d406d..7d31fd2 100644
--- a/plugins/scintilla/scintilla/LexPython.cxx
+++ b/plugins/scintilla/scintilla/LexPython.cxx
@@ -24,17 +24,27 @@
 using namespace Scintilla;
 #endif
 
-enum kwType { kwOther, kwClass, kwDef, kwImport };
+/* kwCDef, kwCTypeName only used for Cython */
+enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName };
+
 static const int indicatorWhitespace = 1;
 
 static bool IsPyComment(Accessor &styler, int pos, int len) {
 	return len > 0 && styler[pos] == '#';
 }
 
-static bool IsPyStringStart(int ch, int chNext, int chNext2) {
+enum literalsAllowed { litNone=0, litU=1, litB=2};
+
+static bool IsPyStringTypeChar(int ch, literalsAllowed allowed) {
+	return 
+		((allowed & litB) && (ch == 'b' || ch == 'B')) ||
+		((allowed & litU) && (ch == 'u' || ch == 'U'));
+}
+
+static bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) {
 	if (ch == '\'' || ch == '"')
 		return true;
-	if (ch == 'u' || ch == 'U') {
+	if (IsPyStringTypeChar(ch, allowed)) {
 		if (chNext == '"' || chNext == '\'')
 			return true;
 		if ((chNext == 'r' || chNext == 'R') && (chNext2 == '"' || chNext2 == '\''))
@@ -47,16 +57,16 @@ static bool IsPyStringStart(int ch, int chNext, int chNext2) {
 }
 
 /* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */
-static int GetPyStringState(Accessor &styler, int i, unsigned int *nextIndex) {
+static int GetPyStringState(Accessor &styler, int i, unsigned int *nextIndex, literalsAllowed allowed) {
 	char ch = styler.SafeGetCharAt(i);
 	char chNext = styler.SafeGetCharAt(i + 1);
 
-	// Advance beyond r, u, or ur prefix, but bail if there are any unexpected chars
+	// Advance beyond r, u, or ur prefix (or r, b, or br in Python 3.0), but bail if there are any unexpected chars
 	if (ch == 'r' || ch == 'R') {
 		i++;
 		ch = styler.SafeGetCharAt(i);
 		chNext = styler.SafeGetCharAt(i + 1);
-	} else if (ch == 'u' || ch == 'U') {
+	} else if (IsPyStringTypeChar(ch, allowed)) {
 		if (chNext == 'r' || chNext == 'R')
 			i += 2;
 		else
@@ -96,7 +106,7 @@ static inline bool IsAWordStart(int ch) {
 }
 
 static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
-                           WordList *keywordlists[], Accessor &styler) {
+        WordList *keywordlists[], Accessor &styler) {
 
 	int endPos = startPos + length;
 
@@ -105,19 +115,49 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
 	if (startPos > 0) {
 		if (lineCurrent > 0) {
 			lineCurrent--;
+			// Look for backslash-continued lines
+			while (lineCurrent > 0) {
+				int eolPos = styler.LineStart(lineCurrent) - 1;
+				int eolStyle = styler.StyleAt(eolPos);
+				if (eolStyle == SCE_P_STRING
+				    || eolStyle == SCE_P_CHARACTER
+				    || eolStyle == SCE_P_STRINGEOL) {
+					lineCurrent -= 1;
+				} else {
+					break;
+				}
+			}
 			startPos = styler.LineStart(lineCurrent);
-			if (startPos == 0)
-				initStyle = SCE_P_DEFAULT;
-			else
-				initStyle = styler.StyleAt(startPos - 1);
 		}
+		initStyle = startPos == 0 ? SCE_P_DEFAULT : styler.StyleAt(startPos - 1);
 	}
 
 	WordList &keywords = *keywordlists[0];
 	WordList &keywords2 = *keywordlists[1];
 
+	// property tab.timmy.whinge.level
+	//	For Python code, checks whether indenting is consistent. 
+	//	The default, 0 turns off indentation checking, 
+	//	1 checks whether each line is potentially inconsistent with the previous line, 
+	//	2 checks whether any space characters occur before a tab character in the indentation, 
+	//	3 checks whether any spaces are in the indentation, and 
+	//	4 checks for any tab characters in the indentation.
+	//	1 is a good level to use. 
 	const int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
 
+	// property lexer.python.literals.binary
+	//	Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712.
+	bool base2or8Literals = styler.GetPropertyInt("lexer.python.literals.binary", 1) != 0;
+
+	// property lexer.python.strings.u
+	//	Set to 0 to not recognise Python Unicode literals u"x" as used before Python 3.
+	literalsAllowed allowedLiterals = (styler.GetPropertyInt("lexer.python.strings.u", 1)) ? litU : litNone;
+
+	// property lexer.python.strings.b
+	//	Set to 0 to not recognise Python 3 bytes literals b"x".
+	if (styler.GetPropertyInt("lexer.python.strings.b", 1))
+		allowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litB);
+
 	initStyle = initStyle & 31;
 	if (initStyle == SCE_P_STRINGEOL) {
 		initStyle = SCE_P_DEFAULT;
@@ -126,12 +166,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
 	kwType kwLast = kwOther;
 	int spaceFlags = 0;
 	styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
-	bool hexadecimal = false;
+	bool base_n_number = false;
 
 	StyleContext sc(startPos, endPos - startPos, initStyle, styler);
 
 	bool indentGood = true;
 	int startIndicator = sc.currentPos;
+	bool inContinuedString = false;
 
 	for (; sc.More(); sc.Forward()) {
 
@@ -163,8 +204,12 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
 			}
 			lineCurrent++;
 			if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
-				sc.ChangeState(SCE_P_STRINGEOL);
-				sc.ForwardSetState(SCE_P_DEFAULT);
+				if (inContinuedString) {
+					inContinuedString = false;
+				} else {
+					sc.ChangeState(SCE_P_STRINGEOL);
+					sc.ForwardSetState(SCE_P_DEFAULT);
+				}
 			}
 			if (!sc.More())
 				break;
@@ -178,7 +223,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
 			sc.SetState(SCE_P_DEFAULT);
 		} else if (sc.state == SCE_P_NUMBER) {
 			if (!IsAWordChar(sc.ch) &&
-			        !(!hexadecimal && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
+			        !(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
 				sc.SetState(SCE_P_DEFAULT);
 			}
 		} else if (sc.state == SCE_P_IDENTIFIER) {
@@ -194,6 +239,23 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
 					style = SCE_P_CLASSNAME;
 				} else if (kwLast == kwDef) {
 					style = SCE_P_DEFNAME;
+				} else if (kwLast == kwCDef) {
+					int pos = sc.currentPos;
+					unsigned char ch = styler.SafeGetCharAt(pos, '\0');
+					while (ch != '\0') {
+						if (ch == '(') {
+							style = SCE_P_DEFNAME;
+							break;
+						} else if (ch == ':') {
+							style = SCE_P_CLASSNAME;
+							break;
+						} else if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') {
+							pos++;
+							ch = styler.SafeGetCharAt(pos, '\0');
+						} else {
+							break;
+						}
+					}
 				} else if (keywords2.InList(s)) {
 					style = SCE_P_WORD2;
 				}
@@ -206,9 +268,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
 						kwLast = kwDef;
 					else if (0 == strcmp(s, "import"))
 						kwLast = kwImport;
-					else
+					else if (0 == strcmp(s, "cdef"))
+						kwLast = kwCDef;
+					else if (0 == strcmp(s, "cimport"))
+						kwLast = kwImport;
+					else if (kwLast != kwCDef)
 						kwLast = kwOther;
-				} else {
+				} else if (kwLast != kwCDef) {
 					kwLast = kwOther;
 				}
 			}
@@ -225,7 +291,12 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
 				if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) {
 					sc.Forward();
 				}
-				sc.Forward();
+				if (sc.chNext == '\n' || sc.chNext == '\r') {
+					inContinuedString = true;
+				} else {
+					// Don't roll over the newline.
+					sc.Forward();
+				}
 			} else if ((sc.state == SCE_P_STRING) && (sc.ch == '\"')) {
 				sc.ForwardSetState(SCE_P_DEFAULT);
 				needEOLCheck = true;
@@ -259,6 +330,11 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
 			indentGood = true;
 		}
 
+		// One cdef line, clear kwLast only at end of line
+		if (kwLast == kwCDef && sc.atLineEnd) {
+			kwLast = kwOther;
+		}
+
 		// State exit code may have moved on to end of line
 		if (needEOLCheck && sc.atLineEnd) {
 			lineCurrent++;
@@ -271,20 +347,30 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
 		if (sc.state == SCE_P_DEFAULT) {
 			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 				if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) {
-					hexadecimal = true;
+					base_n_number = true;
+					sc.SetState(SCE_P_NUMBER);
+				} else if (sc.ch == '0' && 
+					(sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) {
+					if (base2or8Literals) {
+						base_n_number = true;
+						sc.SetState(SCE_P_NUMBER);
+					} else {
+						sc.SetState(SCE_P_NUMBER);
+						sc.ForwardSetState(SCE_P_IDENTIFIER);
+					}
 				} else {
-					hexadecimal = false;
+					base_n_number = false;
+					sc.SetState(SCE_P_NUMBER);
 				}
-				sc.SetState(SCE_P_NUMBER);
-			} else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch)) || sc.ch == '`') {
+			} else if ((isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) || sc.ch == '`') {
 				sc.SetState(SCE_P_OPERATOR);
 			} else if (sc.ch == '#') {
 				sc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE);
 			} else if (sc.ch == '@') {
 				sc.SetState(SCE_P_DECORATOR);
-			} else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2))) {
+			} else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2), allowedLiterals)) {
 				unsigned int nextIndex = 0;
-				sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex));
+				sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex, allowedLiterals));
 				while (nextIndex > (sc.currentPos + 1) && sc.More()) {
 					sc.Forward();
 				}
@@ -321,9 +407,17 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
 	const int maxPos = startPos + length;
 	const int maxLines = styler.GetLine(maxPos - 1);             // Requested last line
 	const int docLines = styler.GetLine(styler.Length() - 1);  // Available last line
+
+	// property fold.comment.python
+	//	This option enables folding multi-line comments when using the Python lexer.
 	const bool foldComment = styler.GetPropertyInt("fold.comment.python") != 0;
+
+	// property fold.quotes.python
+	//	This option enables folding multi-line quoted strings when using the Python lexer.
 	const bool foldQuotes = styler.GetPropertyInt("fold.quotes.python") != 0;
 
+	const bool foldCompact = styler.GetPropertyInt("fold.compact") != 0;
+
 	// Backtrack to previous non-blank line so we can determine indent level
 	// for any white space lines (needed esp. within triple quoted strings)
 	// and so we can fix any preceding fold level (which is why we go back
@@ -422,12 +516,21 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
 		while (--skipLine > lineCurrent) {
 			int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
 
-			if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
-				skipLevel = levelBeforeComments;
+			if (foldCompact) {
+				if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
+					skipLevel = levelBeforeComments;
 
-			int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
+				int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
 
-			styler.SetLevel(skipLine, skipLevel | whiteFlag);
+				styler.SetLevel(skipLine, skipLevel | whiteFlag);
+			} else {
+				if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&
+					!(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&
+					!IsCommentLine(skipLine, styler))
+					skipLevel = levelBeforeComments;
+
+				styler.SetLevel(skipLine, skipLevel);
+			}
 		}
 
 		// Set fold header on non-quote/non-comment line
@@ -459,3 +562,4 @@ static const char * const pythonWordListDesc[] = {
 
 LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc,
 					 pythonWordListDesc);
+
diff --git a/plugins/scintilla/scintilla/LexRuby.cxx b/plugins/scintilla/scintilla/LexRuby.cxx
index 7cb0b95..8d6dc90 100755
--- a/plugins/scintilla/scintilla/LexRuby.cxx
+++ b/plugins/scintilla/scintilla/LexRuby.cxx
@@ -784,13 +784,13 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
 				state = SCE_RB_COMMENTLINE;
 			} else if (ch == '=') {
 				// =begin indicates the start of a comment (doc) block
-                if (i == 0 || isEOLChar(chPrev)
+                if (i == 0 || (isEOLChar(chPrev)
                     && chNext == 'b'
                     && styler.SafeGetCharAt(i + 2) == 'e'
                     && styler.SafeGetCharAt(i + 3) == 'g'
                     && styler.SafeGetCharAt(i + 4) == 'i'
                     && styler.SafeGetCharAt(i + 5) == 'n'
-                    && !isSafeWordcharOrHigh(styler.SafeGetCharAt(i + 6))) {
+                    && !isSafeWordcharOrHigh(styler.SafeGetCharAt(i + 6)))) {
                     styler.ColourTo(i - 1, state);
                     state = SCE_RB_POD;
 				} else {
diff --git a/plugins/scintilla/scintilla/LexSML.cxx b/plugins/scintilla/scintilla/LexSML.cxx
new file mode 100644
index 0000000..a617530
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexSML.cxx
@@ -0,0 +1,223 @@
+// Scintilla source code edit control
+/** @file LexSML.cxx
+ ** Lexer for SML.
+ **/
+// Copyright 2009 by James Moffatt and Yuzhou Xin
+// Modified from LexCaml.cxx by Robert Roessler <robertr rftp com> Copyright 2005
+// The License.txt file describes the conditions under which this software may be distributed.
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+inline int  issml(int c) {return isalnum(c) || c == '_';}
+inline int issmlf(int c) {return isalpha(c) || c == '_';}
+inline int issmld(int c) {return isdigit(c) || c == '_';}
+
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+void ColouriseSMLDoc(
+	unsigned int startPos, int length,
+	int initStyle,
+	WordList *keywordlists[],
+	Accessor &styler)
+{
+	StyleContext sc(startPos, length, initStyle, styler);
+	int nesting = 0;
+	if (sc.state < SCE_SML_STRING)
+		sc.state = SCE_SML_DEFAULT;
+	if (sc.state >= SCE_SML_COMMENT)
+		nesting = (sc.state & 0x0f) - SCE_SML_COMMENT;
+
+	int chBase = 0, chToken = 0, chLit = 0;
+	WordList& keywords  = *keywordlists[0];
+	WordList& keywords2 = *keywordlists[1];
+	WordList& keywords3 = *keywordlists[2];
+	const int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0);
+
+	while (sc.More()) {
+		int state2 = -1;
+		int chColor = sc.currentPos - 1;
+		bool advance = true;
+
+		switch (sc.state & 0x0f) {
+		case SCE_SML_DEFAULT:
+			chToken = sc.currentPos;
+			if (issmlf(sc.ch))
+				state2 = SCE_SML_IDENTIFIER;
+			else if (sc.Match('`') && issmlf(sc.chNext))
+				state2 = SCE_SML_TAGNAME;
+			else if (sc.Match('#')&&isdigit(sc.chNext))
+					state2 = SCE_SML_LINENUM;
+			else if (sc.Match('#','\"')){
+					state2 = SCE_SML_CHAR,chLit = 0;
+					sc.Forward();
+					
+				}
+			else if (isdigit(sc.ch)) {
+				state2 = SCE_SML_NUMBER, chBase = 10;
+				if (sc.Match('0') && strchr("xX", sc.chNext))
+					chBase = 16, sc.Forward();}
+			else if (sc.Match('\"')&&sc.chPrev!='#')
+				state2 = SCE_SML_STRING;
+			else if (sc.Match('(', '*')){
+				state2 = SCE_SML_COMMENT,
+					sc.ch = ' ',
+					sc.Forward();}
+			else if (strchr("!~"
+					"=<>@^+-*/"
+					"()[];,:.#", sc.ch))
+				state2 = SCE_SML_OPERATOR;
+			break;
+
+		case SCE_SML_IDENTIFIER:
+			if (!(issml(sc.ch) || sc.Match('\''))) {
+				const int n = sc.currentPos - chToken;
+				if (n < 24) {
+					char t[24];
+					for (int i = -n; i < 0; i++)
+						t[n + i] = static_cast<char>(sc.GetRelative(i));
+					t[n] = '\0';
+					if ((n == 1 && sc.chPrev == '_') || keywords.InList(t))
+						sc.ChangeState(SCE_SML_KEYWORD);
+					else if (keywords2.InList(t))
+						sc.ChangeState(SCE_SML_KEYWORD2);
+					else if (keywords3.InList(t))
+						sc.ChangeState(SCE_SML_KEYWORD3);
+				}
+				state2 = SCE_SML_DEFAULT, advance = false;
+			}
+			break;
+
+		case SCE_SML_TAGNAME:
+			if (!(issml(sc.ch) || sc.Match('\'')))
+				state2 = SCE_SML_DEFAULT, advance = false;
+			break;
+
+		case SCE_SML_LINENUM:
+			if (!isdigit(sc.ch))
+				state2 = SCE_SML_DEFAULT, advance = false;
+			break;
+
+		case SCE_SML_OPERATOR: {
+			const char* o = 0;
+			if (issml(sc.ch) || isspace(sc.ch)
+				|| (o = strchr(")]};,\'\"`#", sc.ch),o)
+				|| !strchr("!$%&*+-./:<=>? ^|~", sc.ch)) {
+				if (o && strchr(")]};,", sc.ch)) {
+					if ((sc.Match(')') && sc.chPrev == '(')
+						|| (sc.Match(']') && sc.chPrev == '['))
+						sc.ChangeState(SCE_SML_KEYWORD);
+					chColor++;
+				} else
+					advance = false;
+				state2 = SCE_SML_DEFAULT;
+			}
+			break;
+		}
+
+		case SCE_SML_NUMBER:
+			if (issmld(sc.ch) || IsADigit(sc.ch, chBase))
+				break;
+			if ((sc.Match('l') || sc.Match('L') || sc.Match('n'))
+				&& (issmld(sc.chPrev) || IsADigit(sc.chPrev, chBase)))
+				break;
+			if (chBase == 10) {
+				if (sc.Match('.') && issmld(sc.chPrev))
+					break;
+				if ((sc.Match('e') || sc.Match('E'))
+					&& (issmld(sc.chPrev) || sc.chPrev == '.'))
+					break;
+				if ((sc.Match('+') || sc.Match('-'))
+					&& (sc.chPrev == 'e' || sc.chPrev == 'E'))
+					break;
+			}
+			state2 = SCE_SML_DEFAULT, advance = false;
+			break;
+
+		case SCE_SML_CHAR:
+			if (sc.Match('\\')) {
+				chLit = 1;
+				if (sc.chPrev == '\\')
+					sc.ch = ' ';
+			} else if ((sc.Match('\"') && sc.chPrev != '\\') || sc.atLineEnd) {
+				state2 = SCE_SML_DEFAULT;
+				chLit = 1;
+				if (sc.Match('\"'))
+					chColor++;
+				else
+					sc.ChangeState(SCE_SML_IDENTIFIER);
+			} else if (chLit < 1 && sc.currentPos - chToken >= 3)
+				sc.ChangeState(SCE_SML_IDENTIFIER), advance = false;
+			break;
+
+		case SCE_SML_STRING:
+			if (sc.Match('\\') && sc.chPrev == '\\')
+				sc.ch = ' ';
+			else if (sc.Match('\"') && sc.chPrev != '\\')
+				state2 = SCE_SML_DEFAULT, chColor++;
+			break;
+
+		case SCE_SML_COMMENT:
+		case SCE_SML_COMMENT1:
+		case SCE_SML_COMMENT2:
+		case SCE_SML_COMMENT3:
+			if (sc.Match('(', '*'))
+				state2 = sc.state + 1, chToken = sc.currentPos,
+					sc.ch = ' ',
+					sc.Forward(), nesting++;
+			else if (sc.Match(')') && sc.chPrev == '*') {
+				if (nesting)
+					state2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--;
+				else
+					state2 = SCE_SML_DEFAULT;
+				chColor++;
+			} else if (useMagic && sc.currentPos - chToken == 4
+				&& sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@')
+				sc.state |= 0x10;
+			break;
+		}
+
+		if (state2 >= 0)
+			styler.ColourTo(chColor, sc.state), sc.ChangeState(state2);
+		if (advance)
+			sc.Forward();
+	}
+
+	sc.Complete();
+}
+
+void FoldSMLDoc(
+	unsigned int startPos, int length,
+	int initStyle,
+	WordList *keywordlists[],
+	Accessor &styler)
+{
+	//supress "not used" warnings
+	startPos || length || initStyle || keywordlists[0] || styler.Length();
+}
+
+static const char * const SMLWordListDesc[] = {
+	"Keywords",
+	"Keywords2",
+	"Keywords3",
+	0
+};
+
+LexerModule lmSML(SCLEX_SML, ColouriseSMLDoc, "SML", FoldSMLDoc, SMLWordListDesc);
+ 	  	 
diff --git a/plugins/scintilla/scintilla/LexSQL.cxx b/plugins/scintilla/scintilla/LexSQL.cxx
index eb1cddb..01aa7ad 100644
--- a/plugins/scintilla/scintilla/LexSQL.cxx
+++ b/plugins/scintilla/scintilla/LexSQL.cxx
@@ -61,7 +61,10 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
 
 	StyleContext sc(startPos, length, initStyle, styler);
 
+	// property sql.backslash.escapes 
+	//	Enables backslash as an escape character in SQL. 
 	bool sqlBackslashEscapes = styler.GetPropertyInt("sql.backslash.escapes", 0) != 0;
+
 	bool sqlBackticksIdentifier = styler.GetPropertyInt("lexer.sql.backticks.identifier", 0) != 0;
 	int styleBeforeDCKeyword = SCE_SQL_DEFAULT;
 	for (; sc.More(); sc.Forward()) {
diff --git a/plugins/scintilla/scintilla/LexSorcus.cxx b/plugins/scintilla/scintilla/LexSorcus.cxx
new file mode 100644
index 0000000..1d8ba27
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexSorcus.cxx
@@ -0,0 +1,205 @@
+// Scintilla source code edit control
+/** @file LexSorcus.cxx
+** Lexer for SORCUS installation files
+** Written by Eugen Bitter and Christoph Baumann at SORCUS Computer, Heidelberg Germany
+** Based on the ASM Lexer by The Black Horus
+**/
+
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+
+//each character a..z and A..Z + '_' can be part of a keyword
+//additionally numbers that follow 'M' can be contained in a keyword
+static inline bool IsSWordStart(const int ch, const int prev_ch)           
+{
+    if (isalpha(ch) || (ch == '_') || ((isdigit(ch)) && (prev_ch == 'M')))
+        return true;
+
+    return false;
+}
+
+
+//only digits that are not preceded by 'M' count as a number
+static inline bool IsSorcusNumber(const int ch, const int prev_ch)         
+{
+    if ((isdigit(ch)) && (prev_ch != 'M'))
+        return true;
+
+    return false;
+}
+
+
+//only = is a valid operator
+static inline bool IsSorcusOperator(const int ch)           
+{
+    if (ch == '=')
+        return true;
+    
+    return false;
+}
+
+
+static void ColouriseSorcusDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+                               Accessor &styler)                                        
+{
+    
+    WordList &Command = *keywordlists[0];
+    WordList &Parameter = *keywordlists[1];
+    WordList &Constant = *keywordlists[2];
+    
+    // Do not leak onto next line
+    if (initStyle == SCE_SORCUS_STRINGEOL)              
+        initStyle = SCE_SORCUS_DEFAULT;
+    
+    StyleContext sc(startPos, length, initStyle, styler);
+    
+    for (; sc.More(); sc.Forward())
+    {
+        
+        // Prevent SCE_SORCUS_STRINGEOL from leaking back to previous line
+        if (sc.atLineStart && (sc.state == SCE_SORCUS_STRING))
+        {
+            sc.SetState(SCE_SORCUS_STRING);         
+        }       
+        
+        // Determine if the current state should terminate.
+        if (sc.state == SCE_SORCUS_OPERATOR)
+        {
+            if (!IsSorcusOperator(sc.ch)) 
+            {
+                sc.SetState(SCE_SORCUS_DEFAULT);
+            }
+        }       
+        else if(sc.state == SCE_SORCUS_NUMBER)
+        {
+            if(!IsSorcusNumber(sc.ch, sc.chPrev))
+            {
+                sc.SetState(SCE_SORCUS_DEFAULT);
+            }
+        }
+        else if (sc.state == SCE_SORCUS_IDENTIFIER)
+        {
+            if (!IsSWordStart(sc.ch, sc.chPrev))
+            {
+                char s[100];
+                
+                sc.GetCurrent(s, sizeof(s));
+                
+                if (Command.InList(s))
+                { 
+                    sc.ChangeState(SCE_SORCUS_COMMAND); 
+                }
+                else if (Parameter.InList(s))
+                { 
+                    sc.ChangeState(SCE_SORCUS_PARAMETER);
+                }
+                else if (Constant.InList(s))
+                { 
+                    sc.ChangeState(SCE_SORCUS_CONSTANT);
+                }
+                
+                sc.SetState(SCE_SORCUS_DEFAULT);
+            }
+        }       
+        else if (sc.state == SCE_SORCUS_COMMENTLINE )
+        {
+            if (sc.atLineEnd)
+            {
+                sc.SetState(SCE_SORCUS_DEFAULT);
+            }
+        }
+        else if (sc.state == SCE_SORCUS_STRING)
+        {
+            if (sc.ch == '\"')
+            {
+                sc.ForwardSetState(SCE_SORCUS_DEFAULT);
+            }
+            else if (sc.atLineEnd) 
+            {
+                sc.ChangeState(SCE_SORCUS_STRINGEOL);
+                sc.ForwardSetState(SCE_SORCUS_DEFAULT);
+            }
+        }
+        
+        // Determine if a new state should be entered.
+        if (sc.state == SCE_SORCUS_DEFAULT)
+        {
+            if ((sc.ch == ';') || (sc.ch == '\''))
+            {
+                sc.SetState(SCE_SORCUS_COMMENTLINE);
+            }   
+            else if (IsSWordStart(sc.ch, sc.chPrev))
+            {
+                sc.SetState(SCE_SORCUS_IDENTIFIER);
+            }   
+            else if (sc.ch == '\"')
+            {
+                sc.SetState(SCE_SORCUS_STRING);
+            }
+            else if (IsSorcusOperator(sc.ch))
+            {
+                sc.SetState(SCE_SORCUS_OPERATOR);
+            }
+            else if (IsSorcusNumber(sc.ch, sc.chPrev))
+            {
+                sc.SetState(SCE_SORCUS_NUMBER);
+            }
+        }
+        
+    }
+    sc.Complete();
+}
+
+
+static const char* const SorcusWordListDesc[] = {"Command","Parameter", "Constant", 0};
+  
+LexerModule lmSorc(SCLEX_SORCUS, ColouriseSorcusDoc, "sorcins", 0, SorcusWordListDesc);
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
diff --git a/plugins/scintilla/scintilla/LexSpice.cxx b/plugins/scintilla/scintilla/LexSpice.cxx
index b2953c0..6aa2e8f 100644
--- a/plugins/scintilla/scintilla/LexSpice.cxx
+++ b/plugins/scintilla/scintilla/LexSpice.cxx
@@ -10,6 +10,8 @@
 #include <string.h>
 #include <stdio.h>
 
+#include <string>
+
 #include "Platform.h"
 
 #include "Accessor.h"
@@ -17,7 +19,6 @@
 #include "PropSet.h"
 #include "KeyWords.h"
 #include "SciLexer.h"
-#include "SString.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -75,7 +76,7 @@ static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute
 
 static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
     apostropheStartsAttribute = true;
-    SString number;
+    std::string number;
     sc.SetState(SCE_SPICE_NUMBER);
     // Get all characters up to a delimiter or a separator, including points, but excluding
     // double points (ranges).
@@ -104,7 +105,7 @@ static void ColouriseWhiteSpace(StyleContext& sc, bool& ) {
 static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute) {
     apostropheStartsAttribute = true;
     sc.SetState(SCE_SPICE_IDENTIFIER);
-    SString word;
+    std::string word;
     while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
         word += static_cast<char>(tolower(sc.ch));
         sc.Forward();
diff --git a/plugins/scintilla/scintilla/LexTACL.cxx b/plugins/scintilla/scintilla/LexTACL.cxx
new file mode 100644
index 0000000..b0c1244
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexTACL.cxx
@@ -0,0 +1,397 @@
+// Scintilla source code edit control
+/** @file LexTAL.cxx
+ ** Lexer for TAL
+ ** Based on LexPascal.cxx
+ ** Written by Laurent le Tynevez
+ ** Updated by Simon Steele <s steele pnotepad org> September 2002
+ ** Updated by Mathias Rauen <scite madshi net> May 2003 (Delphi adjustments)
+ ** Updated by Rod Falck, Aug 2006 Converted to TACL
+ **/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+#include "StyleContext.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+inline bool isTACLoperator(char ch)
+	{
+	return ch == '\'' || isoperator(ch);
+	}
+
+inline bool isTACLwordchar(char ch)
+	{
+	return ch == '#' || ch == '^' || ch == '|' || ch == '_' || iswordchar(ch);
+	}
+
+inline bool isTACLwordstart(char ch)
+	{
+	return ch == '#' || ch == '|' || ch == '_' || iswordstart(ch);
+	}
+
+static void getRange(unsigned int start,
+		unsigned int end,
+		Accessor &styler,
+		char *s,
+		unsigned int len) {
+	unsigned int i = 0;
+	while ((i < end - start + 1) && (i < len-1)) {
+		s[i] = static_cast<char>(tolower(styler[start + i]));
+		i++;
+	}
+	s[i] = '\0';
+}
+
+static bool IsStreamCommentStyle(int style) {
+	return style == SCE_C_COMMENT ||
+		style == SCE_C_COMMENTDOC ||
+		style == SCE_C_COMMENTDOCKEYWORD ||
+		style == SCE_C_COMMENTDOCKEYWORDERROR;
+}
+
+static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
+	if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
+		styler.ColourTo(end, SCE_C_REGEX);
+	} else
+		styler.ColourTo(end, attr);
+}
+
+// returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
+static int classifyWordTACL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) {
+	int ret = 0;
+
+	WordList& keywords = *keywordlists[0];
+	WordList& builtins = *keywordlists[1];
+	WordList& commands = *keywordlists[2];
+
+	char s[100];
+	getRange(start, end, styler, s, sizeof(s));
+
+	char chAttr = SCE_C_IDENTIFIER;
+	if (isdigit(s[0]) || (s[0] == '.')) {
+		chAttr = SCE_C_NUMBER;
+	}
+	else {
+		if (s[0] == '#' || keywords.InList(s)) {
+			chAttr = SCE_C_WORD;
+
+			if (strcmp(s, "asm") == 0) {
+				ret = 2;
+			}
+			else if (strcmp(s, "end") == 0) {
+				ret = -1;
+			}
+		}
+		else if (s[0] == '|' || builtins.InList(s)) {
+			chAttr = SCE_C_WORD2;
+		}
+		else if (commands.InList(s)) {
+			chAttr = SCE_C_UUID;
+		}
+		else if (strcmp(s, "comment") == 0) {
+			chAttr = SCE_C_COMMENTLINE;
+			ret = 3;
+		}
+	}
+	ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
+	return ret;
+}
+
+static int classifyFoldPointTACL(const char* s) {
+	int lev = 0;
+	if (s[0] == '[')
+		lev=1;
+	else if (s[0] == ']')
+		lev=-1;
+	return lev;
+}
+
+static void ColouriseTACLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+	Accessor &styler) {
+
+	styler.StartAt(startPos);
+
+	int state = initStyle;
+	if (state == SCE_C_CHARACTER)	// Does not leak onto next line
+		state = SCE_C_DEFAULT;
+	char chPrev = ' ';
+	char chNext = styler[startPos];
+	unsigned int lengthDoc = startPos + length;
+
+	bool bInClassDefinition;
+
+	int currentLine = styler.GetLine(startPos);
+	if (currentLine > 0) {
+		styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
+		bInClassDefinition = (styler.GetLineState(currentLine) == 1);
+	} else {
+		styler.SetLineState(currentLine, 0);
+		bInClassDefinition = false;
+	}
+
+	bool bInAsm = (state == SCE_C_REGEX);
+	if (bInAsm)
+		state = SCE_C_DEFAULT;
+
+	styler.StartSegment(startPos);
+	int visibleChars = 0;
+	unsigned int i;
+	for (i = startPos; i < lengthDoc; i++) {
+		char ch = chNext;
+
+		chNext = styler.SafeGetCharAt(i + 1);
+
+		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+			// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
+			// Avoid triggering two times on Dos/Win
+			// End of line
+			if (state == SCE_C_CHARACTER) {
+				ColourTo(styler, i, state, bInAsm);
+				state = SCE_C_DEFAULT;
+			}
+			visibleChars = 0;
+			currentLine++;
+			styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
+		}
+
+		if (styler.IsLeadByte(ch)) {
+			chNext = styler.SafeGetCharAt(i + 2);
+			chPrev = ' ';
+			i += 1;
+			continue;
+		}
+
+		if (state == SCE_C_DEFAULT) {
+			if (isTACLwordstart(ch)) {
+				ColourTo(styler, i-1, state, bInAsm);
+				state = SCE_C_IDENTIFIER;
+			} else if (ch == '{') {
+				ColourTo(styler, i-1, state, bInAsm);
+				state = SCE_C_COMMENT;
+			} else if (ch == '{' && chNext == '*') {
+				ColourTo(styler, i-1, state, bInAsm);
+				state = SCE_C_COMMENTDOC;
+			} else if (ch == '=' && chNext == '=') {
+				ColourTo(styler, i-1, state, bInAsm);
+				state = SCE_C_COMMENTLINE;
+			} else if (ch == '"') {
+				ColourTo(styler, i-1, state, bInAsm);
+				state = SCE_C_STRING;
+			} else if (ch == '?' && visibleChars == 0) {
+				ColourTo(styler, i-1, state, bInAsm);
+				state = SCE_C_PREPROCESSOR;
+			} else if (isTACLoperator(ch)) {
+				ColourTo(styler, i-1, state, bInAsm);
+				ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
+			}
+		} else if (state == SCE_C_IDENTIFIER) {
+			if (!isTACLwordchar(ch)) {
+				int lStateChange = classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
+
+				if(lStateChange == 1) {
+					styler.SetLineState(currentLine, 1);
+					bInClassDefinition = true;
+				} else if(lStateChange == 2) {
+					bInAsm = true;
+				} else if(lStateChange == -1) {
+					styler.SetLineState(currentLine, 0);
+					bInClassDefinition = false;
+					bInAsm = false;
+				}
+
+				if (lStateChange == 3) {
+					 state = SCE_C_COMMENTLINE;
+				}
+				else {
+					state = SCE_C_DEFAULT;
+					chNext = styler.SafeGetCharAt(i + 1);
+					if (ch == '{') {
+						state = SCE_C_COMMENT;
+					} else if (ch == '{' && chNext == '*') {
+						ColourTo(styler, i-1, state, bInAsm);
+						state = SCE_C_COMMENTDOC;
+					} else if (ch == '=' && chNext == '=') {
+						state = SCE_C_COMMENTLINE;
+					} else if (ch == '"') {
+						state = SCE_C_STRING;
+					} else if (isTACLoperator(ch)) {
+						ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
+					}
+				}
+			}
+		} else {
+			if (state == SCE_C_PREPROCESSOR) {
+				if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
+					ColourTo(styler, i-1, state, bInAsm);
+					state = SCE_C_DEFAULT;
+				}
+			} else if (state == SCE_C_COMMENT) {
+				if (ch == '}' || (ch == '\r' || ch == '\n') ) {
+					ColourTo(styler, i, state, bInAsm);
+					state = SCE_C_DEFAULT;
+				}
+			} else if (state == SCE_C_COMMENTDOC) {
+				if (ch == '}' || (ch == '\r' || ch == '\n')) {
+					if (((i > styler.GetStartSegment() + 2) || (
+						(initStyle == SCE_C_COMMENTDOC) &&
+						(styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
+							ColourTo(styler, i, state, bInAsm);
+							state = SCE_C_DEFAULT;
+					}
+				}
+			} else if (state == SCE_C_COMMENTLINE) {
+				if (ch == '\r' || ch == '\n') {
+					ColourTo(styler, i-1, state, bInAsm);
+					state = SCE_C_DEFAULT;
+				}
+			} else if (state == SCE_C_STRING) {
+				if (ch == '"' || ch == '\r' || ch == '\n') {
+					ColourTo(styler, i, state, bInAsm);
+					state = SCE_C_DEFAULT;
+				}
+			}
+		}
+        if (!isspacechar(ch))
+            visibleChars++;
+		chPrev = ch;
+	}
+
+	// Process to end of document
+	if (state == SCE_C_IDENTIFIER) {
+		classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
+		}
+	else
+		ColourTo(styler, lengthDoc - 1, state, bInAsm);
+}
+
+static void FoldTACLDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+                            Accessor &styler) {
+	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+	bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+	unsigned int endPos = startPos + length;
+	int visibleChars = 0;
+	int lineCurrent = styler.GetLine(startPos);
+	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+	int levelCurrent = levelPrev;
+	char chNext = styler[startPos];
+	int styleNext = styler.StyleAt(startPos);
+	int style = initStyle;
+	bool section = false;
+
+	int lastStart = 0;
+
+	for (unsigned int i = startPos; i < endPos; i++) {
+		char ch = chNext;
+		chNext = styler.SafeGetCharAt(i + 1);
+		int stylePrev = style;
+		style = styleNext;
+		styleNext = styler.StyleAt(i + 1);
+		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+		if (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_PREPROCESSOR))
+		{
+			// Store last word start point.
+			lastStart = i;
+		}
+
+		if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_PREPROCESSOR) {
+			if(isTACLwordchar(ch) && !isTACLwordchar(chNext)) {
+				char s[100];
+				getRange(lastStart, i, styler, s, sizeof(s));
+				if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0)
+					{
+					section = true;
+					levelCurrent = 1;
+					levelPrev = 0;
+					}
+				else if (stylePrev == SCE_C_WORD)
+					levelCurrent += classifyFoldPointTACL(s);
+			}
+		}
+
+		if (style == SCE_C_OPERATOR) {
+			if (ch == '[') {
+				levelCurrent++;
+			} else if (ch == ']') {
+				levelCurrent--;
+			}
+		}
+		if (foldComment && (style == SCE_C_COMMENTLINE)) {
+			if ((ch == '/') && (chNext == '/')) {
+				char chNext2 = styler.SafeGetCharAt(i + 2);
+				if (chNext2 == '{') {
+					levelCurrent++;
+				} else if (chNext2 == '}') {
+					levelCurrent--;
+				}
+			}
+		}
+
+		if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
+			if (ch == '{' && chNext == '$') {
+				unsigned int j=i+2; // skip {$
+				while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+					j++;
+				}
+				if (styler.Match(j, "region") || styler.Match(j, "if")) {
+					levelCurrent++;
+				} else if (styler.Match(j, "end")) {
+					levelCurrent--;
+				}
+			}
+		}
+
+		if (foldComment && IsStreamCommentStyle(style)) {
+			if (!IsStreamCommentStyle(stylePrev)) {
+				levelCurrent++;
+			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+				// Comments don't end at end of line and the next character may be unstyled.
+				levelCurrent--;
+			}
+		}
+		if (atEOL) {
+			int lev = levelPrev | SC_FOLDLEVELBASE;
+			if (visibleChars == 0 && foldCompact)
+				lev |= SC_FOLDLEVELWHITEFLAG;
+			if ((levelCurrent > levelPrev || section) && (visibleChars > 0))
+				lev |= SC_FOLDLEVELHEADERFLAG;
+			if (lev != styler.LevelAt(lineCurrent)) {
+				styler.SetLevel(lineCurrent, lev);
+			}
+			lineCurrent++;
+			levelPrev = levelCurrent;
+			visibleChars = 0;
+			section = false;
+		}
+
+		if (!isspacechar(ch))
+			visibleChars++;
+	}
+
+	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
+	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const TACLWordListDesc[] = {
+	"Builtins",
+	"Labels",
+	"Commands",
+	0
+};
+
+LexerModule lmTACL(SCLEX_TACL, ColouriseTACLDoc, "TACL", FoldTACLDoc, TACLWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexTADS3.cxx b/plugins/scintilla/scintilla/LexTADS3.cxx
index 7cc85f1..ee16a0a 100644
--- a/plugins/scintilla/scintilla/LexTADS3.cxx
+++ b/plugins/scintilla/scintilla/LexTADS3.cxx
@@ -679,7 +679,7 @@ static const int T3_EXPECTINGPUNCTUATION = 1 << 14;
 static inline bool IsStringTransition(int s1, int s2) {
         return s1 != s2
                 && (s1 == SCE_T3_S_STRING || s1 == SCE_T3_X_STRING
-                        || s1 == SCE_T3_D_STRING && s2 != SCE_T3_X_DEFAULT)
+                        || (s1 == SCE_T3_D_STRING && s2 != SCE_T3_X_DEFAULT))
                 && s2 != SCE_T3_LIB_DIRECTIVE
                 && s2 != SCE_T3_MSG_PARAM
                 && s2 != SCE_T3_HTML_TAG
diff --git a/plugins/scintilla/scintilla/LexTAL.cxx b/plugins/scintilla/scintilla/LexTAL.cxx
new file mode 100644
index 0000000..a76a296
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexTAL.cxx
@@ -0,0 +1,396 @@
+// Scintilla source code edit control
+/** @file LexTAL.cxx
+ ** Lexer for TAL
+ ** Based on LexPascal.cxx
+ ** Written by Laurent le Tynevez
+ ** Updated by Simon Steele <s steele pnotepad org> September 2002
+ ** Updated by Mathias Rauen <scite madshi net> May 2003 (Delphi adjustments)
+ ** Updated by Rod Falck, Aug 2006 Converted to TAL
+ **/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "Platform.h"
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+#include "StyleContext.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+inline bool isTALoperator(char ch)
+	{
+	return ch == '\'' || ch == '@' || ch == '#' || isoperator(ch);
+	}
+
+inline bool isTALwordchar(char ch)
+	{
+	return ch == '$' || ch == '^' || iswordchar(ch);
+	}
+
+inline bool isTALwordstart(char ch)
+	{
+	return ch == '$' || ch == '^' || iswordstart(ch);
+	}
+
+static void getRange(unsigned int start,
+		unsigned int end,
+		Accessor &styler,
+		char *s,
+		unsigned int len) {
+	unsigned int i = 0;
+	while ((i < end - start + 1) && (i < len-1)) {
+		s[i] = static_cast<char>(tolower(styler[start + i]));
+		i++;
+	}
+	s[i] = '\0';
+}
+
+static bool IsStreamCommentStyle(int style) {
+	return style == SCE_C_COMMENT ||
+		style == SCE_C_COMMENTDOC ||
+		style == SCE_C_COMMENTDOCKEYWORD ||
+		style == SCE_C_COMMENTDOCKEYWORDERROR;
+}
+
+static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
+	if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
+		styler.ColourTo(end, SCE_C_REGEX);
+	} else
+		styler.ColourTo(end, attr);
+}
+
+// returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm"
+static int classifyWordTAL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) {
+	int ret = 0;
+
+	WordList& keywords = *keywordlists[0];
+	WordList& builtins = *keywordlists[1];
+	WordList& nonreserved_keywords = *keywordlists[2];
+
+	char s[100];
+	getRange(start, end, styler, s, sizeof(s));
+
+	char chAttr = SCE_C_IDENTIFIER;
+	if (isdigit(s[0]) || (s[0] == '.')) {
+		chAttr = SCE_C_NUMBER;
+	}
+	else {
+		if (keywords.InList(s)) {
+			chAttr = SCE_C_WORD;
+
+			if (strcmp(s, "asm") == 0) {
+				ret = 2;
+			}
+			else if (strcmp(s, "end") == 0) {
+				ret = -1;
+			}
+		} 
+		else if (s[0] == '$' || builtins.InList(s)) {
+			chAttr = SCE_C_WORD2;
+		}
+		else if (nonreserved_keywords.InList(s)) {
+			chAttr = SCE_C_UUID;
+		}
+	}
+	ColourTo(styler, end, chAttr, (bInAsm && ret != -1));
+	return ret;
+}
+
+static int classifyFoldPointTAL(const char* s) {
+	int lev = 0;
+	if (!(isdigit(s[0]) || (s[0] == '.'))) {
+		if (strcmp(s, "begin") == 0 ||
+			strcmp(s, "block") == 0) {
+			lev=1;
+		} else if (strcmp(s, "end") == 0) {
+			lev=-1;
+		}
+	}
+	return lev;
+}
+
+static void ColouriseTALDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
+	Accessor &styler) {
+
+	styler.StartAt(startPos);
+
+	int state = initStyle;
+	if (state == SCE_C_CHARACTER)	// Does not leak onto next line
+		state = SCE_C_DEFAULT;
+	char chPrev = ' ';
+	char chNext = styler[startPos];
+	unsigned int lengthDoc = startPos + length;
+
+	bool bInClassDefinition;
+
+	int currentLine = styler.GetLine(startPos);
+	if (currentLine > 0) {
+		styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
+		bInClassDefinition = (styler.GetLineState(currentLine) == 1);
+	} else {
+		styler.SetLineState(currentLine, 0);
+		bInClassDefinition = false;
+	}
+
+	bool bInAsm = (state == SCE_C_REGEX);
+	if (bInAsm)
+		state = SCE_C_DEFAULT;
+
+	styler.StartSegment(startPos);
+	int visibleChars = 0;
+	for (unsigned int i = startPos; i < lengthDoc; i++) {
+		char ch = chNext;
+
+		chNext = styler.SafeGetCharAt(i + 1);
+
+		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+			// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
+			// Avoid triggering two times on Dos/Win
+			// End of line
+			if (state == SCE_C_CHARACTER) {
+				ColourTo(styler, i, state, bInAsm);
+				state = SCE_C_DEFAULT;
+			}
+			visibleChars = 0;
+			currentLine++;
+			styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
+		}
+
+		if (styler.IsLeadByte(ch)) {
+			chNext = styler.SafeGetCharAt(i + 2);
+			chPrev = ' ';
+			i += 1;
+			continue;
+		}
+
+		if (state == SCE_C_DEFAULT) {
+			if (isTALwordstart(ch)) {
+				ColourTo(styler, i-1, state, bInAsm);
+				state = SCE_C_IDENTIFIER;
+			} else if (ch == '!' && chNext != '*') {
+				ColourTo(styler, i-1, state, bInAsm);
+				state = SCE_C_COMMENT;
+			} else if (ch == '!' && chNext == '*') {
+				ColourTo(styler, i-1, state, bInAsm);
+				state = SCE_C_COMMENTDOC;
+			} else if (ch == '-' && chNext == '-') {
+				ColourTo(styler, i-1, state, bInAsm);
+				state = SCE_C_COMMENTLINE;
+			} else if (ch == '"') {
+				ColourTo(styler, i-1, state, bInAsm);
+				state = SCE_C_STRING;
+			} else if (ch == '?' && visibleChars == 0) {
+				ColourTo(styler, i-1, state, bInAsm);
+				state = SCE_C_PREPROCESSOR;
+			} else if (isTALoperator(ch)) {
+				ColourTo(styler, i-1, state, bInAsm);
+				ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
+			}
+		} else if (state == SCE_C_IDENTIFIER) {
+			if (!isTALwordchar(ch)) {
+				int lStateChange = classifyWordTAL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
+
+				if(lStateChange == 1) {
+					styler.SetLineState(currentLine, 1);
+					bInClassDefinition = true;
+				} else if(lStateChange == 2) {
+					bInAsm = true;
+				} else if(lStateChange == -1) {
+					styler.SetLineState(currentLine, 0);
+					bInClassDefinition = false;
+					bInAsm = false;
+				}
+
+				state = SCE_C_DEFAULT;
+				chNext = styler.SafeGetCharAt(i + 1);
+				if (ch == '!' && chNext != '*') {
+					state = SCE_C_COMMENT;
+				} else if (ch == '!' && chNext == '*') {
+					ColourTo(styler, i-1, state, bInAsm);
+					state = SCE_C_COMMENTDOC;
+				} else if (ch == '-' && chNext == '-') {
+					state = SCE_C_COMMENTLINE;
+				} else if (ch == '"') {
+					state = SCE_C_STRING;
+				} else if (isTALoperator(ch)) {
+					ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
+				}
+			}
+		} else {
+			if (state == SCE_C_PREPROCESSOR) {
+				if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
+					ColourTo(styler, i-1, state, bInAsm);
+					state = SCE_C_DEFAULT;
+				}
+			} else if (state == SCE_C_COMMENT) {
+				if (ch == '!' || (ch == '\r' || ch == '\n') ) {
+					ColourTo(styler, i, state, bInAsm);
+					state = SCE_C_DEFAULT;
+				}
+			} else if (state == SCE_C_COMMENTDOC) {
+				if (ch == '!' || (ch == '\r' || ch == '\n')) {
+					if (((i > styler.GetStartSegment() + 2) || (
+						(initStyle == SCE_C_COMMENTDOC) &&
+						(styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
+							ColourTo(styler, i, state, bInAsm);
+							state = SCE_C_DEFAULT;
+					}
+				}
+			} else if (state == SCE_C_COMMENTLINE) {
+				if (ch == '\r' || ch == '\n') {
+					ColourTo(styler, i-1, state, bInAsm);
+					state = SCE_C_DEFAULT;
+				}
+			} else if (state == SCE_C_STRING) {
+				if (ch == '"') {
+					ColourTo(styler, i, state, bInAsm);
+					state = SCE_C_DEFAULT;
+				}
+			}
+		}
+        if (!isspacechar(ch))
+            visibleChars++;
+		chPrev = ch;
+	}
+	ColourTo(styler, lengthDoc - 1, state, bInAsm);
+}
+
+static void FoldTALDoc(unsigned int startPos, int length, int initStyle, WordList *[],
+                            Accessor &styler) {
+	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+	bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+	unsigned int endPos = startPos + length;
+	int visibleChars = 0;
+	int lineCurrent = styler.GetLine(startPos);
+	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
+	int levelCurrent = levelPrev;
+	char chNext = styler[startPos];
+	int styleNext = styler.StyleAt(startPos);
+	int style = initStyle;
+	bool was_end = false;
+	bool section = false;
+
+	int lastStart = 0;
+
+	for (unsigned int i = startPos; i < endPos; i++) {
+		char ch = chNext;
+		chNext = styler.SafeGetCharAt(i + 1);
+		int stylePrev = style;
+		style = styleNext;
+		styleNext = styler.StyleAt(i + 1);
+		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+		if (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_UUID || style == SCE_C_PREPROCESSOR))
+		{
+			// Store last word start point.
+			lastStart = i;
+		}
+
+		if (stylePrev == SCE_C_WORD || style == SCE_C_UUID || stylePrev == SCE_C_PREPROCESSOR) {
+			if(isTALwordchar(ch) && !isTALwordchar(chNext)) {
+				char s[100];
+				getRange(lastStart, i, styler, s, sizeof(s));
+				if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0)
+					{
+					section = true;
+					levelCurrent = 1;
+					levelPrev = 0;
+					}
+				else if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_UUID)
+					{
+					if (strcmp(s, "block") == 0)
+						{
+						// block keyword is ignored immediately after end keyword
+						if (!was_end)
+							levelCurrent++;
+						}
+					else
+						levelCurrent += classifyFoldPointTAL(s);
+					if (strcmp(s, "end") == 0)
+						{
+						was_end = true;
+						}
+					else
+						{
+						was_end = false;
+						}
+					}
+			}
+		}
+
+		if (foldComment && (style == SCE_C_COMMENTLINE)) {
+			if ((ch == '/') && (chNext == '/')) {
+				char chNext2 = styler.SafeGetCharAt(i + 2);
+				if (chNext2 == '{') {
+					levelCurrent++;
+				} else if (chNext2 == '}') {
+					levelCurrent--;
+				}
+			}
+		}
+
+		if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
+			if (ch == '{' && chNext == '$') {
+				unsigned int j=i+2; // skip {$
+				while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+					j++;
+				}
+				if (styler.Match(j, "region") || styler.Match(j, "if")) {
+					levelCurrent++;
+				} else if (styler.Match(j, "end")) {
+					levelCurrent--;
+				}
+			}
+		}
+
+		if (foldComment && IsStreamCommentStyle(style)) {
+			if (!IsStreamCommentStyle(stylePrev)) {
+				levelCurrent++;
+			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+				// Comments don't end at end of line and the next character may be unstyled.
+				levelCurrent--;
+			}
+		}
+
+		if (atEOL) {
+			int lev = levelPrev | SC_FOLDLEVELBASE;
+			if (visibleChars == 0 && foldCompact)
+				lev |= SC_FOLDLEVELWHITEFLAG;
+			if ((levelCurrent > levelPrev || section) && (visibleChars > 0))
+				lev |= SC_FOLDLEVELHEADERFLAG;
+			if (lev != styler.LevelAt(lineCurrent)) {
+				styler.SetLevel(lineCurrent, lev);
+			}
+			lineCurrent++;
+			levelPrev = levelCurrent;
+			visibleChars = 0;
+			section = false;
+		}
+
+		if (!isspacechar(ch))
+			visibleChars++;
+	}
+
+	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
+	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
+	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
+}
+
+static const char * const TALWordListDesc[] = {
+	"Keywords",
+	"Builtins",
+	0
+};
+
+LexerModule lmTAL(SCLEX_TAL, ColouriseTALDoc, "TAL", FoldTALDoc, TALWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexTeX.cxx b/plugins/scintilla/scintilla/LexTeX.cxx
index 18c99ab..62ade1d 100644
--- a/plugins/scintilla/scintilla/LexTeX.cxx
+++ b/plugins/scintilla/scintilla/LexTeX.cxx
@@ -242,8 +242,11 @@ static void ColouriseTeXDoc(
 					}
 				}
 				if (isTeXzero(sc.ch)) {
-					sc.SetState(SCE_TEX_SYMBOL) ;
-					sc.ForwardSetState(SCE_TEX_DEFAULT) ;
+					sc.SetState(SCE_TEX_SYMBOL);
+
+					if (!endOfLine(styler,sc.currentPos + 1))
+						sc.ForwardSetState(SCE_TEX_DEFAULT) ;
+
 					inComment = ! processComment ;
 					newifDone = false ;
 				} else if (isTeXseven(sc.ch) && isTeXseven(sc.chNext)) {
diff --git a/plugins/scintilla/scintilla/LexVerilog.cxx b/plugins/scintilla/scintilla/LexVerilog.cxx
index 52183fe..3fd0fc3 100644
--- a/plugins/scintilla/scintilla/LexVerilog.cxx
+++ b/plugins/scintilla/scintilla/LexVerilog.cxx
@@ -248,7 +248,7 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle
                             styler.Match(j, "generate") ||
                             styler.Match(j, "specify") ||
                             styler.Match(j, "primitive") ||
-                            styler.Match(j, "module") && foldAtModule ||
+                            (styler.Match(j, "module") && foldAtModule) ||
                             styler.Match(j, "begin")) {
                                 levelNext++;
                         } else if (styler.Match(j, "endcase") ||
@@ -259,8 +259,8 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle
                                    styler.Match(j, "endtable") ||
                                    styler.Match(j, "endspecify") ||
                                    styler.Match(j, "endprimitive") ||
-                                   styler.Match(j, "endmodule") && foldAtModule ||
-                                   styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3))) {
+                                   (styler.Match(j, "endmodule") && foldAtModule) ||
+                                   (styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) {
                                 levelNext--;
                         }
 		}
diff --git a/plugins/scintilla/scintilla/LexYAML.cxx b/plugins/scintilla/scintilla/LexYAML.cxx
index a4eac3c..99f34da 100644
--- a/plugins/scintilla/scintilla/LexYAML.cxx
+++ b/plugins/scintilla/scintilla/LexYAML.cxx
@@ -3,7 +3,7 @@
  ** Lexer for YAML.
  **/
 // Copyright 2003- by Sean O'Dell <sean celsoft com>
-// Release under the same license as Scintilla/SciTE.
+// The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
 #include <string.h>
diff --git a/plugins/scintilla/scintilla/LineMarker.cxx b/plugins/scintilla/scintilla/LineMarker.cxx
index f79c3c0..0bfd479 100644
--- a/plugins/scintilla/scintilla/LineMarker.cxx
+++ b/plugins/scintilla/scintilla/LineMarker.cxx
@@ -154,7 +154,8 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
 		rcSmall.bottom = rc.bottom - 2;
 		surface->RectangleDraw(rcSmall, fore.allocated, back.allocated);
 
-	} else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND) {
+	} else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND || 
+		markType == SC_MARK_UNDERLINE || markType == SC_MARK_AVAILABLE) {
 		// An invisible marker so don't draw anything
 
 	} else if (markType == SC_MARK_VLINE) {
diff --git a/plugins/scintilla/scintilla/Makefile.am b/plugins/scintilla/scintilla/Makefile.am
index bc23d88..ef46e24 100644
--- a/plugins/scintilla/scintilla/Makefile.am
+++ b/plugins/scintilla/scintilla/Makefile.am
@@ -18,57 +18,62 @@ libanjuta_scintilla_la_SOURCES =\
 	AutoComplete.cxx \
 	CallTip.cxx \
 	CellBuffer.cxx \
-	ContractionState.cxx \
-	Converter.h \
-	CharClassify.h \
 	CharClassify.cxx \
-	ExternalLexer.cxx \
-	ExternalLexer.h \
-	Document.cxx \
+	ContractionState.cxx \
+	Decoration.cxx \
 	DocumentAccessor.cxx \
+	Document.cxx \
 	Editor.cxx \
+	ExternalLexer.cxx \
 	Indicator.cxx \
 	KeyMap.cxx \
 	KeyWords.cxx \
 	LineMarker.cxx \
+	PerLine.cxx \
 	PlatGTK.cxx \
+	PositionCache.cxx \
 	PropSet.cxx \
 	RESearch.cxx \
+	RunStyles.cxx \
 	ScintillaBase.cxx \
 	ScintillaGTK.cxx \
-	Style.cxx \
+	Selection.cxx \
 	StyleContext.cxx\
+	Style.cxx \
 	UniConversion.cxx \
 	ViewStyle.cxx \
 	WindowAccessor.cxx \
+	XPM.cxx\
 	AutoComplete.h \
 	CallTip.h \
 	CellBuffer.h \
+	CharacterSet.h \
+	CharClassify.h \
 	ContractionState.h \
-	Document.h \
+	Converter.h \
+	Decoration.h \
 	DocumentAccessor.h \
+	Document.h \
 	Editor.h \
+	ExternalLexer.h \
 	Indicator.h \
 	KeyMap.h \
 	LineMarker.h \
+	Partitioning.h \
+	PerLine.h \
+	PositionCache.h \
+	PropSetSimple.h \
 	RESearch.h \
-	SVector.h \
+	RunStyles.h \
 	ScintillaBase.h \
+	Selection.h \
+	SplitVector.h \
+	StyleContext.h\
 	Style.h \
+	SVector.h \
 	UniConversion.h \
 	ViewStyle.h\
-	StyleContext.h\
 	XPM.h\
-	XPM.cxx\
-	Decoration.h \
-	Decoration.cxx \
-	PositionCache.h \
-	PositionCache.cxx \
-	RunStyles.cxx \
-	RunStyles.h \
-	SplitVector.h \
-	Partitioning.h \
-	CharacterSet.h \
 	scintilla-marshal.h\
 	scintilla-marshal.c\
 	$(LEXER_SRCS)
@@ -84,36 +89,38 @@ test_scintilla_SOURCES = test-scintilla.cxx
 test_scintilla_LDADD = libanjuta-scintilla.la
 
 update-scintilla:
-	cp $(srcdir)/scintilla/gtk/*.cxx $(srcdir)/
-	cp $(srcdir)/scintilla/gtk/*.h $(srcdir)/
-	cp $(srcdir)/scintilla/src/*.cxx $(srcdir)/
-	cp $(srcdir)/scintilla/src/*.h $(srcdir)/
-	cp $(srcdir)/scintilla/include/*.h $(srcdir)/include/
-	cp $(srcdir)/scintilla/include/*.py $(srcdir)/include/
-	cp $(srcdir)/scintilla/include/*.iface $(srcdir)/include/
-	echo "## Lexers make file" > lexers.make
-	echo 'LEXER_OBJS = \' >> lexers.make;
-	echo -n '	$$(top_srcdir)/plugins/editor/scintilla/StyleContext.o' >> lexers.make
+	cd $(srcdir); \
+	cp scintilla/gtk/*.cxx .; \
+	cp scintilla/gtk/*.h .; \ 
+	cp scintilla/src/*.cxx .; \
+	cp scintilla/src/*.h ?; \
+	cp scintilla/include/*.h include; \
+	cp scintilla/include/*.py include; \
+	cp scintilla/include/*.iface include; \
+	echo "## Lexers make file" > lexers.make; \
+	echo 'LEXER_OBJS = \' >> lexers.make; \
+	echo -n '	StyleContext.o' >> lexers.make; \
 	for lex in Lex*.cxx; do \
-		lex=`echo $$lex | sed -e "s/cxx$$/o/"`; \
+		lex=`echo $$lex | sed -e "s,.*/,," -e "s/cxx$$/o/"`; \
 		echo '\' >> lexers.make; \
-		echo -n '	$$(top_srcdir)/plugins/editor/scintilla/' >> lexers.make; \
-		echo -n "$$lex" >> lexers.make; \
-	done
-	echo "" >> lexers.make
-	echo "" >> lexers.make
-	echo -n 'LEXER_SRCS = ' >> lexers.make
+		echo -n "	$$lex" >> lexers.make; \
+	done; \
+	echo "" >> lexers.make; \
+	echo "" >> lexers.make; \
+	echo -n 'LEXER_SRCS = ' >> lexers.make; \
 	for lex in Lex*.cxx; do \
 		echo '\' >> lexers.make; \
 		echo -n "	$$lex" >> lexers.make; \
-	done
+	done; \
 	echo "" >> lexers.make
 	echo "Patching files ..."
+	cd $(srcdir); \
 	for patchfile in patches/*.diff; do \
 		patch -p1 < $$patchfile; \
 	done
 	echo "Updating properties file..."
-	./update-properties.pl $(srcdir)/../properties/styles.properties $(srcdir)/scite/src
+	cd $(srcdir); \
+	./update-properties.pl ../properties/styles.properties scite/src
 
 marshallers: scintilla-marshal.list
 	glib-genmarshal --prefix scintilla_marshal scintilla-marshal.list --header > scintilla-marshal.h
diff --git a/plugins/scintilla/scintilla/Partitioning.h b/plugins/scintilla/scintilla/Partitioning.h
index 752e696..225e350 100644
--- a/plugins/scintilla/scintilla/Partitioning.h
+++ b/plugins/scintilla/scintilla/Partitioning.h
@@ -153,7 +153,7 @@ public:
 		return pos;
 	}
 
-	int PartitionFromPosition(int pos) {
+	int PartitionFromPosition(int pos) const {
 		if (body->Length() <= 1)
 			return 0;
 		if (pos >= (PositionFromPartition(body->Length()-1)))
diff --git a/plugins/scintilla/scintilla/PerLine.cxx b/plugins/scintilla/scintilla/PerLine.cxx
new file mode 100644
index 0000000..e2e892d
--- /dev/null
+++ b/plugins/scintilla/scintilla/PerLine.cxx
@@ -0,0 +1,485 @@
+// Scintilla source code edit control
+/** @file PerLine.cxx
+ ** Manages data associated with each line of the document
+ **/
+// Copyright 1998-2009 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <string.h>
+
+#include "Platform.h"
+
+#include "Scintilla.h"
+#include "SplitVector.h"
+#include "Partitioning.h"
+#include "CellBuffer.h"
+#include "PerLine.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+MarkerHandleSet::MarkerHandleSet() {
+	root = 0;
+}
+
+MarkerHandleSet::~MarkerHandleSet() {
+	MarkerHandleNumber *mhn = root;
+	while (mhn) {
+		MarkerHandleNumber *mhnToFree = mhn;
+		mhn = mhn->next;
+		delete mhnToFree;
+	}
+	root = 0;
+}
+
+int MarkerHandleSet::Length() const {
+	int c = 0;
+	MarkerHandleNumber *mhn = root;
+	while (mhn) {
+		c++;
+		mhn = mhn->next;
+	}
+	return c;
+}
+
+int MarkerHandleSet::NumberFromHandle(int handle) const {
+	MarkerHandleNumber *mhn = root;
+	while (mhn) {
+		if (mhn->handle == handle) {
+			return mhn->number;
+		}
+		mhn = mhn->next;
+	}
+	return - 1;
+}
+
+int MarkerHandleSet::MarkValue() const {
+	unsigned int m = 0;
+	MarkerHandleNumber *mhn = root;
+	while (mhn) {
+		m |= (1 << mhn->number);
+		mhn = mhn->next;
+	}
+	return m;
+}
+
+bool MarkerHandleSet::Contains(int handle) const {
+	MarkerHandleNumber *mhn = root;
+	while (mhn) {
+		if (mhn->handle == handle) {
+			return true;
+		}
+		mhn = mhn->next;
+	}
+	return false;
+}
+
+bool MarkerHandleSet::InsertHandle(int handle, int markerNum) {
+	MarkerHandleNumber *mhn = new MarkerHandleNumber;
+	if (!mhn)
+		return false;
+	mhn->handle = handle;
+	mhn->number = markerNum;
+	mhn->next = root;
+	root = mhn;
+	return true;
+}
+
+void MarkerHandleSet::RemoveHandle(int handle) {
+	MarkerHandleNumber **pmhn = &root;
+	while (*pmhn) {
+		MarkerHandleNumber *mhn = *pmhn;
+		if (mhn->handle == handle) {
+			*pmhn = mhn->next;
+			delete mhn;
+			return;
+		}
+		pmhn = &((*pmhn)->next);
+	}
+}
+
+bool MarkerHandleSet::RemoveNumber(int markerNum) {
+	bool performedDeletion = false;
+	MarkerHandleNumber **pmhn = &root;
+	while (*pmhn) {
+		MarkerHandleNumber *mhn = *pmhn;
+		if (mhn->number == markerNum) {
+			*pmhn = mhn->next;
+			delete mhn;
+			performedDeletion = true;
+		} else {
+			pmhn = &((*pmhn)->next);
+		}
+	}
+	return performedDeletion;
+}
+
+void MarkerHandleSet::CombineWith(MarkerHandleSet *other) {
+	MarkerHandleNumber **pmhn = &root;
+	while (*pmhn) {
+		pmhn = &((*pmhn)->next);
+	}
+	*pmhn = other->root;
+	other->root = 0;
+}
+
+LineMarkers::~LineMarkers() {
+	Init();
+}
+
+void LineMarkers::Init() {
+	for (int line = 0; line < markers.Length(); line++) {
+		delete markers[line];
+		markers[line] = 0;
+	}
+	markers.DeleteAll();
+}
+
+void LineMarkers::InsertLine(int line) {
+	if (markers.Length()) {
+		markers.Insert(line, 0);
+	}
+}
+
+void LineMarkers::RemoveLine(int line) {
+	// Retain the markers from the deleted line by oring them into the previous line
+	if (markers.Length()) {
+		if (line > 0) {
+			MergeMarkers(line - 1);
+		}
+		markers.Delete(line);
+	}
+}
+
+int LineMarkers::LineFromHandle(int markerHandle) {
+	if (markers.Length()) {
+		for (int line = 0; line < markers.Length(); line++) {
+			if (markers[line]) {
+				if (markers[line]->Contains(markerHandle)) {
+					return line;
+				}
+			}
+		}
+	}
+	return -1;
+}
+
+void LineMarkers::MergeMarkers(int pos) {
+	if (markers[pos + 1] != NULL) {
+		if (markers[pos] == NULL)
+			markers[pos] = new MarkerHandleSet;
+		markers[pos]->CombineWith(markers[pos + 1]);
+		delete markers[pos + 1];
+		markers[pos + 1] = NULL;
+	}
+}
+
+int LineMarkers::MarkValue(int line) {
+	if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line])
+		return markers[line]->MarkValue();
+	else
+		return 0;
+}
+
+int LineMarkers::AddMark(int line, int markerNum, int lines) {
+	handleCurrent++;
+	if (!markers.Length()) {
+		// No existing markers so allocate one element per line
+		markers.InsertValue(0, lines, 0);
+	}
+	if (line >= markers.Length()) {
+		return -1;
+	}
+	if (!markers[line]) {
+		// Need new structure to hold marker handle
+		markers[line] = new MarkerHandleSet();
+		if (!markers[line])
+			return -1;
+	}
+	markers[line]->InsertHandle(handleCurrent, markerNum);
+
+	return handleCurrent;
+}
+
+void LineMarkers::DeleteMark(int line, int markerNum, bool all) {
+	if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) {
+		if (markerNum == -1) {
+			delete markers[line];
+			markers[line] = NULL;
+		} else {
+			bool performedDeletion = markers[line]->RemoveNumber(markerNum);
+			while (all && performedDeletion) {
+				performedDeletion = markers[line]->RemoveNumber(markerNum);
+			}
+			if (markers[line]->Length() == 0) {
+				delete markers[line];
+				markers[line] = NULL;
+			}
+		}
+	}
+}
+
+void LineMarkers::DeleteMarkFromHandle(int markerHandle) {
+	int line = LineFromHandle(markerHandle);
+	if (line >= 0) {
+		markers[line]->RemoveHandle(markerHandle);
+		if (markers[line]->Length() == 0) {
+			delete markers[line];
+			markers[line] = NULL;
+		}
+	}
+}
+
+LineLevels::~LineLevels() {
+}
+
+void LineLevels::Init() {
+	levels.DeleteAll();
+}
+
+void LineLevels::InsertLine(int line) {
+	if (levels.Length()) {
+		int level = SC_FOLDLEVELBASE;
+		if ((line > 0) && (line < levels.Length())) {	
+			level = levels[line-1] & ~SC_FOLDLEVELWHITEFLAG;
+		}
+		levels.InsertValue(line, 1, level);
+	}
+}
+
+void LineLevels::RemoveLine(int line) {
+	if (levels.Length()) {
+		// Move up following lines but merge header flag from this line
+		// to line before to avoid a temporary disappearence causing expansion.
+		int firstHeader = levels[line] & SC_FOLDLEVELHEADERFLAG;
+		levels.Delete(line);
+		if (line == levels.Length()-1) // Last line loses the header flag
+			levels[line-1] &= ~SC_FOLDLEVELHEADERFLAG;
+		else if (line > 0)
+			levels[line-1] |= firstHeader;
+	}
+}
+
+void LineLevels::ExpandLevels(int sizeNew) {
+	levels.InsertValue(levels.Length(), sizeNew - levels.Length(), SC_FOLDLEVELBASE);
+}
+
+void LineLevels::ClearLevels() {
+	levels.DeleteAll();
+}
+
+int LineLevels::SetLevel(int line, int level, int lines) {
+	int prev = 0;
+	if ((line >= 0) && (line < lines)) {
+		if (!levels.Length()) {
+			ExpandLevels(lines + 1);
+		}
+		prev = levels[line];
+		if (prev != level) {
+			levels[line] = level;
+		}
+	}
+	return prev;
+}
+
+int LineLevels::GetLevel(int line) {
+	if (levels.Length() && (line >= 0) && (line < levels.Length())) {
+		return levels[line];
+	} else {
+		return SC_FOLDLEVELBASE;
+	}
+}
+
+LineState::~LineState() {
+}
+
+void LineState::Init() {
+	lineStates.DeleteAll();
+}
+
+void LineState::InsertLine(int line) {
+	if (lineStates.Length()) {
+		lineStates.EnsureLength(line);
+		lineStates.Insert(line, 0);
+	}
+}
+
+void LineState::RemoveLine(int line) {
+	if (lineStates.Length() > line) {
+		lineStates.Delete(line);
+	}
+}
+
+int LineState::SetLineState(int line, int state) {
+	lineStates.EnsureLength(line + 1);
+	int stateOld = lineStates[line];
+	lineStates[line] = state;
+	return stateOld;
+}
+
+int LineState::GetLineState(int line) {
+	lineStates.EnsureLength(line + 1);
+	return lineStates[line];
+}
+
+int LineState::GetMaxLineState() {
+	return lineStates.Length();
+}
+
+static int NumberLines(const char *text) {
+	if (text) {
+		int newLines = 0;
+		while (*text) {
+			if (*text == '\n')
+				newLines++;
+			text++;
+		}
+		return newLines+1;
+	} else {
+		return 0;
+	}
+}
+
+// Each allocated LineAnnotation is a char array which starts with an AnnotationHeader
+// and then has text and optional styles.
+
+static const int IndividualStyles = 0x100;
+
+struct AnnotationHeader {
+	short style;	// Style IndividualStyles implies array of styles
+	short lines;
+	int length;
+};
+
+LineAnnotation::~LineAnnotation() {
+	ClearAll();
+}
+
+void LineAnnotation::Init() {
+	ClearAll();
+}
+
+void LineAnnotation::InsertLine(int line) {
+	if (annotations.Length()) {
+		annotations.Insert(line, 0);
+	}
+}
+
+void LineAnnotation::RemoveLine(int line) {
+	if (annotations.Length() && (line < annotations.Length())) {
+		delete []annotations[line];
+		annotations.Delete(line);
+	}
+}
+
+bool LineAnnotation::AnySet() const {
+	return annotations.Length() > 0;
+}
+
+bool LineAnnotation::MultipleStyles(int line) const {
+	if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+		return reinterpret_cast<AnnotationHeader *>(annotations[line])->style == IndividualStyles;
+	else
+		return 0;
+}
+
+int LineAnnotation::Style(int line) {
+	if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+		return reinterpret_cast<AnnotationHeader *>(annotations[line])->style;
+	else
+		return 0;
+}
+
+const char *LineAnnotation::Text(int line) const {
+	if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+		return annotations[line]+sizeof(AnnotationHeader);
+	else
+		return 0;
+}
+
+const unsigned char *LineAnnotation::Styles(int line) const {
+	if (annotations.Length() && (line < annotations.Length()) && annotations[line] && MultipleStyles(line))
+		return reinterpret_cast<unsigned char *>(annotations[line] + sizeof(AnnotationHeader) + Length(line));
+	else
+		return 0;
+}
+
+static char *AllocateAnnotation(int length, int style) {
+	size_t len = sizeof(AnnotationHeader) + length + ((style == IndividualStyles) ? length : 0);
+	char *ret = new char[len];
+	memset(ret, 0, len);
+	return ret;
+}
+
+void LineAnnotation::SetText(int line, const char *text) {
+	if (text) {
+		annotations.EnsureLength(line+1);
+		int style = Style(line);
+		if (annotations[line]) {
+			delete []annotations[line];
+		}
+		annotations[line] = AllocateAnnotation(strlen(text), style);
+		AnnotationHeader *pah = reinterpret_cast<AnnotationHeader*>(annotations[line]);
+		pah->style = static_cast<short>(style);
+		pah->length = strlen(text);
+		pah->lines = static_cast<short>(NumberLines(text));
+		memcpy(annotations[line]+sizeof(AnnotationHeader), text, pah->length);
+	} else {
+		if (annotations.Length() && (line < annotations.Length()) && annotations[line]) {
+			delete []annotations[line];
+			annotations[line] = 0;
+		}
+	}
+}
+
+void LineAnnotation::ClearAll() {
+	for (int line = 0; line < annotations.Length(); line++) {
+		delete []annotations[line];
+		annotations[line] = 0;
+	}
+	annotations.DeleteAll();
+}
+
+void LineAnnotation::SetStyle(int line, int style) {
+	annotations.EnsureLength(line+1);
+	if (!annotations[line]) {
+		annotations[line] = AllocateAnnotation(0, style);
+	}
+	reinterpret_cast<AnnotationHeader *>(annotations[line])->style = static_cast<short>(style);
+}
+
+void LineAnnotation::SetStyles(int line, const unsigned char *styles) {
+	annotations.EnsureLength(line+1);
+	if (!annotations[line]) {
+		annotations[line] = AllocateAnnotation(0, IndividualStyles);
+	} else {
+		AnnotationHeader *pahSource = reinterpret_cast<AnnotationHeader *>(annotations[line]);
+		if (pahSource->style != IndividualStyles) {
+			char *allocation = AllocateAnnotation(pahSource->length, IndividualStyles);
+			AnnotationHeader *pahAlloc = reinterpret_cast<AnnotationHeader *>(allocation);
+			pahAlloc->length = pahSource->length;
+			pahAlloc->lines = pahSource->lines;
+			memcpy(allocation + sizeof(AnnotationHeader), annotations[line] + sizeof(AnnotationHeader), pahSource->length);
+			delete []annotations[line];
+			annotations[line] = allocation;
+		}
+	}
+	AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
+	pah->style = IndividualStyles;
+	memcpy(annotations[line] + sizeof(AnnotationHeader) + pah->length, styles, pah->length);
+}
+
+int LineAnnotation::Length(int line) const {
+	if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+		return reinterpret_cast<AnnotationHeader *>(annotations[line])->length;
+	else
+		return 0;
+}
+
+int LineAnnotation::Lines(int line) const {
+	if (annotations.Length() && (line < annotations.Length()) && annotations[line])
+		return reinterpret_cast<AnnotationHeader *>(annotations[line])->lines;
+	else
+		return 0;
+}
diff --git a/plugins/scintilla/scintilla/PerLine.h b/plugins/scintilla/scintilla/PerLine.h
new file mode 100644
index 0000000..ab34c46
--- /dev/null
+++ b/plugins/scintilla/scintilla/PerLine.h
@@ -0,0 +1,120 @@
+// Scintilla source code edit control
+/** @file PerLine.h
+ ** Manages data associated with each line of the document
+ **/
+// Copyright 1998-2009 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef PERLINE_H
+#define PERLINE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+	
+/**
+ * This holds the marker identifier and the marker type to display.
+ * MarkerHandleNumbers are members of lists.
+ */
+struct MarkerHandleNumber {
+	int handle;
+	int number;
+	MarkerHandleNumber *next;
+};
+
+/**
+ * A marker handle set contains any number of MarkerHandleNumbers.
+ */
+class MarkerHandleSet {
+	MarkerHandleNumber *root;
+
+public:
+	MarkerHandleSet();
+	~MarkerHandleSet();
+	int Length() const;
+	int NumberFromHandle(int handle) const;
+	int MarkValue() const;	///< Bit set of marker numbers.
+	bool Contains(int handle) const;
+	bool InsertHandle(int handle, int markerNum);
+	void RemoveHandle(int handle);
+	bool RemoveNumber(int markerNum);
+	void CombineWith(MarkerHandleSet *other);
+};
+
+class LineMarkers : public PerLine {
+	SplitVector<MarkerHandleSet *> markers;
+	/// Handles are allocated sequentially and should never have to be reused as 32 bit ints are very big.
+	int handleCurrent;
+public:
+	LineMarkers() : handleCurrent(0) {
+	}
+	virtual ~LineMarkers();
+	virtual void Init();
+	virtual void InsertLine(int line);
+	virtual void RemoveLine(int line);
+
+	int MarkValue(int line);
+	int AddMark(int line, int marker, int lines);
+	void MergeMarkers(int pos);
+	void DeleteMark(int line, int markerNum, bool all);
+	void DeleteMarkFromHandle(int markerHandle);
+	int LineFromHandle(int markerHandle);
+};
+
+class LineLevels : public PerLine {
+	SplitVector<int> levels;
+public:
+	virtual ~LineLevels();
+	virtual void Init();
+	virtual void InsertLine(int line);
+	virtual void RemoveLine(int line);
+
+	void ExpandLevels(int sizeNew=-1);
+	void ClearLevels();
+	int SetLevel(int line, int level, int lines);
+	int GetLevel(int line);
+};
+
+class LineState : public PerLine {
+	SplitVector<int> lineStates;
+public:
+	LineState() {
+	}
+	virtual ~LineState();
+	virtual void Init();
+	virtual void InsertLine(int line);
+	virtual void RemoveLine(int line);
+
+	int SetLineState(int line, int state);
+	int GetLineState(int line);
+	int GetMaxLineState();
+};
+
+class LineAnnotation : public PerLine {
+	SplitVector<char *> annotations;
+public:
+	LineAnnotation() {
+	}
+	virtual ~LineAnnotation();
+	virtual void Init();
+	virtual void InsertLine(int line);
+	virtual void RemoveLine(int line);
+
+	bool AnySet() const;
+	bool MultipleStyles(int line) const;
+	int Style(int line);
+	const char *Text(int line) const;
+	const unsigned char *Styles(int line) const;
+	void SetText(int line, const char *text);
+	void ClearAll();
+	void SetStyle(int line, int style);
+	void SetStyles(int line, const unsigned char *styles);
+	int Length(int line) const;
+	int Lines(int line) const;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/PlatGTK.cxx b/plugins/scintilla/scintilla/PlatGTK.cxx
index 30fcf52..bb9fc22 100644
--- a/plugins/scintilla/scintilla/PlatGTK.cxx
+++ b/plugins/scintilla/scintilla/PlatGTK.cxx
@@ -41,6 +41,10 @@
 #pragma warning(disable: 4505)
 #endif
 
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
 enum encodingType { singleByte, UTF8, dbcs};
 
 struct LOGFONT {
@@ -169,8 +173,8 @@ static FontHandle *PFont(Font &f) {
 	return reinterpret_cast<FontHandle *>(f.GetID());
 }
 
-static GtkWidget *PWidget(WindowID id) {
-	return reinterpret_cast<GtkWidget *>(id);
+static GtkWidget *PWidget(WindowID wid) {
+	return reinterpret_cast<GtkWidget *>(wid);
 }
 
 static GtkWidget *PWidget(Window &w) {
@@ -417,7 +421,7 @@ class FontCached : Font {
 	static FontCached *first;
 public:
 	static FontID FindOrCreate(const char *faceName_, int characterSet_, int size_, bool bold_, bool italic_);
-	static void ReleaseId(FontID id_);
+	static void ReleaseId(FontID fid_);
 };
 
 FontCached *FontCached::first = 0;
@@ -426,7 +430,7 @@ FontCached::FontCached(const char *faceName_, int characterSet_, int size_, bool
 next(0), usage(0), hash(0) {
 	::SetLogFont(lf, faceName_, characterSet_, size_, bold_, italic_);
 	hash = HashFont(faceName_, characterSet_, size_, bold_, italic_);
-	id = CreateNewFont(faceName_, characterSet_, size_, bold_, italic_);
+	fid = CreateNewFont(faceName_, characterSet_, size_, bold_, italic_);
 	usage = 1;
 }
 
@@ -440,9 +444,9 @@ bool FontCached::SameAs(const char *faceName_, int characterSet_, int size_, boo
 }
 
 void FontCached::Release() {
-	if (id)
+	if (fid)
 		delete PFont(*this);
-	id = 0;
+	fid = 0;
 }
 
 FontID FontCached::FindOrCreate(const char *faceName_, int characterSet_, int size_, bool bold_, bool italic_) {
@@ -453,7 +457,7 @@ FontID FontCached::FindOrCreate(const char *faceName_, int characterSet_, int si
 		if ((cur->hash == hashFind) &&
 		        cur->SameAs(faceName_, characterSet_, size_, bold_, italic_)) {
 			cur->usage++;
-			ret = cur->id;
+			ret = cur->fid;
 		}
 	}
 	if (ret == 0) {
@@ -461,18 +465,18 @@ FontID FontCached::FindOrCreate(const char *faceName_, int characterSet_, int si
 		if (fc) {
 			fc->next = first;
 			first = fc;
-			ret = fc->id;
+			ret = fc->fid;
 		}
 	}
 	FontMutexUnlock();
 	return ret;
 }
 
-void FontCached::ReleaseId(FontID id_) {
+void FontCached::ReleaseId(FontID fid_) {
 	FontMutexLock();
 	FontCached **pcur = &first;
 	for (FontCached *cur = first; cur; cur = cur->next) {
-		if (cur->id == id_) {
+		if (cur->fid == fid_) {
 			cur->usage--;
 			if (cur->usage == 0) {
 				*pcur = cur->next;
@@ -657,23 +661,29 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
 	return new FontHandle(newid);
 }
 
-Font::Font() : id(0) {}
+Font::Font() : fid(0) {}
 
 Font::~Font() {}
 
 void Font::Create(const char *faceName, int characterSet, int size,
 	bool bold, bool italic, bool) {
 	Release();
-	id = FontCached::FindOrCreate(faceName, characterSet, size, bold, italic);
+	fid = FontCached::FindOrCreate(faceName, characterSet, size, bold, italic);
 }
 
 void Font::Release() {
-	if (id)
-		FontCached::ReleaseId(id);
-	id = 0;
+	if (fid)
+		FontCached::ReleaseId(fid);
+	fid = 0;
 }
 
-class SurfaceImpl : public Surface {
+// Required on OS X
+#ifdef SCI_NAMESPACE
+class Scintilla::SurfaceImpl : public Surface
+#else
+class SurfaceImpl : public Surface
+#endif
+{
 	encodingType et;
 	GdkDrawable *drawable;
 	GdkGC *gc;
@@ -1047,6 +1057,19 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int , ColourAllocated , int , Co
 	}
 }
 #else
+
+static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
+	union {
+		guint8 pixVal[4];
+		guint32 val;
+	} converter;
+	converter.pixVal[0] = r;
+	converter.pixVal[1] = g;
+	converter.pixVal[2] = b;
+	converter.pixVal[3] = a;
+	return converter.val;
+}
+
 void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
 		ColourAllocated outline, int alphaOutline, int flags) {
 	if (gc && drawable && rc.Width() > 0) {
@@ -1057,18 +1080,11 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated
 		// Make a 32 bit deep pixbuf with alpha
 		GdkPixbuf *pixalpha = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
 
-		guint8 pixVal[4] = {0};
-		guint32 valEmpty = *(reinterpret_cast<guint32 *>(pixVal));
-		pixVal[0] = GetRValue(fill.AsLong());
-		pixVal[1] = GetGValue(fill.AsLong());
-		pixVal[2] = GetBValue(fill.AsLong());
-		pixVal[3] = alphaFill;
-		guint32 valFill = *(reinterpret_cast<guint32 *>(pixVal));
-		pixVal[0] = GetRValue(outline.AsLong());
-		pixVal[1] = GetGValue(outline.AsLong());
-		pixVal[2] = GetBValue(outline.AsLong());
-		pixVal[3] = alphaOutline;
-		guint32 valOutline = *(reinterpret_cast<guint32 *>(pixVal));
+		guint32 valEmpty = u32FromRGBA(0,0,0,0);
+		guint32 valFill = u32FromRGBA(GetRValue(fill.AsLong()), 
+			GetGValue(fill.AsLong()), GetBValue(fill.AsLong()), alphaFill);
+		guint32 valOutline = u32FromRGBA(GetRValue(outline.AsLong()), 
+			GetGValue(outline.AsLong()), GetBValue(outline.AsLong()), alphaOutline);
 		guint32 *pixels = reinterpret_cast<guint32 *>(gdk_pixbuf_get_pixels(pixalpha));
 		int stride = gdk_pixbuf_get_rowstride(pixalpha) / 4;
 		for (int yr=0; yr<height; yr++) {
@@ -1096,6 +1112,7 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated
 		g_object_unref(pixalpha);
 	}
 }
+
 #endif
 
 void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
@@ -1725,24 +1742,24 @@ Surface *Surface::Allocate() {
 Window::~Window() {}
 
 void Window::Destroy() {
-	if (id)
-		gtk_widget_destroy(GTK_WIDGET(id));
-	id = 0;
+	if (wid)
+		gtk_widget_destroy(GTK_WIDGET(wid));
+	wid = 0;
 }
 
 bool Window::HasFocus() {
-	return GTK_WIDGET_HAS_FOCUS(id);
+	return GTK_WIDGET_HAS_FOCUS(wid);
 }
 
 PRectangle Window::GetPosition() {
 	// Before any size allocated pretend its 1000 wide so not scrolled
 	PRectangle rc(0, 0, 1000, 1000);
-	if (id) {
-		rc.left = PWidget(id)->allocation.x;
-		rc.top = PWidget(id)->allocation.y;
-		if (PWidget(id)->allocation.width > 20) {
-			rc.right = rc.left + PWidget(id)->allocation.width;
-			rc.bottom = rc.top + PWidget(id)->allocation.height;
+	if (wid) {
+		rc.left = PWidget(wid)->allocation.x;
+		rc.top = PWidget(wid)->allocation.y;
+		if (PWidget(wid)->allocation.width > 20) {
+			rc.right = rc.left + PWidget(wid)->allocation.width;
+			rc.bottom = rc.top + PWidget(wid)->allocation.height;
 		}
 	}
 	return rc;
@@ -1750,24 +1767,23 @@ PRectangle Window::GetPosition() {
 
 void Window::SetPosition(PRectangle rc) {
 #if 1
-	//gtk_widget_set_uposition(id, rc.left, rc.top);
 	GtkAllocation alloc;
 	alloc.x = rc.left;
 	alloc.y = rc.top;
 	alloc.width = rc.Width();
 	alloc.height = rc.Height();
-	gtk_widget_size_allocate(PWidget(id), &alloc);
+	gtk_widget_size_allocate(PWidget(wid), &alloc);
 #else
 
-	gtk_widget_set_uposition(id, rc.left, rc.top);
-	gtk_widget_set_size_request(id, rc.right - rc.left, rc.bottom - rc.top);
+	gtk_widget_set_uposition(wid, rc.left, rc.top);
+	gtk_widget_set_size_request(wid, rc.right - rc.left, rc.bottom - rc.top);
 #endif
 }
 
 void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
 	int ox = 0;
 	int oy = 0;
-	gdk_window_get_origin(PWidget(relativeTo.id)->window, &ox, &oy);
+	gdk_window_get_origin(PWidget(relativeTo.wid)->window, &ox, &oy);
 	ox += rc.left;
 	if (ox < 0)
 		ox = 0;
@@ -1787,7 +1803,12 @@ void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
 	if (oy + sizey > screenHeight)
 		oy = screenHeight - sizey;
 
-	gtk_window_move(GTK_WINDOW(id), ox, oy);
+#if GTK_MAJOR_VERSION >= 2
+	gtk_window_move(GTK_WINDOW(PWidget(wid)), ox, oy);
+#else
+	gtk_widget_set_uposition(PWidget(wid), ox, oy);
+#endif
+
 #if 0
 
 	GtkAllocation alloc;
@@ -1795,9 +1816,9 @@ void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
 	alloc.y = rc.top + oy;
 	alloc.width = rc.right - rc.left;
 	alloc.height = rc.bottom - rc.top;
-	gtk_widget_size_allocate(id, &alloc);
+	gtk_widget_size_allocate(wid, &alloc);
 #endif
-	gtk_widget_set_size_request(PWidget(id), sizex, sizey);
+	gtk_widget_set_size_request(PWidget(wid), sizex, sizey);
 }
 
 PRectangle Window::GetClientPosition() {
@@ -1807,18 +1828,18 @@ PRectangle Window::GetClientPosition() {
 
 void Window::Show(bool show) {
 	if (show)
-		gtk_widget_show(PWidget(id));
+		gtk_widget_show(PWidget(wid));
 }
 
 void Window::InvalidateAll() {
-	if (id) {
-		gtk_widget_queue_draw(PWidget(id));
+	if (wid) {
+		gtk_widget_queue_draw(PWidget(wid));
 	}
 }
 
 void Window::InvalidateRectangle(PRectangle rc) {
-	if (id) {
-		gtk_widget_queue_draw_area(PWidget(id),
+	if (wid) {
+		gtk_widget_queue_draw_area(PWidget(wid),
 		                           rc.left, rc.top,
 		                           rc.right - rc.left, rc.bottom - rc.top);
 	}
@@ -1861,13 +1882,13 @@ void Window::SetCursor(Cursor curs) {
 		break;
 	}
 
-	if (PWidget(id)->window)
-		gdk_window_set_cursor(PWidget(id)->window, gdkCurs);
+	if (PWidget(wid)->window)
+		gdk_window_set_cursor(PWidget(wid)->window, gdkCurs);
 	gdk_cursor_destroy(gdkCurs);
 }
 
 void Window::SetTitle(const char *s) {
-	gtk_window_set_title(GTK_WINDOW(id), s);
+	gtk_window_set_title(GTK_WINDOW(wid), s);
 }
 
 /* Returns rectangle of monitor pt is on, both rect and pt are in Window's
@@ -1876,7 +1897,7 @@ PRectangle Window::GetMonitorRect(Point pt) {
 	gint x_offset, y_offset;
 	pt = pt;
 
-	gdk_window_get_origin(PWidget(id)->window, &x_offset, &y_offset);
+	gdk_window_get_origin(PWidget(wid)->window, &x_offset, &y_offset);
 
 // gtk 2.2+
 #if GTK_MAJOR_VERSION > 2 || (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 2)
@@ -1885,7 +1906,7 @@ PRectangle Window::GetMonitorRect(Point pt) {
 		gint monitor_num;
 		GdkRectangle rect;
 
-		screen = gtk_widget_get_screen(PWidget(id));
+		screen = gtk_widget_get_screen(PWidget(wid));
 		monitor_num = gdk_screen_get_monitor_at_point(screen, pt.x + x_offset, pt.y + y_offset);
 		gdk_screen_get_monitor_geometry(screen, monitor_num, &rect);
 		rect.x -= x_offset;
@@ -1943,6 +1964,9 @@ class ListBoxX : public ListBox {
 	int current;
 #endif
 	void *pixhash;
+#if GTK_MAJOR_VERSION >= 2
+        GtkCellRenderer* pixbuf_renderer;
+#endif
 	int lineHeight;
 	XPMSet xset;
 	bool unicodeMode;
@@ -1958,6 +1982,9 @@ public:
 #if GTK_MAJOR_VERSION < 2
 			current = 0;
 #endif
+#if GTK_MAJOR_VERSION >= 2
+			pixbuf_renderer = 0;
+#endif
 	}
 	virtual ~ListBoxX() {
 		if (pixhash) {
@@ -2007,12 +2034,16 @@ static void SelectionAC(GtkWidget *, gint row, gint,
 #endif
 
 static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) {
-	ListBoxX* lb = reinterpret_cast<ListBoxX*>(p);
-	if (ev->type == GDK_2BUTTON_PRESS && lb->doubleClickAction != NULL) {
-		lb->doubleClickAction(lb->doubleClickActionData);
-		return TRUE;
-	}
+	try {
+		ListBoxX* lb = reinterpret_cast<ListBoxX*>(p);
+		if (ev->type == GDK_2BUTTON_PRESS && lb->doubleClickAction != NULL) {
+			lb->doubleClickAction(lb->doubleClickActionData);
+			return TRUE;
+		}
 
+	} catch (...) {
+		// No pointer back to Scintilla to save status
+	}
 	return FALSE;
 }
 
@@ -2042,7 +2073,7 @@ static void StyleSet(GtkWidget *w, GtkStyle*, void*) {
 #endif
 
 void ListBoxX::Create(Window &, int, Point, int, bool) {
-	id = gtk_window_new(GTK_WINDOW_POPUP);
+	wid = gtk_window_new(GTK_WINDOW_POPUP);
 
 	GtkWidget *frame = gtk_frame_new(NULL);
 	gtk_widget_show(frame);
@@ -2090,12 +2121,13 @@ void ListBoxX::Create(Window &, int, Point, int, bool) {
 	gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
 	gtk_tree_view_column_set_title(column, "Autocomplete");
 
-	GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
-	gtk_tree_view_column_pack_start(column, renderer, FALSE);
-	gtk_tree_view_column_add_attribute(column, renderer,
+	pixbuf_renderer = gtk_cell_renderer_pixbuf_new();
+	gtk_cell_renderer_set_fixed_size(pixbuf_renderer, 0, -1);
+	gtk_tree_view_column_pack_start(column, pixbuf_renderer, FALSE);
+	gtk_tree_view_column_add_attribute(column, pixbuf_renderer,
 										"pixbuf", PIXBUF_COLUMN);
-
-	renderer = gtk_cell_renderer_text_new();
+	
+	GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
 	gtk_cell_renderer_text_set_fixed_height_from_font(GTK_CELL_RENDERER_TEXT(renderer), 1);
 	gtk_tree_view_column_pack_start(column, renderer, TRUE);
 	gtk_tree_view_column_add_attribute(column, renderer,
@@ -2111,7 +2143,7 @@ void ListBoxX::Create(Window &, int, Point, int, bool) {
 	g_signal_connect(G_OBJECT(wid), "button_press_event",
 	                   G_CALLBACK(ButtonPress), this);
 #endif
-	gtk_widget_realize(PWidget(id));
+	gtk_widget_realize(PWidget(wid));
 }
 
 void ListBoxX::SetFont(Font &scint_font) {
@@ -2149,7 +2181,7 @@ int ListBoxX::GetVisibleRows() const {
 PRectangle ListBoxX::GetDesiredRect() {
 	// Before any size allocated pretend its 100 wide so not scrolled
 	PRectangle rc(0, 0, 100, 100);
-	if (id) {
+	if (wid) {
 		int rows = Length();
 		if ((rows == 0) || (rows > desiredVisibleRows))
 			rows = desiredVisibleRows;
@@ -2197,6 +2229,12 @@ PRectangle ListBoxX::GetDesiredRect() {
 }
 
 int ListBoxX::CaretFromEdge() {
+#if GTK_MAJOR_VERSION >= 2
+	gint renderer_width, renderer_height;
+	gtk_cell_renderer_get_fixed_size(pixbuf_renderer, &renderer_width,
+						&renderer_height);
+	return 4 + renderer_width;
+#endif
 	return 4 + xset.GetWidth();
 }
 
@@ -2283,6 +2321,14 @@ void ListBoxX::Append(char *s, int type) {
 			gtk_list_store_set(GTK_LIST_STORE(store), &iter,
 								PIXBUF_COLUMN, list_image->pixbuf,
 								TEXT_COLUMN, s, -1);
+
+			gint pixbuf_width = gdk_pixbuf_get_width(list_image->pixbuf);
+			gint renderer_height, renderer_width;
+			gtk_cell_renderer_get_fixed_size(pixbuf_renderer, 
+								&renderer_width, &renderer_height);
+			if (pixbuf_width > renderer_width)
+				gtk_cell_renderer_set_fixed_size(pixbuf_renderer,
+								pixbuf_width, -1);
 		} else {
 			gtk_list_store_set(GTK_LIST_STORE(store), &iter,
 								TEXT_COLUMN, s, -1);
@@ -2298,7 +2344,7 @@ void ListBoxX::Append(char *s, int type) {
 }
 
 int ListBoxX::Length() {
-	if (id)
+	if (wid)
 #if GTK_MAJOR_VERSION < 2
 		return GTK_CLIST(list)->rows;
 #else
@@ -2520,27 +2566,27 @@ void ListBoxX::SetList(const char *listText, char separator, char typesep) {
 	}
 }
 
-Menu::Menu() : id(0) {}
+Menu::Menu() : mid(0) {}
 
 void Menu::CreatePopUp() {
 	Destroy();
-	id = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
+	mid = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
 }
 
 void Menu::Destroy() {
-	if (id)
+	if (mid)
 #if GTK_MAJOR_VERSION < 2
-		gtk_object_unref(GTK_OBJECT(id));
+		gtk_object_unref(GTK_OBJECT(mid));
 #else
-		g_object_unref(G_OBJECT(id));
+		g_object_unref(G_OBJECT(mid));
 #endif
-	id = 0;
+	mid = 0;
 }
 
 void Menu::Show(Point pt, Window &) {
 	int screenHeight = gdk_screen_height();
 	int screenWidth = gdk_screen_width();
-	GtkItemFactory *factory = reinterpret_cast<GtkItemFactory *>(id);
+	GtkItemFactory *factory = reinterpret_cast<GtkItemFactory *>(mid);
 	GtkWidget *widget = gtk_item_factory_get_widget(factory, "<main>");
 	gtk_widget_show_all(widget);
 	GtkRequisition requisition;
diff --git a/plugins/scintilla/scintilla/PositionCache.cxx b/plugins/scintilla/scintilla/PositionCache.cxx
index f40a153..580a179 100644
--- a/plugins/scintilla/scintilla/PositionCache.cxx
+++ b/plugins/scintilla/scintilla/PositionCache.cxx
@@ -10,6 +10,8 @@
 #include <stdio.h>
 #include <ctype.h>
 
+#include <vector>
+
 #include "Platform.h"
 
 #include "Scintilla.h"
@@ -28,6 +30,7 @@
 #include "CharClassify.h"
 #include "Decoration.h"
 #include "Document.h"
+#include "Selection.h"
 #include "PositionCache.h"
 
 #ifdef SCI_NAMESPACE
@@ -46,11 +49,11 @@ LineLayout::LineLayout(int maxLineLength_) :
 	inCache(false),
 	maxLineLength(-1),
 	numCharsInLine(0),
+	numCharsBeforeEOL(0),
 	validity(llInvalid),
 	xHighlightGuide(0),
 	highlightColumn(0),
-	selStart(0),
-	selEnd(0),
+	psel(NULL),
 	containsCaret(false),
 	edgeColumn(0),
 	chars(0),
@@ -61,7 +64,8 @@ LineLayout::LineLayout(int maxLineLength_) :
 	hsStart(0),
 	hsEnd(0),
 	widthLine(wrapWidthInfinite),
-	lines(1) {
+	lines(1),
+	wrapIndent(0) {
 	Resize(maxLineLength_);
 }
 
@@ -114,28 +118,21 @@ int LineLayout::LineLastVisible(int line) const {
 	if (line < 0) {
 		return 0;
 	} else if ((line >= lines-1) || !lineStarts) {
-		int startLine = LineStart(line);
-		int endLine = numCharsInLine;
-		while ((endLine > startLine) && IsEOLChar(chars[endLine-1])) {
-			endLine--;
-		}
-		return endLine;
+		return numCharsBeforeEOL;
 	} else {
 		return lineStarts[line+1];
 	}
 }
 
 bool LineLayout::InLine(int offset, int line) const {
-	return ((offset >= LineStart(line)) && (offset < LineStart(line + 1)) ||
-		((offset == numCharsInLine) && (line == (lines-1))));
+	return ((offset >= LineStart(line)) && (offset < LineStart(line + 1))) ||
+		((offset == numCharsInLine) && (line == (lines-1)));
 }
 
 void LineLayout::SetLineStart(int line, int start) {
 	if ((line >= lenLineStarts) && (line != 0)) {
 		int newMaxLines = line + 20;
 		int *newLineStarts = new int[newMaxLines];
-		if (!newLineStarts)
-			return;
 		for (int i = 0; i < newMaxLines; i++) {
 			if (i < lenLineStarts)
 				newLineStarts[i] = lineStarts[i];
@@ -200,6 +197,10 @@ int LineLayout::FindBefore(int x, int lower, int upper) const {
 	return lower;
 }
 
+int LineLayout::EndLineStyle() const {
+	return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0];
+}
+
 LineLayoutCache::LineLayoutCache() :
 	level(0), length(0), size(0), cache(0),
 	allInvalidated(false), styleClock(-1), useCount(0) {
@@ -411,9 +412,13 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL
 		nextBreak--;
 	}
 
-	if (ll->selStart != ll->selEnd) {
-		Insert(ll->selStart - posLineStart - 1);
-		Insert(ll->selEnd - posLineStart - 1);
+	SelectionSegment segmentLine(SelectionPosition(posLineStart), SelectionPosition(posLineStart + lineEnd));
+	for (size_t r=0; r<ll->psel->Count(); r++) {
+		SelectionSegment portion = ll->psel->Range(r).Intersect(segmentLine);
+		if (portion.start.IsValid())
+			Insert(portion.start.Position() - posLineStart - 1);
+		if (portion.end.IsValid())
+			Insert(portion.end.Position() - posLineStart - 1);
 	}
 
 	Insert(ll->edgeColumn - 1);
@@ -440,6 +445,10 @@ int BreakFinder::First() {
 	return nextBreak;
 }
 
+static bool IsTrailByte(int ch) {
+	return (ch >= 0x80) && (ch < (0x80 + 0x40));
+}
+
 int BreakFinder::Next() {
 	if (subBreak == -1) {
 		int prev = nextBreak;
@@ -472,15 +481,20 @@ int BreakFinder::Next() {
 	} else {
 		int lastGoodBreak = -1;
 		int lastOKBreak = -1;
+		int lastUTF8Break = -1;
 		int j;
 		for (j = subBreak + 1; j <= nextBreak; j++) {
 			if (IsSpaceOrTab(ll->chars[j - 1]) && !IsSpaceOrTab(ll->chars[j])) {
 				lastGoodBreak = j;
 			}
-			if (ll->chars[j] < 'A') {
+			if (static_cast<unsigned char>(ll->chars[j]) < 'A') {
 				lastOKBreak = j;
 			}
-			if (((j - subBreak) >= lengthEachSubdivision) && ((lastGoodBreak >= 0) || (lastOKBreak >= 0))) {
+			if (utf8 && !IsTrailByte(static_cast<unsigned char>(ll->chars[j]))) {
+				lastUTF8Break = j;
+			}
+			if (((j - subBreak) >= lengthEachSubdivision) &&
+				((lastGoodBreak >= 0) || (lastOKBreak >= 0) || (lastUTF8Break >= 0))) {
 				break;
 			}
 		}
@@ -488,6 +502,8 @@ int BreakFinder::Next() {
 			subBreak = lastGoodBreak;
 		} else if (lastOKBreak >= 0) {
 			subBreak = lastOKBreak;
+		} else if (lastUTF8Break >= 0) {
+			subBreak = lastUTF8Break;
 		} else {
 			subBreak = nextBreak;
 		}
diff --git a/plugins/scintilla/scintilla/PositionCache.h b/plugins/scintilla/scintilla/PositionCache.h
index 5d486cb..a868810 100644
--- a/plugins/scintilla/scintilla/PositionCache.h
+++ b/plugins/scintilla/scintilla/PositionCache.h
@@ -2,7 +2,7 @@
 /** @file PositionCache.h
  ** Classes for caching layout information.
  **/
-// Copyright 1998-2007 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2009 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef POSITIONCACHE_H
@@ -30,11 +30,11 @@ public:
 	enum { wrapWidthInfinite = 0x7ffffff };
 	int maxLineLength;
 	int numCharsInLine;
+	int numCharsBeforeEOL;
 	enum validLevel { llInvalid, llCheckTextAndStyle, llPositions, llLines } validity;
 	int xHighlightGuide;
 	bool highlightColumn;
-	int selStart;
-	int selEnd;
+	Selection *psel;
 	bool containsCaret;
 	int edgeColumn;
 	char *chars;
@@ -51,6 +51,7 @@ public:
 	// Wrapped line support
 	int widthLine;
 	int lines;
+	int wrapIndent; // In pixels
 
 	LineLayout(int maxLineLength_);
 	virtual ~LineLayout();
@@ -65,6 +66,7 @@ public:
 		char bracesMatchStyle, int xHighlight);
 	void RestoreBracesHighlight(Range rangeLine, Position braces[]);
 	int FindBefore(int x, int lower, int upper) const;
+	int EndLineStyle() const;
 };
 
 /**
diff --git a/plugins/scintilla/scintilla/PropSet.cxx b/plugins/scintilla/scintilla/PropSet.cxx
index a1c366c..294d08e 100644
--- a/plugins/scintilla/scintilla/PropSet.cxx
+++ b/plugins/scintilla/scintilla/PropSet.cxx
@@ -11,370 +11,53 @@
 #include <string.h>
 #include <stdio.h>
 
+#ifdef _MSC_VER
+// Visual C++ doesn't like unreachable code or long decorated names in its own headers.
+#pragma warning(disable: 4018 4100 4245 4511 4512 4663 4702 4786)
+#endif
+
+#include <string>
+#include <map>
+
 #include "Platform.h"
 
 #include "PropSet.h"
+#include "PropSetSimple.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-// The comparison and case changing functions here assume ASCII
-// or extended ASCII such as the normal Windows code page.
-
-static inline char MakeUpperCase(char ch) {
-	if (ch < 'a' || ch > 'z')
-		return ch;
-	else
-		return static_cast<char>(ch - 'a' + 'A');
-}
-
-static inline bool IsLetter(char ch) {
-	return ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'));
-}
-
-inline bool IsASpace(unsigned int ch) {
-    return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
-}
-
-int CompareCaseInsensitive(const char *a, const char *b) {
-	while (*a && *b) {
-		if (*a != *b) {
-			char upperA = MakeUpperCase(*a);
-			char upperB = MakeUpperCase(*b);
-			if (upperA != upperB)
-				return upperA - upperB;
-		}
-		a++;
-		b++;
-	}
-	// Either *a or *b is nul
-	return *a - *b;
-}
-
-int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
-	while (*a && *b && len) {
-		if (*a != *b) {
-			char upperA = MakeUpperCase(*a);
-			char upperB = MakeUpperCase(*b);
-			if (upperA != upperB)
-				return upperA - upperB;
-		}
-		a++;
-		b++;
-		len--;
-	}
-	if (len == 0)
-		return 0;
-	else
-		// Either *a or *b is nul
-		return *a - *b;
-}
-
-bool EqualCaseInsensitive(const char *a, const char *b) {
-	return 0 == CompareCaseInsensitive(a, b);
-}
-
-// Since the CaseInsensitive functions declared in SString
-// are implemented here, I will for now put the non-inline
-// implementations of the SString members here as well, so
-// that I can quickly see what effect this has.
-
-SString::SString(int i) : sizeGrowth(sizeGrowthDefault) {
-	char number[32];
-	sprintf(number, "%0d", i);
-	s = StringAllocate(number);
-	sSize = sLen = (s) ? strlen(s) : 0;
-}
-
-SString::SString(double d, int precision) : sizeGrowth(sizeGrowthDefault) {
-	char number[32];
-	sprintf(number, "%.*f", precision, d);
-	s = StringAllocate(number);
-	sSize = sLen = (s) ? strlen(s) : 0;
-}
-
-bool SString::grow(lenpos_t lenNew) {
-	while (sizeGrowth * 6 < lenNew) {
-		sizeGrowth *= 2;
-	}
-	char *sNew = new char[lenNew + sizeGrowth + 1];
-	if (sNew) {
-		if (s) {
-			memcpy(sNew, s, sLen);
-			delete []s;
-		}
-		s = sNew;
-		s[sLen] = '\0';
-		sSize = lenNew + sizeGrowth;
-	}
-	return sNew != 0;
-}
-
-SString &SString::assign(const char *sOther, lenpos_t sSize_) {
-	if (!sOther) {
-		sSize_ = 0;
-	} else if (sSize_ == measure_length) {
-		sSize_ = strlen(sOther);
-	}
-	if (sSize > 0 && sSize_ <= sSize) {	// Does not allocate new buffer if the current is big enough
-		if (s && sSize_) {
-			memcpy(s, sOther, sSize_);
-		}
-		s[sSize_] = '\0';
-		sLen = sSize_;
-	} else {
-		delete []s;
-		s = StringAllocate(sOther, sSize_);
-		if (s) {
-			sSize = sSize_;	// Allow buffer bigger than real string, thus providing space to grow
-			sLen = sSize_;
-		} else {
-			sSize = sLen = 0;
-		}
-	}
-	return *this;
-}
-
-bool SString::operator==(const SString &sOther) const {
-	if ((s == 0) && (sOther.s == 0))
-		return true;
-	if ((s == 0) || (sOther.s == 0))
-		return false;
-	return strcmp(s, sOther.s) == 0;
-}
-
-bool SString::operator==(const char *sOther) const {
-	if ((s == 0) && (sOther == 0))
-		return true;
-	if ((s == 0) || (sOther == 0))
-		return false;
-	return strcmp(s, sOther) == 0;
-}
-
-SString SString::substr(lenpos_t subPos, lenpos_t subLen) const {
-	if (subPos >= sLen) {
-		return SString();					// return a null string if start index is out of bounds
-	}
-	if ((subLen == measure_length) || (subPos + subLen > sLen)) {
-		subLen = sLen - subPos;		// can't substr past end of source string
-	}
-	return SString(s, subPos, subPos + subLen);
-}
+typedef std::map<std::string, std::string> mapss;
 
-SString &SString::lowercase(lenpos_t subPos, lenpos_t subLen) {
-	if ((subLen == measure_length) || (subPos + subLen > sLen)) {
-		subLen = sLen - subPos;		// don't apply past end of string
-	}
-	for (lenpos_t i = subPos; i < subPos + subLen; i++) {
-		if (s[i] < 'A' || s[i] > 'Z')
-			continue;
-		else
-			s[i] = static_cast<char>(s[i] - 'A' + 'a');
-	}
-	return *this;
+PropSetSimple::PropSetSimple() {
+	mapss *props = new mapss;
+	impl = static_cast<void *>(props);
 }
 
-SString &SString::uppercase(lenpos_t subPos, lenpos_t subLen) {
-	if ((subLen == measure_length) || (subPos + subLen > sLen)) {
-		subLen = sLen - subPos;		// don't apply past end of string
-	}
-	for (lenpos_t i = subPos; i < subPos + subLen; i++) {
-		if (s[i] < 'a' || s[i] > 'z')
-			continue;
-		else
-			s[i] = static_cast<char>(s[i] - 'a' + 'A');
-	}
-	return *this;
-}
-
-SString &SString::append(const char *sOther, lenpos_t sLenOther, char sep) {
-	if (!sOther) {
-		return *this;
-	}
-	if (sLenOther == measure_length) {
-		sLenOther = strlen(sOther);
-	}
-	int lenSep = 0;
-	if (sLen && sep) {	// Only add a separator if not empty
-		lenSep = 1;
-	}
-	lenpos_t lenNew = sLen + sLenOther + lenSep;
-	// Conservative about growing the buffer: don't do it, unless really needed
-	if ((lenNew < sSize) || (grow(lenNew))) {
-		if (lenSep) {
-			s[sLen] = sep;
-			sLen++;
-		}
-		memcpy(&s[sLen], sOther, sLenOther);
-		sLen += sLenOther;
-		s[sLen] = '\0';
-	}
-	return *this;
-}
-
-SString &SString::insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther) {
-	if (!sOther || pos > sLen) {
-		return *this;
-	}
-	if (sLenOther == measure_length) {
-		sLenOther = strlen(sOther);
-	}
-	lenpos_t lenNew = sLen + sLenOther;
-	// Conservative about growing the buffer: don't do it, unless really needed
-	if ((lenNew < sSize) || grow(lenNew)) {
-		lenpos_t moveChars = sLen - pos + 1;
-		for (lenpos_t i = moveChars; i > 0; i--) {
-			s[pos + sLenOther + i - 1] = s[pos + i - 1];
-		}
-		memcpy(s + pos, sOther, sLenOther);
-		sLen = lenNew;
-	}
-	return *this;
+PropSetSimple::~PropSetSimple() {
+	mapss *props = static_cast<mapss *>(impl);
+	delete props;
+	impl = 0;
 }
 
-/**
- * Remove @a len characters from the @a pos position, included.
- * Characters at pos + len and beyond replace characters at pos.
- * If @a len is 0, or greater than the length of the string
- * starting at @a pos, the string is just truncated at @a pos.
- */
-void SString::remove(lenpos_t pos, lenpos_t len) {
-	if (pos >= sLen) {
-		return;
-	}
-	if (len < 1 || pos + len >= sLen) {
-		s[pos] = '\0';
-		sLen = pos;
-	} else {
-		for (lenpos_t i = pos; i < sLen - len + 1; i++) {
-			s[i] = s[i+len];
-		}
-		sLen -= len;
-	}
-}
-
-bool SString::startswith(const char *prefix) {
-	lenpos_t lenPrefix = strlen(prefix);
-	if (lenPrefix > sLen) {
-		return false;
-	}
-	return strncmp(s, prefix, lenPrefix) == 0;
-}
-
-bool SString::endswith(const char *suffix) {
-	lenpos_t lenSuffix = strlen(suffix);
-	if (lenSuffix > sLen) {
-		return false;
-	}
-	return strncmp(s + sLen - lenSuffix, suffix, lenSuffix) == 0;
-}
-
-int SString::search(const char *sFind, lenpos_t start) const {
-	if (start < sLen) {
-		const char *sFound = strstr(s + start, sFind);
-		if (sFound) {
-			return sFound - s;
-		}
-	}
-	return -1;
-}
-
-int SString::substitute(char chFind, char chReplace) {
-	int c = 0;
-	char *t = s;
-	while (t) {
-		t = strchr(t, chFind);
-		if (t) {
-			*t = chReplace;
-			t++;
-			c++;
-		}
-	}
-	return c;
-}
-
-int SString::substitute(const char *sFind, const char *sReplace) {
-	int c = 0;
-	lenpos_t lenFind = strlen(sFind);
-	lenpos_t lenReplace = strlen(sReplace);
-	int posFound = search(sFind);
-	while (posFound >= 0) {
-		remove(posFound, lenFind);
-		insert(posFound, sReplace, lenReplace);
-		posFound = search(sFind, posFound + lenReplace);
-		c++;
-	}
-	return c;
-}
-
-char *SContainer::StringAllocate(lenpos_t len) {
-	if (len != measure_length) {
-		return new char[len + 1];
-	} else {
-		return 0;
-	}
-}
-
-char *SContainer::StringAllocate(const char *s, lenpos_t len) {
-	if (s == 0) {
-		return 0;
-	}
-	if (len == measure_length) {
-		len = strlen(s);
-	}
-	char *sNew = new char[len + 1];
-	if (sNew) {
-		memcpy(sNew, s, len);
-		sNew[len] = '\0';
-	}
-	return sNew;
-}
-
-// End SString functions
-
-PropSet::PropSet() {
-	superPS = 0;
-	for (int root = 0; root < hashRoots; root++)
-		props[root] = 0;
-}
-
-PropSet::~PropSet() {
-	superPS = 0;
-	Clear();
-}
-
-void PropSet::Set(const char *key, const char *val, int lenKey, int lenVal) {
+void PropSetSimple::Set(const char *key, const char *val, int lenKey, int lenVal) {
+	mapss *props = static_cast<mapss *>(impl);
 	if (!*key)	// Empty keys are not supported
 		return;
 	if (lenKey == -1)
 		lenKey = static_cast<int>(strlen(key));
 	if (lenVal == -1)
 		lenVal = static_cast<int>(strlen(val));
-	unsigned int hash = HashString(key, lenKey);
-	for (Property *p = props[hash % hashRoots]; p; p = p->next) {
-		if ((hash == p->hash) &&
-			((strlen(p->key) == static_cast<unsigned int>(lenKey)) &&
-				(0 == strncmp(p->key, key, lenKey)))) {
-			// Replace current value
-			delete [](p->val);
-			p->val = StringDup(val, lenVal);
-			return;
-		}
-	}
-	// Not found
-	Property *pNew = new Property;
-	if (pNew) {
-		pNew->hash = hash;
-		pNew->key = StringDup(key, lenKey);
-		pNew->val = StringDup(val, lenVal);
-		pNew->next = props[hash % hashRoots];
-		props[hash % hashRoots] = pNew;
-	}
+	(*props)[std::string(key, lenKey)] = std::string(val, lenVal);
 }
 
-void PropSet::Set(const char *keyVal) {
-	while (IsASpace(*keyVal))
+static bool IsASpaceCharacter(unsigned int ch) {
+    return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
+void PropSetSimple::Set(const char *keyVal) {
+	while (IsASpaceCharacter(*keyVal))
 		keyVal++;
 	const char *endVal = keyVal;
 	while (*endVal && (*endVal != '\n'))
@@ -387,34 +70,7 @@ void PropSet::Set(const char *keyVal) {
 	}
 }
 
-void PropSet::Unset(const char *key, int lenKey) {
-	if (!*key)	// Empty keys are not supported
-		return;
-	if (lenKey == -1)
-		lenKey = static_cast<int>(strlen(key));
-	unsigned int hash = HashString(key, lenKey);
-	Property *pPrev = NULL;
-	for (Property *p = props[hash % hashRoots]; p; p = p->next) {
-		if ((hash == p->hash) &&
-			((strlen(p->key) == static_cast<unsigned int>(lenKey)) &&
-				(0 == strncmp(p->key, key, lenKey)))) {
-			if (pPrev)
-				pPrev->next = p->next;
-			else
-				props[hash % hashRoots] = p->next;
-			if (p == enumnext)
-				enumnext = p->next; // Not that anyone should mix enum and Set / Unset.
-			delete [](p->key);
-			delete [](p->val);
-			delete p;
-			return;
-		} else {
-			pPrev = p;
-		}
-	}
-}
-
-void PropSet::SetMultiple(const char *s) {
+void PropSetSimple::SetMultiple(const char *s) {
 	const char *eol = strchr(s, '\n');
 	while (eol) {
 		Set(s);
@@ -424,16 +80,11 @@ void PropSet::SetMultiple(const char *s) {
 	Set(s);
 }
 
-SString PropSet::Get(const char *key) const {
-	unsigned int hash = HashString(key, strlen(key));
-	for (Property *p = props[hash % hashRoots]; p; p = p->next) {
-		if ((hash == p->hash) && (0 == strcmp(p->key, key))) {
-			return p->val;
-		}
-	}
-	if (superPS) {
-		// Failed here, so try in base property set
-		return superPS->Get(key);
+const char *PropSetSimple::Get(const char *key) const {
+	mapss *props = static_cast<mapss *>(impl);
+	mapss::const_iterator keyPos = props->find(std::string(key));
+	if (keyPos != props->end()) {
+		return keyPos->second.c_str();
 	} else {
 		return "";
 	}
@@ -456,300 +107,70 @@ struct VarChain {
 	const VarChain *link;
 };
 
-static int ExpandAllInPlace(const PropSet &props, SString &withVars, int maxExpands, const VarChain &blankVars = VarChain()) {
-	int varStart = withVars.search("$(");
-	while ((varStart >= 0) && (maxExpands > 0)) {
-		int varEnd = withVars.search(")", varStart+2);
-		if (varEnd < 0) {
+static int ExpandAllInPlace(const PropSetSimple &props, std::string &withVars, int maxExpands, const VarChain &blankVars) {
+	size_t varStart = withVars.find("$(");
+	while ((varStart != std::string::npos) && (maxExpands > 0)) {
+		size_t varEnd = withVars.find(")", varStart+2);
+		if (varEnd == std::string::npos) {
 			break;
 		}
 
 		// For consistency, when we see '$(ab$(cde))', expand the inner variable first,
 		// regardless whether there is actually a degenerate variable named 'ab$(cde'.
-		int innerVarStart = withVars.search("$(", varStart+2);
-		while ((innerVarStart > varStart) && (innerVarStart < varEnd)) {
+		size_t innerVarStart = withVars.find("$(", varStart+2);
+		while ((innerVarStart != std::string::npos) && (innerVarStart > varStart) && (innerVarStart < varEnd)) {
 			varStart = innerVarStart;
-			innerVarStart = withVars.search("$(", varStart+2);
+			innerVarStart = withVars.find("$(", varStart+2);
 		}
 
-		SString var(withVars.c_str(), varStart + 2, varEnd);
-		SString val = props.Get(var.c_str());
+		std::string var(withVars.c_str(), varStart + 2, varEnd - varStart - 2);
+		std::string val = props.Get(var.c_str());
 
 		if (blankVars.contains(var.c_str())) {
-			val.clear(); // treat blankVar as an empty string (e.g. to block self-reference)
+			val = ""; // treat blankVar as an empty string (e.g. to block self-reference)
 		}
 
 		if (--maxExpands >= 0) {
 			maxExpands = ExpandAllInPlace(props, val, maxExpands, VarChain(var.c_str(), &blankVars));
 		}
 
-		withVars.remove(varStart, varEnd-varStart+1);
+		withVars.erase(varStart, varEnd-varStart+1);
 		withVars.insert(varStart, val.c_str(), val.length());
 
-		varStart = withVars.search("$(");
+		varStart = withVars.find("$(");
 	}
 
 	return maxExpands;
 }
 
-SString PropSet::GetExpanded(const char *key) const {
-	SString val = Get(key);
+char *PropSetSimple::Expanded(const char *key) const {
+	std::string val = Get(key);
 	ExpandAllInPlace(*this, val, 100, VarChain(key));
-	return val;
-}
-
-SString PropSet::Expand(const char *withVars, int maxExpands) const {
-	SString val = withVars;
-	ExpandAllInPlace(*this, val, maxExpands);
-	return val;
-}
-
-int PropSet::GetInt(const char *key, int defaultValue) const {
-	SString val = GetExpanded(key);
-	if (val.length())
-		return val.value();
-	return defaultValue;
-}
-
-bool isprefix(const char *target, const char *prefix) {
-	while (*target && *prefix) {
-		if (*target != *prefix)
-			return false;
-		target++;
-		prefix++;
-	}
-	if (*prefix)
-		return false;
-	else
-		return true;
-}
-
-void PropSet::Clear() {
-	for (int root = 0; root < hashRoots; root++) {
-		Property *p = props[root];
-		while (p) {
-			Property *pNext = p->next;
-			p->hash = 0;
-			delete []p->key;
-			p->key = 0;
-			delete []p->val;
-			p->val = 0;
-			delete p;
-			p = pNext;
-		}
-		props[root] = 0;
-	}
-}
-
-char *PropSet::ToString() const {
-	size_t len=0;
-	for (int r = 0; r < hashRoots; r++) {
-		for (Property *p = props[r]; p; p = p->next) {
-			len += strlen(p->key) + 1;
-			len += strlen(p->val) + 1;
-		}
-	}
-	if (len == 0)
-		len = 1;	// Return as empty string
-	char *ret = new char [len];
-	if (ret) {
-		char *w = ret;
-		for (int root = 0; root < hashRoots; root++) {
-			for (Property *p = props[root]; p; p = p->next) {
-				strcpy(w, p->key);
-				w += strlen(p->key);
-				*w++ = '=';
-				strcpy(w, p->val);
-				w += strlen(p->val);
-				*w++ = '\n';
-			}
-		}
-		ret[len-1] = '\0';
-	}
+	char *ret = new char [val.size() + 1];
+	strcpy(ret, val.c_str());
 	return ret;
 }
 
-/**
- * Creates an array that points into each word in the string and puts \0 terminators
- * after each word.
- */
-static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) {
-	int prev = '\n';
-	int words = 0;
-	// For rapid determination of whether a character is a separator, build
-	// a look up table.
-	bool wordSeparator[256];
-	for (int i=0;i<256; i++) {
-		wordSeparator[i] = false;
-	}
-	wordSeparator['\r'] = true;
-	wordSeparator['\n'] = true;
-	if (!onlyLineEnds) {
-		wordSeparator[' '] = true;
-		wordSeparator['\t'] = true;
-	}
-	for (int j = 0; wordlist[j]; j++) {
-		int curr = static_cast<unsigned char>(wordlist[j]);
-		if (!wordSeparator[curr] && wordSeparator[prev])
-			words++;
-		prev = curr;
-	}
-	char **keywords = new char *[words + 1];
-	if (keywords) {
-		words = 0;
-		prev = '\0';
-		size_t slen = strlen(wordlist);
-		for (size_t k = 0; k < slen; k++) {
-			if (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) {
-				if (!prev) {
-					keywords[words] = &wordlist[k];
-					words++;
-				}
-			} else {
-				wordlist[k] = '\0';
-			}
-			prev = wordlist[k];
-		}
-		keywords[words] = &wordlist[slen];
-		*len = words;
-	} else {
-		*len = 0;
-	}
-	return keywords;
-}
-
-void WordList::Clear() {
-	if (words) {
-		delete []list;
-		delete []words;
-	}
-	words = 0;
-	list = 0;
-	len = 0;
-	sorted = false;
-}
-
-void WordList::Set(const char *s) {
-	list = StringDup(s);
-	sorted = false;
-	words = ArrayFromWordList(list, &len, onlyLineEnds);
-}
-
-extern "C" int cmpString(const void *a1, const void *a2) {
-	// Can't work out the correct incantation to use modern casts here
-	return strcmp(*(char**)(a1), *(char**)(a2));
-}
-
-static void SortWordList(char **words, unsigned int len) {
-	qsort(reinterpret_cast<void*>(words), len, sizeof(*words),
-	      cmpString);
-}
-
-bool WordList::InList(const char *s) {
-	if (0 == words)
-		return false;
-	if (!sorted) {
-		sorted = true;
-		SortWordList(words, len);
-		for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
-			starts[k] = -1;
-		for (int l = len - 1; l >= 0; l--) {
-			unsigned char indexChar = words[l][0];
-			starts[indexChar] = l;
-		}
-	}
-	unsigned char firstChar = s[0];
-	int j = starts[firstChar];
-	if (j >= 0) {
-		while ((unsigned char)words[j][0] == firstChar) {
-			if (s[1] == words[j][1]) {
-				const char *a = words[j] + 1;
-				const char *b = s + 1;
-				while (*a && *a == *b) {
-					a++;
-					b++;
-				}
-				if (!*a && !*b)
-					return true;
-			}
-			j++;
-		}
-	}
-	j = starts['^'];
-	if (j >= 0) {
-		while (words[j][0] == '^') {
-			const char *a = words[j] + 1;
-			const char *b = s;
-			while (*a && *a == *b) {
-				a++;
-				b++;
-			}
-			if (!*a)
-				return true;
-			j++;
-		}
+char *PropSetSimple::ToString() const {
+	mapss *props = static_cast<mapss *>(impl);
+	std::string sval;
+	for (mapss::const_iterator it=props->begin(); it != props->end(); it++) {
+		sval += it->first;
+		sval += "=";
+		sval += it->second;
+		sval += "\n";
 	}
-	return false;
+	char *ret = new char [sval.size() + 1];
+	strcpy(ret, sval.c_str());
+	return ret;
 }
 
-/** similar to InList, but word s can be a substring of keyword.
- * eg. the keyword define is defined as def~ine. This means the word must start
- * with def to be a keyword, but also defi, defin and define are valid.
- * The marker is ~ in this case.
- */
-bool WordList::InListAbbreviated(const char *s, const char marker) {
-	if (0 == words)
-		return false;
-	if (!sorted) {
-		sorted = true;
-		SortWordList(words, len);
-		for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
-			starts[k] = -1;
-		for (int l = len - 1; l >= 0; l--) {
-			unsigned char indexChar = words[l][0];
-			starts[indexChar] = l;
-		}
+int PropSetSimple::GetInt(const char *key, int defaultValue) const {
+	char *val = Expanded(key);
+	if (val) {
+		int retVal = atoi(val);
+		delete []val;
+		return retVal;
 	}
-	unsigned char firstChar = s[0];
-	int j = starts[firstChar];
-	if (j >= 0) {
-		while (words[j][0] == firstChar) {
-			bool isSubword = false;
-			int start = 1;
-			if (words[j][1] == marker) {
-				isSubword = true;
-				start++;
-			}
-			if (s[1] == words[j][start]) {
-				const char *a = words[j] + start;
-				const char *b = s + 1;
-				while (*a && *a == *b) {
-					a++;
-					if (*a == marker) {
-						isSubword = true;
-						a++;
-					}
-					b++;
-				}
-				if ((!*a || isSubword) && !*b)
-					return true;
-			}
-			j++;
-		}
-	}
-	j = starts['^'];
-	if (j >= 0) {
-		while (words[j][0] == '^') {
-			const char *a = words[j] + 1;
-			const char *b = s;
-			while (*a && *a == *b) {
-				a++;
-				b++;
-			}
-			if (!*a)
-				return true;
-			j++;
-		}
-	}
-	return false;
+	return defaultValue;
 }
diff --git a/plugins/scintilla/scintilla/PropSetSimple.h b/plugins/scintilla/scintilla/PropSetSimple.h
new file mode 100644
index 0000000..1674cfb
--- /dev/null
+++ b/plugins/scintilla/scintilla/PropSetSimple.h
@@ -0,0 +1,33 @@
+// Scintilla source code edit control
+/** @file PropSetSimple.h
+ ** A basic string to string map.
+ **/
+// Copyright 1998-2009 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef PROPSETSIMPLE_H
+#define PROPSETSIMPLE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class PropSetSimple : public PropertyGet {
+	void *impl;
+	void Set(const char *keyVal);
+public:
+	PropSetSimple();
+	virtual ~PropSetSimple();
+	void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1);
+	void SetMultiple(const char *);
+	const char *Get(const char *key) const;
+	char *Expanded(const char *key) const;
+	char *ToString() const;
+	int GetInt(const char *key, int defaultValue=0) const;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/RESearch.cxx b/plugins/scintilla/scintilla/RESearch.cxx
index 57c745e..200bba5 100644
--- a/plugins/scintilla/scintilla/RESearch.cxx
+++ b/plugins/scintilla/scintilla/RESearch.cxx
@@ -198,6 +198,8 @@
  *  matches:    foo-foo fo-fo fob-fob foobar-foobar ...
  */
 
+#include <stdlib.h>
+
 #include "CharClassify.h"
 #include "RESearch.h"
 
@@ -449,11 +451,12 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
 	char mask;             /* xor mask -CCL/NCL */
 	int c1, c2, prevChar;
 
-	if (!pattern || !length)
+	if (!pattern || !length) {
 		if (sta)
 			return 0;
 		else
 			return badpat("No previous regular expression");
+	}
 	sta = NOP;
 
 	const char *p=pattern;     /* pattern pointer   */
@@ -875,7 +878,7 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
 			eopat[*ap++] = lp;
 			break;
  		case BOW:
-			if (lp!=bol && iswordc(ci.CharAt(lp-1)) || !iswordc(ci.CharAt(lp)))
+			if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp)))
 				return NOTFOUND;
 			break;
 		case EOW:
diff --git a/plugins/scintilla/scintilla/SVector.h b/plugins/scintilla/scintilla/SVector.h
index 9f56da5..7b92919 100644
--- a/plugins/scintilla/scintilla/SVector.h
+++ b/plugins/scintilla/scintilla/SVector.h
@@ -23,7 +23,6 @@ class SVector {
 	int *v;				///< The vector
 	unsigned int size;	///< Number of elements allocated
 	unsigned int len;	///< Number of elements used in vector
-	bool allocFailure;	///< A memory allocation call has failed
 	
 	/** Internally allocate more elements than the user wants
 	 * to avoid thrashing the memory allocator. */
@@ -33,12 +32,8 @@ class SVector {
 		else 
 			newSize = (newSize * 3) / 2;
 		int* newv = new int[newSize];
-		if (!newv) {
-			allocFailure = true;
-			return;
-		}
 		size = newSize;
-        	unsigned int i=0;
+        unsigned int i=0;
 		for (; i<len; i++) {
 			newv[i] = v[i];
 		}
@@ -51,7 +46,6 @@ class SVector {
 	
 public:
 	SVector() {
-		allocFailure = false;
 		v = 0;
 		len = 0;
 		size = 0;
@@ -61,33 +55,27 @@ public:
 	}
 	/// Constructor from another vector.
 	SVector(const SVector &other) {
-		allocFailure = false;
 		v = 0;
 		len = 0;
 		size = 0;
 		if (other.Length() > 0) {
 			SizeTo(other.Length());
-			if (!allocFailure) {
-				for (int i=0;i<other.Length();i++)
-					v[i] = other.v[i];
-				len = other.Length();
-			}
+			for (int i=0;i<other.Length();i++)
+				v[i] = other.v[i];
+			len = other.Length();
 		}
 	}
 	/// Copy constructor.
 	SVector &operator=(const SVector &other) {
 		if (this != &other) {
 			delete []v;
-			allocFailure = false;
 			v = 0;
 			len = 0;
 			size = 0;
 			if (other.Length() > 0) {
 				SizeTo(other.Length());
-				if (!allocFailure) {
-					for (int i=0;i<other.Length();i++)
-						v[i] = other.v[i];
-				}
+				for (int i=0;i<other.Length();i++)
+					v[i] = other.v[i];
 				len = other.Length();
 			}
 		}
diff --git a/plugins/scintilla/scintilla/ScintillaBase.cxx b/plugins/scintilla/scintilla/ScintillaBase.cxx
index d1d9ad4..3aba5fb 100644
--- a/plugins/scintilla/scintilla/ScintillaBase.cxx
+++ b/plugins/scintilla/scintilla/ScintillaBase.cxx
@@ -10,10 +10,13 @@
 #include <stdio.h>
 #include <ctype.h>
 
+#include <vector>
+
 #include "Platform.h"
 
 #include "Scintilla.h"
 #include "PropSet.h"
+#include "PropSetSimple.h"
 #ifdef SCI_LEXER
 #include "SciLexer.h"
 #include "Accessor.h"
@@ -36,6 +39,7 @@
 #include "CharClassify.h"
 #include "Decoration.h"
 #include "Document.h"
+#include "Selection.h"
 #include "PositionCache.h"
 #include "Editor.h"
 #include "ScintillaBase.h"
@@ -190,7 +194,7 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
 			ct.CallTipCancel();
 		}
 		if ((iMessage == SCI_DELETEBACK) || (iMessage == SCI_DELETEBACKNOTLINE)) {
-			if (currentPos <= ct.posStartCallTip) {
+			if (sel.MainCaret() <= ct.posStartCallTip) {
 				ct.CallTipCancel();
 			}
 		}
@@ -212,24 +216,24 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
 			const char *typeSep = strchr(list, ac.GetTypesep());
 			size_t lenInsert = (typeSep) ? (typeSep-list) : strlen(list);
 			if (ac.ignoreCase) {
-				SetEmptySelection(currentPos - lenEntered);
-				pdoc->DeleteChars(currentPos, lenEntered);
-				SetEmptySelection(currentPos);
-				pdoc->InsertString(currentPos, list, lenInsert);
-				SetEmptySelection(currentPos + lenInsert);
+				SetEmptySelection(sel.MainCaret() - lenEntered);
+				pdoc->DeleteChars(sel.MainCaret(), lenEntered);
+				SetEmptySelection(sel.MainCaret());
+				pdoc->InsertString(sel.MainCaret(), list, lenInsert);
+				SetEmptySelection(sel.MainCaret() + lenInsert);
 			} else {
-				SetEmptySelection(currentPos);
-				pdoc->InsertString(currentPos, list + lenEntered, lenInsert - lenEntered);
-				SetEmptySelection(currentPos + lenInsert - lenEntered);
+				SetEmptySelection(sel.MainCaret());
+				pdoc->InsertString(sel.MainCaret(), list + lenEntered, lenInsert - lenEntered);
+				SetEmptySelection(sel.MainCaret() + lenInsert - lenEntered);
 			}
 			return;
 		}
 	}
-	ac.Start(wMain, idAutoComplete, currentPos, LocationFromPosition(currentPos),
+	ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(),
 				lenEntered, vs.lineHeight, IsUnicodeMode());
 
 	PRectangle rcClient = GetClientRectangle();
-	Point pt = LocationFromPosition(currentPos - lenEntered);
+	Point pt = LocationFromPosition(sel.MainCaret() - lenEntered);
 	PRectangle rcPopupBounds = wMain.GetMonitorRect(pt);
 	if (rcPopupBounds.Height() == 0)
 		rcPopupBounds = rcClient;
@@ -239,7 +243,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
 	if (pt.x >= rcClient.right - widthLB) {
 		HorizontalScrollTo(xOffset + pt.x - rcClient.right + widthLB);
 		Redraw();
-		pt = LocationFromPosition(currentPos);
+		pt = PointMainCaret();
 	}
 	PRectangle rcac;
 	rcac.left = pt.x - ac.lb->CaretFromEdge();
@@ -305,7 +309,7 @@ void ScintillaBase::AutoCompleteMoveToCurrentWord() {
 	char wordCurrent[1000];
 	int i;
 	int startWord = ac.posStart - ac.startLen;
-	for (i = startWord; i < currentPos && i - startWord < 1000; i++)
+	for (i = startWord; i < sel.MainCaret() && i - startWord < 1000; i++)
 		wordCurrent[i - startWord] = pdoc->CharAt(i);
 	wordCurrent[Platform::Minimum(i - startWord, 999)] = '\0';
 	ac.Select(wordCurrent);
@@ -322,13 +326,18 @@ void ScintillaBase::AutoCompleteCharacterAdded(char ch) {
 }
 
 void ScintillaBase::AutoCompleteCharacterDeleted() {
-	if (currentPos < ac.posStart - ac.startLen) {
+	if (sel.MainCaret() < ac.posStart - ac.startLen) {
 		AutoCompleteCancel();
-	} else if (ac.cancelAtStartPos && (currentPos <= ac.posStart)) {
+	} else if (ac.cancelAtStartPos && (sel.MainCaret() <= ac.posStart)) {
 		AutoCompleteCancel();
 	} else {
 		AutoCompleteMoveToCurrentWord();
 	}
+	SCNotification scn = {0};
+	scn.nmhdr.code = SCN_AUTOCCHARDELETED;
+	scn.wParam = 0;
+	scn.listType = 0;
+	NotifyParent(scn);
 }
 
 void ScintillaBase::AutoCompleteCompleted() {
@@ -344,7 +353,6 @@ void ScintillaBase::AutoCompleteCompleted() {
 
 	ac.Show(false);
 
-	listSelected = selected;
 	SCNotification scn = {0};
 	scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION;
 	scn.message = 0;
@@ -352,7 +360,7 @@ void ScintillaBase::AutoCompleteCompleted() {
 	scn.listType = listType;
 	Position firstPos = ac.posStart - ac.startLen;
 	scn.lParam = firstPos;
-	scn.text = listSelected.c_str();
+	scn.text = selected;
 	NotifyParent(scn);
 
 	if (!ac.Active())
@@ -362,25 +370,25 @@ void ScintillaBase::AutoCompleteCompleted() {
 	if (listType > 0)
 		return;
 
-	Position endPos = currentPos;
+	Position endPos = sel.MainCaret();
 	if (ac.dropRestOfWord)
 		endPos = pdoc->ExtendWordSelect(endPos, 1, true);
 	if (endPos < firstPos)
 		return;
-	pdoc->BeginUndoAction();
+	UndoGroup ug(pdoc);
 	if (endPos != firstPos) {
 		pdoc->DeleteChars(firstPos, endPos - firstPos);
 	}
 	SetEmptySelection(ac.posStart);
 	if (item != -1) {
-		SString piece = selected;
-		pdoc->InsertCString(firstPos, piece.c_str());
-		SetEmptySelection(firstPos + static_cast<int>(piece.length()));
+		pdoc->InsertCString(firstPos, selected);
+		SetEmptySelection(firstPos + static_cast<int>(strlen(selected)));
 	}
-	pdoc->EndUndoAction();
 }
 
 int ScintillaBase::AutoCompleteGetCurrent() {
+	if (!ac.Active())
+		return -1;
 	return ac.lb->GetSelection();
 }
 
@@ -394,7 +402,7 @@ void ScintillaBase::CallTipShow(Point pt, const char *defn) {
 	if (ct.UseStyleCallTip()) {
 		ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back);
 	}
-	PRectangle rc = ct.CallTipStart(currentPos, pt,
+	PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt,
 		defn,
 		vs.styles[ctStyle].fontName,
 		vs.styles[ctStyle].sizeZoomed,
@@ -429,10 +437,10 @@ void ScintillaBase::ContextMenu(Point pt) {
 		AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo());
 		AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo());
 		AddToPopUp("");
-		AddToPopUp("Cut", idcmdCut, writable && currentPos != anchor);
-		AddToPopUp("Copy", idcmdCopy, currentPos != anchor);
+		AddToPopUp("Cut", idcmdCut, writable && !sel.Empty());
+		AddToPopUp("Copy", idcmdCopy, !sel.Empty());
 		AddToPopUp("Paste", idcmdPaste, writable && WndProc(SCI_CANPASTE, 0, 0));
-		AddToPopUp("Delete", idcmdDelete, writable && currentPos != anchor);
+		AddToPopUp("Delete", idcmdDelete, writable && !sel.Empty());
 		AddToPopUp("");
 		AddToPopUp("Select All", idcmdSelectAll);
 		popup.Show(pt, wMain);
@@ -699,24 +707,23 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
 		break;
 
 	case SCI_GETPROPERTY: {
-			SString val = props.Get(reinterpret_cast<const char *>(wParam));
-			const int n = val.length();
+			const char *val = props.Get(reinterpret_cast<const char *>(wParam));
+			const int n = strlen(val);
 			if (lParam != 0) {
 				char *ptr = reinterpret_cast<char *>(lParam);
-				memcpy(ptr, val.c_str(), n);
-				ptr[n] = '\0';	// terminate
+				strcpy(ptr, val);
 			}
 			return n;	// Not including NUL
 		}
 
 	case SCI_GETPROPERTYEXPANDED: {
-			SString val = props.GetExpanded(reinterpret_cast<const char *>(wParam));
-			const int n = val.length();
+			char *val = props.Expanded(reinterpret_cast<const char *>(wParam));
+			const int n = strlen(val);
 			if (lParam != 0) {
 				char *ptr = reinterpret_cast<char *>(lParam);
-				memcpy(ptr, val.c_str(), n);
-				ptr[n] = '\0';	// terminate
+				strcpy(ptr, val);
 			}
+			delete []val;
 			return n;	// Not including NUL
 		}
 
diff --git a/plugins/scintilla/scintilla/ScintillaBase.h b/plugins/scintilla/scintilla/ScintillaBase.h
index 0554d94..15b514c 100644
--- a/plugins/scintilla/scintilla/ScintillaBase.h
+++ b/plugins/scintilla/scintilla/ScintillaBase.h
@@ -41,7 +41,6 @@ protected:
 	CallTip ct;
 
 	int listType;			///< 0 is an autocomplete list
-	SString listSelected;	///< Receives listbox selected string
 	int maxListWidth;		/// Maximum width of list, in average character widths
 
 	bool performingStyle;	///< Prevent reentrance
@@ -49,7 +48,7 @@ protected:
 #ifdef SCI_LEXER
 	int lexLanguage;
 	const LexerModule *lexCurrent;
-	PropSet props;
+	PropSetSimple props;
 	enum {numWordLists=KEYWORDSET_MAX+1};
 	WordList *keyWordLists[numWordLists+1];
 	void SetLexer(uptr_t wParam);
diff --git a/plugins/scintilla/scintilla/ScintillaGTK.cxx b/plugins/scintilla/scintilla/ScintillaGTK.cxx
index 7a2193f..4aad5eb 100644
--- a/plugins/scintilla/scintilla/ScintillaGTK.cxx
+++ b/plugins/scintilla/scintilla/ScintillaGTK.cxx
@@ -3,12 +3,16 @@
 // Copyright 1998-2004 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
+#include <new>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <time.h>
 
+#include <string>
+#include <vector>
+
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
 
@@ -23,6 +27,7 @@
 #ifdef SCI_LEXER
 #include "SciLexer.h"
 #include "PropSet.h"
+#include "PropSetSimple.h"
 #include "Accessor.h"
 #include "KeyWords.h"
 #endif
@@ -43,9 +48,9 @@
 #include "Decoration.h"
 #include "CharClassify.h"
 #include "Document.h"
+#include "Selection.h"
 #include "PositionCache.h"
 #include "Editor.h"
-#include "SString.h"
 #include "ScintillaBase.h"
 #include "UniConversion.h"
 
@@ -88,6 +93,10 @@
 #define OBJECT_CLASS GObjectClass
 #endif
 
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
 extern char *UTF8FromLatin1(const char *s, int &len);
 
 class ScintillaGTK : public ScintillaBase {
@@ -111,6 +120,7 @@ class ScintillaGTK : public ScintillaBase {
 	bool capturedMouse;
 	bool dragWasDropped;
 	int lastKey;
+	int rectangularSelectionModifier;
 
 	GtkWidgetClass *parentClass;
 
@@ -216,7 +226,9 @@ private:
 	void UnMapThis();
 	static void UnMap(GtkWidget *widget);
 	static gint CursorMoved(GtkWidget *widget, int xoffset, int yoffset, ScintillaGTK *sciThis);
+	gint FocusInThis(GtkWidget *widget);
 	static gint FocusIn(GtkWidget *widget, GdkEventFocus *event);
+	gint FocusOutThis(GtkWidget *widget);
 	static gint FocusOut(GtkWidget *widget, GdkEventFocus *event);
 	static void SizeRequest(GtkWidget *widget, GtkRequisition *requisition);
 	static void SizeAllocate(GtkWidget *widget, GtkAllocation *allocation);
@@ -239,12 +251,12 @@ private:
 	static gboolean KeyPress(GtkWidget *widget, GdkEventKey *event);
 	static gboolean KeyRelease(GtkWidget *widget, GdkEventKey *event);
 #if GTK_MAJOR_VERSION >= 2
-	static gboolean ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis);
 	gboolean ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose);
-	static void Commit(GtkIMContext *context, char *str, ScintillaGTK *sciThis);
+	static gboolean ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis);
 	void CommitThis(char *str);
-	static void PreeditChanged(GtkIMContext *context, ScintillaGTK *sciThis);
+	static void Commit(GtkIMContext *context, char *str, ScintillaGTK *sciThis);
 	void PreeditChangedThis();
+	static void PreeditChanged(GtkIMContext *context, ScintillaGTK *sciThis);
 #endif
 	static gint StyleSetText(GtkWidget *widget, GtkStyle *previous, void*);
 	static gint RealizeText(GtkWidget *widget, void*);
@@ -339,7 +351,7 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
 		adjustmentv(0), adjustmenth(0),
 		scrollBarWidth(30), scrollBarHeight(30),
 		capturedMouse(false), dragWasDropped(false),
-		lastKey(0), parentClass(0),
+		lastKey(0), rectangularSelectionModifier(SCMOD_CTRL), parentClass(0),
 #ifdef INTERNATIONAL_INPUT
 #if GTK_MAJOR_VERSION < 2
 		ic(NULL),
@@ -355,6 +367,12 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
 	wMain = GTK_WIDGET(sci);
 
 #if PLAT_GTK_WIN32
+	rectangularSelectionModifier = SCMOD_ALT;
+#else
+	rectangularSelectionModifier = SCMOD_CTRL;
+#endif
+
+#if PLAT_GTK_WIN32
  	// There does not seem to be a real standard for indicating that the clipboard
 	// contains a rectangular selection, so copy Developer Studio.
 	cfColumnSelect = static_cast<CLIPFORMAT>(
@@ -394,7 +412,7 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) {
 	GdkCursor *cursor = gdk_cursor_new(GDK_XTERM);
 	attrs.cursor = cursor;
 	widget->window = gdk_window_new(gtk_widget_get_parent_window(widget), &attrs,
-	                                GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_CURSOR);
+		GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_CURSOR);
 	gdk_window_set_user_data(widget->window, widget);
 	gdk_window_set_background(widget->window, &widget->style->bg[GTK_STATE_NORMAL]);
 	gdk_window_show(widget->window);
@@ -410,10 +428,10 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) {
 		GdkICAttributesType attrmask = GDK_IC_ALL_REQ;
 		GdkIMStyle style;
 		GdkIMStyle supported_style = (GdkIMStyle) (GDK_IM_PREEDIT_NONE |
-		                             GDK_IM_PREEDIT_NOTHING |
-		                             GDK_IM_PREEDIT_POSITION |
-		                             GDK_IM_STATUS_NONE |
-		                             GDK_IM_STATUS_NOTHING);
+			GDK_IM_PREEDIT_NOTHING |
+			GDK_IM_PREEDIT_POSITION |
+			GDK_IM_STATUS_NONE |
+			GDK_IM_STATUS_NOTHING);
 
 		if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
 			supported_style = (GdkIMStyle) ((int) supported_style & ~GDK_IM_PREEDIT_POSITION);
@@ -463,7 +481,7 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) {
 	wPreeditDraw = gtk_drawing_area_new();
 	GtkWidget *predrw = PWidget(wPreeditDraw);	// No code inside the G_OBJECT macro
 	g_signal_connect(G_OBJECT(predrw), "expose_event",
-			   G_CALLBACK(ExposePreedit), this);
+		G_CALLBACK(ExposePreedit), this);
 	gtk_container_add(GTK_CONTAINER(PWidget(wPreedit)), predrw);
 	gtk_widget_realize(PWidget(wPreedit));
 	gtk_widget_realize(predrw);
@@ -471,23 +489,23 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) {
 
 	im_context = gtk_im_multicontext_new();
 	g_signal_connect(G_OBJECT(im_context), "commit",
-			 G_CALLBACK(Commit), this);
+		G_CALLBACK(Commit), this);
 	g_signal_connect(G_OBJECT(im_context), "preedit_changed",
-			 G_CALLBACK(PreeditChanged), this);
+		G_CALLBACK(PreeditChanged), this);
 	gtk_im_context_set_client_window(im_context, widget->window);
 #endif
 #endif
 	GtkWidget *widtxt = PWidget(wText);	//	// No code inside the G_OBJECT macro
 #if GLIB_MAJOR_VERSION < 2
 	gtk_signal_connect_after(GTK_OBJECT(widtxt), "style_set",
-				 GtkSignalFunc(ScintillaGTK::StyleSetText), NULL);
+		GtkSignalFunc(ScintillaGTK::StyleSetText), NULL);
 	gtk_signal_connect_after(GTK_OBJECT(widtxt), "realize",
-				 GtkSignalFunc(ScintillaGTK::RealizeText), NULL);
+		GtkSignalFunc(ScintillaGTK::RealizeText), NULL);
 #else
 	g_signal_connect_after(G_OBJECT(widtxt), "style_set",
-				 G_CALLBACK(ScintillaGTK::StyleSetText), NULL);
+		G_CALLBACK(ScintillaGTK::StyleSetText), NULL);
 	g_signal_connect_after(G_OBJECT(widtxt), "realize",
-				 G_CALLBACK(ScintillaGTK::RealizeText), NULL);
+		G_CALLBACK(ScintillaGTK::RealizeText), NULL);
 #endif
 	gtk_widget_realize(widtxt);
 	gtk_widget_realize(PWidget(scrollbarv));
@@ -500,34 +518,38 @@ void ScintillaGTK::Realize(GtkWidget *widget) {
 }
 
 void ScintillaGTK::UnRealizeThis(GtkWidget *widget) {
-	if (GTK_WIDGET_MAPPED(widget)) {
-		gtk_widget_unmap(widget);
-	}
-	GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);
-	gtk_widget_unrealize(PWidget(wText));
-	gtk_widget_unrealize(PWidget(scrollbarv));
-	gtk_widget_unrealize(PWidget(scrollbarh));
+	try {
+		if (GTK_WIDGET_MAPPED(widget)) {
+			gtk_widget_unmap(widget);
+		}
+		GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);
+		gtk_widget_unrealize(PWidget(wText));
+		gtk_widget_unrealize(PWidget(scrollbarv));
+		gtk_widget_unrealize(PWidget(scrollbarh));
 #ifdef INTERNATIONAL_INPUT
 #if GTK_MAJOR_VERSION < 2
-	if (ic) {
-		gdk_ic_destroy(ic);
-		ic = NULL;
-	}
-	if (ic_attr) {
-		gdk_ic_attr_destroy(ic_attr);
-		ic_attr = NULL;
-	}
+		if (ic) {
+			gdk_ic_destroy(ic);
+			ic = NULL;
+		}
+		if (ic_attr) {
+			gdk_ic_attr_destroy(ic_attr);
+			ic_attr = NULL;
+		}
 #else
-	gtk_widget_unrealize(PWidget(wPreedit));
-	gtk_widget_unrealize(PWidget(wPreeditDraw));
-	g_object_unref(im_context);
-	im_context = NULL;
+		gtk_widget_unrealize(PWidget(wPreedit));
+		gtk_widget_unrealize(PWidget(wPreeditDraw));
+		g_object_unref(im_context);
+		im_context = NULL;
 #endif
 #endif
-	if (GTK_WIDGET_CLASS(parentClass)->unrealize)
-		GTK_WIDGET_CLASS(parentClass)->unrealize(widget);
+		if (GTK_WIDGET_CLASS(parentClass)->unrealize)
+			GTK_WIDGET_CLASS(parentClass)->unrealize(widget);
 
-	Finalise();
+		Finalise();
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
+	}
 }
 
 void ScintillaGTK::UnRealize(GtkWidget *widget) {
@@ -544,16 +566,20 @@ static void MapWidget(GtkWidget *widget) {
 }
 
 void ScintillaGTK::MapThis() {
-	//Platform::DebugPrintf("ScintillaGTK::map this\n");
-	GTK_WIDGET_SET_FLAGS(PWidget(wMain), GTK_MAPPED);
-	MapWidget(PWidget(wText));
-	MapWidget(PWidget(scrollbarh));
-	MapWidget(PWidget(scrollbarv));
-	wMain.SetCursor(Window::cursorArrow);
-	scrollbarv.SetCursor(Window::cursorArrow);
-	scrollbarh.SetCursor(Window::cursorArrow);
-	ChangeSize();
-	gdk_window_show(PWidget(wMain)->window);
+	try {
+		//Platform::DebugPrintf("ScintillaGTK::map this\n");
+		GTK_WIDGET_SET_FLAGS(PWidget(wMain), GTK_MAPPED);
+		MapWidget(PWidget(wText));
+		MapWidget(PWidget(scrollbarh));
+		MapWidget(PWidget(scrollbarv));
+		wMain.SetCursor(Window::cursorArrow);
+		scrollbarv.SetCursor(Window::cursorArrow);
+		scrollbarh.SetCursor(Window::cursorArrow);
+		ChangeSize();
+		gdk_window_show(PWidget(wMain)->window);
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
+	}
 }
 
 void ScintillaGTK::Map(GtkWidget *widget) {
@@ -562,13 +588,17 @@ void ScintillaGTK::Map(GtkWidget *widget) {
 }
 
 void ScintillaGTK::UnMapThis() {
-	//Platform::DebugPrintf("ScintillaGTK::unmap this\n");
-	GTK_WIDGET_UNSET_FLAGS(PWidget(wMain), GTK_MAPPED);
-	DropGraphics();
-	gdk_window_hide(PWidget(wMain)->window);
-	gtk_widget_unmap(PWidget(wText));
-	gtk_widget_unmap(PWidget(scrollbarh));
-	gtk_widget_unmap(PWidget(scrollbarv));
+	try {
+		//Platform::DebugPrintf("ScintillaGTK::unmap this\n");
+		GTK_WIDGET_UNSET_FLAGS(PWidget(wMain), GTK_MAPPED);
+		DropGraphics();
+		gdk_window_hide(PWidget(wMain)->window);
+		gtk_widget_unmap(PWidget(wText));
+		gtk_widget_unmap(PWidget(scrollbarh));
+		gtk_widget_unmap(PWidget(scrollbarv));
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
+	}
 }
 
 void ScintillaGTK::UnMap(GtkWidget *widget) {
@@ -577,9 +607,13 @@ void ScintillaGTK::UnMap(GtkWidget *widget) {
 }
 
 void ScintillaGTK::ForAll(GtkCallback callback, gpointer callback_data) {
-	(*callback) (PWidget(wText), callback_data);
-	(*callback) (PWidget(scrollbarv), callback_data);
-	(*callback) (PWidget(scrollbarh), callback_data);
+	try {
+		(*callback) (PWidget(wText), callback_data);
+		(*callback) (PWidget(scrollbarv), callback_data);
+		(*callback) (PWidget(scrollbarh), callback_data);
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
+	}
 }
 
 void ScintillaGTK::MainForAll(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) {
@@ -618,92 +652,109 @@ gint ScintillaGTK::CursorMoved(GtkWidget *, int, int, ScintillaGTK *) {
 }
 #endif
 
-gint ScintillaGTK::FocusIn(GtkWidget *widget, GdkEventFocus * /*event*/) {
-	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	//Platform::DebugPrintf("ScintillaGTK::focus in %x\n", sciThis);
-	GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
-	sciThis->SetFocusState(true);
-
+gint ScintillaGTK::FocusInThis(GtkWidget *widget) {
+	try {
+		GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
+		SetFocusState(true);
 #ifdef INTERNATIONAL_INPUT
 #if GTK_MAJOR_VERSION < 2
-	if (sciThis->ic)
-		gdk_im_begin(sciThis->ic, widget->window);
+		if (ic)
+			gdk_im_begin(ic, widget->window);
 #else
-	if (sciThis->im_context != NULL) {
-		gchar *str = NULL;
-		gint cursor_pos;
-
-		gtk_im_context_get_preedit_string(sciThis->im_context, &str, NULL, &cursor_pos);
-		if (PWidget(sciThis->wPreedit) != NULL) {
-			if (strlen(str) > 0) {
-				gtk_widget_show(PWidget(sciThis->wPreedit));
-			} else {
-				gtk_widget_hide(PWidget(sciThis->wPreedit));
+		if (im_context != NULL) {
+			gchar *str = NULL;
+			gint cursor_pos;
+
+			gtk_im_context_get_preedit_string(im_context, &str, NULL, &cursor_pos);
+			if (PWidget(wPreedit) != NULL) {
+				if (strlen(str) > 0) {
+					gtk_widget_show(PWidget(wPreedit));
+				} else {
+					gtk_widget_hide(PWidget(wPreedit));
+				}
 			}
+			g_free(str);
+			gtk_im_context_focus_in(im_context);
 		}
-		g_free(str);
-		gtk_im_context_focus_in(sciThis->im_context);
-	}
 #endif
 #endif
 
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
+	}
 	return FALSE;
 }
 
-gint ScintillaGTK::FocusOut(GtkWidget *widget, GdkEventFocus * /*event*/) {
+gint ScintillaGTK::FocusIn(GtkWidget *widget, GdkEventFocus * /*event*/) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	//Platform::DebugPrintf("ScintillaGTK::focus out %x\n", sciThis);
-	GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
-	sciThis->SetFocusState(false);
+	return sciThis->FocusInThis(widget);
+}
+
+gint ScintillaGTK::FocusOutThis(GtkWidget *widget) {
+	try {
+		GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
+		SetFocusState(false);
 
 #ifdef INTERNATIONAL_INPUT
 #if GTK_MAJOR_VERSION < 2
-	gdk_im_end();
+		gdk_im_end();
 #else
-	if (PWidget(sciThis->wPreedit) != NULL)
-		gtk_widget_hide(PWidget(sciThis->wPreedit));
-	if (sciThis->im_context != NULL)
-		gtk_im_context_focus_out(sciThis->im_context);
+		if (PWidget(wPreedit) != NULL)
+			gtk_widget_hide(PWidget(wPreedit));
+		if (im_context != NULL)
+			gtk_im_context_focus_out(im_context);
 #endif
 #endif
 
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
+	}
 	return FALSE;
 }
 
+gint ScintillaGTK::FocusOut(GtkWidget *widget, GdkEventFocus * /*event*/) {
+	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
+	return sciThis->FocusOutThis(widget);
+}
+
 void ScintillaGTK::SizeRequest(GtkWidget *widget, GtkRequisition *requisition) {
+	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
 	requisition->width = 600;
 	requisition->height = gdk_screen_height();
-	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
 	GtkRequisition child_requisition;
 	gtk_widget_size_request(PWidget(sciThis->scrollbarh), &child_requisition);
 	gtk_widget_size_request(PWidget(sciThis->scrollbarv), &child_requisition);
 }
 
 void ScintillaGTK::SizeAllocate(GtkWidget *widget, GtkAllocation *allocation) {
-	widget->allocation = *allocation;
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	if (GTK_WIDGET_REALIZED(widget))
-		gdk_window_move_resize(widget->window,
-		                       widget->allocation.x,
-		                       widget->allocation.y,
-		                       widget->allocation.width,
-		                       widget->allocation.height);
+	try {
+		widget->allocation = *allocation;
+		if (GTK_WIDGET_REALIZED(widget))
+			gdk_window_move_resize(widget->window,
+			        widget->allocation.x,
+			        widget->allocation.y,
+			        widget->allocation.width,
+			        widget->allocation.height);
 
-	sciThis->Resize(allocation->width, allocation->height);
+		sciThis->Resize(allocation->width, allocation->height);
 
 #ifdef INTERNATIONAL_INPUT
 #if GTK_MAJOR_VERSION < 2
-	if (sciThis->ic && (gdk_ic_get_style(sciThis->ic) & GDK_IM_PREEDIT_POSITION)) {
-		gint width, height;
+		if (sciThis->ic && (gdk_ic_get_style(sciThis->ic) & GDK_IM_PREEDIT_POSITION)) {
+			gint width, height;
 
-		gdk_window_get_size(widget->window, &width, &height);
-		sciThis->ic_attr->preedit_area.width = width;
-		sciThis->ic_attr->preedit_area.height = height;
+			gdk_window_get_size(widget->window, &width, &height);
+			sciThis->ic_attr->preedit_area.width = width;
+			sciThis->ic_attr->preedit_area.height = height;
 
-		gdk_ic_set_attr(sciThis->ic, sciThis->ic_attr, GDK_IC_PREEDIT_AREA);
-	}
+			gdk_ic_set_attr(sciThis->ic, sciThis->ic_attr, GDK_IC_PREEDIT_AREA);
+		}
 #endif
 #endif
+	} catch (...) {
+		sciThis->errorStatus = SC_STATUS_FAILURE;
+	}
 }
 
 void ScintillaGTK::Initialise() {
@@ -954,32 +1005,45 @@ bool ScintillaGTK::ValidCodePage(int codePage) const {
 }
 
 sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
-	switch (iMessage) {
+	try {
+		switch (iMessage) {
 
-	case SCI_GRABFOCUS:
-		gtk_widget_grab_focus(PWidget(wMain));
-		break;
+		case SCI_GRABFOCUS:
+			gtk_widget_grab_focus(PWidget(wMain));
+			break;
 
-	case SCI_GETDIRECTFUNCTION:
-		return reinterpret_cast<sptr_t>(DirectFunction);
+		case SCI_GETDIRECTFUNCTION:
+			return reinterpret_cast<sptr_t>(DirectFunction);
 
-	case SCI_GETDIRECTPOINTER:
-		return reinterpret_cast<sptr_t>(this);
+		case SCI_GETDIRECTPOINTER:
+			return reinterpret_cast<sptr_t>(this);
 
 #ifdef SCI_LEXER
-	case SCI_LOADLEXERLIBRARY:
-		LexerManager::GetInstance()->Load(reinterpret_cast<const char*>(wParam));
-		break;
+		case SCI_LOADLEXERLIBRARY:
+			LexerManager::GetInstance()->Load(reinterpret_cast<const char*>(wParam));
+			break;
 #endif
-	case SCI_TARGETASUTF8:
-		return TargetAsUTF8(reinterpret_cast<char*>(lParam));
+		case SCI_TARGETASUTF8:
+			return TargetAsUTF8(reinterpret_cast<char*>(lParam));
 
-	case SCI_ENCODEDFROMUTF8:
-		return EncodedFromUTF8(reinterpret_cast<char*>(wParam),
-			reinterpret_cast<char*>(lParam));
+		case SCI_ENCODEDFROMUTF8:
+			return EncodedFromUTF8(reinterpret_cast<char*>(wParam),
+			        reinterpret_cast<char*>(lParam));
 
-	default:
-		return ScintillaBase::WndProc(iMessage, wParam, lParam);
+		case SCI_SETRECTANGULARSELECTIONMODIFIER:
+			rectangularSelectionModifier = wParam;
+			break;
+		
+		case SCI_GETRECTANGULARSELECTIONMODIFIER:
+			return rectangularSelectionModifier;
+		
+		default:
+			return ScintillaBase::WndProc(iMessage, wParam, lParam);
+		}
+	} catch (std::bad_alloc&) {
+		errorStatus = SC_STATUS_BADALLOC;
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
 	}
 	return 0l;
 }
@@ -992,11 +1056,7 @@ void ScintillaGTK::SetTicking(bool on) {
 	if (timer.ticking != on) {
 		timer.ticking = on;
 		if (timer.ticking) {
-#if GLIB_MAJOR_VERSION < 2
-			timer.tickerID = reinterpret_cast<TickerID>(gtk_timeout_add(timer.tickSize, (GtkFunction)TimeOut, this));
-#else
 			timer.tickerID = reinterpret_cast<TickerID>(g_timeout_add(timer.tickSize, (GSourceFunc)TimeOut, this));
-#endif
 		} else {
 			gtk_timeout_remove(GPOINTER_TO_UINT(timer.tickerID));
 		}
@@ -1303,7 +1363,7 @@ void ScintillaGTK::CopyToClipboard(const SelectionText &selectedText) {
 }
 
 void ScintillaGTK::Copy() {
-	if (currentPos != anchor) {
+	if (!sel.Empty()) {
 #ifndef USE_GTK_CLIPBOARD
 		CopySelectionRange(&copyText);
 		gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)),
@@ -1315,7 +1375,7 @@ void ScintillaGTK::Copy() {
 		StoreOnClipboard(clipText);
 #endif
 #if PLAT_GTK_WIN32
-		if (selType == selRectangle) {
+		if (sel.IsRectangular()) {
 			::OpenClipboard(NULL);
 			::SetClipboardData(cfColumnSelect, 0);
 			::CloseClipboard();
@@ -1391,7 +1451,7 @@ bool ScintillaGTK::OwnPrimarySelection() {
 void ScintillaGTK::ClaimSelection() {
 	// X Windows has a 'primary selection' as well as the clipboard.
 	// Whenever the user selects some text, we become the primary selection
-	if (currentPos != anchor && GTK_WIDGET_REALIZED(GTK_WIDGET(PWidget(wMain)))) {
+	if (!sel.Empty() && GTK_WIDGET_REALIZED(GTK_WIDGET(PWidget(wMain)))) {
 		primarySelection = true;
 		gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)),
 		                        GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
@@ -1459,36 +1519,41 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio
 }
 
 void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) {
-	if ((selection_data->selection == atomClipboard) ||
-		(selection_data->selection == GDK_SELECTION_PRIMARY)) {
-		if ((atomSought == atomUTF8) && (selection_data->length <= 0)) {
-			atomSought = atomString;
-			gtk_selection_convert(GTK_WIDGET(PWidget(wMain)),
-					      selection_data->selection, atomSought, GDK_CURRENT_TIME);
-		} else if ((selection_data->length > 0) &&
-			((selection_data->type == GDK_TARGET_STRING) || (selection_data->type == atomUTF8))) {
-			SelectionText selText;
-			GetGtkSelectionText(selection_data, selText);
-
-			pdoc->BeginUndoAction();
-			if (selection_data->selection != GDK_SELECTION_PRIMARY) {
-				ClearSelection();
-			}
-			int selStart = SelectionStart();
+	try {
+		if ((selection_data->selection == atomClipboard) ||
+		        (selection_data->selection == GDK_SELECTION_PRIMARY)) {
+			if ((atomSought == atomUTF8) && (selection_data->length <= 0)) {
+				atomSought = atomString;
+				gtk_selection_convert(GTK_WIDGET(PWidget(wMain)),
+				        selection_data->selection, atomSought, GDK_CURRENT_TIME);
+			} else if ((selection_data->length > 0) &&
+			        ((selection_data->type == GDK_TARGET_STRING) || (selection_data->type == atomUTF8))) {
+				SelectionText selText;
+				GetGtkSelectionText(selection_data, selText);
+
+				UndoGroup ug(pdoc);
+				if (selection_data->selection != GDK_SELECTION_PRIMARY) {
+					ClearSelection();
+				}
+				SelectionPosition selStart = SelectionStart();
 
-			if (selText.rectangular) {
-				PasteRectangular(selStart, selText.s, selText.len);
-			} else {
-				pdoc->InsertString(currentPos, selText.s, selText.len);
-				SetEmptySelection(currentPos + selText.len);
+				if (selText.rectangular) {
+					PasteRectangular(selStart, selText.s, selText.len);
+				} else {
+					selStart = SelectionPosition(InsertSpace(selStart.Position(), selStart.VirtualSpace()));
+					if (pdoc->InsertString(selStart.Position(),selText.s, selText.len)) {
+						SetEmptySelection(selStart.Position() + selText.len);
+					}
+				}
+				EnsureCaretVisible();
 			}
-			pdoc->EndUndoAction();
-			EnsureCaretVisible();
 		}
-	}
 //	else fprintf(stderr, "Target non string %d %d\n", (int)(selection_data->type),
 //		(int)(atomUTF8));
-	Redraw();
+		Redraw();
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
+	}
 }
 
 void ScintillaGTK::ReceivedDrop(GtkSelectionData *selection_data) {
@@ -1506,7 +1571,7 @@ void ScintillaGTK::ReceivedDrop(GtkSelectionData *selection_data) {
 			DropAt(posDrop, selText.s, false, selText.rectangular);
 		}
 	} else if (selection_data->length > 0) {
-	    //~ fprintf(stderr, "ReceivedDrop other %p\n", static_cast<void *>(selection_data->type));
+		//~ fprintf(stderr, "ReceivedDrop other %p\n", static_cast<void *>(selection_data->type));
 	}
 	Redraw();
 }
@@ -1549,18 +1614,19 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se
 	// All other tested aplications behave benignly by ignoring the \0.
 	// The #if is here because on Windows cfColumnSelect clip entry is used
 	// instead as standard indicator of rectangularness (so no need to kludge)
-	int len = strlen(text->s);
+	const char *textData = text->s ? text->s : "";
+	int len = strlen(textData);
 #if PLAT_GTK_WIN32 == 0
 	if (text->rectangular)
 		len++;
 #endif
 
 	if (info == TARGET_UTF8_STRING) {
-		gtk_selection_data_set_text(selection_data, text->s, len);
+		gtk_selection_data_set_text(selection_data, textData, len);
 	} else {
 		gtk_selection_data_set(selection_data,
 			static_cast<GdkAtom>(GDK_SELECTION_TYPE_STRING),
-			8, reinterpret_cast<unsigned char *>(text->s), len);
+			8, reinterpret_cast<const unsigned char *>(textData), len);
 	}
 	delete converted;
 
@@ -1577,13 +1643,13 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se
 			//fprintf(stderr, "Copy to clipboard as UTF-8\n");
 			if (text->codePage != SC_CP_UTF8) {
 				// Convert to UTF-8
-	//fprintf(stderr, "Convert to UTF-8 from %s\n", charSetBuffer);
+				//fprintf(stderr, "Convert to UTF-8 from %s\n", charSetBuffer);
 				tmputf = ConvertText(&len, selBuffer, len, "UTF-8", charSetBuffer, false);
 				selBuffer = tmputf;
 			}
 		} else if (info == TARGET_STRING) {
 			if (text->codePage == SC_CP_UTF8) {
-	//fprintf(stderr, "Convert to locale %s\n", charSetBuffer);
+				//fprintf(stderr, "Convert to locale %s\n", charSetBuffer);
 				// Convert to locale
 				tmputf = ConvertText(&len, selBuffer, len, charSetBuffer, "UTF-8", true);
 				selBuffer = tmputf;
@@ -1597,7 +1663,7 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se
 		// the terminating \0 is included in the length for rectangular clippings.
 		// All other tested aplications behave benignly by ignoring the \0.
 		// The #if is here because on Windows cfColumnSelect clip entry is used
-                // instead as standard indicator of rectangularness (so no need to kludge)
+		// instead as standard indicator of rectangularness (so no need to kludge)
 #if PLAT_GTK_WIN32 == 0
 		if (text->rectangular)
 			len++;
@@ -1651,14 +1717,18 @@ void ScintillaGTK::ClipboardClearSelection(GtkClipboard *, void *data) {
 #endif
 
 void ScintillaGTK::UnclaimSelection(GdkEventSelection *selection_event) {
-	//Platform::DebugPrintf("UnclaimSelection\n");
-	if (selection_event->selection == GDK_SELECTION_PRIMARY) {
-		//Platform::DebugPrintf("UnclaimPrimarySelection\n");
-		if (!OwnPrimarySelection()) {
-			primary.Free();
-			primarySelection = false;
-			FullPaint();
+	try {
+		//Platform::DebugPrintf("UnclaimSelection\n");
+		if (selection_event->selection == GDK_SELECTION_PRIMARY) {
+			//Platform::DebugPrintf("UnclaimPrimarySelection\n");
+			if (!OwnPrimarySelection()) {
+				primary.Free();
+				primarySelection = false;
+				FullPaint();
+			}
 		}
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
 	}
 }
 
@@ -1730,74 +1800,87 @@ static void SetAdjustmentValue(GtkObject *object, int value) {
 	gtk_adjustment_set_value(adjustment, value);
 }
 
-gint ScintillaGTK::PressThis(GdkEventButton *event) {
-	//Platform::DebugPrintf("Press %x time=%d state = %x button = %x\n",this,event->time, event->state, event->button);
-	// Do not use GTK+ double click events as Scintilla has its own double click detection
-	if (event->type != GDK_BUTTON_PRESS)
-		return FALSE;
-
-	evbtn = *event;
-	Point pt;
-	pt.x = int(event->x);
-	pt.y = int(event->y);
-	PRectangle rcClient = GetClientRectangle();
-	//Platform::DebugPrintf("Press %0d,%0d in %0d,%0d %0d,%0d\n",
-	//	pt.x, pt.y, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
-	if ((pt.x > rcClient.right) || (pt.y > rcClient.bottom)) {
-		Platform::DebugPrintf("Bad location\n");
-		return FALSE;
+static int modifierTranslated(int sciModifier) {
+	switch (sciModifier) {
+		case SCMOD_SHIFT:
+			return GDK_SHIFT_MASK;
+		case SCMOD_CTRL:
+			return GDK_CONTROL_MASK;
+		case SCMOD_ALT:
+			return GDK_MOD1_MASK;
+		case SCMOD_SUPER:
+			return GDK_MOD4_MASK;
+		default: 
+			return 0;
 	}
+}
 
-	bool ctrl = (event->state & GDK_CONTROL_MASK) != 0;
+gint ScintillaGTK::PressThis(GdkEventButton *event) {
+	try {
+		//Platform::DebugPrintf("Press %x time=%d state = %x button = %x\n",this,event->time, event->state, event->button);
+		// Do not use GTK+ double click events as Scintilla has its own double click detection
+		if (event->type != GDK_BUTTON_PRESS)
+			return FALSE;
 
-	gtk_widget_grab_focus(PWidget(wMain));
-	if (event->button == 1) {
-		// On X, instead of sending literal modifiers use control instead of alt
-		// This is because most X window managers grab alt + click for moving
-#if !PLAT_GTK_WIN32
-		ButtonDown(pt, event->time,
-				    (event->state & GDK_SHIFT_MASK) != 0,
-				    (event->state & GDK_CONTROL_MASK) != 0,
-				    (event->state & GDK_CONTROL_MASK) != 0);
-#else
-		ButtonDown(pt, event->time,
-				    (event->state & GDK_SHIFT_MASK) != 0,
-				    (event->state & GDK_CONTROL_MASK) != 0,
-				    (event->state & GDK_MOD1_MASK) != 0);
-#endif
-	} else if (event->button == 2) {
-		// Grab the primary selection if it exists
-		Position pos = PositionFromLocation(pt);
-		if (OwnPrimarySelection() && primary.s == NULL)
-			CopySelectionRange(&primary);
-
-		SetSelection(pos, pos);
-		atomSought = atomUTF8;
-		gtk_selection_convert(GTK_WIDGET(PWidget(wMain)), GDK_SELECTION_PRIMARY,
-		                      atomSought, event->time);
-	} else if (event->button == 3) {
-		if (displayPopupMenu) {
-			// PopUp menu
-			// Convert to screen
-			int ox = 0;
-			int oy = 0;
-			gdk_window_get_origin(PWidget(wMain)->window, &ox, &oy);
-			ContextMenu(Point(pt.x + ox, pt.y + oy));
-		} else {
+		evbtn = *event;
+		Point pt;
+		pt.x = int(event->x);
+		pt.y = int(event->y);
+		PRectangle rcClient = GetClientRectangle();
+		//Platform::DebugPrintf("Press %0d,%0d in %0d,%0d %0d,%0d\n",
+		//	pt.x, pt.y, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
+		if ((pt.x > rcClient.right) || (pt.y > rcClient.bottom)) {
+			Platform::DebugPrintf("Bad location\n");
 			return FALSE;
 		}
-	} else if (event->button == 4) {
-		// Wheel scrolling up (only GTK 1.x does it this way)
-		if (ctrl)
-			SetAdjustmentValue(adjustmenth, (xOffset / 2) - 6);
-		else
-			SetAdjustmentValue(adjustmentv, topLine - 3);
-	} else if (event->button == 5) {
-		// Wheel scrolling down (only GTK 1.x does it this way)
-		if (ctrl)
-			SetAdjustmentValue(adjustmenth, (xOffset / 2) + 6);
-		else
-			SetAdjustmentValue(adjustmentv, topLine + 3);
+
+		bool ctrl = (event->state & GDK_CONTROL_MASK) != 0;
+
+		gtk_widget_grab_focus(PWidget(wMain));
+		if (event->button == 1) {
+			// On X, instead of sending literal modifiers use the user specified
+			// modifier, defaulting to control instead of alt.
+			// This is because most X window managers grab alt + click for moving
+			ButtonDown(pt, event->time,
+			        (event->state & GDK_SHIFT_MASK) != 0,
+			        (event->state & GDK_CONTROL_MASK) != 0,
+			        (event->state & modifierTranslated(rectangularSelectionModifier)) != 0);
+		} else if (event->button == 2) {
+			// Grab the primary selection if it exists
+			SelectionPosition pos = SPositionFromLocation(pt);
+			if (OwnPrimarySelection() && primary.s == NULL)
+				CopySelectionRange(&primary);
+
+			SetSelection(pos, pos);
+			atomSought = atomUTF8;
+			gtk_selection_convert(GTK_WIDGET(PWidget(wMain)), GDK_SELECTION_PRIMARY,
+			        atomSought, event->time);
+		} else if (event->button == 3) {
+			if (displayPopupMenu) {
+				// PopUp menu
+				// Convert to screen
+				int ox = 0;
+				int oy = 0;
+				gdk_window_get_origin(PWidget(wMain)->window, &ox, &oy);
+				ContextMenu(Point(pt.x + ox, pt.y + oy));
+			} else {
+				return FALSE;
+			}
+		} else if (event->button == 4) {
+			// Wheel scrolling up (only GTK 1.x does it this way)
+			if (ctrl)
+				SetAdjustmentValue(adjustmenth, (xOffset / 2) - 6);
+			else
+				SetAdjustmentValue(adjustmentv, topLine - 3);
+		} else if (event->button == 5) {
+			// Wheel scrolling down (only GTK 1.x does it this way)
+			if (ctrl)
+				SetAdjustmentValue(adjustmenth, (xOffset / 2) + 6);
+			else
+				SetAdjustmentValue(adjustmentv, topLine + 3);
+		}
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
 	}
 #if GTK_MAJOR_VERSION >= 2
 	return TRUE;
@@ -1815,20 +1898,24 @@ gint ScintillaGTK::Press(GtkWidget *widget, GdkEventButton *event) {
 
 gint ScintillaGTK::MouseRelease(GtkWidget *widget, GdkEventButton *event) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	//Platform::DebugPrintf("Release %x %d %d\n",sciThis,event->time,event->state);
-	if (!sciThis->HaveMouseCapture())
-		return FALSE;
-	if (event->button == 1) {
-		Point pt;
-		pt.x = int(event->x);
-		pt.y = int(event->y);
-		//Platform::DebugPrintf("Up %x %x %d %d %d\n",
-		//	sciThis,event->window,event->time, pt.x, pt.y);
-		if (event->window != PWidget(sciThis->wMain)->window)
-			// If mouse released on scroll bar then the position is relative to the
-			// scrollbar, not the drawing window so just repeat the most recent point.
-			pt = sciThis->ptMouseLast;
-		sciThis->ButtonUp(pt, event->time, (event->state & 4) != 0);
+	try {
+		//Platform::DebugPrintf("Release %x %d %d\n",sciThis,event->time,event->state);
+		if (!sciThis->HaveMouseCapture())
+			return FALSE;
+		if (event->button == 1) {
+			Point pt;
+			pt.x = int(event->x);
+			pt.y = int(event->y);
+			//Platform::DebugPrintf("Up %x %x %d %d %d\n",
+			//	sciThis,event->window,event->time, pt.x, pt.y);
+			if (event->window != PWidget(sciThis->wMain)->window)
+				// If mouse released on scroll bar then the position is relative to the
+				// scrollbar, not the drawing window so just repeat the most recent point.
+				pt = sciThis->ptMouseLast;
+			sciThis->ButtonUp(pt, event->time, (event->state & 4) != 0);
+		}
+	} catch (...) {
+		sciThis->errorStatus = SC_STATUS_FAILURE;
 	}
 	return FALSE;
 }
@@ -1839,95 +1926,104 @@ gint ScintillaGTK::MouseRelease(GtkWidget *widget, GdkEventButton *event) {
 gint ScintillaGTK::ScrollEvent(GtkWidget *widget,
                                GdkEventScroll *event) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
+	try {
 
-	if (widget == NULL || event == NULL)
-		return FALSE;
+		if (widget == NULL || event == NULL)
+			return FALSE;
 
-	// Compute amount and direction to scroll (even tho on win32 there is
-	// intensity of scrolling info in the native message, gtk doesn't
-	// support this so we simulate similarly adaptive scrolling)
-	// Note that this is disabled on OS X (Darwin) where the X11 server already has
-	// and adaptive scrolling algorithm that fights with this one
-	int cLineScroll;
+		// Compute amount and direction to scroll (even tho on win32 there is
+		// intensity of scrolling info in the native message, gtk doesn't
+		// support this so we simulate similarly adaptive scrolling)
+		// Note that this is disabled on OS X (Darwin) where the X11 server already has
+		// and adaptive scrolling algorithm that fights with this one
+		int cLineScroll;
 #if defined(__MWERKS__) || defined(__APPLE_CPP__) || defined(__APPLE_CC__)
-	cLineScroll = sciThis->linesPerScroll;
-	if (cLineScroll == 0)
-		cLineScroll = 4;
-	sciThis->wheelMouseIntensity = cLineScroll;
-#else
-	int timeDelta = 1000000;
-	GTimeVal curTime;
-	g_get_current_time(&curTime);
-	if (curTime.tv_sec == sciThis->lastWheelMouseTime.tv_sec)
-		timeDelta = curTime.tv_usec - sciThis->lastWheelMouseTime.tv_usec;
-	else if (curTime.tv_sec == sciThis->lastWheelMouseTime.tv_sec + 1)
-		timeDelta = 1000000 + (curTime.tv_usec - sciThis->lastWheelMouseTime.tv_usec);
-	if ((event->direction == sciThis->lastWheelMouseDirection) && (timeDelta < 250000)) {
-		if (sciThis->wheelMouseIntensity < 12)
-			sciThis->wheelMouseIntensity++;
-		cLineScroll = sciThis->wheelMouseIntensity;
-	} else {
 		cLineScroll = sciThis->linesPerScroll;
 		if (cLineScroll == 0)
 			cLineScroll = 4;
 		sciThis->wheelMouseIntensity = cLineScroll;
-	}
+#else
+		int timeDelta = 1000000;
+		GTimeVal curTime;
+		g_get_current_time(&curTime);
+		if (curTime.tv_sec == sciThis->lastWheelMouseTime.tv_sec)
+			timeDelta = curTime.tv_usec - sciThis->lastWheelMouseTime.tv_usec;
+		else if (curTime.tv_sec == sciThis->lastWheelMouseTime.tv_sec + 1)
+			timeDelta = 1000000 + (curTime.tv_usec - sciThis->lastWheelMouseTime.tv_usec);
+		if ((event->direction == sciThis->lastWheelMouseDirection) && (timeDelta < 250000)) {
+			if (sciThis->wheelMouseIntensity < 12)
+				sciThis->wheelMouseIntensity++;
+			cLineScroll = sciThis->wheelMouseIntensity;
+		} else {
+			cLineScroll = sciThis->linesPerScroll;
+			if (cLineScroll == 0)
+				cLineScroll = 4;
+			sciThis->wheelMouseIntensity = cLineScroll;
+		}
 #endif
-	if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_LEFT) {
-		cLineScroll *= -1;
-	}
-	g_get_current_time(&sciThis->lastWheelMouseTime);
-	sciThis->lastWheelMouseDirection = event->direction;
+		if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_LEFT) {
+			cLineScroll *= -1;
+		}
+		g_get_current_time(&sciThis->lastWheelMouseTime);
+		sciThis->lastWheelMouseDirection = event->direction;
 
-	// Note:  Unpatched versions of win32gtk don't set the 'state' value so
-	// only regular scrolling is supported there.  Also, unpatched win32gtk
-	// issues spurious button 2 mouse events during wheeling, which can cause
-	// problems (a patch for both was submitted by archaeopteryx.com on 13Jun2001)
+		// Note:  Unpatched versions of win32gtk don't set the 'state' value so
+		// only regular scrolling is supported there.  Also, unpatched win32gtk
+		// issues spurious button 2 mouse events during wheeling, which can cause
+		// problems (a patch for both was submitted by archaeopteryx.com on 13Jun2001)
 
-	// Data zoom not supported
-	if (event->state & GDK_SHIFT_MASK) {
-		return FALSE;
-	}
+		// Data zoom not supported
+		if (event->state & GDK_SHIFT_MASK) {
+			return FALSE;
+		}
+
+		// Horizontal scrolling
+		if (event->direction == GDK_SCROLL_LEFT || event->direction == GDK_SCROLL_RIGHT) {
+			sciThis->HorizontalScrollTo(sciThis->xOffset + cLineScroll);
 
-	// Horizontal scrolling
-	if (event->direction == GDK_SCROLL_LEFT || event->direction == GDK_SCROLL_RIGHT) {
-		sciThis->HorizontalScrollTo(sciThis->xOffset + cLineScroll);
+			// Text font size zoom
+		} else if (event->state & GDK_CONTROL_MASK) {
+			if (cLineScroll < 0) {
+				sciThis->KeyCommand(SCI_ZOOMIN);
+			} else {
+				sciThis->KeyCommand(SCI_ZOOMOUT);
+			}
 
-	// Text font size zoom
-	} else if (event->state & GDK_CONTROL_MASK) {
-		if (cLineScroll < 0) {
-			sciThis->KeyCommand(SCI_ZOOMIN);
+			// Regular scrolling
 		} else {
-			sciThis->KeyCommand(SCI_ZOOMOUT);
+			sciThis->ScrollTo(sciThis->topLine + cLineScroll);
 		}
-
-	// Regular scrolling
-	} else {
-		sciThis->ScrollTo(sciThis->topLine + cLineScroll);
+		return TRUE;
+	} catch (...) {
+		sciThis->errorStatus = SC_STATUS_FAILURE;
 	}
-	return TRUE;
+	return FALSE;
 }
 #endif
 
 gint ScintillaGTK::Motion(GtkWidget *widget, GdkEventMotion *event) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	//Platform::DebugPrintf("Motion %x %d\n",sciThis,event->time);
-	if (event->window != widget->window)
-		return FALSE;
-	int x = 0;
-	int y = 0;
-	GdkModifierType state;
-	if (event->is_hint) {
-		gdk_window_get_pointer(event->window, &x, &y, &state);
-	} else {
-		x = static_cast<int>(event->x);
-		y = static_cast<int>(event->y);
-		state = static_cast<GdkModifierType>(event->state);
-	}
-	//Platform::DebugPrintf("Move %x %x %d %c %d %d\n",
-	//	sciThis,event->window,event->time,event->is_hint? 'h' :'.', x, y);
-	Point pt(x, y);
-	sciThis->ButtonMove(pt);
+	try {
+		//Platform::DebugPrintf("Motion %x %d\n",sciThis,event->time);
+		if (event->window != widget->window)
+			return FALSE;
+		int x = 0;
+		int y = 0;
+		GdkModifierType state;
+		if (event->is_hint) {
+			gdk_window_get_pointer(event->window, &x, &y, &state);
+		} else {
+			x = static_cast<int>(event->x);
+			y = static_cast<int>(event->y);
+			state = static_cast<GdkModifierType>(event->state);
+		}
+		//Platform::DebugPrintf("Move %x %x %d %c %d %d\n",
+		//	sciThis,event->window,event->time,event->is_hint? 'h' :'.', x, y);
+		Point pt(x, y);
+		sciThis->ButtonMove(pt);
+	} catch (...) {
+		sciThis->errorStatus = SC_STATUS_FAILURE;
+	}
 	return FALSE;
 }
 
@@ -2005,46 +2101,51 @@ static int KeyTranslate(int keyIn) {
 }
 
 gboolean ScintillaGTK::KeyThis(GdkEventKey *event) {
-	//fprintf(stderr, "SC-key: %d %x [%s]\n",
-	//	event->keyval, event->state, (event->length > 0) ? event->string : "empty");
+	try {
+		//fprintf(stderr, "SC-key: %d %x [%s]\n",
+		//	event->keyval, event->state, (event->length > 0) ? event->string : "empty");
 #if GTK_MAJOR_VERSION >= 2
-	if (gtk_im_context_filter_keypress(im_context, event)) {
-		return 1;
-	}
-#endif
-	if (!event->keyval) {
-		return true;
-	}
-
-	bool shift = (event->state & GDK_SHIFT_MASK) != 0;
-	bool ctrl = (event->state & GDK_CONTROL_MASK) != 0;
-	bool alt = (event->state & GDK_MOD1_MASK) != 0;
-	guint key = event->keyval;
-	if (ctrl && (key < 128))
-		key = toupper(key);
-	else if (!ctrl && (key >= GDK_KP_Multiply && key <= GDK_KP_9))
-		key &= 0x7F;
-	// Hack for keys over 256 and below command keys but makes Hungarian work.
-	// This will have to change for Unicode
-	else if (key >= 0xFE00)
-		key = KeyTranslate(key);
+		if (gtk_im_context_filter_keypress(im_context, event)) {
+			return 1;
+		}
+#endif
+		if (!event->keyval) {
+			return true;
+		}
+
+		bool shift = (event->state & GDK_SHIFT_MASK) != 0;
+		bool ctrl = (event->state & GDK_CONTROL_MASK) != 0;
+		bool alt = (event->state & GDK_MOD1_MASK) != 0;
+		guint key = event->keyval;
+		if (ctrl && (key < 128))
+			key = toupper(key);
+		else if (!ctrl && (key >= GDK_KP_Multiply && key <= GDK_KP_9))
+			key &= 0x7F;
+		// Hack for keys over 256 and below command keys but makes Hungarian work.
+		// This will have to change for Unicode
+		else if (key >= 0xFE00)
+			key = KeyTranslate(key);
 #if GTK_MAJOR_VERSION < 2
-	else if (!IsUnicodeMode() && (key >= 0x100) && (key < 0x1000))
-		key &= 0xff;
-#endif
-
-	bool consumed = false;
-	bool added = KeyDown(key, shift, ctrl, alt, &consumed) != 0;
-	if (!consumed)
-		consumed = added;
-	//fprintf(stderr, "SK-key: %d %x %x\n",event->keyval, event->state, consumed);
-	if (event->keyval == 0xffffff && event->length > 0) {
-		ClearSelection();
-		if (pdoc->InsertCString(CurrentPosition(), event->string)) {
-			MovePositionTo(CurrentPosition() + event->length);
+		else if (!IsUnicodeMode() && (key >= 0x100) && (key < 0x1000))
+			key &= 0xff;
+#endif
+
+		bool consumed = false;
+		bool added = KeyDown(key, shift, ctrl, alt, &consumed) != 0;
+		if (!consumed)
+			consumed = added;
+		//fprintf(stderr, "SK-key: %d %x %x\n",event->keyval, event->state, consumed);
+		if (event->keyval == 0xffffff && event->length > 0) {
+			ClearSelection();
+			if (pdoc->InsertCString(CurrentPosition(), event->string)) {
+				MovePositionTo(CurrentPosition() + event->length);
+			}
 		}
+		return consumed;
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
 	}
-	return consumed;
+	return FALSE;
 }
 
 gboolean ScintillaGTK::KeyPress(GtkWidget *widget, GdkEventKey *event) {
@@ -2058,107 +2159,120 @@ gboolean ScintillaGTK::KeyRelease(GtkWidget *, GdkEventKey * /*event*/) {
 }
 
 #if GTK_MAJOR_VERSION >= 2
-gboolean ScintillaGTK::ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis) {
-	return sciThis->ExposePreeditThis(widget, ose);
-}
-
 gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose) {
-	gchar *str;
-	gint cursor_pos;
-	PangoAttrList *attrs;
+	try {
+		gchar *str;
+		gint cursor_pos;
+		PangoAttrList *attrs;
 
-	gtk_im_context_get_preedit_string(im_context, &str, &attrs, &cursor_pos);
-	PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str);
-	pango_layout_set_attributes(layout, attrs);
+		gtk_im_context_get_preedit_string(im_context, &str, &attrs, &cursor_pos);
+		PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str);
+		pango_layout_set_attributes(layout, attrs);
 
-	GdkGC *gc = gdk_gc_new(widget->window);
-	GdkColor color[2] = {   {0, 0x0000, 0x0000, 0x0000},
-                            {0, 0xffff, 0xffff, 0xffff}};
-	gdk_color_alloc(gdk_colormap_get_system(), color);
-	gdk_color_alloc(gdk_colormap_get_system(), color + 1);
+		GdkGC *gc = gdk_gc_new(widget->window);
+		GdkColor color[2] = {   {0, 0x0000, 0x0000, 0x0000},
+			{0, 0xffff, 0xffff, 0xffff}
+		};
+		gdk_color_alloc(gdk_colormap_get_system(), color);
+		gdk_color_alloc(gdk_colormap_get_system(), color + 1);
 
-	gdk_gc_set_foreground(gc, color + 1);
-	gdk_draw_rectangle(widget->window, gc, TRUE, ose->area.x, ose->area.y,
-	                   ose->area.width, ose->area.height);
+		gdk_gc_set_foreground(gc, color + 1);
+		gdk_draw_rectangle(widget->window, gc, TRUE, ose->area.x, ose->area.y,
+		        ose->area.width, ose->area.height);
 
-	gdk_gc_set_foreground(gc, color);
-	gdk_gc_set_background(gc, color + 1);
-	gdk_draw_layout(widget->window, gc, 0, 0, layout);
+		gdk_gc_set_foreground(gc, color);
+		gdk_gc_set_background(gc, color + 1);
+		gdk_draw_layout(widget->window, gc, 0, 0, layout);
 
-	gdk_gc_unref(gc);
-	g_free(str);
-	pango_attr_list_unref(attrs);
-	g_object_unref(layout);
+		gdk_gc_unref(gc);
+		g_free(str);
+		pango_attr_list_unref(attrs);
+		g_object_unref(layout);
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
+	}
 	return TRUE;
 }
 
-void ScintillaGTK::Commit(GtkIMContext *, char  *str, ScintillaGTK *sciThis) {
-	sciThis->CommitThis(str);
+gboolean ScintillaGTK::ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis) {
+	return sciThis->ExposePreeditThis(widget, ose);
 }
 
 void ScintillaGTK::CommitThis(char *utfVal) {
-	//~ fprintf(stderr, "Commit '%s'\n", utfVal);
-	if (IsUnicodeMode()) {
-		AddCharUTF(utfVal,strlen(utfVal));
-	} else {
-		const char *source = CharacterSetID();
-		if (*source) {
-			Converter conv(source, "UTF-8", true);
-			if (conv) {
-				char localeVal[4]="\0\0\0";
-				char *pin = utfVal;
-				size_t inLeft = strlen(utfVal);
-				char *pout = localeVal;
-				size_t outLeft = sizeof(localeVal);
-				size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft);
-				if (conversions != ((size_t)(-1))) {
-					*pout = '\0';
-					for (int i=0; localeVal[i]; i++) {
-						AddChar(localeVal[i]);
+	try {
+		//~ fprintf(stderr, "Commit '%s'\n", utfVal);
+		if (IsUnicodeMode()) {
+			AddCharUTF(utfVal, strlen(utfVal));
+		} else {
+			const char *source = CharacterSetID();
+			if (*source) {
+				Converter conv(source, "UTF-8", true);
+				if (conv) {
+					char localeVal[4] = "\0\0\0";
+					char *pin = utfVal;
+					size_t inLeft = strlen(utfVal);
+					char *pout = localeVal;
+					size_t outLeft = sizeof(localeVal);
+					size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft);
+					if (conversions != ((size_t)(-1))) {
+						*pout = '\0';
+						for (int i = 0; localeVal[i]; i++) {
+							AddChar(localeVal[i]);
+						}
+					} else {
+						fprintf(stderr, "Conversion failed '%s'\n", utfVal);
 					}
-				} else {
-					fprintf(stderr, "Conversion failed '%s'\n", utfVal);
 				}
 			}
 		}
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
 	}
 }
 
-void ScintillaGTK::PreeditChanged(GtkIMContext *, ScintillaGTK *sciThis) {
-	sciThis->PreeditChangedThis();
+void ScintillaGTK::Commit(GtkIMContext *, char  *str, ScintillaGTK *sciThis) {
+	sciThis->CommitThis(str);
 }
 
 void ScintillaGTK::PreeditChangedThis() {
-	gchar *str;
-	PangoAttrList *attrs;
-	gint cursor_pos;
-	gtk_im_context_get_preedit_string(im_context, &str, &attrs, &cursor_pos);
-	if (strlen(str) > 0){
-		PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str);
-		pango_layout_set_attributes(layout, attrs);
-
-		gint w, h;
-		pango_layout_get_pixel_size(layout, &w, &h);
-		g_object_unref(layout);
-
-		gint x, y;
-		gdk_window_get_origin((PWidget(wText))->window, &x, &y);
-
-		Point pt = LocationFromPosition(currentPos);
-		if (pt.x < 0)
-			pt.x = 0;
-		if (pt.y < 0)
-			pt.y = 0;
-
-		gtk_window_move(GTK_WINDOW(PWidget(wPreedit)), x+pt.x, y+pt.y);
-		gtk_window_resize(GTK_WINDOW(PWidget(wPreedit)), w, h);
-		gtk_widget_show(PWidget(wPreedit));
-		gtk_widget_queue_draw_area(PWidget(wPreeditDraw), 0, 0, w, h);
-	} else {
-		gtk_widget_hide(PWidget(wPreedit));
+	try {
+		gchar *str;
+		PangoAttrList *attrs;
+		gint cursor_pos;
+		gtk_im_context_get_preedit_string(im_context, &str, &attrs, &cursor_pos);
+		if (strlen(str) > 0) {
+			PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str);
+			pango_layout_set_attributes(layout, attrs);
+
+			gint w, h;
+			pango_layout_get_pixel_size(layout, &w, &h);
+			g_object_unref(layout);
+
+			gint x, y;
+			gdk_window_get_origin((PWidget(wText))->window, &x, &y);
+
+			Point pt = PointMainCaret();
+			if (pt.x < 0)
+				pt.x = 0;
+			if (pt.y < 0)
+				pt.y = 0;
+
+			gtk_window_move(GTK_WINDOW(PWidget(wPreedit)), x + pt.x, y + pt.y);
+			gtk_window_resize(GTK_WINDOW(PWidget(wPreedit)), w, h);
+			gtk_widget_show(PWidget(wPreedit));
+			gtk_widget_queue_draw_area(PWidget(wPreeditDraw), 0, 0, w, h);
+		} else {
+			gtk_widget_hide(PWidget(wPreedit));
+		}
+		g_free(str);
+		pango_attr_list_unref(attrs);
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
 	}
-	g_free(str);
-	pango_attr_list_unref(attrs);
+}
+
+void ScintillaGTK::PreeditChanged(GtkIMContext *, ScintillaGTK *sciThis) {
+	sciThis->PreeditChangedThis();
 }
 #endif
 
@@ -2180,23 +2294,27 @@ void ScintillaGTK::Destroy(GtkObject *object)
 void ScintillaGTK::Destroy(GObject *object)
 #endif
 {
-	ScintillaObject *scio = reinterpret_cast<ScintillaObject *>(object);
-	// This avoids a double destruction
-	if (!scio->pscin)
-		return;
-	ScintillaGTK *sciThis = reinterpret_cast<ScintillaGTK *>(scio->pscin);
-	//Platform::DebugPrintf("Destroying %x %x\n", sciThis, object);
-	sciThis->Finalise();
+	try {
+		ScintillaObject *scio = reinterpret_cast<ScintillaObject *>(object);
+		// This avoids a double destruction
+		if (!scio->pscin)
+			return;
+		ScintillaGTK *sciThis = reinterpret_cast<ScintillaGTK *>(scio->pscin);
+		//Platform::DebugPrintf("Destroying %x %x\n", sciThis, object);
+		sciThis->Finalise();
 
 #if GLIB_MAJOR_VERSION < 2
-	if (GTK_OBJECT_CLASS(parent_class)->destroy)
-		(* GTK_OBJECT_CLASS(parent_class)->destroy)(object);
+		if (GTK_OBJECT_CLASS(parent_class)->destroy)
+			(* GTK_OBJECT_CLASS(parent_class)->destroy)(object);
 #else
-	// IS ANYTHING NEEDED ?
+		// IS ANYTHING NEEDED ?
 #endif
 
-	delete sciThis;
-	scio->pscin = 0;
+		delete sciThis;
+		scio->pscin = 0;
+	} catch (...) {
+		// Its dead so nowhere to save the status
+	}
 }
 
 static void DrawChild(GtkWidget *widget, GdkRectangle *area) {
@@ -2210,54 +2328,62 @@ static void DrawChild(GtkWidget *widget, GdkRectangle *area) {
 
 void ScintillaGTK::Draw(GtkWidget *widget, GdkRectangle *area) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	//Platform::DebugPrintf("Draw %p %0d,%0d %0d,%0d\n", widget, area->x, area->y, area->width, area->height);
-	PRectangle rcPaint(area->x, area->y, area->x + area->width, area->y + area->height);
-	sciThis->SyncPaint(rcPaint);
-	if (GTK_WIDGET_DRAWABLE(PWidget(sciThis->wMain))) {
-		DrawChild(PWidget(sciThis->scrollbarh), area);
-		DrawChild(PWidget(sciThis->scrollbarv), area);
-	}
+	try {
+		//Platform::DebugPrintf("Draw %p %0d,%0d %0d,%0d\n", widget, area->x, area->y, area->width, area->height);
+		PRectangle rcPaint(area->x, area->y, area->x + area->width, area->y + area->height);
+		sciThis->SyncPaint(rcPaint);
+		if (GTK_WIDGET_DRAWABLE(PWidget(sciThis->wMain))) {
+			DrawChild(PWidget(sciThis->scrollbarh), area);
+			DrawChild(PWidget(sciThis->scrollbarv), area);
+		}
 
 #ifdef INTERNATIONAL_INPUT
-	Point pt = sciThis->LocationFromPosition(sciThis->currentPos);
-	pt.y += sciThis->vs.lineHeight - 2;
-	if (pt.x < 0) pt.x = 0;
-	if (pt.y < 0) pt.y = 0;
-	CursorMoved(widget, pt.x, pt.y, sciThis);
+		Point pt = sciThis->PointMainCaret();
+		pt.y += sciThis->vs.lineHeight - 2;
+		if (pt.x < 0) pt.x = 0;
+		if (pt.y < 0) pt.y = 0;
+		CursorMoved(widget, pt.x, pt.y, sciThis);
 #endif
+	} catch (...) {
+		sciThis->errorStatus = SC_STATUS_FAILURE;
+	}
 }
 
 gint ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) {
-	paintState = painting;
+	try {
+		paintState = painting;
 
-	rcPaint.left = ose->area.x;
-	rcPaint.top = ose->area.y;
-	rcPaint.right = ose->area.x + ose->area.width;
-	rcPaint.bottom = ose->area.y + ose->area.height;
+		rcPaint.left = ose->area.x;
+		rcPaint.top = ose->area.y;
+		rcPaint.right = ose->area.x + ose->area.width;
+		rcPaint.bottom = ose->area.y + ose->area.height;
 
-	PLATFORM_ASSERT(rgnUpdate == NULL);
+		PLATFORM_ASSERT(rgnUpdate == NULL);
 #if GTK_MAJOR_VERSION >= 2
-	rgnUpdate = gdk_region_copy(ose->region);
-#endif
-	PRectangle rcClient = GetClientRectangle();
-	paintingAllText = rcPaint.Contains(rcClient);
-	Surface *surfaceWindow = Surface::Allocate();
-	if (surfaceWindow) {
-		surfaceWindow->Init(PWidget(wText)->window, PWidget(wText));
-		Paint(surfaceWindow, rcPaint);
-		surfaceWindow->Release();
-		delete surfaceWindow;
-	}
-	if (paintState == paintAbandoned) {
-		// Painting area was insufficient to cover new styling or brace highlight positions
-		FullPaint();
-	}
-	paintState = notPainting;
+		rgnUpdate = gdk_region_copy(ose->region);
+#endif
+		PRectangle rcClient = GetClientRectangle();
+		paintingAllText = rcPaint.Contains(rcClient);
+		Surface *surfaceWindow = Surface::Allocate();
+		if (surfaceWindow) {
+			surfaceWindow->Init(PWidget(wText)->window, PWidget(wText));
+			Paint(surfaceWindow, rcPaint);
+			surfaceWindow->Release();
+			delete surfaceWindow;
+		}
+		if (paintState == paintAbandoned) {
+			// Painting area was insufficient to cover new styling or brace highlight positions
+			FullPaint();
+		}
+		paintState = notPainting;
 
-	if (rgnUpdate) {
-		gdk_region_destroy(rgnUpdate);
+		if (rgnUpdate) {
+			gdk_region_destroy(rgnUpdate);
+		}
+		rgnUpdate = 0;
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
 	}
-	rgnUpdate = 0;
 
 	return FALSE;
 }
@@ -2274,64 +2400,76 @@ gint ScintillaGTK::ExposeMain(GtkWidget *widget, GdkEventExpose *ose) {
 }
 
 gint ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) {
-	//fprintf(stderr, "Expose %0d,%0d %0d,%0d\n",
-	//ose->area.x, ose->area.y, ose->area.width, ose->area.height);
+	try {
+		//fprintf(stderr, "Expose %0d,%0d %0d,%0d\n",
+		//ose->area.x, ose->area.y, ose->area.width, ose->area.height);
 
 #if GTK_MAJOR_VERSION < 2
 
-	paintState = painting;
-
-	rcPaint.left = ose->area.x;
-	rcPaint.top = ose->area.y;
-	rcPaint.right = ose->area.x + ose->area.width;
-	rcPaint.bottom = ose->area.y + ose->area.height;
-
-	PRectangle rcClient = GetClientRectangle();
-	paintingAllText = rcPaint.Contains(rcClient);
-	Surface *surfaceWindow = Surface::Allocate();
-	if (surfaceWindow) {
-		surfaceWindow->Init(PWidget(wMain)->window, PWidget(wMain));
-
-		// Fill the corner between the scrollbars
-		if (verticalScrollBarVisible) {
-			if (horizontalScrollBarVisible && (wrapState == eWrapNone)) {
-				PRectangle rcCorner = wMain.GetClientPosition();
-				rcCorner.left = rcCorner.right - scrollBarWidth + 1;
-				rcCorner.top = rcCorner.bottom - scrollBarHeight + 1;
-				//fprintf(stderr, "Corner %0d,%0d %0d,%0d\n",
-				//rcCorner.left, rcCorner.top, rcCorner.right, rcCorner.bottom);
-				surfaceWindow->FillRectangle(rcCorner,
-					vs.styles[STYLE_LINENUMBER].back.allocated);
+		paintState = painting;
+
+		rcPaint.left = ose->area.x;
+		rcPaint.top = ose->area.y;
+		rcPaint.right = ose->area.x + ose->area.width;
+		rcPaint.bottom = ose->area.y + ose->area.height;
+
+		PRectangle rcClient = GetClientRectangle();
+		paintingAllText = rcPaint.Contains(rcClient);
+		Surface *surfaceWindow = Surface::Allocate();
+		if (surfaceWindow) {
+			surfaceWindow->Init(PWidget(wMain)->window, PWidget(wMain));
+
+			// Fill the corner between the scrollbars
+			if (verticalScrollBarVisible) {
+				if (horizontalScrollBarVisible && (wrapState == eWrapNone)) {
+					PRectangle rcCorner = wMain.GetClientPosition();
+					rcCorner.left = rcCorner.right - scrollBarWidth + 1;
+					rcCorner.top = rcCorner.bottom - scrollBarHeight + 1;
+					//fprintf(stderr, "Corner %0d,%0d %0d,%0d\n",
+					//rcCorner.left, rcCorner.top, rcCorner.right, rcCorner.bottom);
+					surfaceWindow->FillRectangle(rcCorner,
+					        vs.styles[STYLE_LINENUMBER].back.allocated);
+				}
 			}
-		}
 
-		//Paint(surfaceWindow, rcPaint);
-		surfaceWindow->Release();
-		delete surfaceWindow;
-	}
-	if (paintState == paintAbandoned) {
-		// Painting area was insufficient to cover new styling or brace highlight positions
-		FullPaint();
-	}
-	paintState = notPainting;
+			//Paint(surfaceWindow, rcPaint);
+			surfaceWindow->Release();
+			delete surfaceWindow;
+		}
+		if (paintState == paintAbandoned) {
+			// Painting area was insufficient to cover new styling or brace highlight positions
+			FullPaint();
+		}
+		paintState = notPainting;
 
 #else
-	// For GTK+ 2, the text is painted in ExposeText
-	gtk_container_propagate_expose(
-		GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarh), ose);
-	gtk_container_propagate_expose(
-		GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarv), ose);
+		// For GTK+ 2, the text is painted in ExposeText
+		gtk_container_propagate_expose(
+		    GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarh), ose);
+		gtk_container_propagate_expose(
+		    GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarv), ose);
 #endif
 
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
+	}
 	return FALSE;
 }
 
 void ScintillaGTK::ScrollSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) {
-	sciThis->ScrollTo(static_cast<int>(adj->value), false);
+	try {
+		sciThis->ScrollTo(static_cast<int>(adj->value), false);
+	} catch (...) {
+		sciThis->errorStatus = SC_STATUS_FAILURE;
+	}
 }
 
 void ScintillaGTK::ScrollHSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) {
-	sciThis->HorizontalScrollTo(static_cast<int>(adj->value * 2));
+	try {
+		sciThis->HorizontalScrollTo(static_cast<int>(adj->value * 2));
+	} catch (...) {
+		sciThis->errorStatus = SC_STATUS_FAILURE;
+	}
 }
 
 void ScintillaGTK::SelectionReceived(GtkWidget *widget,
@@ -2344,18 +2482,22 @@ void ScintillaGTK::SelectionReceived(GtkWidget *widget,
 void ScintillaGTK::SelectionGet(GtkWidget *widget,
                                 GtkSelectionData *selection_data, guint info, guint) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	//Platform::DebugPrintf("Selection get\n");
-	if (selection_data->selection == GDK_SELECTION_PRIMARY) {
-		if (sciThis->primary.s == NULL) {
-			sciThis->CopySelectionRange(&sciThis->primary);
+	try {
+		//Platform::DebugPrintf("Selection get\n");
+		if (selection_data->selection == GDK_SELECTION_PRIMARY) {
+			if (sciThis->primary.s == NULL) {
+				sciThis->CopySelectionRange(&sciThis->primary);
+			}
+			sciThis->GetSelection(selection_data, info, &sciThis->primary);
 		}
-		sciThis->GetSelection(selection_data, info, &sciThis->primary);
-	}
 #ifndef USE_GTK_CLIPBOARD
-	else {
-		sciThis->GetSelection(selection_data, info, &sciThis->copyText);
-	}
+		else {
+			sciThis->GetSelection(selection_data, info, &sciThis->copyText);
+		}
 #endif
+	} catch (...) {
+		sciThis->errorStatus = SC_STATUS_FAILURE;
+	}
 }
 
 gint ScintillaGTK::SelectionClear(GtkWidget *widget, GdkEventSelection *selection_event) {
@@ -2378,19 +2520,23 @@ void ScintillaGTK::DragBegin(GtkWidget *, GdkDragContext *) {
 
 gboolean ScintillaGTK::DragMotionThis(GdkDragContext *context,
                                  gint x, gint y, guint dragtime) {
-	Point npt(x, y);
-	SetDragPosition(PositionFromLocation(npt));
-	GdkDragAction preferredAction = context->suggested_action;
-	int pos = PositionFromLocation(npt);
-	if ((inDragDrop == ddDragging) && (0 == PositionInSelection(pos))) {
-		// Avoid dragging selection onto itself as that produces a move
-		// with no real effect but which creates undo actions.
-		preferredAction = static_cast<GdkDragAction>(0);
-	} else if (context->actions == static_cast<GdkDragAction>
-		(GDK_ACTION_COPY | GDK_ACTION_MOVE)) {
-		preferredAction = GDK_ACTION_MOVE;
-	}
-	gdk_drag_status(context, preferredAction, dragtime);
+	try {
+		Point npt(x, y);
+		SetDragPosition(SPositionFromLocation(npt, false, false, UserVirtualSpace()));
+		GdkDragAction preferredAction = context->suggested_action;
+		SelectionPosition pos = SPositionFromLocation(npt);
+		if ((inDragDrop == ddDragging) && (PositionInSelection(pos.Position()))) {
+			// Avoid dragging selection onto itself as that produces a move
+			// with no real effect but which creates undo actions.
+			preferredAction = static_cast<GdkDragAction>(0);
+		} else if (context->actions == static_cast<GdkDragAction>
+		        (GDK_ACTION_COPY | GDK_ACTION_MOVE)) {
+			preferredAction = GDK_ACTION_MOVE;
+		}
+		gdk_drag_status(context, preferredAction, dragtime);
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
+	}
 	return FALSE;
 }
 
@@ -2402,55 +2548,76 @@ gboolean ScintillaGTK::DragMotion(GtkWidget *widget, GdkDragContext *context,
 
 void ScintillaGTK::DragLeave(GtkWidget *widget, GdkDragContext * /*context*/, guint) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	sciThis->SetDragPosition(invalidPosition);
-	//Platform::DebugPrintf("DragLeave %x\n", sciThis);
+	try {
+		sciThis->SetDragPosition(SelectionPosition(invalidPosition));
+		//Platform::DebugPrintf("DragLeave %x\n", sciThis);
+	} catch (...) {
+		sciThis->errorStatus = SC_STATUS_FAILURE;
+	}
 }
 
 void ScintillaGTK::DragEnd(GtkWidget *widget, GdkDragContext * /*context*/) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	// If drag did not result in drop here or elsewhere
-	if (!sciThis->dragWasDropped)
-		sciThis->SetEmptySelection(sciThis->posDrag);
-	sciThis->SetDragPosition(invalidPosition);
-	//Platform::DebugPrintf("DragEnd %x %d\n", sciThis, sciThis->dragWasDropped);
-	sciThis->inDragDrop = ddNone;
+	try {
+		// If drag did not result in drop here or elsewhere
+		if (!sciThis->dragWasDropped)
+			sciThis->SetEmptySelection(sciThis->posDrag);
+		sciThis->SetDragPosition(SelectionPosition(invalidPosition));
+		//Platform::DebugPrintf("DragEnd %x %d\n", sciThis, sciThis->dragWasDropped);
+		sciThis->inDragDrop = ddNone;
+	} catch (...) {
+		sciThis->errorStatus = SC_STATUS_FAILURE;
+	}
 }
 
 gboolean ScintillaGTK::Drop(GtkWidget *widget, GdkDragContext * /*context*/,
                             gint, gint, guint) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	//Platform::DebugPrintf("Drop %x\n", sciThis);
-	sciThis->SetDragPosition(invalidPosition);
+	try {
+		//Platform::DebugPrintf("Drop %x\n", sciThis);
+		sciThis->SetDragPosition(SelectionPosition(invalidPosition));
+	} catch (...) {
+		sciThis->errorStatus = SC_STATUS_FAILURE;
+	}
 	return FALSE;
 }
 
 void ScintillaGTK::DragDataReceived(GtkWidget *widget, GdkDragContext * /*context*/,
                                     gint, gint, GtkSelectionData *selection_data, guint /*info*/, guint) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	sciThis->ReceivedDrop(selection_data);
-	sciThis->SetDragPosition(invalidPosition);
+	try {
+		sciThis->ReceivedDrop(selection_data);
+		sciThis->SetDragPosition(SelectionPosition(invalidPosition));
+	} catch (...) {
+		sciThis->errorStatus = SC_STATUS_FAILURE;
+	}
 }
 
 void ScintillaGTK::DragDataGet(GtkWidget *widget, GdkDragContext *context,
                                GtkSelectionData *selection_data, guint info, guint) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	sciThis->dragWasDropped = true;
-	if (sciThis->currentPos != sciThis->anchor) {
-		sciThis->GetSelection(selection_data, info, &sciThis->drag);
-	}
-	if (context->action == GDK_ACTION_MOVE) {
-		int selStart = sciThis->SelectionStart();
-		int selEnd = sciThis->SelectionEnd();
-		if (sciThis->posDrop > selStart) {
-			if (sciThis->posDrop > selEnd)
-				sciThis->posDrop = sciThis->posDrop - (selEnd - selStart);
-			else
-				sciThis->posDrop = selStart;
-			sciThis->posDrop = sciThis->pdoc->ClampPositionIntoDocument(sciThis->posDrop);
+	try {
+		sciThis->dragWasDropped = true;
+		if (!sciThis->sel.Empty()) {
+			sciThis->GetSelection(selection_data, info, &sciThis->drag);
+		}
+		if (context->action == GDK_ACTION_MOVE) {
+			SelectionPosition selStart = sciThis->SelectionStart();
+			SelectionPosition selEnd = sciThis->SelectionEnd();
+			if (sciThis->posDrop > selStart) {
+				if (sciThis->posDrop > selEnd)
+					sciThis->posDrop.Add(-((selEnd.Position() - selStart.Position())));
+				else
+					sciThis->posDrop = selStart;
+				sciThis->posDrop = SelectionPosition(
+					sciThis->pdoc->ClampPositionIntoDocument(sciThis->posDrop.Position()));
+			}
+			sciThis->ClearSelection();
 		}
-		sciThis->ClearSelection();
+		sciThis->SetDragPosition(SelectionPosition(invalidPosition));
+	} catch (...) {
+		sciThis->errorStatus = SC_STATUS_FAILURE;
 	}
-	sciThis->SetDragPosition(invalidPosition);
 }
 
 int ScintillaGTK::TimeOut(ScintillaGTK *sciThis) {
@@ -2478,15 +2645,18 @@ void ScintillaGTK::PopUpCB(ScintillaGTK *sciThis, guint action, GtkWidget *) {
 }
 
 gint ScintillaGTK::PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGTK *sciThis) {
-	if (event->window != widget->window)
-		return FALSE;
-	if (event->type != GDK_BUTTON_PRESS)
-		return FALSE;
-	Point pt;
-	pt.x = int(event->x);
-	pt.y = int(event->y);
-	sciThis->ct.MouseClick(pt);
-	sciThis->CallTipClick();
+	try {
+		if (event->window != widget->window)
+			return FALSE;
+		if (event->type != GDK_BUTTON_PRESS)
+			return FALSE;
+		Point pt;
+		pt.x = int(event->x);
+		pt.y = int(event->y);
+		sciThis->ct.MouseClick(pt);
+		sciThis->CallTipClick();
+	} catch (...) {
+	}
 #if GTK_MAJOR_VERSION >= 2
 	return TRUE;
 #else
@@ -2495,12 +2665,18 @@ gint ScintillaGTK::PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGT
 }
 
 gint ScintillaGTK::ExposeCT(GtkWidget *widget, GdkEventExpose * /*ose*/, CallTip *ctip) {
-	Surface *surfaceWindow = Surface::Allocate();
-	if (surfaceWindow) {
-		surfaceWindow->Init(widget->window, widget);
-		ctip->PaintCT(surfaceWindow);
-		surfaceWindow->Release();
-		delete surfaceWindow;
+	try {
+		Surface *surfaceWindow = Surface::Allocate();
+		if (surfaceWindow) {
+			surfaceWindow->Init(widget->window, widget);
+			surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ctip->codePage);
+			surfaceWindow->SetDBCSMode(ctip->codePage);
+			ctip->PaintCT(surfaceWindow);
+			surfaceWindow->Release();
+			delete surfaceWindow;
+		}
+	} catch (...) {
+		// No pointer back to Scintilla to save status
 	}
 	return TRUE;
 }
@@ -2524,50 +2700,56 @@ extern void Platform_Finalise();
 #if GLIB_MAJOR_VERSION < 2
 GtkType scintilla_get_type() {
 	static GtkType scintilla_type = 0;
+	try {
 
-	if (!scintilla_type) {
-		Platform_Initialise();
-		static GtkTypeInfo scintilla_info = {
-		    "Scintilla",
-		    sizeof (ScintillaObject),
-		    sizeof (ScintillaClass),
-		    (GtkClassInitFunc) scintilla_class_init,
-		    (GtkObjectInitFunc) scintilla_init,
-		    (gpointer) NULL,
-		    (gpointer) NULL,
-		    0
-		};
+		if (!scintilla_type) {
+			Platform_Initialise();
+			static GtkTypeInfo scintilla_info = {
+				"Scintilla",
+				sizeof (ScintillaObject),
+				sizeof (ScintillaClass),
+				(GtkClassInitFunc) scintilla_class_init,
+				(GtkObjectInitFunc) scintilla_init,
+				(gpointer) NULL,
+				(gpointer) NULL,
+				0
+			};
 
-		scintilla_type = gtk_type_unique(gtk_container_get_type(), &scintilla_info);
-	}
+			scintilla_type = gtk_type_unique(gtk_container_get_type(), &scintilla_info);
+		}
 
+	} catch (...) {
+	}
 	return scintilla_type;
 }
 #else
 GType scintilla_get_type() {
 	static GType scintilla_type = 0;
+	try {
 
-	if (!scintilla_type) {
-		scintilla_type = g_type_from_name("Scintilla");
 		if (!scintilla_type) {
-			static GTypeInfo scintilla_info = {
-				(guint16) sizeof (ScintillaClass),
-				NULL, //(GBaseInitFunc)
-				NULL, //(GBaseFinalizeFunc)
-				(GClassInitFunc) scintilla_class_init,
-				NULL, //(GClassFinalizeFunc)
-				NULL, //gconstpointer data
-				(guint16) sizeof (ScintillaObject),
-				0, //n_preallocs
-				(GInstanceInitFunc) scintilla_init,
-				NULL //(GTypeValueTable*)
-			};
-
-			scintilla_type = g_type_register_static(
-				GTK_TYPE_CONTAINER, "Scintilla", &scintilla_info, (GTypeFlags) 0);
+			scintilla_type = g_type_from_name("Scintilla");
+			if (!scintilla_type) {
+				static GTypeInfo scintilla_info = {
+					(guint16) sizeof (ScintillaClass),
+					NULL, //(GBaseInitFunc)
+					NULL, //(GBaseFinalizeFunc)
+					(GClassInitFunc) scintilla_class_init,
+					NULL, //(GClassFinalizeFunc)
+					NULL, //gconstpointer data
+					(guint16) sizeof (ScintillaObject),
+					0, //n_preallocs
+					(GInstanceInitFunc) scintilla_init,
+					NULL //(GTypeValueTable*)
+				};
+
+				scintilla_type = g_type_register_static(
+				            GTK_TYPE_CONTAINER, "Scintilla", &scintilla_info, (GTypeFlags) 0);
+			}
 		}
-	}
 
+	} catch (...) {
+	}
 	return scintilla_type;
 }
 #endif
@@ -2639,65 +2821,71 @@ void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_
 #endif
 
 static void scintilla_class_init(ScintillaClass *klass) {
-	OBJECT_CLASS *object_class = (OBJECT_CLASS*) klass;
-	GtkWidgetClass *widget_class = (GtkWidgetClass*) klass;
-	GtkContainerClass *container_class = (GtkContainerClass*) klass;
+	try {
+		OBJECT_CLASS *object_class = (OBJECT_CLASS*) klass;
+		GtkWidgetClass *widget_class = (GtkWidgetClass*) klass;
+		GtkContainerClass *container_class = (GtkContainerClass*) klass;
 
 #if GLIB_MAJOR_VERSION < 2
-	parent_class = (GtkWidgetClass*) gtk_type_class(gtk_container_get_type());
-
-	scintilla_signals[COMMAND_SIGNAL] = gtk_signal_new(
-	                                        "command",
-	                                        GTK_RUN_LAST,
-	                                        GTK_CLASS_TYPE(object_class),
-	                                        GTK_SIGNAL_OFFSET(ScintillaClass, command),
-	                                        SIG_MARSHAL,
-	                                        GTK_TYPE_NONE,
-	                                        2, MARSHAL_ARGUMENTS);
-
-	scintilla_signals[NOTIFY_SIGNAL] = gtk_signal_new(
-	                                       SCINTILLA_NOTIFY,
-	                                       GTK_RUN_LAST,
-	                                       GTK_CLASS_TYPE(object_class),
-	                                       GTK_SIGNAL_OFFSET(ScintillaClass, notify),
-	                                       SIG_MARSHAL,
-	                                       GTK_TYPE_NONE,
-	                                       2, MARSHAL_ARGUMENTS);
-	gtk_object_class_add_signals(object_class,
-	                             reinterpret_cast<unsigned int *>(scintilla_signals), LAST_SIGNAL);
+		parent_class = (GtkWidgetClass*) gtk_type_class(gtk_container_get_type());
+
+		scintilla_signals[COMMAND_SIGNAL] = gtk_signal_new(
+		            "command",
+		            GTK_RUN_LAST,
+		            GTK_CLASS_TYPE(object_class),
+		            GTK_SIGNAL_OFFSET(ScintillaClass, command),
+		            SIG_MARSHAL,
+		            GTK_TYPE_NONE,
+		            2, MARSHAL_ARGUMENTS);
+
+		scintilla_signals[NOTIFY_SIGNAL] = gtk_signal_new(
+		            SCINTILLA_NOTIFY,
+		            GTK_RUN_LAST,
+		            GTK_CLASS_TYPE(object_class),
+		            GTK_SIGNAL_OFFSET(ScintillaClass, notify),
+		            SIG_MARSHAL,
+		            GTK_TYPE_NONE,
+		            2, MARSHAL_ARGUMENTS);
+		gtk_object_class_add_signals(object_class,
+		        reinterpret_cast<unsigned int *>(scintilla_signals), LAST_SIGNAL);
 #else
-	GSignalFlags sigflags = GSignalFlags(G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST);
-	scintilla_signals[COMMAND_SIGNAL] = g_signal_new(
-	                                       "command",
-	                                       G_TYPE_FROM_CLASS(object_class),
-	                                       sigflags,
-	                                       G_STRUCT_OFFSET(ScintillaClass, command),
-	                                       NULL, //(GSignalAccumulator)
-	                                       NULL, //(gpointer)
-	                                       SIG_MARSHAL,
-	                                       G_TYPE_NONE,
-	                                       2, MARSHAL_ARGUMENTS);
-
-	scintilla_signals[NOTIFY_SIGNAL] = g_signal_new(
-	                                       SCINTILLA_NOTIFY,
-	                                       G_TYPE_FROM_CLASS(object_class),
-	                                       sigflags,
-	                                       G_STRUCT_OFFSET(ScintillaClass, notify),
-	                                       NULL,
-	                                       NULL,
-	                                       SIG_MARSHAL,
-	                                       G_TYPE_NONE,
-	                                       2, MARSHAL_ARGUMENTS);
-#endif
-	klass->command = NULL;
-	klass->notify = NULL;
-
-	ScintillaGTK::ClassInit(object_class, widget_class, container_class);
+		GSignalFlags sigflags = GSignalFlags(G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST);
+		scintilla_signals[COMMAND_SIGNAL] = g_signal_new(
+		            "command",
+		            G_TYPE_FROM_CLASS(object_class),
+		            sigflags,
+		            G_STRUCT_OFFSET(ScintillaClass, command),
+		            NULL, //(GSignalAccumulator)
+		            NULL, //(gpointer)
+		            SIG_MARSHAL,
+		            G_TYPE_NONE,
+		            2, MARSHAL_ARGUMENTS);
+
+		scintilla_signals[NOTIFY_SIGNAL] = g_signal_new(
+		            SCINTILLA_NOTIFY,
+		            G_TYPE_FROM_CLASS(object_class),
+		            sigflags,
+		            G_STRUCT_OFFSET(ScintillaClass, notify),
+		            NULL,
+		            NULL,
+		            SIG_MARSHAL,
+		            G_TYPE_NONE,
+		            2, MARSHAL_ARGUMENTS);
+#endif
+		klass->command = NULL;
+		klass->notify = NULL;
+
+		ScintillaGTK::ClassInit(object_class, widget_class, container_class);
+	} catch (...) {
+	}
 }
 
 static void scintilla_init(ScintillaObject *sci) {
-	GTK_WIDGET_SET_FLAGS(sci, GTK_CAN_FOCUS);
-	sci->pscin = new ScintillaGTK(sci);
+	try {
+		GTK_WIDGET_SET_FLAGS(sci, GTK_CAN_FOCUS);
+		sci->pscin = new ScintillaGTK(sci);
+	} catch (...) {
+	}
 }
 
 GtkWidget* scintilla_new() {
@@ -2714,5 +2902,8 @@ void scintilla_set_id(ScintillaObject *sci, uptr_t id) {
 }
 
 void scintilla_release_resources(void) {
-	Platform_Finalise();
+	try {
+		Platform_Finalise();
+	} catch (...) {
+	}
 }
diff --git a/plugins/scintilla/scintilla/Selection.cxx b/plugins/scintilla/scintilla/Selection.cxx
new file mode 100644
index 0000000..47d0786
--- /dev/null
+++ b/plugins/scintilla/scintilla/Selection.cxx
@@ -0,0 +1,345 @@
+// Scintilla source code edit control
+/** @file Selection.cxx
+ ** Classes maintaining the selection.
+ **/
+// Copyright 2009 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+
+#include <vector>
+
+#include "Platform.h"
+
+#include "Scintilla.h"
+
+#include "Selection.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) {
+	if (insertion) {
+		if (position > startChange) {
+			position += length;
+		}
+	} else {
+		if (position > startChange) {
+			int endDeletion = startChange + length;
+			if (position > endDeletion) {
+				position -= length;
+			} else {
+				position = startChange;
+			}
+		}
+	}
+}
+
+bool SelectionPosition::operator <(const SelectionPosition &other) const {
+	if (position == other.position)
+		return virtualSpace < other.virtualSpace;
+	else
+		return position < other.position;
+}
+
+bool SelectionPosition::operator >(const SelectionPosition &other) const {
+	if (position == other.position)
+		return virtualSpace > other.virtualSpace;
+	else
+		return position > other.position;
+}
+
+bool SelectionPosition::operator <=(const SelectionPosition &other) const {
+	if (position == other.position && virtualSpace == other.virtualSpace)
+		return true;
+	else
+		return other > *this;
+}
+
+bool SelectionPosition::operator >=(const SelectionPosition &other) const {
+	if (position == other.position && virtualSpace == other.virtualSpace)
+		return true;
+	else
+		return *this > other;
+}
+
+int SelectionRange::Length() const {
+	if (anchor > caret) {
+		return anchor.Position() - caret.Position();
+	} else {
+		return caret.Position() - anchor.Position();
+	}
+}
+
+bool SelectionRange::Contains(int pos) const {
+	if (anchor > caret)
+		return (pos >= caret.Position()) && (pos <= anchor.Position());
+	else
+		return (pos >= anchor.Position()) && (pos <= caret.Position());
+}
+
+bool SelectionRange::Contains(SelectionPosition sp) const {
+	if (anchor > caret)
+		return (sp >= caret) && (sp <= anchor);
+	else
+		return (sp >= anchor) && (sp <= caret);
+}
+
+bool SelectionRange::ContainsCharacter(int posCharacter) const {
+	if (anchor > caret)
+		return (posCharacter >= caret.Position()) && (posCharacter < anchor.Position());
+	else
+		return (posCharacter >= anchor.Position()) && (posCharacter < caret.Position());
+}
+
+SelectionSegment SelectionRange::Intersect(SelectionSegment check) const {
+	SelectionSegment inOrder(caret, anchor);
+	if ((inOrder.start <= check.end) || (inOrder.end >= check.start)) {
+		SelectionSegment portion = check;
+		if (portion.start < inOrder.start)
+			portion.start = inOrder.start;
+		if (portion.end > inOrder.end)
+			portion.end = inOrder.end;
+		if (portion.start > portion.end)
+			return SelectionSegment();
+		else
+			return portion;
+	} else {
+		return SelectionSegment();
+	}
+}
+
+bool SelectionRange::Trim(SelectionRange range) {
+	SelectionPosition startRange = range.Start();
+	SelectionPosition endRange = range.End();
+	SelectionPosition start = Start();
+	SelectionPosition end = End();
+	PLATFORM_ASSERT(start <= end);
+	PLATFORM_ASSERT(startRange <= endRange);
+	if ((startRange <= end) && (endRange >= start)) {
+		if ((start > startRange) && (end < endRange)) {
+			// Completely covered by range -> empty at start
+			end = start;
+		} else if ((start < startRange) && (end > endRange)) {
+			// Completely covers range -> empty at start
+			end = start;
+		} else if (start <= startRange) {
+			// Trim end
+			end = startRange;
+		} else { // 
+			PLATFORM_ASSERT(end >= endRange);
+			// Trim start
+			start = endRange;
+		}
+		if (anchor > caret) {
+			caret = start;
+			anchor = end;
+		} else {
+			anchor = start;
+			caret = end;
+		}
+		return Empty();
+	} else {
+		return false;
+	}
+}
+
+// If range is all virtual collapse to start of virtual space
+void SelectionRange::MinimizeVirtualSpace() {
+	if (caret.Position() == anchor.Position()) {
+		int virtualSpace = caret.VirtualSpace();
+		if (virtualSpace > anchor.VirtualSpace())
+			virtualSpace = anchor.VirtualSpace();
+		caret.SetVirtualSpace(virtualSpace);
+		anchor.SetVirtualSpace(virtualSpace);
+	}
+}
+
+Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) {
+	AddSelection(SelectionPosition(0));
+}
+
+Selection::~Selection() {
+}
+
+bool Selection::IsRectangular() const {
+	return (selType == selRectangle) || (selType == selThin);
+}
+
+int Selection::MainCaret() const {
+	return ranges[mainRange].caret.Position();
+}
+
+int Selection::MainAnchor() const {
+	return ranges[mainRange].anchor.Position();
+}
+
+SelectionRange &Selection::Rectangular() {
+	return rangeRectangular;
+}
+
+size_t Selection::Count() const {
+	return ranges.size();
+}
+
+size_t Selection::Main() const {
+	return mainRange;
+}
+
+void Selection::SetMain(size_t r) {
+	PLATFORM_ASSERT(r < ranges.size());
+	mainRange = r;
+}
+
+SelectionRange &Selection::Range(size_t r) {
+	return ranges[r];
+}
+
+SelectionRange &Selection::RangeMain() {
+	return ranges[mainRange];
+}
+
+bool Selection::MoveExtends() const {
+	return moveExtends;
+}
+
+void Selection::SetMoveExtends(bool moveExtends_) {
+	moveExtends = moveExtends_;
+}
+
+bool Selection::Empty() const {
+	for (size_t i=0; i<ranges.size(); i++) {
+		if (!ranges[i].Empty())
+			return false;
+	}
+	return true;
+}
+
+SelectionPosition Selection::Last() const {
+	SelectionPosition lastPosition;
+	for (size_t i=0; i<ranges.size(); i++) {
+		if (lastPosition < ranges[i].caret)
+			lastPosition = ranges[i].caret;
+		if (lastPosition < ranges[i].anchor)
+			lastPosition = ranges[i].anchor;
+	}
+	return lastPosition;
+}
+
+int Selection::Length() const {
+	int len = 0;
+	for (size_t i=0; i<ranges.size(); i++) {
+		len += ranges[i].Length();
+	}
+	return len;
+}
+
+void Selection::MovePositions(bool insertion, int startChange, int length) {
+	for (size_t i=0; i<ranges.size(); i++) {
+		ranges[i].caret.MoveForInsertDelete(insertion, startChange, length);
+		ranges[i].anchor.MoveForInsertDelete(insertion, startChange, length);
+	}
+}
+
+void Selection::TrimSelection(SelectionRange range) {
+	for (size_t i=0; i<ranges.size();) {
+		if ((i != mainRange) && (ranges[i].Trim(range))) {
+			// Trimmed to empty so remove
+			for (size_t j=i;j<ranges.size()-1;j++) {
+				ranges[j] = ranges[j+1];
+				if (j == mainRange-1)
+					mainRange--;
+			}
+			ranges.pop_back();
+		} else {
+			i++;
+		}
+	}
+}
+
+void Selection::SetSelection(SelectionRange range) {
+	ranges.clear();
+	ranges.push_back(range);
+	mainRange = ranges.size() - 1;
+}
+
+void Selection::AddSelection(SelectionRange range) {
+	TrimSelection(range);
+	ranges.push_back(range);
+	mainRange = ranges.size() - 1;
+}
+
+void Selection::TentativeSelection(SelectionRange range) {
+	if (!tentativeMain) {
+		rangesSaved = ranges;
+	}
+	ranges = rangesSaved;
+	AddSelection(range);
+	TrimSelection(ranges[mainRange]);
+	tentativeMain = true;
+}
+
+void Selection::CommitTentative() {
+	rangesSaved.clear();
+	tentativeMain = false;
+}
+
+int Selection::CharacterInSelection(int posCharacter) const {
+	for (size_t i=0; i<ranges.size(); i++) {
+		if (ranges[i].ContainsCharacter(posCharacter))
+			return i == mainRange ? 1 : 2;
+	}
+	return 0;
+}
+
+int Selection::InSelectionForEOL(int pos) const {
+	for (size_t i=0; i<ranges.size(); i++) {
+		if (!ranges[i].Empty() && (pos > ranges[i].Start().Position()) && (pos <= ranges[i].End().Position()))
+			return i == mainRange ? 1 : 2;
+	}
+	return 0;
+}
+
+int Selection::VirtualSpaceFor(int pos) const {
+	int virtualSpace = 0;
+	for (size_t i=0; i<ranges.size(); i++) {
+		if ((ranges[i].caret.Position() == pos) && (virtualSpace < ranges[i].caret.VirtualSpace()))
+			virtualSpace = ranges[i].caret.VirtualSpace();
+		if ((ranges[i].anchor.Position() == pos) && (virtualSpace < ranges[i].anchor.VirtualSpace()))
+			virtualSpace = ranges[i].anchor.VirtualSpace();
+	}
+	return virtualSpace;
+}
+
+void Selection::Clear() {
+	ranges.clear();
+	ranges.push_back(SelectionRange());
+	mainRange = ranges.size() - 1;
+	selType = selStream;
+	moveExtends = false;
+	ranges[mainRange].Reset();
+	rangeRectangular.Reset();
+}
+
+void Selection::RemoveDuplicates() {
+	for (size_t i=0; i<ranges.size()-1; i++) {
+		if (ranges[i].Empty()) {
+			size_t j=i+1;
+			while (j<ranges.size()) {
+				if (ranges[i] == ranges[j]) {
+					ranges.erase(ranges.begin() + j);
+					if (mainRange >= j)
+						mainRange--;
+				} else {
+					j++;
+				}
+			}
+		}
+	}
+}
+
+void Selection::RotateMain() {
+	mainRange = (mainRange + 1) % ranges.size();
+}
+
diff --git a/plugins/scintilla/scintilla/Selection.h b/plugins/scintilla/scintilla/Selection.h
new file mode 100644
index 0000000..c18e5c0
--- /dev/null
+++ b/plugins/scintilla/scintilla/Selection.h
@@ -0,0 +1,170 @@
+// Scintilla source code edit control
+/** @file Selection.h
+ ** Classes maintaining the selection.
+ **/
+// Copyright 2009 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef SELECTION_H
+#define SELECTION_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class SelectionPosition {
+	int position;
+	int virtualSpace;
+public:
+	explicit SelectionPosition(int position_=INVALID_POSITION, int virtualSpace_=0) : position(position_), virtualSpace(virtualSpace_) {
+		PLATFORM_ASSERT(virtualSpace < 800000);
+		if (virtualSpace < 0)
+			virtualSpace = 0;
+	}
+	void Reset() {
+		position = 0;
+		virtualSpace = 0;
+	}
+	void MoveForInsertDelete(bool insertion, int startChange, int length);
+	bool operator ==(const SelectionPosition &other) const {
+		return position == other.position && virtualSpace == other.virtualSpace;
+	}
+	bool operator <(const SelectionPosition &other) const;
+	bool operator >(const SelectionPosition &other) const;
+	bool operator <=(const SelectionPosition &other) const;
+	bool operator >=(const SelectionPosition &other) const;
+	int Position() const {
+		return position;
+	}
+	void SetPosition(int position_) {
+		position = position_;
+		virtualSpace = 0;
+	}
+	int VirtualSpace() const {
+		return virtualSpace;
+	}
+	void SetVirtualSpace(int virtualSpace_) {
+		PLATFORM_ASSERT(virtualSpace_ < 800000);
+		if (virtualSpace_ >= 0)
+			virtualSpace = virtualSpace_;
+	}
+	void Add(int increment) {
+		position = position + increment;
+	}
+	bool IsValid() const {
+		return position >= 0;
+	}
+};
+
+// Ordered range to make drawing simpler
+struct SelectionSegment {	
+	SelectionPosition start;
+	SelectionPosition end;
+	SelectionSegment() {
+	}
+	SelectionSegment(SelectionPosition a, SelectionPosition b) {
+		if (a < b) {
+			start = a;
+			end = b;
+		} else {
+			start = b;
+			end = a;
+		}
+	}
+	bool Empty() const {
+		return start == end;
+	}
+};
+
+struct SelectionRange {
+	SelectionPosition caret;
+	SelectionPosition anchor;
+
+	SelectionRange() {
+	}
+	SelectionRange(SelectionPosition single) : caret(single), anchor(single) {
+	}
+	SelectionRange(int single) : caret(single), anchor(single) {
+	}
+	SelectionRange(SelectionPosition caret_, SelectionPosition anchor_) : caret(caret_), anchor(anchor_) {
+	}
+	SelectionRange(int caret_, int anchor_) : caret(caret_), anchor(anchor_) {
+	}
+	bool Empty() const {
+		return anchor == caret;
+	}
+	int Length() const;
+	// int Width() const;	// Like Length but takes virtual space into account
+	bool operator ==(const SelectionRange &other) const {
+		return caret == other.caret && anchor == other.anchor;
+	}
+	void Reset() {
+		anchor.Reset();
+		caret.Reset();
+	}
+	void ClearVirtualSpace() {
+		anchor.SetVirtualSpace(0);
+		caret.SetVirtualSpace(0);
+	}
+	bool Contains(int pos) const;
+	bool Contains(SelectionPosition sp) const;
+	bool ContainsCharacter(int posCharacter) const;
+	SelectionSegment Intersect(SelectionSegment check) const;
+	SelectionPosition Start() const {
+		return (anchor < caret) ? anchor : caret;
+	}
+	SelectionPosition End() const {
+		return (anchor < caret) ? caret : anchor;
+	}
+	bool Trim(SelectionRange range);
+	// If range is all virtual collapse to start of virtual space
+	void MinimizeVirtualSpace();
+};
+
+class Selection {
+	std::vector<SelectionRange> ranges;
+	std::vector<SelectionRange> rangesSaved;
+	SelectionRange rangeRectangular;
+	size_t mainRange;
+	bool moveExtends;
+	bool tentativeMain;
+public:
+	enum selTypes { noSel, selStream, selRectangle, selLines, selThin };
+	selTypes selType;
+
+	Selection();
+	~Selection();
+	bool IsRectangular() const;
+	int MainCaret() const;
+	int MainAnchor() const;
+	SelectionRange &Rectangular();
+	size_t Count() const;
+	size_t Main() const;
+	void SetMain(size_t r);
+	SelectionRange &Range(size_t r);
+	SelectionRange &RangeMain();
+	bool MoveExtends() const;
+	void SetMoveExtends(bool moveExtends_);
+	bool Empty() const;
+	SelectionPosition Last() const;
+	int Length() const;
+	void MovePositions(bool insertion, int startChange, int length);
+	void TrimSelection(SelectionRange range);
+	void SetSelection(SelectionRange range);
+	void AddSelection(SelectionRange range);
+	void TentativeSelection(SelectionRange range);
+	void CommitTentative();
+	int CharacterInSelection(int posCharacter) const;
+	int InSelectionForEOL(int pos) const;
+	int VirtualSpaceFor(int pos) const;
+	void Clear();
+	void RemoveDuplicates();
+	void RotateMain();
+	bool Tentative() const { return tentativeMain; }
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/SplitVector.h b/plugins/scintilla/scintilla/SplitVector.h
index 76f9a8f..af4e890 100644
--- a/plugins/scintilla/scintilla/SplitVector.h
+++ b/plugins/scintilla/scintilla/SplitVector.h
@@ -43,7 +43,7 @@ protected:
 	/// reallocating if more space needed.
 	void RoomFor(int insertionLength) {
 		if (gapLength <= insertionLength) {
-			if (growSize * 6 < size)
+			while (growSize < size / 6)
 				growSize *= 2;
 			ReAllocate(size + insertionLength + growSize);
 		}
diff --git a/plugins/scintilla/scintilla/UniConversion.cxx b/plugins/scintilla/scintilla/UniConversion.cxx
index 863eb82..7dbe9e2 100644
--- a/plugins/scintilla/scintilla/UniConversion.cxx
+++ b/plugins/scintilla/scintilla/UniConversion.cxx
@@ -48,7 +48,7 @@ void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned
 			i++;
 			unsigned int xch = 0x10000 + ((uch & 0x3ff) << 10) + (uptr[i] & 0x3ff);
 			putf[k++] = static_cast<char>(0xF0 | (xch >> 18));
-			putf[k++] = static_cast<char>(0x80 | (xch >> 12) & 0x3f);
+			putf[k++] = static_cast<char>(0x80 | ((xch >> 12) & 0x3f));
 			putf[k++] = static_cast<char>(0x80 | ((xch >> 6) & 0x3f));
 			putf[k++] = static_cast<char>(0x80 | (xch & 0x3f));
 		} else {
diff --git a/plugins/scintilla/scintilla/ViewStyle.cxx b/plugins/scintilla/scintilla/ViewStyle.cxx
index 15efea8..e162f72 100644
--- a/plugins/scintilla/scintilla/ViewStyle.cxx
+++ b/plugins/scintilla/scintilla/ViewStyle.cxx
@@ -92,10 +92,13 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
 
 	selforeset = source.selforeset;
 	selforeground.desired = source.selforeground.desired;
+	selAdditionalForeground.desired = source.selAdditionalForeground.desired;
 	selbackset = source.selbackset;
 	selbackground.desired = source.selbackground.desired;
+	selAdditionalBackground.desired = source.selAdditionalBackground.desired;
 	selbackground2.desired = source.selbackground2.desired;
 	selAlpha = source.selAlpha;
+	selAdditionalAlpha = source.selAdditionalAlpha;
 	selEOLFilled = source.selEOLFilled;
 
 	foldmarginColourSet = source.foldmarginColourSet;
@@ -117,6 +120,7 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
 	selbar.desired = source.selbar.desired;
 	selbarlight.desired = source.selbarlight.desired;
 	caretcolour.desired = source.caretcolour.desired;
+	additionalCaretColour.desired = source.additionalCaretColour.desired;
 	showCaretLineBackground = source.showCaretLineBackground;
 	caretLineBackground.desired = source.caretLineBackground.desired;
 	caretLineAlpha = source.caretLineAlpha;
@@ -139,6 +143,11 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
 	viewEOL = source.viewEOL;
 	showMarkedLines = source.showMarkedLines;
 	extraFontFlag = source.extraFontFlag;
+	extraAscent = source.extraAscent;
+	extraDescent = source.extraDescent;
+	marginStyleOffset = source.marginStyleOffset;
+	annotationVisible = source.annotationVisible;
+	annotationStyleOffset = source.annotationStyleOffset;
 }
 
 ViewStyle::~ViewStyle() {
@@ -171,10 +180,13 @@ void ViewStyle::Init(size_t stylesSize_) {
 
 	selforeset = false;
 	selforeground.desired = ColourDesired(0xff, 0, 0);
+	selAdditionalForeground.desired = ColourDesired(0xff, 0, 0);
 	selbackset = true;
 	selbackground.desired = ColourDesired(0xc0, 0xc0, 0xc0);
+	selAdditionalBackground.desired = ColourDesired(0xd7, 0xd7, 0xd7);
 	selbackground2.desired = ColourDesired(0xb0, 0xb0, 0xb0);
 	selAlpha = SC_ALPHA_NOALPHA;
+	selAdditionalAlpha = SC_ALPHA_NOALPHA;
 	selEOLFilled = false;
 
 	foldmarginColourSet = false;
@@ -191,6 +203,7 @@ void ViewStyle::Init(size_t stylesSize_) {
 	styles[STYLE_LINENUMBER].fore.desired = ColourDesired(0, 0, 0);
 	styles[STYLE_LINENUMBER].back.desired = Platform::Chrome();
 	caretcolour.desired = ColourDesired(0, 0, 0);
+	additionalCaretColour.desired = ColourDesired(0x7f, 0x7f, 0x7f);
 	showCaretLineBackground = false;
 	caretLineBackground.desired = ColourDesired(0xff, 0xff, 0);
 	caretLineAlpha = SC_ALPHA_NOALPHA;
@@ -233,6 +246,11 @@ void ViewStyle::Init(size_t stylesSize_) {
 	viewEOL = false;
 	showMarkedLines = true;
 	extraFontFlag = false;
+	extraAscent = 0;
+	extraDescent = 0;
+	marginStyleOffset = 0;
+	annotationVisible = ANNOTATION_HIDDEN;
+	annotationStyleOffset = 0;
 }
 
 void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
@@ -248,7 +266,9 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
 		markers[i].RefreshColourPalette(pal, want);
 	}
 	pal.WantFind(selforeground, want);
+	pal.WantFind(selAdditionalForeground, want);
 	pal.WantFind(selbackground, want);
+	pal.WantFind(selAdditionalBackground, want);
 	pal.WantFind(selbackground2, want);
 
 	pal.WantFind(foldmarginColour, want);
@@ -259,6 +279,7 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
 	pal.WantFind(selbar, want);
 	pal.WantFind(selbarlight, want);
 	pal.WantFind(caretcolour, want);
+	pal.WantFind(additionalCaretColour, want);
 	pal.WantFind(caretLineBackground, want);
 	pal.WantFind(edgecolour, want);
 	pal.WantFind(hotspotForeground, want);
@@ -284,6 +305,8 @@ void ViewStyle::Refresh(Surface &surface) {
 			someStylesProtected = true;
 		}
 	}
+	maxAscent += extraAscent;
+	maxDescent += extraDescent;
 
 	lineHeight = maxAscent + maxDescent;
 	aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
@@ -322,7 +345,7 @@ void ViewStyle::AllocStyles(size_t sizeNew) {
 void ViewStyle::EnsureStyle(size_t index) {
 	if (index >= stylesSize) {
 		size_t sizeNew = stylesSize * 2;
-		while (sizeNew < index)
+		while (sizeNew <= index)
 			sizeNew *= 2;
 		AllocStyles(sizeNew);
 	}
@@ -357,3 +380,8 @@ void ViewStyle::SetStyleFontName(int styleIndex, const char *name) {
 bool ViewStyle::ProtectionActive() const {
 	return someStylesProtected;
 }
+
+bool ViewStyle::ValidStyle(size_t styleIndex) const {
+	return styleIndex < stylesSize;
+}
+
diff --git a/plugins/scintilla/scintilla/ViewStyle.h b/plugins/scintilla/scintilla/ViewStyle.h
index 2f2d524..fe17a0a 100644
--- a/plugins/scintilla/scintilla/ViewStyle.h
+++ b/plugins/scintilla/scintilla/ViewStyle.h
@@ -58,10 +58,13 @@ public:
 	unsigned int spaceWidth;
 	bool selforeset;
 	ColourPair selforeground;
+	ColourPair selAdditionalForeground;
 	bool selbackset;
 	ColourPair selbackground;
+	ColourPair selAdditionalBackground;
 	ColourPair selbackground2;
 	int selAlpha;
+	int selAdditionalAlpha;
 	bool selEOLFilled;
 	bool whitespaceForegroundSet;
 	ColourPair whitespaceForeground;
@@ -93,6 +96,7 @@ public:
 	bool viewEOL;
 	bool showMarkedLines;
 	ColourPair caretcolour;
+	ColourPair additionalCaretColour;
 	bool showCaretLineBackground;
 	ColourPair caretLineBackground;
 	int caretLineAlpha;
@@ -102,6 +106,11 @@ public:
 	int caretWidth;
 	bool someStylesProtected;
 	bool extraFontFlag;
+	int extraAscent;
+	int extraDescent;
+	int marginStyleOffset;
+	int annotationVisible;
+	int annotationStyleOffset;
 
 	ViewStyle();
 	ViewStyle(const ViewStyle &source);
@@ -115,6 +124,7 @@ public:
 	void ClearStyles();
 	void SetStyleFontName(int styleIndex, const char *name);
 	bool ProtectionActive() const;
+	bool ValidStyle(size_t styleIndex) const;
 };
 
 #ifdef SCI_NAMESPACE
diff --git a/plugins/scintilla/scintilla/WindowAccessor.cxx b/plugins/scintilla/scintilla/WindowAccessor.cxx
index 8093300..9de106f 100644
--- a/plugins/scintilla/scintilla/WindowAccessor.cxx
+++ b/plugins/scintilla/scintilla/WindowAccessor.cxx
@@ -45,7 +45,7 @@ void WindowAccessor::Fill(int position) {
 	if (endPos > lenDoc)
 		endPos = lenDoc;
 
-	TextRange tr = {{startPos, endPos}, buf};
+	Sci_TextRange tr = {{startPos, endPos}, buf};
 	Platform::SendScintillaPointer(id, SCI_GETTEXTRANGE, 0, &tr);
 }
 
diff --git a/plugins/scintilla/scintilla/XPM.h b/plugins/scintilla/scintilla/XPM.h
index 0ee68c0..07cb580 100755
--- a/plugins/scintilla/scintilla/XPM.h
+++ b/plugins/scintilla/scintilla/XPM.h
@@ -16,7 +16,7 @@ namespace Scintilla {
  * Hold a pixmap in XPM format.
  */
 class XPM {
-	int id;		// Assigned by container
+	int pid;		// Assigned by container
 	int height;
 	int width;
 	int nColours;
@@ -42,8 +42,8 @@ public:
 	/// Decompose image into runs and use FillRectangle for each run
 	void Draw(Surface *surface, PRectangle &rc);
 	char **InLinesForm() { return lines; }
-	void SetId(int id_) { id = id_; }
-	int GetId() { return id; }
+	void SetId(int pid_) { pid = pid_; }
+	int GetId() { return pid; }
 	int GetHeight() { return height; }
 	int GetWidth() { return width; }
 	static const char **LinesFormFromTextForm(const char *textForm);
diff --git a/plugins/scintilla/scintilla/include/Face.py b/plugins/scintilla/scintilla/include/Face.py
index 08ac7a9..52c9b8d 100755
--- a/plugins/scintilla/scintilla/include/Face.py
+++ b/plugins/scintilla/scintilla/include/Face.py
@@ -1,36 +1,35 @@
 # Module for reading and parsing Scintilla.iface file
-import string
 
 def sanitiseLine(line):
 	if line[-1:] == '\n': line = line[:-1]
-	if string.find(line, "##") != -1:
-		line = line[:string.find(line, "##")]
-	line = string.strip(line)
+	if line.find("##") != -1:
+		line = line[:line.find("##")]
+	line = line.strip()
 	return line
 	
 def decodeFunction(featureVal):
-	retType, rest = string.split(featureVal, " ", 1)
-	nameIdent, params = string.split(rest, "(")
-	name, value = string.split(nameIdent, "=")
-	params, rest = string.split(params, ")")
-	param1, param2 = string.split(params, ",")[0:2]
+	retType, rest = featureVal.split(" ", 1)
+	nameIdent, params = rest.split("(")
+	name, value = nameIdent.split("=")
+	params, rest = params.split(")")
+	param1, param2 = params.split(",")[0:2]
 	return retType, name, value, param1, param2
 	
 def decodeEvent(featureVal):
-	retType, rest = string.split(featureVal, " ", 1)
-	nameIdent, params = string.split(rest, "(")
-	name, value = string.split(nameIdent, "=")
+	retType, rest = featureVal.split(" ", 1)
+	nameIdent, params = rest.split("(")
+	name, value = nameIdent.split("=")
 	return retType, name, value
 	
 def decodeParam(p):
-	param = string.strip(p)
+	param = p.strip()
 	type = ""
 	name = ""
 	value = ""
 	if " " in param:
-		type, nv = string.split(param, " ")
+		type, nv = param.split(" ")
 		if "=" in nv:
-			name, value = string.split(nv, "=")
+			name, value = nv.split("=")
 		else:
 			name = nv
 	return type, name, value
@@ -59,7 +58,7 @@ class Face:
 						currentComment.append(line[2:])
 				else:
 					currentCommentFinished = 1
-					featureType, featureVal = string.split(line, " ", 1)
+					featureType, featureVal = line.split(" ", 1)
 					if featureType in ["fun", "get", "set"]:
 						retType, name, value, param1, param2 = decodeFunction(featureVal)
 						p1 = decodeParam(param1)
@@ -72,7 +71,7 @@ class Face:
 							"Param2Type": p2[0],	"Param2Name": p2[1], "Param2Value": p2[2],
 							"Category": currentCategory, "Comment": currentComment
 						}
-						if self.values.has_key(value):
+						if value in self.values:
 							raise "Duplicate value " + value + " " + name
 						self.values[value] = 1
 						self.order.append(name)
@@ -84,21 +83,25 @@ class Face:
 							"Value": value, 
 							"Category": currentCategory, "Comment": currentComment
 						}
-						if self.events.has_key(value):
+						if value in self.events:
 							raise "Duplicate event " + value + " " + name
 						self.events[value] = 1
 						self.order.append(name)
 					elif featureType == "cat":
 						currentCategory = featureVal
 					elif featureType == "val":
-						name, value = string.split(featureVal, "=", 1)
+						try:
+							name, value = featureVal.split("=", 1)
+						except ValueError:
+							print("Failure %s" % featureVal)
+							raise
 						self.features[name] = { 
 							"FeatureType": featureType, 
 							"Category": currentCategory, 
 							"Value": value }
 						self.order.append(name)
 					elif featureType == "enu" or featureType == "lex":
-						name, value = string.split(featureVal, "=", 1)
+						name, value = featureVal.split("=", 1)
 						self.features[name] = { 
 							"FeatureType": featureType, 
 							"Category": currentCategory, 
diff --git a/plugins/scintilla/scintilla/include/HFacer.py b/plugins/scintilla/scintilla/include/HFacer.py
index b3c8c28..62a8273 100755
--- a/plugins/scintilla/scintilla/include/HFacer.py
+++ b/plugins/scintilla/scintilla/include/HFacer.py
@@ -1,16 +1,15 @@
 # HFacer.py - regenerate the Scintilla.h and SciLexer.h files from the Scintilla.iface interface
 # definition file.
-# The header files are copied to a temporary file apart from the section between a //++Autogenerated
-# comment and a //--Autogenerated comment which is generated by the printHFile and printLexHFile
+# The header files are copied to a temporary file apart from the section between a /* ++Autogenerated*/
+# comment and a /* --Autogenerated*/ comment which is generated by the printHFile and printLexHFile
 # functions. After the temporary file is created, it is copied back to the original file name.
 
-import string
 import sys
 import os
 import Face
 
 def Contains(s,sub):
-	return string.find(s, sub) != -1
+	return s.find(sub) != -1
 
 def printLexHFile(f,out):
 	for name in f.order:
@@ -24,10 +23,10 @@ def printHFile(f,out):
 		v = f.features[name]
 		if v["Category"] != "Deprecated":
 			if v["FeatureType"] in ["fun", "get", "set"]:
-				featureDefineName = "SCI_" + string.upper(name)
+				featureDefineName = "SCI_" + name.upper()
 				out.write("#define " + featureDefineName + " " + v["Value"] + "\n")
 			elif v["FeatureType"] in ["evt"]:
-				featureDefineName = "SCN_" + string.upper(name)
+				featureDefineName = "SCN_" + name.upper()
 				out.write("#define " + featureDefineName + " " + v["Value"] + "\n")
 			elif v["FeatureType"] in ["val"]:
 				if not (Contains(name, "SCE_") or Contains(name, "SCLEX_")):
@@ -38,15 +37,15 @@ def CopyWithInsertion(input, output, genfn, definition):
 	for line in input.readlines():
 		if copying:
 			output.write(line)
-		if Contains(line, "//++Autogenerated"):
+		if Contains(line, "/* ++Autogenerated"):
 			copying = 0
 			genfn(definition, output)
-		if Contains(line, "//--Autogenerated"):
+		if Contains(line, "/* --Autogenerated"):
 			copying = 1
 			output.write(line)
 
 def contents(filename):
-	f = file(filename)
+	f = open(filename)
 	t = f.read()
 	f.close()
 	return t
@@ -71,6 +70,6 @@ try:
 	f.ReadFromFile("Scintilla.iface")
 	Regenerate("Scintilla.h", printHFile, f)
 	Regenerate("SciLexer.h", printLexHFile, f)
-	print "Maximum ID is", max([x for x in f.values if int(x) < 3000])
+	print("Maximum ID is %s" % max([x for x in f.values if int(x) < 3000]))
 except:
 	raise
diff --git a/plugins/scintilla/scintilla/include/KeyWords.h b/plugins/scintilla/scintilla/include/KeyWords.h
index 6abae59..5593b7d 100644
--- a/plugins/scintilla/scintilla/include/KeyWords.h
+++ b/plugins/scintilla/scintilla/include/KeyWords.h
@@ -9,6 +9,29 @@
 namespace Scintilla {
 #endif
 
+/**
+ */
+class WordList {
+public:
+	// Each word contains at least one character - a empty word acts as sentinel at the end.
+	char **words;
+	char *list;
+	int len;
+	bool onlyLineEnds;	///< Delimited by any white space or only line ends
+	bool sorted;
+	int starts[256];
+	WordList(bool onlyLineEnds_ = false) :
+		words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_),
+		sorted(false)
+		{}
+	~WordList() { Clear(); }
+	operator bool() { return len ? true : false; }
+	void Clear();
+	void Set(const char *s);
+	bool InList(const char *s);
+	bool InListAbbreviated(const char *s, const char marker);
+};
+
 typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
                   WordList *keywordlists[], Accessor &styler);
                   
diff --git a/plugins/scintilla/scintilla/include/Platform.h b/plugins/scintilla/scintilla/include/Platform.h
index 98fd7e0..1d4df48 100644
--- a/plugins/scintilla/scintilla/include/Platform.h
+++ b/plugins/scintilla/scintilla/include/Platform.h
@@ -3,7 +3,7 @@
  ** Interface to platform facilities. Also includes some basic utilities.
  ** Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows.
  **/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2009 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef PLATFORM_H
@@ -38,7 +38,8 @@
 #define PLAT_GTK_WIN32 1
 #endif
 
-#elif defined(MACOSX)
+#elif defined(__APPLE__)
+
 #undef PLAT_MACOSX
 #define PLAT_MACOSX 1
 
@@ -282,13 +283,13 @@ public:
  */
 class Font {
 protected:
-	FontID id;
+	FontID fid;
 #if PLAT_WX
 	int ascent;
 #endif
 	// Private so Font objects can not be copied
 	Font(const Font &) {}
-	Font &operator=(const Font &) { id=0; return *this; }
+	Font &operator=(const Font &) { fid=0; return *this; }
 public:
 	Font();
 	virtual ~Font();
@@ -297,9 +298,9 @@ public:
 		bool bold, bool italic, bool extraFontFlag=false);
 	virtual void Release();
 
-	FontID GetID() { return id; }
+	FontID GetID() { return fid; }
 	// Alias another font - caller guarantees not to Release
-	void SetID(FontID id_) { id = id_; }
+	void SetID(FontID fid_) { fid = fid_; }
 	friend class Surface;
         friend class SurfaceImpl;
 };
@@ -370,31 +371,31 @@ typedef void (*CallBackAction)(void*);
  */
 class Window {
 protected:
-	WindowID id;
+	WindowID wid;
 #if PLAT_MACOSX
 	void *windowRef;
 	void *control;
 #endif
 public:
-	Window() : id(0), cursorLast(cursorInvalid) {
+	Window() : wid(0), cursorLast(cursorInvalid) {
 #if PLAT_MACOSX
 	  windowRef = 0;
 	  control = 0;
 #endif
 	}
-	Window(const Window &source) : id(source.id), cursorLast(cursorInvalid) {
+	Window(const Window &source) : wid(source.wid), cursorLast(cursorInvalid) {
 #if PLAT_MACOSX
 	  windowRef = 0;
 	  control = 0;
 #endif
 	}
 	virtual ~Window();
-	Window &operator=(WindowID id_) {
-		id = id_;
+	Window &operator=(WindowID wid_) {
+		wid = wid_;
 		return *this;
 	}
-	WindowID GetID() const { return id; }
-	bool Created() const { return id != 0; }
+	WindowID GetID() const { return wid; }
+	bool Created() const { return wid != 0; }
 	void Destroy();
 	bool HasFocus();
 	PRectangle GetPosition();
@@ -451,10 +452,10 @@ public:
  * Menu management.
  */
 class Menu {
-	MenuID id;
+	MenuID mid;
 public:
 	Menu();
-	MenuID GetID() { return id; }
+	MenuID GetID() { return mid; }
 	void CreatePopUp();
 	void Destroy();
 	void Show(Point pt, Window &w);
diff --git a/plugins/scintilla/scintilla/include/PropSet.h b/plugins/scintilla/scintilla/include/PropSet.h
index 91bc707..c952021 100644
--- a/plugins/scintilla/scintilla/include/PropSet.h
+++ b/plugins/scintilla/scintilla/include/PropSet.h
@@ -1,104 +1,26 @@
 // Scintilla source code edit control
 /** @file PropSet.h
- ** A Java style properties file module.
+ ** An interface to the methods needed for access to property sets inside lexers.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2009 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef PROPSET_H
 #define PROPSET_H
-#include "SString.h"
-
-bool EqualCaseInsensitive(const char *a, const char *b);
-
-bool isprefix(const char *target, const char *prefix);
 
 #ifdef SCI_NAMESPACE
 namespace Scintilla {
 #endif
 
-struct Property {
-	unsigned int hash;
-	char *key;
-	char *val;
-	Property *next;
-	Property() : hash(0), key(0), val(0), next(0) {}
-};
-
-/**
- */
-class PropSet {
-protected:
-	enum { hashRoots=31 };
-	Property *props[hashRoots];
-	Property *enumnext;
-	int enumhash;
-	static unsigned int HashString(const char *s, size_t len) {
-		unsigned int ret = 0;
-		while (len--) {
-			ret <<= 4;
-			ret ^= *s;
-			s++;
-		}
-		return ret;
-	}
-
+class PropertyGet {
 public:
-	PropSet *superPS;
-	PropSet();
-	~PropSet();
-	void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1);
-	void Set(const char *keyVal);
-	void Unset(const char *key, int lenKey=-1);
-	void SetMultiple(const char *s);
-	SString Get(const char *key) const;
-	SString GetExpanded(const char *key) const;
-	SString Expand(const char *withVars, int maxExpands=100) const;
-	int GetInt(const char *key, int defaultValue=0) const;
-	void Clear();
-	char *ToString() const;	// Caller must delete[] the return value
-
-private:
-	// copy-value semantics not implemented
-	PropSet(const PropSet &copy);
-	void operator=(const PropSet &assign);
+	virtual char *ToString() const=0;	// Caller must delete[] the return value
+	virtual int GetInt(const char *key, int defaultValue=0) const=0;
+	virtual ~PropertyGet() {}
 };
 
-/**
- */
-class WordList {
-public:
-	// Each word contains at least one character - a empty word acts as sentinel at the end.
-	char **words;
-	char *list;
-	int len;
-	bool onlyLineEnds;	///< Delimited by any white space or only line ends
-	bool sorted;
-	int starts[256];
-	WordList(bool onlyLineEnds_ = false) :
-		words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_),
-		sorted(false)
-		{}
-	~WordList() { Clear(); }
-	operator bool() { return len ? true : false; }
-	void Clear();
-	void Set(const char *s);
-	bool InList(const char *s);
-	bool InListAbbreviated(const char *s, const char marker);
-};
-
-inline bool IsAlphabetic(unsigned int ch) {
-	return ((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z'));
-}
-
 #ifdef SCI_NAMESPACE
 }
 #endif
 
-#ifdef _MSC_VER
-// Visual C++ doesn't like the private copy idiom for disabling
-// the default copy constructor and operator=, but it's fine.
-#pragma warning(disable: 4511 4512)
-#endif
-
 #endif
diff --git a/plugins/scintilla/scintilla/include/SciLexer.h b/plugins/scintilla/scintilla/include/SciLexer.h
index defd72c..e741ff4 100644
--- a/plugins/scintilla/scintilla/include/SciLexer.h
+++ b/plugins/scintilla/scintilla/include/SciLexer.h
@@ -1,19 +1,19 @@
-// Scintilla source code edit control
+/* Scintilla source code edit control */
 /** @file SciLexer.h
  ** Interface to the added lexer functions in the SciLexer version of the edit control.
  **/
-// Copyright 1998-2002 by Neil Hodgson <neilh scintilla org>
-// The License.txt file describes the conditions under which this software may be distributed.
+/* Copyright 1998-2002 by Neil Hodgson <neilh scintilla org>
+ * The License.txt file describes the conditions under which this software may be distributed. */
 
-// Most of this file is automatically generated from the Scintilla.iface interface definition
-// file which contains any comments about the definitions. HFacer.py does the generation.
+/* Most of this file is automatically generated from the Scintilla.iface interface definition
+ * file which contains any comments about the definitions. HFacer.py does the generation. */
 
 #ifndef SCILEXER_H
 #define SCILEXER_H
 
-// SciLexer features - not in standard Scintilla
+/* SciLexer features - not in standard Scintilla */
 
-//++Autogenerated -- start of section automatically generated from Scintilla.iface
+/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */
 #define SCLEX_CONTAINER 0
 #define SCLEX_NULL 1
 #define SCLEX_PYTHON 2
@@ -103,6 +103,13 @@
 #define SCLEX_POWERSHELL 88
 #define SCLEX_MYSQL 89
 #define SCLEX_PO 90
+#define SCLEX_TAL 91
+#define SCLEX_COBOL 92
+#define SCLEX_TACL 93
+#define SCLEX_SORCUS 94
+#define SCLEX_POWERPRO 95
+#define SCLEX_NIMROD 96
+#define SCLEX_SML 97
 #define SCLEX_AUTOMATIC 1000
 #define SCE_P_DEFAULT 0
 #define SCE_P_COMMENTLINE 1
@@ -158,6 +165,11 @@
 #define SCE_D_COMMENTLINEDOC 15
 #define SCE_D_COMMENTDOCKEYWORD 16
 #define SCE_D_COMMENTDOCKEYWORDERROR 17
+#define SCE_D_STRINGB 18
+#define SCE_D_STRINGR 19
+#define SCE_D_WORD5 20
+#define SCE_D_WORD6 21
+#define SCE_D_WORD7 22
 #define SCE_TCL_DEFAULT 0
 #define SCE_TCL_COMMENT 1
 #define SCE_TCL_COMMENTLINE 2
@@ -926,6 +938,7 @@
 #define SCE_CAML_OPERATOR 7
 #define SCE_CAML_NUMBER 8
 #define SCE_CAML_CHAR 9
+#define SCE_CAML_WHITE 10
 #define SCE_CAML_STRING 11
 #define SCE_CAML_COMMENT 12
 #define SCE_CAML_COMMENT1 13
@@ -1084,6 +1097,7 @@
 #define SCE_INNO_SECTION 4
 #define SCE_INNO_PREPROC 5
 #define SCE_INNO_PREPROC_INLINE 6
+#define SCE_INNO_INLINE_EXPANSION 6
 #define SCE_INNO_COMMENT_PASCAL 7
 #define SCE_INNO_KEYWORD_PASCAL 8
 #define SCE_INNO_KEYWORD_USER 9
@@ -1262,6 +1276,7 @@
 #define SCE_MYSQL_USER1 18
 #define SCE_MYSQL_USER2 19
 #define SCE_MYSQL_USER3 20
+#define SCE_MYSQL_HIDDENCOMMAND 21
 #define SCE_PO_DEFAULT 0
 #define SCE_PO_COMMENT 1
 #define SCE_PO_MSGID 2
@@ -1271,8 +1286,63 @@
 #define SCE_PO_MSGCTXT 6
 #define SCE_PO_MSGCTXT_TEXT 7
 #define SCE_PO_FUZZY 8
-#define SCLEX_ASP 29
-#define SCLEX_PHP 30
-//--Autogenerated -- end of section automatically generated from Scintilla.iface
+#define SCE_PAS_DEFAULT 0
+#define SCE_PAS_IDENTIFIER 1
+#define SCE_PAS_COMMENT 2
+#define SCE_PAS_COMMENT2 3
+#define SCE_PAS_COMMENTLINE 4
+#define SCE_PAS_PREPROCESSOR 5
+#define SCE_PAS_PREPROCESSOR2 6
+#define SCE_PAS_NUMBER 7
+#define SCE_PAS_HEXNUMBER 8
+#define SCE_PAS_WORD 9
+#define SCE_PAS_STRING 10
+#define SCE_PAS_STRINGEOL 11
+#define SCE_PAS_CHARACTER 12
+#define SCE_PAS_OPERATOR 13
+#define SCE_PAS_ASM 14
+#define SCE_SORCUS_DEFAULT 0
+#define SCE_SORCUS_COMMAND 1
+#define SCE_SORCUS_PARAMETER 2
+#define SCE_SORCUS_COMMENTLINE 3
+#define SCE_SORCUS_STRING 4
+#define SCE_SORCUS_STRINGEOL 5
+#define SCE_SORCUS_IDENTIFIER 6
+#define SCE_SORCUS_OPERATOR 7
+#define SCE_SORCUS_NUMBER 8
+#define SCE_SORCUS_CONSTANT 9
+#define SCE_POWERPRO_DEFAULT 0
+#define SCE_POWERPRO_COMMENTBLOCK 1
+#define SCE_POWERPRO_COMMENTLINE 2
+#define SCE_POWERPRO_NUMBER 3
+#define SCE_POWERPRO_WORD 4
+#define SCE_POWERPRO_WORD2 5
+#define SCE_POWERPRO_WORD3 6
+#define SCE_POWERPRO_WORD4 7
+#define SCE_POWERPRO_DOUBLEQUOTEDSTRING 8
+#define SCE_POWERPRO_SINGLEQUOTEDSTRING 9
+#define SCE_POWERPRO_LINECONTINUE 10
+#define SCE_POWERPRO_OPERATOR 11
+#define SCE_POWERPRO_IDENTIFIER 12
+#define SCE_POWERPRO_STRINGEOL 13
+#define SCE_POWERPRO_VERBATIM 14
+#define SCE_POWERPRO_ALTQUOTE 15
+#define SCE_POWERPRO_FUNCTION 16
+#define SCE_SML_DEFAULT 0
+#define SCE_SML_IDENTIFIER 1
+#define SCE_SML_TAGNAME 2
+#define SCE_SML_KEYWORD 3
+#define SCE_SML_KEYWORD2 4
+#define SCE_SML_KEYWORD3 5
+#define SCE_SML_LINENUM 6
+#define SCE_SML_OPERATOR 7
+#define SCE_SML_NUMBER 8
+#define SCE_SML_CHAR 9
+#define SCE_SML_STRING 11
+#define SCE_SML_COMMENT 12
+#define SCE_SML_COMMENT1 13
+#define SCE_SML_COMMENT2 14
+#define SCE_SML_COMMENT3 15
+/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
 
 #endif
diff --git a/plugins/scintilla/scintilla/include/Scintilla.h b/plugins/scintilla/scintilla/include/Scintilla.h
index 14858fc..d300288 100644
--- a/plugins/scintilla/scintilla/include/Scintilla.h
+++ b/plugins/scintilla/scintilla/include/Scintilla.h
@@ -1,12 +1,12 @@
-// Scintilla source code edit control
+/* Scintilla source code edit control */
 /** @file Scintilla.h
  ** Interface to the edit control.
  **/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
-// The License.txt file describes the conditions under which this software may be distributed.
+/* Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+ * The License.txt file describes the conditions under which this software may be distributed. */
 
-// Most of this file is automatically generated from the Scintilla.iface interface definition
-// file which contains any comments about the definitions. HFacer.py does the generation.
+/* Most of this file is automatically generated from the Scintilla.iface interface definition
+ * file which contains any comments about the definitions. HFacer.py does the generation. */
 
 #ifndef SCINTILLA_H
 #define SCINTILLA_H
@@ -16,17 +16,17 @@ typedef BOOL bool;
 #endif
 
 #if PLAT_WIN
-// Return false on failure:
+/* Return false on failure: */
 bool Scintilla_RegisterClasses(void *hInstance);
 bool Scintilla_ReleaseResources();
 #endif
 int Scintilla_LinkLexers();
 
-// Here should be placed typedefs for uptr_t, an unsigned integer type large enough to
-// hold a pointer and sptr_t, a signed integer large enough to hold a pointer.
-// May need to be changed for 64 bit platforms.
-#if _MSC_VER >= 1300
-#include <BaseTsd.h>
+/* Here should be placed typedefs for uptr_t, an unsigned integer type large enough to
+ * hold a pointer and sptr_t, a signed integer large enough to hold a pointer.
+ * May need to be changed for 64 bit platforms. */
+#if defined(_WIN32)
+#include <basetsd.h>
 #endif
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
@@ -44,7 +44,7 @@ typedef long sptr_t;
 
 typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam);
 
-//++Autogenerated -- start of section automatically generated from Scintilla.iface
+/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */
 #define INVALID_POSITION -1
 #define SCI_START 2000
 #define SCI_OPTIONAL_START 3000
@@ -125,6 +125,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_MARK_PIXMAP 25
 #define SC_MARK_FULLRECT 26
 #define SC_MARK_LEFTRECT 27
+#define SC_MARK_AVAILABLE 28
+#define SC_MARK_UNDERLINE 29
 #define SC_MARK_CHARACTER 10000
 #define SC_MARKNUM_FOLDEREND 25
 #define SC_MARKNUM_FOLDEROPENMID 26
@@ -150,6 +152,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_MARGIN_NUMBER 1
 #define SC_MARGIN_BACK 2
 #define SC_MARGIN_FORE 3
+#define SC_MARGIN_TEXT 4
+#define SC_MARGIN_RTEXT 5
 #define SCI_SETMARGINTYPEN 2240
 #define SCI_GETMARGINTYPEN 2241
 #define SCI_SETMARGINWIDTHN 2242
@@ -401,10 +405,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_FOLDLEVELBASE 0x400
 #define SC_FOLDLEVELWHITEFLAG 0x1000
 #define SC_FOLDLEVELHEADERFLAG 0x2000
-#define SC_FOLDLEVELBOXHEADERFLAG 0x4000
-#define SC_FOLDLEVELBOXFOOTERFLAG 0x8000
-#define SC_FOLDLEVELCONTRACTED 0x10000
-#define SC_FOLDLEVELUNINDENT 0x20000
 #define SC_FOLDLEVELNUMBERMASK 0x0FFF
 #define SCI_SETFOLDLEVEL 2222
 #define SCI_GETFOLDLEVEL 2223
@@ -422,7 +422,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_FOLDFLAG_LINEAFTER_EXPANDED 0x0008
 #define SC_FOLDFLAG_LINEAFTER_CONTRACTED 0x0010
 #define SC_FOLDFLAG_LEVELNUMBERS 0x0040
-#define SC_FOLDFLAG_BOX 0x0001
 #define SCI_SETFOLDFLAGS 2233
 #define SCI_ENSUREVISIBLEENFORCEPOLICY 2234
 #define SCI_SETTABINDENTS 2260
@@ -451,6 +450,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_GETWRAPVISUALFLAGSLOCATION 2463
 #define SCI_SETWRAPSTARTINDENT 2464
 #define SCI_GETWRAPSTARTINDENT 2465
+#define SC_WRAPINDENT_FIXED 0
+#define SC_WRAPINDENT_SAME 1
+#define SC_WRAPINDENT_INDENT 2
+#define SCI_SETWRAPINDENTMODE 2472
+#define SCI_GETWRAPINDENTMODE 2473
 #define SC_CACHE_NONE 0
 #define SC_CACHE_CARET 1
 #define SC_CACHE_PAGE 2
@@ -566,6 +570,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_GETMODEVENTMASK 2378
 #define SCI_SETFOCUS 2380
 #define SCI_GETFOCUS 2381
+#define SC_STATUS_OK 0
+#define SC_STATUS_FAILURE 1
+#define SC_STATUS_BADALLOC 2
 #define SCI_SETSTATUS 2382
 #define SCI_GETSTATUS 2383
 #define SCI_SETMOUSEDOWNCAPTURES 2384
@@ -616,6 +623,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_SEL_STREAM 0
 #define SC_SEL_RECTANGLE 1
 #define SC_SEL_LINES 2
+#define SC_SEL_THIN 3
 #define SCI_SETSELECTIONMODE 2422
 #define SCI_GETSELECTIONMODE 2423
 #define SCI_GETLINESELSTARTPOSITION 2424
@@ -677,6 +685,88 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_GETCHARACTERPOINTER 2520
 #define SCI_SETKEYSUNICODE 2521
 #define SCI_GETKEYSUNICODE 2522
+#define SCI_INDICSETALPHA 2523
+#define SCI_INDICGETALPHA 2524
+#define SCI_SETEXTRAASCENT 2525
+#define SCI_GETEXTRAASCENT 2526
+#define SCI_SETEXTRADESCENT 2527
+#define SCI_GETEXTRADESCENT 2528
+#define SCI_MARKERSYMBOLDEFINED 2529
+#define SCI_MARGINSETTEXT 2530
+#define SCI_MARGINGETTEXT 2531
+#define SCI_MARGINSETSTYLE 2532
+#define SCI_MARGINGETSTYLE 2533
+#define SCI_MARGINSETSTYLES 2534
+#define SCI_MARGINGETSTYLES 2535
+#define SCI_MARGINTEXTCLEARALL 2536
+#define SCI_MARGINSETSTYLEOFFSET 2537
+#define SCI_MARGINGETSTYLEOFFSET 2538
+#define SCI_ANNOTATIONSETTEXT 2540
+#define SCI_ANNOTATIONGETTEXT 2541
+#define SCI_ANNOTATIONSETSTYLE 2542
+#define SCI_ANNOTATIONGETSTYLE 2543
+#define SCI_ANNOTATIONSETSTYLES 2544
+#define SCI_ANNOTATIONGETSTYLES 2545
+#define SCI_ANNOTATIONGETLINES 2546
+#define SCI_ANNOTATIONCLEARALL 2547
+#define ANNOTATION_HIDDEN 0
+#define ANNOTATION_STANDARD 1
+#define ANNOTATION_BOXED 2
+#define SCI_ANNOTATIONSETVISIBLE 2548
+#define SCI_ANNOTATIONGETVISIBLE 2549
+#define SCI_ANNOTATIONSETSTYLEOFFSET 2550
+#define SCI_ANNOTATIONGETSTYLEOFFSET 2551
+#define UNDO_MAY_COALESCE 1
+#define SCI_ADDUNDOACTION 2560
+#define SCI_CHARPOSITIONFROMPOINT 2561
+#define SCI_CHARPOSITIONFROMPOINTCLOSE 2562
+#define SCI_SETMULTIPLESELECTION 2563
+#define SCI_GETMULTIPLESELECTION 2564
+#define SCI_SETADDITIONALSELECTIONTYPING 2565
+#define SCI_GETADDITIONALSELECTIONTYPING 2566
+#define SCI_SETADDITIONALCARETSBLINK 2567
+#define SCI_GETADDITIONALCARETSBLINK 2568
+#define SCI_GETSELECTIONS 2570
+#define SCI_CLEARSELECTIONS 2571
+#define SCI_SETSELECTION 2572
+#define SCI_ADDSELECTION 2573
+#define SCI_SETMAINSELECTION 2574
+#define SCI_GETMAINSELECTION 2575
+#define SCI_SETSELECTIONNCARET 2576
+#define SCI_GETSELECTIONNCARET 2577
+#define SCI_SETSELECTIONNANCHOR 2578
+#define SCI_GETSELECTIONNANCHOR 2579
+#define SCI_SETSELECTIONNCARETVIRTUALSPACE 2580
+#define SCI_GETSELECTIONNCARETVIRTUALSPACE 2581
+#define SCI_SETSELECTIONNANCHORVIRTUALSPACE 2582
+#define SCI_GETSELECTIONNANCHORVIRTUALSPACE 2583
+#define SCI_SETSELECTIONNSTART 2584
+#define SCI_GETSELECTIONNSTART 2585
+#define SCI_SETSELECTIONNEND 2586
+#define SCI_GETSELECTIONNEND 2587
+#define SCI_SETRECTANGULARSELECTIONCARET 2588
+#define SCI_GETRECTANGULARSELECTIONCARET 2589
+#define SCI_SETRECTANGULARSELECTIONANCHOR 2590
+#define SCI_GETRECTANGULARSELECTIONANCHOR 2591
+#define SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE 2592
+#define SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE 2593
+#define SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE 2594
+#define SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE 2595
+#define SCVS_NONE 0
+#define SCVS_RECTANGULARSELECTION 1
+#define SCVS_USERACCESSIBLE 2
+#define SCI_SETVIRTUALSPACEOPTIONS 2596
+#define SCI_GETVIRTUALSPACEOPTIONS 2597
+#define SCI_SETRECTANGULARSELECTIONMODIFIER 2598
+#define SCI_GETRECTANGULARSELECTIONMODIFIER 2599
+#define SCI_SETADDITIONALSELFORE 2600
+#define SCI_SETADDITIONALSELBACK 2601
+#define SCI_SETADDITIONALSELALPHA 2602
+#define SCI_GETADDITIONALSELALPHA 2603
+#define SCI_SETADDITIONALCARETFORE 2604
+#define SCI_GETADDITIONALCARETFORE 2605
+#define SCI_ROTATESELECTION 2606
+#define SCI_SWAPMAINANCHORCARET 2607
 #define SCI_STARTRECORD 3001
 #define SCI_STOPRECORD 3002
 #define SCI_SETLEXER 4001
@@ -707,7 +797,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_STARTACTION 0x2000
 #define SC_MOD_CHANGEINDICATOR 0x4000
 #define SC_MOD_CHANGELINESTATE 0x8000
-#define SC_MODEVENTMASKALL 0xFFFF
+#define SC_MOD_CHANGEMARGIN 0x10000
+#define SC_MOD_CHANGEANNOTATION 0x20000
+#define SC_MOD_CONTAINER 0x40000
+#define SC_MODEVENTMASKALL 0x7FFFF
 #define SCEN_CHANGE 768
 #define SCEN_SETFOCUS 512
 #define SCEN_KILLFOCUS 256
@@ -735,6 +828,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCMOD_SHIFT 1
 #define SCMOD_CTRL 2
 #define SCMOD_ALT 4
+#define SCMOD_SUPER 8
 #define SCN_STYLENEEDED 2000
 #define SCN_CHARADDED 2001
 #define SCN_SAVEPOINTREACHED 2002
@@ -760,95 +854,90 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCN_INDICATORCLICK 2023
 #define SCN_INDICATORRELEASE 2024
 #define SCN_AUTOCCANCELLED 2025
-//--Autogenerated -- end of section automatically generated from Scintilla.iface
+#define SCN_AUTOCCHARDELETED 2026
+/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
 
-// These structures are defined to be exactly the same shape as the Win32
-// CHARRANGE, TEXTRANGE, FINDTEXTEX, FORMATRANGE, and NMHDR structs.
-// So older code that treats Scintilla as a RichEdit will work.
+/* These structures are defined to be exactly the same shape as the Win32
+ * CHARRANGE, TEXTRANGE, FINDTEXTEX, FORMATRANGE, and NMHDR structs.
+ * So older code that treats Scintilla as a RichEdit will work. */
 
 #ifdef SCI_NAMESPACE
 namespace Scintilla {
 #endif
 
-struct CharacterRange {
+struct Sci_CharacterRange {
 	long cpMin;
 	long cpMax;
 };
 
-struct TextRange {
-	struct CharacterRange chrg;
+struct Sci_TextRange {
+	struct Sci_CharacterRange chrg;
 	char *lpstrText;
 };
 
-struct TextToFind {
-	struct CharacterRange chrg;
+struct Sci_TextToFind {
+	struct Sci_CharacterRange chrg;
 	char *lpstrText;
-	struct CharacterRange chrgText;
+	struct Sci_CharacterRange chrgText;
 };
 
+#define CharacterRange Sci_CharacterRange
+#define TextRange Sci_TextRange
+#define TextToFind Sci_TextToFind
+
 #ifdef PLATFORM_H
 
-// This structure is used in printing and requires some of the graphics types
-// from Platform.h.  Not needed by most client code.
+/* This structure is used in printing and requires some of the graphics types
+ * from Platform.h.  Not needed by most client code. */
 
-struct RangeToFormat {
+struct Sci_RangeToFormat {
 	SurfaceID hdc;
 	SurfaceID hdcTarget;
 	PRectangle rc;
 	PRectangle rcPage;
-	CharacterRange chrg;
+	Sci_CharacterRange chrg;
 };
 
+#define RangeToFormat Sci_RangeToFormat
+
 #endif
 
-struct NotifyHeader {
-	// Compatible with Windows NMHDR.
-	// hwndFrom is really an environment specific window handle or pointer
-	// but most clients of Scintilla.h do not have this type visible.
+struct Sci_NotifyHeader {
+	/* Compatible with Windows NMHDR.
+	 * hwndFrom is really an environment specific window handle or pointer
+	 * but most clients of Scintilla.h do not have this type visible. */
 	void *hwndFrom;
 	uptr_t idFrom;
 	unsigned int code;
 };
 
+#define NotifyHeader Sci_NotifyHeader
+
 struct SCNotification {
-	struct NotifyHeader nmhdr;
-	int position;	// SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND
-	int ch;		// SCN_CHARADDED, SCN_KEY
-	int modifiers;	// SCN_KEY
-	int modificationType;	// SCN_MODIFIED
-	const char *text;	// SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION
-	int length;		// SCN_MODIFIED
-	int linesAdded;	// SCN_MODIFIED
-	int message;	// SCN_MACRORECORD
-	uptr_t wParam;	// SCN_MACRORECORD
-	sptr_t lParam;	// SCN_MACRORECORD
-	int line;		// SCN_MODIFIED
-	int foldLevelNow;	// SCN_MODIFIED
-	int foldLevelPrev;	// SCN_MODIFIED
-	int margin;		// SCN_MARGINCLICK
-	int listType;	// SCN_USERLISTSELECTION
-	int x;			// SCN_DWELLSTART, SCN_DWELLEND
-	int y;		// SCN_DWELLSTART, SCN_DWELLEND
+	struct Sci_NotifyHeader nmhdr;
+	int position;	/* SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND */
+	int ch;		/* SCN_CHARADDED, SCN_KEY */
+	int modifiers;	/* SCN_KEY */
+	int modificationType;	/* SCN_MODIFIED */
+	const char *text;	/* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
+	int length;		/* SCN_MODIFIED */
+	int linesAdded;	/* SCN_MODIFIED */
+	int message;	/* SCN_MACRORECORD */
+	uptr_t wParam;	/* SCN_MACRORECORD */
+	sptr_t lParam;	/* SCN_MACRORECORD */
+	int line;		/* SCN_MODIFIED */
+	int foldLevelNow;	/* SCN_MODIFIED */
+	int foldLevelPrev;	/* SCN_MODIFIED */
+	int margin;		/* SCN_MARGINCLICK */
+	int listType;	/* SCN_USERLISTSELECTION */
+	int x;			/* SCN_DWELLSTART, SCN_DWELLEND */
+	int y;		/* SCN_DWELLSTART, SCN_DWELLEND */
+	int token;		/* SCN_MODIFIED with SC_MOD_CONTAINER */
+	int annotationLinesAdded;	/* SC_MOD_CHANGEANNOTATION */
 };
 
 #ifdef SCI_NAMESPACE
 }
 #endif
 
-// Deprecation section listing all API features that are deprecated and will
-// will be removed completely in a future version.
-// To enable these features define INCLUDE_DEPRECATED_FEATURES
-
-#ifdef INCLUDE_DEPRECATED_FEATURES
-
-#define SCI_SETCARETPOLICY 2369
-#define CARET_CENTER 0x02
-#define CARET_XEVEN 0x08
-#define CARET_XJUMPS 0x10
-
-#define SCN_POSCHANGED 2012
-#define SCN_CHECKBRACE 2007
-
-#endif
-
 #endif
diff --git a/plugins/scintilla/scintilla/include/Scintilla.iface b/plugins/scintilla/scintilla/include/Scintilla.iface
index 35daa64..d2682a1 100755
--- a/plugins/scintilla/scintilla/include/Scintilla.iface
+++ b/plugins/scintilla/scintilla/include/Scintilla.iface
@@ -269,6 +269,8 @@ val SC_MARK_ARROWS=24
 val SC_MARK_PIXMAP=25
 val SC_MARK_FULLRECT=26
 val SC_MARK_LEFTRECT=27
+val SC_MARK_AVAILABLE=28
+val SC_MARK_UNDERLINE=29
 
 val SC_MARK_CHARACTER=10000
 
@@ -325,6 +327,8 @@ val SC_MARGIN_SYMBOL=0
 val SC_MARGIN_NUMBER=1
 val SC_MARGIN_BACK=2
 val SC_MARGIN_FORE=3
+val SC_MARGIN_TEXT=4
+val SC_MARGIN_RTEXT=5
 
 # Set a margin to be either numeric or symbolic.
 set void SetMarginTypeN=2240(int margin, int marginType)
@@ -473,10 +477,10 @@ set void StyleSetCharacterSet=2066(int style, int characterSet)
 # Set a style to be a hotspot or not.
 set void StyleSetHotSpot=2409(int style, bool hotspot)
 
-# Set the foreground colour of the selection and whether to use this setting.
+# Set the foreground colour of the main and additional selections and whether to use this setting.
 fun void SetSelFore=2067(bool useSetting, colour fore)
 
-# Set the background colour of the selection and whether to use this setting.
+# Set the background colour of the main and additional selections and whether to use this setting.
 fun void SetSelBack=2068(bool useSetting, colour back)
 
 # Get the alpha of the selection.
@@ -1011,10 +1015,6 @@ enu FoldLevel=SC_FOLDLEVEL
 val SC_FOLDLEVELBASE=0x400
 val SC_FOLDLEVELWHITEFLAG=0x1000
 val SC_FOLDLEVELHEADERFLAG=0x2000
-val SC_FOLDLEVELBOXHEADERFLAG=0x4000
-val SC_FOLDLEVELBOXFOOTERFLAG=0x8000
-val SC_FOLDLEVELCONTRACTED=0x10000
-val SC_FOLDLEVELUNINDENT=0x20000
 val SC_FOLDLEVELNUMBERMASK=0x0FFF
 
 # Set the fold level of a line.
@@ -1058,7 +1058,6 @@ val SC_FOLDFLAG_LINEBEFORE_CONTRACTED=0x0004
 val SC_FOLDFLAG_LINEAFTER_EXPANDED=0x0008
 val SC_FOLDFLAG_LINEAFTER_CONTRACTED=0x0010
 val SC_FOLDFLAG_LEVELNUMBERS=0x0040
-val SC_FOLDFLAG_BOX=0x0001
 
 # Set some style options for folding.
 fun void SetFoldFlags=2233(int flags,)
@@ -1132,6 +1131,17 @@ set void SetWrapStartIndent=2464(int indent,)
 # Retrive the start indent for wrapped lines.
 get int GetWrapStartIndent=2465(,)
 
+enu WrapIndentMode=SC_WRAPINDENT_
+val SC_WRAPINDENT_FIXED=0
+val SC_WRAPINDENT_SAME=1
+val SC_WRAPINDENT_INDENT=2
+
+# Sets how wrapped sublines are placed. Default is fixed.
+set void SetWrapIndentMode=2472(int mode,)
+
+# Retrieve how wrapped sublines are placed. Default is fixed.
+get int GetWrapIndentMode=2473(,)
+
 enu LineCache=SC_CACHE_
 val SC_CACHE_NONE=0
 val SC_CACHE_CARET=1
@@ -1478,6 +1488,11 @@ set void SetFocus=2380(bool focus,)
 # Get internal focus flag.
 get bool GetFocus=2381(,)
 
+enu Status=SC_STATUS_
+val SC_STATUS_OK=0
+val SC_STATUS_FAILURE=1
+val SC_STATUS_BADALLOC=2
+
 # Change error status - 0 = OK.
 set void SetStatus=2382(int statusCode,)
 # Get error status.
@@ -1622,8 +1637,9 @@ enu SelectionMode=SC_SEL_
 val SC_SEL_STREAM=0
 val SC_SEL_RECTANGLE=1
 val SC_SEL_LINES=2
+val SC_SEL_THIN=3
 
-# Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE) or
+# Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE/SC_SEL_THIN) or
 # by lines (SC_SEL_LINES).
 set void SetSelectionMode=2422(int mode,)
 
@@ -1810,6 +1826,217 @@ set void SetKeysUnicode=2521(bool keysUnicode,)
 # Are keys always interpreted as Unicode?
 get bool GetKeysUnicode=2522(,)
 
+# Set the alpha fill colour of the given indicator.
+set void IndicSetAlpha=2523(int indicator, int alpha)
+
+# Get the alpha fill colour of the given indicator.
+get int IndicGetAlpha=2524(int indicator,)
+
+# Set extra ascent for each line
+set void SetExtraAscent=2525(int extraAscent,)
+
+# Get extra ascent for each line
+get int GetExtraAscent=2526(,)
+
+# Set extra descent for each line
+set void SetExtraDescent=2527(int extraDescent,)
+
+# Get extra descent for each line
+get int GetExtraDescent=2528(,)
+
+# Which symbol was defined for markerNumber with MarkerDefine
+fun int MarkerSymbolDefined=2529(int markerNumber,)
+
+# Set the text in the text margin for a line
+set void MarginSetText=2530(int line, string text)
+
+# Get the text in the text margin for a line
+get int MarginGetText=2531(int line, stringresult text)
+
+# Set the style number for the text margin for a line
+set void MarginSetStyle=2532(int line, int style)
+
+# Get the style number for the text margin for a line
+get int MarginGetStyle=2533(int line,)
+
+# Set the style in the text margin for a line
+set void MarginSetStyles=2534(int line, string styles)
+
+# Get the styles in the text margin for a line
+get int MarginGetStyles=2535(int line, stringresult styles)
+
+# Clear the margin text on all lines
+fun void MarginTextClearAll=2536(,)
+
+# Get the start of the range of style numbers used for margin text
+set void MarginSetStyleOffset=2537(int style,)
+
+# Get the start of the range of style numbers used for margin text
+get int MarginGetStyleOffset=2538(,)
+
+# Set the annotation text for a line
+set void AnnotationSetText=2540(int line, string text)
+
+# Get the annotation text for a line
+get int AnnotationGetText=2541(int line, stringresult text)
+
+# Set the style number for the annotations for a line
+set void AnnotationSetStyle=2542(int line, int style)
+
+# Get the style number for the annotations for a line
+get int AnnotationGetStyle=2543(int line,)
+
+# Set the annotation styles for a line
+set void AnnotationSetStyles=2544(int line, string styles)
+
+# Get the annotation styles for a line
+get int AnnotationGetStyles=2545(int line, stringresult styles)
+
+# Get the number of annotation lines for a line
+get int AnnotationGetLines=2546(int line,)
+
+# Clear the annotations from all lines
+fun void AnnotationClearAll=2547(,)
+
+enu AnnotationVisible=ANNOTATION_
+val ANNOTATION_HIDDEN=0
+val ANNOTATION_STANDARD=1
+val ANNOTATION_BOXED=2
+
+# Set the visibility for the annotations for a view
+set void AnnotationSetVisible=2548(int visible,)
+
+# Get the visibility for the annotations for a view
+get int AnnotationGetVisible=2549(,)
+
+# Get the start of the range of style numbers used for annotations
+set void AnnotationSetStyleOffset=2550(int style,)
+
+# Get the start of the range of style numbers used for annotations
+get int AnnotationGetStyleOffset=2551(,)
+
+val UNDO_MAY_COALESCE=1
+
+# Add a container action to the undo stack
+fun void AddUndoAction=2560(int token, int flags)
+
+# Find the position of a character from a point within the window.
+fun position CharPositionFromPoint=2561(int x, int y)
+
+# Find the position of a character from a point within the window.
+# Return INVALID_POSITION if not close to text.
+fun position CharPositionFromPointClose=2562(int x, int y)
+
+# Set whether multiple selections can be made
+set void SetMultipleSelection=2563(bool multipleSelection,)
+
+# Whether multiple selections can be made
+get bool GetMultipleSelection=2564(,)
+
+# Set whether typing can be performed into multiple selections
+set void SetAdditionalSelectionTyping=2565(bool additionalSelectionTyping,)
+
+# Whether typing can be performed into multiple selections
+get bool GetAdditionalSelectionTyping=2566(,)
+
+# Set whether additional carets will blink
+set void SetAdditionalCaretsBlink=2567(bool additionalCaretsBlink,)
+
+# Whether additional carets will blink
+get bool GetAdditionalCaretsBlink=2568(,)
+
+# How many selections are there?
+get int GetSelections=2570(,)
+
+# Clear selections to a single empty stream selection
+fun void ClearSelections=2571(,)
+
+# Set a simple selection
+fun int SetSelection=2572(int caret,int anchor)
+
+# Add a selection
+fun int AddSelection=2573(int caret,int anchor)
+
+# Set the main selection
+set void SetMainSelection=2574(int selection,)
+
+# Which selection is the main selection
+get int GetMainSelection=2575(,)
+
+set void SetSelectionNCaret=2576(int selection, position pos)
+get position GetSelectionNCaret=2577(int selection,)
+set void SetSelectionNAnchor=2578(int selection, position posAnchor)
+get position GetSelectionNAnchor=2579(int selection,)
+set void SetSelectionNCaretVirtualSpace=2580(int selection, int space)
+get int GetSelectionNCaretVirtualSpace=2581(int selection,)
+set void SetSelectionNAnchorVirtualSpace=2582(int selection, int space)
+get int GetSelectionNAnchorVirtualSpace=2583(int selection,)
+
+# Sets the position that starts the selection - this becomes the anchor.
+set void SetSelectionNStart=2584(int selection, position pos)
+
+# Returns the position at the start of the selection.
+get position GetSelectionNStart=2585(,)
+
+# Sets the position that ends the selection - this becomes the currentPosition.
+set void SetSelectionNEnd=2586(int selection, position pos,)
+
+# Returns the position at the end of the selection.
+get position GetSelectionNEnd=2587(,)
+
+set void SetRectangularSelectionCaret=2588(position pos,)
+get position GetRectangularSelectionCaret=2589(,)
+set void SetRectangularSelectionAnchor=2590(position posAnchor,)
+get position GetRectangularSelectionAnchor=2591(,)
+set void SetRectangularSelectionCaretVirtualSpace=2592(int space,)
+get int GetRectangularSelectionCaretVirtualSpace=2593(,)
+set void SetRectangularSelectionAnchorVirtualSpace=2594(int space,)
+get int GetRectangularSelectionAnchorVirtualSpace=2595(,)
+
+enu VirtualSpace=SCVS_
+val SCVS_NONE=0
+val SCVS_RECTANGULARSELECTION=1
+val SCVS_USERACCESSIBLE=2
+
+set void SetVirtualSpaceOptions=2596(int virtualSpaceOptions,)
+get int GetVirtualSpaceOptions=2597(,)
+
+# On GTK+, allow selecting the modifier key to use for mouse-based
+# rectangular selection. Often the window manager requires Alt+Mouse Drag
+# for moving windows.
+# Valid values are SCMOD_CTRL(default), SCMOD_ALT, or SCMOD_SUPER.
+
+set void SetRectangularSelectionModifier=2598(int modifier,)
+
+# Get the modifier key used for rectangular selection.
+get int GetRectangularSelectionModifier=2599(,)
+
+# Set the foreground colour of additional selections.
+# Must have previously called SetSelFore with non-zero first argument for this to have an effect.
+set void SetAdditionalSelFore=2600(colour fore,)
+
+# Set the background colour of additional selections.
+# Must have previously called SetSelBack with non-zero first argument for this to have an effect.
+set void SetAdditionalSelBack=2601(colour back,)
+
+# Set the alpha of the selection.
+set void SetAdditionalSelAlpha=2602(int alpha,)
+
+# Get the alpha of the selection.
+get int GetAdditionalSelAlpha=2603(,)
+
+# Set the foreground colour of additional carets.
+set void SetAdditionalCaretFore=2604(colour fore,)
+
+# Get the foreground colour of additional carets.
+get colour GetAdditionalCaretFore=2605(,)
+
+# Set the main selection to the next selection.
+fun void RotateSelection=2606(,)
+
+# Swap that caret and anchor of the main selection.
+fun void SwapMainAnchorCaret=2607(,)
+
 # Start notifying the container of all key presses and commands.
 fun void StartRecord=3001(,)
 
@@ -1875,7 +2102,10 @@ val SC_MULTILINEUNDOREDO=0x1000
 val SC_STARTACTION=0x2000
 val SC_MOD_CHANGEINDICATOR=0x4000
 val SC_MOD_CHANGELINESTATE=0x8000
-val SC_MODEVENTMASKALL=0xFFFF
+val SC_MOD_CHANGEMARGIN=0x10000
+val SC_MOD_CHANGEANNOTATION=0x20000
+val SC_MOD_CONTAINER=0x40000
+val SC_MODEVENTMASKALL=0x7FFFF
 
 # For compatibility, these go through the COMMAND notification rather than NOTIFY
 # and should have had exactly the same values as the EN_* constants.
@@ -1916,6 +2146,7 @@ val SCMOD_NORM=0
 val SCMOD_SHIFT=1
 val SCMOD_CTRL=2
 val SCMOD_ALT=4
+val SCMOD_SUPER=8
 
 ################################################
 # For SciLexer.h
@@ -2009,12 +2240,20 @@ val SCLEX_MAGIK=87
 val SCLEX_POWERSHELL=88
 val SCLEX_MYSQL=89
 val SCLEX_PO=90
+val SCLEX_TAL=91
+val SCLEX_COBOL=92
+val SCLEX_TACL=93
+val SCLEX_SORCUS=94
+val SCLEX_POWERPRO=95
+val SCLEX_NIMROD=96
+val SCLEX_SML=97
 
 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
 # value assigned in sequence from SCLEX_AUTOMATIC+1.
 val SCLEX_AUTOMATIC=1000
 # Lexical states for SCLEX_PYTHON
 lex Python=SCLEX_PYTHON SCE_P_
+lex Nimrod=SCLEX_NIMROD SCE_P_
 val SCE_P_DEFAULT=0
 val SCE_P_COMMENTLINE=1
 val SCE_P_NUMBER=2
@@ -2033,7 +2272,6 @@ val SCE_P_WORD2=14
 val SCE_P_DECORATOR=15
 # Lexical states for SCLEX_CPP
 lex Cpp=SCLEX_CPP SCE_C_
-lex Pascal=SCLEX_PASCAL SCE_C_
 lex BullAnt=SCLEX_BULLANT SCE_C_
 val SCE_C_DEFAULT=0
 val SCE_C_COMMENT=1
@@ -2075,6 +2313,11 @@ val SCE_D_IDENTIFIER=14
 val SCE_D_COMMENTLINEDOC=15
 val SCE_D_COMMENTDOCKEYWORD=16
 val SCE_D_COMMENTDOCKEYWORDERROR=17
+val SCE_D_STRINGB=18
+val SCE_D_STRINGR=19
+val SCE_D_WORD5=20
+val SCE_D_WORD6=21
+val SCE_D_WORD7=22
 # Lexical states for SCLEX_TCL
 lex TCL=SCLEX_TCL SCE_TCL_
 val SCE_TCL_DEFAULT=0
@@ -2959,6 +3202,7 @@ val SCE_CAML_LINENUM=6
 val SCE_CAML_OPERATOR=7
 val SCE_CAML_NUMBER=8
 val SCE_CAML_CHAR=9
+val SCE_CAML_WHITE=10
 val SCE_CAML_STRING=11
 val SCE_CAML_COMMENT=12
 val SCE_CAML_COMMENT1=13
@@ -3133,6 +3377,7 @@ val SCE_INNO_PARAMETER=3
 val SCE_INNO_SECTION=4
 val SCE_INNO_PREPROC=5
 val SCE_INNO_PREPROC_INLINE=6
+val SCE_INNO_INLINE_EXPANSION=6
 val SCE_INNO_COMMENT_PASCAL=7
 val SCE_INNO_KEYWORD_PASCAL=8
 val SCE_INNO_KEYWORD_USER=9
@@ -3335,6 +3580,7 @@ val SCE_MYSQL_QUOTEDIDENTIFIER=17
 val SCE_MYSQL_USER1=18
 val SCE_MYSQL_USER2=19
 val SCE_MYSQL_USER3=20
+val SCE_MYSQL_HIDDENCOMMAND=21
 # Lexical state for SCLEX_PO
 lex Po=SCLEX_PO SCE_PO_
 val SCE_PO_DEFAULT=0
@@ -3346,6 +3592,71 @@ val SCE_PO_MSGSTR_TEXT=5
 val SCE_PO_MSGCTXT=6
 val SCE_PO_MSGCTXT_TEXT=7
 val SCE_PO_FUZZY=8
+# Lexical states for SCLEX_PASCAL
+lex Pascal=SCLEX_PASCAL SCE_PAS_
+val SCE_PAS_DEFAULT=0
+val SCE_PAS_IDENTIFIER=1
+val SCE_PAS_COMMENT=2
+val SCE_PAS_COMMENT2=3
+val SCE_PAS_COMMENTLINE=4
+val SCE_PAS_PREPROCESSOR=5
+val SCE_PAS_PREPROCESSOR2=6
+val SCE_PAS_NUMBER=7
+val SCE_PAS_HEXNUMBER=8
+val SCE_PAS_WORD=9
+val SCE_PAS_STRING=10
+val SCE_PAS_STRINGEOL=11
+val SCE_PAS_CHARACTER=12
+val SCE_PAS_OPERATOR=13
+val SCE_PAS_ASM=14
+# Lexical state for SCLEX_SORCUS
+lex SORCUS=SCLEX_SORCUS SCE_SORCUS_
+val SCE_SORCUS_DEFAULT=0
+val SCE_SORCUS_COMMAND=1
+val SCE_SORCUS_PARAMETER=2
+val SCE_SORCUS_COMMENTLINE=3
+val SCE_SORCUS_STRING=4
+val SCE_SORCUS_STRINGEOL=5
+val SCE_SORCUS_IDENTIFIER=6
+val SCE_SORCUS_OPERATOR=7
+val SCE_SORCUS_NUMBER=8
+val SCE_SORCUS_CONSTANT=9
+# Lexical state for SCLEX_POWERPRO
+lex PowerPro=SCLEX_POWERPRO SCE_POWERPRO_
+val SCE_POWERPRO_DEFAULT=0
+val SCE_POWERPRO_COMMENTBLOCK=1
+val SCE_POWERPRO_COMMENTLINE=2
+val SCE_POWERPRO_NUMBER=3
+val SCE_POWERPRO_WORD=4
+val SCE_POWERPRO_WORD2=5
+val SCE_POWERPRO_WORD3=6
+val SCE_POWERPRO_WORD4=7
+val SCE_POWERPRO_DOUBLEQUOTEDSTRING=8
+val SCE_POWERPRO_SINGLEQUOTEDSTRING=9
+val SCE_POWERPRO_LINECONTINUE=10
+val SCE_POWERPRO_OPERATOR=11
+val SCE_POWERPRO_IDENTIFIER=12
+val SCE_POWERPRO_STRINGEOL=13
+val SCE_POWERPRO_VERBATIM=14
+val SCE_POWERPRO_ALTQUOTE=15
+val SCE_POWERPRO_FUNCTION=16
+# Lexical states for SCLEX_SML
+lex SML=SCLEX_SML SCE_SML_
+val SCE_SML_DEFAULT=0
+val SCE_SML_IDENTIFIER=1
+val SCE_SML_TAGNAME=2
+val SCE_SML_KEYWORD=3
+val SCE_SML_KEYWORD2=4
+val SCE_SML_KEYWORD3=5
+val SCE_SML_LINENUM=6
+val SCE_SML_OPERATOR=7
+val SCE_SML_NUMBER=8
+val SCE_SML_CHAR=9
+val SCE_SML_STRING=11
+val SCE_SML_COMMENT=12
+val SCE_SML_COMMENT1=13
+val SCE_SML_COMMENT2=14
+val SCE_SML_COMMENT3=15
 
 # Events
 
@@ -3375,19 +3686,4 @@ evt void AutoCSelection=2022(string text)
 evt void IndicatorClick=2023(int modifiers, int position)
 evt void IndicatorRelease=2024(int modifiers, int position)
 evt void AutoCCancelled=2025(void)
-
-cat Deprecated
-
-# CARET_POLICY changed in 1.47
-fun void SetCaretPolicy=2369(int caretPolicy, int caretSlop)
-val CARET_CENTER=0x02
-val CARET_XEVEN=0x08
-val CARET_XJUMPS=0x10
-
-# The old name for SCN_UPDATEUI
-val SCN_CHECKBRACE=2007
-evt void PosChanged=2012(int position)
-
-# SCLEX_HTML should be used in preference to these.
-val SCLEX_ASP=29
-val SCLEX_PHP=30
+evt void AutoCCharDeleted=2026(void)
diff --git a/plugins/scintilla/scintilla/include/ScintillaWidget.h b/plugins/scintilla/scintilla/include/ScintillaWidget.h
index 14eb2cf..eccc983 100644
--- a/plugins/scintilla/scintilla/include/ScintillaWidget.h
+++ b/plugins/scintilla/scintilla/include/ScintillaWidget.h
@@ -1,10 +1,10 @@
-// Scintilla source code edit control
+/* Scintilla source code edit control */
 /** @file ScintillaWidget.h
  ** Definition of Scintilla widget for GTK+.
  ** Only needed by GTK+ code but is harmless on other platforms.
  **/
-// Copyright 1998-2001 by Neil Hodgson <neilh scintilla org>
-// The License.txt file describes the conditions under which this software may be distributed.
+/* Copyright 1998-2001 by Neil Hodgson <neilh scintilla org>
+ * The License.txt file describes the conditions under which this software may be distributed. */
 
 #ifndef SCINTILLAWIDGET_H
 #define SCINTILLAWIDGET_H
diff --git a/plugins/scintilla/scintilla/include/WindowAccessor.h b/plugins/scintilla/scintilla/include/WindowAccessor.h
index e107a06..6f265f6 100644
--- a/plugins/scintilla/scintilla/include/WindowAccessor.h
+++ b/plugins/scintilla/scintilla/include/WindowAccessor.h
@@ -12,13 +12,14 @@ namespace Scintilla {
 
 /**
  */
+
 class WindowAccessor : public Accessor {
 	// Private so WindowAccessor objects can not be copied
 	WindowAccessor(const WindowAccessor &source) : Accessor(), props(source.props) {}
 	WindowAccessor &operator=(const WindowAccessor &) { return *this; }
 protected:
 	WindowID id;
-	PropSet &props;
+	PropertyGet &props;
 	int lenDoc;
 
 	char styleBuf[bufferSize];
@@ -30,7 +31,7 @@ protected:
 	bool InternalIsLeadByte(char ch);
 	void Fill(int position);
 public:
-	WindowAccessor(WindowID id_, PropSet &props_) : 
+	WindowAccessor(WindowID id_, PropertyGet &props_) : 
 		Accessor(), id(id_), props(props_), 
 		lenDoc(-1), validLen(0), chFlags(0), chWhile(0) {
 	}
diff --git a/plugins/scintilla/scintilla/lexers.make b/plugins/scintilla/scintilla/lexers.make
index dc94c8b..fcad92e 100644
--- a/plugins/scintilla/scintilla/lexers.make
+++ b/plugins/scintilla/scintilla/lexers.make
@@ -1,76 +1,83 @@
 ## Lexers make file
 LEXER_OBJS = \
-	$(top_srcdir)/plugins/editor/scintilla/StyleContext.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexAbaqus.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexAda.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexAPDL.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexAsm.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexAsn1.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexASY.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexAU3.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexAVE.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexBaan.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexBash.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexBasic.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexBullant.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexCaml.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexCLW.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexCmake.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexConf.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexCPP.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexCrontab.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexCsound.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexCSS.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexD.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexEiffel.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexErlang.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexEScript.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexFlagship.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexForth.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexFortran.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexGAP.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexGui4Cli.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexHaskell.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexHTML.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexInno.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexKix.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexLisp.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexLout.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexLua.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexMagik.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexMatlab.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexMetapost.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexMMIXAL.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexMPT.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexMSSQL.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexMySQL.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexNsis.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexOpal.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexOthers.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexPascal.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexPB.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexPerl.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexPLM.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexPOV.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexPowerShell.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexProgress.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexPS.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexPython.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexR.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexRebol.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexRuby.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexScriptol.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexSmalltalk.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexSpecman.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexSpice.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexSQL.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexTADS3.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexTCL.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexTeX.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexVB.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexVerilog.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexVHDL.o\
-	$(top_srcdir)/plugins/editor/scintilla/LexYAML.o
+	StyleContext.o\
+	LexAbaqus.o\
+	LexAda.o\
+	LexAPDL.o\
+	LexAsm.o\
+	LexAsn1.o\
+	LexASY.o\
+	LexAU3.o\
+	LexAVE.o\
+	LexBaan.o\
+	LexBash.o\
+	LexBasic.o\
+	LexBullant.o\
+	LexCaml.o\
+	LexCLW.o\
+	LexCmake.o\
+	LexCOBOL.o\
+	LexConf.o\
+	LexCPP.o\
+	LexCrontab.o\
+	LexCsound.o\
+	LexCSS.o\
+	LexD.o\
+	LexEiffel.o\
+	LexErlang.o\
+	LexEScript.o\
+	LexFlagship.o\
+	LexForth.o\
+	LexFortran.o\
+	LexGAP.o\
+	LexGui4Cli.o\
+	LexHaskell.o\
+	LexHTML.o\
+	LexInno.o\
+	LexKix.o\
+	LexLisp.o\
+	LexLout.o\
+	LexLua.o\
+	LexMagik.o\
+	LexMatlab.o\
+	LexMetapost.o\
+	LexMMIXAL.o\
+	LexMPT.o\
+	LexMSSQL.o\
+	LexMySQL.o\
+	LexNimrod.o\
+	LexNsis.o\
+	LexOpal.o\
+	LexOthers.o\
+	LexPascal.o\
+	LexPB.o\
+	LexPerl.o\
+	LexPLM.o\
+	LexPOV.o\
+	LexPowerPro.o\
+	LexPowerShell.o\
+	LexProgress.o\
+	LexPS.o\
+	LexPython.o\
+	LexR.o\
+	LexRebol.o\
+	LexRuby.o\
+	LexScriptol.o\
+	LexSmalltalk.o\
+	LexSML.o\
+	LexSorcus.o\
+	LexSpecman.o\
+	LexSpice.o\
+	LexSQL.o\
+	LexTACL.o\
+	LexTADS3.o\
+	LexTAL.o\
+	LexTCL.o\
+	LexTeX.o\
+	LexVB.o\
+	LexVerilog.o\
+	LexVHDL.o\
+	LexYAML.o
 
 LEXER_SRCS = \
 	LexAbaqus.cxx\
@@ -88,6 +95,7 @@ LEXER_SRCS = \
 	LexCaml.cxx\
 	LexCLW.cxx\
 	LexCmake.cxx\
+	LexCOBOL.cxx\
 	LexConf.cxx\
 	LexCPP.cxx\
 	LexCrontab.cxx\
@@ -116,6 +124,7 @@ LEXER_SRCS = \
 	LexMPT.cxx\
 	LexMSSQL.cxx\
 	LexMySQL.cxx\
+	LexNimrod.cxx\
 	LexNsis.cxx\
 	LexOpal.cxx\
 	LexOthers.cxx\
@@ -124,6 +133,7 @@ LEXER_SRCS = \
 	LexPerl.cxx\
 	LexPLM.cxx\
 	LexPOV.cxx\
+	LexPowerPro.cxx\
 	LexPowerShell.cxx\
 	LexProgress.cxx\
 	LexPS.cxx\
@@ -133,10 +143,14 @@ LEXER_SRCS = \
 	LexRuby.cxx\
 	LexScriptol.cxx\
 	LexSmalltalk.cxx\
+	LexSML.cxx\
+	LexSorcus.cxx\
 	LexSpecman.cxx\
 	LexSpice.cxx\
 	LexSQL.cxx\
+	LexTACL.cxx\
 	LexTADS3.cxx\
+	LexTAL.cxx\
 	LexTCL.cxx\
 	LexTeX.cxx\
 	LexVB.cxx\
diff --git a/plugins/scintilla/scintilla/patches/scintilla-64-bit.diff b/plugins/scintilla/scintilla/patches/scintilla-64-bit.diff
new file mode 100644
index 0000000..7ab699f
--- /dev/null
+++ b/plugins/scintilla/scintilla/patches/scintilla-64-bit.diff
@@ -0,0 +1,22 @@
+--- scintilla/scintilla/include/Scintilla.h	2009-07-21 12:55:09.000000000 +0200
++++ scintilla/include/Scintilla.h	2009-08-13 18:15:01.000000000 +0200
+@@ -28,6 +28,11 @@
+ #if defined(_WIN32)
+ #include <basetsd.h>
+ #endif
++#ifdef HAVE_STDINT_H
++#include <stdint.h>
++typedef uintptr_t uptr_t;
++typedef intptr_t sptr_t;
++#else
+ #ifdef MAXULONG_PTR
+ typedef ULONG_PTR uptr_t;
+ typedef LONG_PTR sptr_t;
+@@ -35,6 +40,7 @@
+ typedef unsigned long uptr_t;
+ typedef long sptr_t;
+ #endif
++#endif
+ 
+ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam);
+ 
diff --git a/plugins/scintilla/scintilla/patches/scintilla-pango-always.diff b/plugins/scintilla/scintilla/patches/scintilla-pango-always.diff
new file mode 100644
index 0000000..58587a1
--- /dev/null
+++ b/plugins/scintilla/scintilla/patches/scintilla-pango-always.diff
@@ -0,0 +1,28 @@
+--- scintilla/scintilla/gtk/PlatGTK.cxx	2009-06-13 02:12:31.000000000 +0200
++++ scintilla/PlatGTK.cxx	2009-08-13 18:15:01.000000000 +0200
+@@ -513,16 +513,16 @@
+ 	charset[0] = '\0';
+ 
+ #ifdef USE_PANGO
+-	if (fontName[0] == '!') {
+-		PangoFontDescription *pfd = pango_font_description_new();
+-		if (pfd) {
+-			pango_font_description_set_family(pfd, fontName+1);
+-			pango_font_description_set_size(pfd, size * PANGO_SCALE);
+-			pango_font_description_set_weight(pfd, bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
+-			pango_font_description_set_style(pfd, italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL);
+-			return new FontHandle(pfd, characterSet);
+-		}
++	//if (fontName[0] == '!') {
++	PangoFontDescription *pfd = pango_font_description_new();
++	if (pfd) {
++		pango_font_description_set_family(pfd, fontName);
++		pango_font_description_set_size(pfd, size * PANGO_SCALE);
++		pango_font_description_set_weight(pfd, bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
++		pango_font_description_set_style(pfd, italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL);
++		return new FontHandle(pfd, characterSet);
+ 	}
++	//}
+ #endif
+ 
+ 	GdkFont *newid = 0;
diff --git a/plugins/scintilla/scintilla/patches/scintilla-remove-deprecated.diff b/plugins/scintilla/scintilla/patches/scintilla-remove-deprecated.diff
new file mode 100644
index 0000000..a27a9f8
--- /dev/null
+++ b/plugins/scintilla/scintilla/patches/scintilla-remove-deprecated.diff
@@ -0,0 +1,90 @@
+--- scintilla/scintilla/include/ScintillaWidget.h	2009-01-08 10:14:54.000000000 +0100
++++ scintilla/include/ScintillaWidget.h	2009-08-17 16:34:56.000000000 +0200
+@@ -15,9 +15,9 @@
+ extern "C" {
+ #endif
+ 
+-#define SCINTILLA(obj)          GTK_CHECK_CAST (obj, scintilla_get_type (), ScintillaObject)
+-#define SCINTILLA_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass)
+-#define IS_SCINTILLA(obj)       GTK_CHECK_TYPE (obj, scintilla_get_type ())
++#define SCINTILLA(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, scintilla_get_type (), ScintillaObject)
++#define SCINTILLA_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass)
++#define IS_SCINTILLA(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, scintilla_get_type ())
+ 
+ typedef struct _ScintillaObject ScintillaObject;
+ typedef struct _ScintillaClass  ScintillaClass;
+--- scintilla/scintilla/gtk/PlatGTK.cxx	2009-06-13 02:12:31.000000000 +0200
++++ scintilla/PlatGTK.cxx	2009-08-17 16:44:41.000000000 +0200
+@@ -1776,7 +1776,7 @@
+ #else
+ 
+ 	gtk_widget_set_uposition(wid, rc.left, rc.top);
+-	gtk_widget_set_usize(wid, rc.right - rc.left, rc.bottom - rc.top);
++	gtk_widget_set_size_request(wid, rc.right - rc.left, rc.bottom - rc.top);
+ #endif
+ }
+ 
+@@ -1818,7 +1818,7 @@
+ 	alloc.height = rc.bottom - rc.top;
+ 	gtk_widget_size_allocate(wid, &alloc);
+ #endif
+-	gtk_widget_set_usize(PWidget(wid), sizex, sizey);
++	gtk_widget_set_size_request(PWidget(wid), sizex, sizey);
+ }
+ 
+ PRectangle Window::GetClientPosition() {
+@@ -1938,7 +1938,7 @@
+ 		gdk_bitmap_unref(list_image->bitmap);
+ #else
+ 	if (list_image->pixbuf)
+-		gdk_pixbuf_unref (list_image->pixbuf);
++		g_object_unref (list_image->pixbuf);
+ #endif
+ 	g_free(list_image);
+ }
+@@ -2210,14 +2210,14 @@
+ 		          + 2 * (ythickness
+ 		                 + GTK_CONTAINER(PWidget(list))->border_width + 1));
+ #endif
+-		gtk_widget_set_usize(GTK_WIDGET(PWidget(list)), -1, height);
++		gtk_widget_set_size_request(GTK_WIDGET(PWidget(list)), -1, height);
+ 
+ 		// Get the size of the scroller because we set usize on the window
+ 		gtk_widget_size_request(GTK_WIDGET(scroller), &req);
+ 		rc.right = req.width;
+ 		rc.bottom = req.height;
+ 
+-		gtk_widget_set_usize(GTK_WIDGET(list), -1, -1);
++		gtk_widget_set_size_request(GTK_WIDGET(list), -1, -1);
+ 		int width = maxItemCharacters;
+ 		if (width < 12)
+ 			width = 12;
+@@ -2285,7 +2285,7 @@
+ 	}
+ #else
+ 	if (list_image->pixbuf)
+-		gdk_pixbuf_unref(list_image->pixbuf);
++		g_object_unref(list_image->pixbuf);
+ 	list_image->pixbuf =
+ 		gdk_pixbuf_new_from_xpm_data((const gchar**)xpm_lineform);
+ #endif
+@@ -2520,7 +2520,7 @@
+ 		list_image->bitmap = 0;
+ #else
+ 		if (list_image->pixbuf)
+-			gdk_pixbuf_unref(list_image->pixbuf);
++			g_object_unref(list_image->pixbuf);
+ 		list_image->pixbuf = NULL;
+ #endif
+ 		list_image->xpm_data = xpm_data;
+--- scintilla/scintilla/gtk/ScintillaGTK.cxx	2009-07-25 04:50:01.000000000 +0200
++++ scintilla/ScintillaGTK.cxx	2009-08-17 16:35:56.000000000 +0200
+@@ -1056,7 +1056,7 @@
+ 	if (timer.ticking != on) {
+ 		timer.ticking = on;
+ 		if (timer.ticking) {
+-			timer.tickerID = reinterpret_cast<TickerID>(gtk_timeout_add(timer.tickSize, (GtkFunction)TimeOut, this));
++			timer.tickerID = reinterpret_cast<TickerID>(g_timeout_add(timer.tickSize, (GSourceFunc)TimeOut, this));
+ 		} else {
+ 			gtk_timeout_remove(GPOINTER_TO_UINT(timer.tickerID));
+ 		}



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