[anjuta-extras/gtk3] scintilla: Update scintilla with changeset 3662:1d1c06df8a2f using gtk+3



commit df10f78c31a5e4608e0a80681b0eb6dbd29715a6
Author: Sébastien Granjoux <seb sfo free fr>
Date:   Sun May 22 18:42:46 2011 +0200

    scintilla: Update scintilla with changeset 3662:1d1c06df8a2f using gtk+3

 configure.ac                                       |   10 +-
 plugins/Makefile.am                                |    4 +-
 plugins/scintilla/aneditor-indent.cxx              |    4 +-
 plugins/scintilla/aneditor-priv.h                  |    1 -
 plugins/scintilla/aneditor.cxx                     |   14 +-
 plugins/scintilla/scintilla/Accessor.cxx           |   79 ++
 plugins/scintilla/scintilla/Accessor.h             |   35 +
 plugins/scintilla/scintilla/AutoComplete.cxx       |   15 +-
 plugins/scintilla/scintilla/AutoComplete.h         |    6 +-
 plugins/scintilla/scintilla/CallTip.cxx            |    9 +-
 plugins/scintilla/scintilla/CallTip.h              |    4 +-
 plugins/scintilla/scintilla/Catalogue.cxx          |  186 +++
 plugins/scintilla/scintilla/Catalogue.h            |   26 +
 plugins/scintilla/scintilla/CellBuffer.cxx         |   45 +-
 plugins/scintilla/scintilla/CellBuffer.h           |   21 +-
 plugins/scintilla/scintilla/CharClassify.cxx       |   38 +-
 plugins/scintilla/scintilla/CharClassify.h         |   15 +-
 plugins/scintilla/scintilla/CharacterSet.cxx       |   61 +
 plugins/scintilla/scintilla/CharacterSet.h         |  104 ++-
 plugins/scintilla/scintilla/ContractionState.cxx   |   21 +-
 plugins/scintilla/scintilla/ContractionState.h     |    1 +
 plugins/scintilla/scintilla/Converter.h            |   19 +-
 plugins/scintilla/scintilla/Decoration.h           |    4 +-
 plugins/scintilla/scintilla/Document.cxx           |  748 ++++++++--
 plugins/scintilla/scintilla/Document.h             |  167 ++-
 plugins/scintilla/scintilla/DocumentAccessor.cxx   |  199 ---
 plugins/scintilla/scintilla/DocumentAccessor.h     |   77 -
 plugins/scintilla/scintilla/Editor.cxx             | 1186 ++++++++++++----
 plugins/scintilla/scintilla/Editor.h               |   79 +-
 plugins/scintilla/scintilla/ExternalLexer.cxx      |  122 +--
 plugins/scintilla/scintilla/ExternalLexer.h        |   42 +-
 plugins/scintilla/scintilla/Indicator.cxx          |    4 +-
 plugins/scintilla/scintilla/Indicator.h            |    3 +-
 plugins/scintilla/scintilla/KeyWords.cxx           |  429 ------
 plugins/scintilla/scintilla/LexA68k.cxx            |  318 +++++
 plugins/scintilla/scintilla/LexAPDL.cxx            |   15 +-
 plugins/scintilla/scintilla/LexASY.cxx             |   27 +-
 plugins/scintilla/scintilla/LexAU3.cxx             |  135 +-
 plugins/scintilla/scintilla/LexAVE.cxx             |   19 +-
 plugins/scintilla/scintilla/LexAbaqus.cxx          |   15 +-
 plugins/scintilla/scintilla/LexAccessor.h          |  175 +++
 plugins/scintilla/scintilla/LexAda.cxx             |   14 +-
 plugins/scintilla/scintilla/LexAsm.cxx             |  338 +++++-
 plugins/scintilla/scintilla/LexAsn1.cxx            |   15 +-
 plugins/scintilla/scintilla/LexBaan.cxx            |   15 +-
 plugins/scintilla/scintilla/LexBash.cxx            |  280 +++-
 plugins/scintilla/scintilla/LexBasic.cxx           |  383 ++++--
 plugins/scintilla/scintilla/LexBullant.cxx         |   19 +-
 plugins/scintilla/scintilla/LexCLW.cxx             |   45 +-
 plugins/scintilla/scintilla/LexCOBOL.cxx           |   21 +-
 plugins/scintilla/scintilla/LexCPP.cxx             |  926 +++++++++++--
 plugins/scintilla/scintilla/LexCSS.cxx             |   35 +-
 plugins/scintilla/scintilla/LexCaml.cxx            |   29 +-
 plugins/scintilla/scintilla/LexCmake.cxx           |   18 +-
 plugins/scintilla/scintilla/LexConf.cxx            |   28 +-
 plugins/scintilla/scintilla/LexCrontab.cxx         |   24 +-
 plugins/scintilla/scintilla/LexCsound.cxx          |   24 +-
 plugins/scintilla/scintilla/LexD.cxx               |  289 +++-
 plugins/scintilla/scintilla/LexEScript.cxx         |   15 +-
 plugins/scintilla/scintilla/LexEiffel.cxx          |   17 +-
 plugins/scintilla/scintilla/LexErlang.cxx          |   26 +-
 plugins/scintilla/scintilla/LexFlagship.cxx        |  382 ++++--
 plugins/scintilla/scintilla/LexForth.cxx           |   19 +-
 plugins/scintilla/scintilla/LexFortran.cxx         |   19 +-
 plugins/scintilla/scintilla/LexGAP.cxx             |   17 +-
 plugins/scintilla/scintilla/LexGen.py              |  304 ++++
 plugins/scintilla/scintilla/LexGui4Cli.cxx         |   15 +-
 plugins/scintilla/scintilla/LexHTML.cxx            |  236 +++-
 plugins/scintilla/scintilla/LexHaskell.cxx         |  267 +++--
 plugins/scintilla/scintilla/LexInno.cxx            |   27 +-
 plugins/scintilla/scintilla/LexKix.cxx             |   15 +-
 plugins/scintilla/scintilla/LexLisp.cxx            |   19 +-
 plugins/scintilla/scintilla/LexLout.cxx            |   15 +-
 plugins/scintilla/scintilla/LexLua.cxx             |   59 +-
 plugins/scintilla/scintilla/LexMMIXAL.cxx          |   17 +-
 plugins/scintilla/scintilla/LexMPT.cxx             |   32 +-
 plugins/scintilla/scintilla/LexMSSQL.cxx           |   16 +-
 plugins/scintilla/scintilla/LexMagik.cxx           |   15 +-
 plugins/scintilla/scintilla/LexMarkdown.cxx        |   76 +-
 plugins/scintilla/scintilla/LexMatlab.cxx          |   15 +-
 plugins/scintilla/scintilla/LexMetapost.cxx        |   31 +-
 plugins/scintilla/scintilla/LexModula.cxx          |  743 ++++++++++
 plugins/scintilla/scintilla/LexMySQL.cxx           |  215 ++--
 plugins/scintilla/scintilla/LexNimrod.cxx          |   33 +-
 plugins/scintilla/scintilla/LexNsis.cxx            |   18 +-
 plugins/scintilla/scintilla/LexOpal.cxx            |   71 +-
 plugins/scintilla/scintilla/LexOthers.cxx          |   75 +-
 plugins/scintilla/scintilla/LexPB.cxx              |   15 +-
 plugins/scintilla/scintilla/LexPLM.cxx             |   15 +-
 plugins/scintilla/scintilla/LexPOV.cxx             |   15 +-
 plugins/scintilla/scintilla/LexPS.cxx              |   17 +-
 plugins/scintilla/scintilla/LexPascal.cxx          |  162 ++--
 plugins/scintilla/scintilla/LexPerl.cxx            | 1000 ++++++++------
 plugins/scintilla/scintilla/LexPowerPro.cxx        |  396 +++---
 plugins/scintilla/scintilla/LexPowerShell.cxx      |   44 +-
 plugins/scintilla/scintilla/LexProgress.cxx        |   19 +-
 plugins/scintilla/scintilla/LexPython.cxx          |   51 +-
 plugins/scintilla/scintilla/LexR.cxx               |   19 +-
 plugins/scintilla/scintilla/LexRebol.cxx           |   15 +-
 plugins/scintilla/scintilla/LexRuby.cxx            |  168 ++-
 plugins/scintilla/scintilla/LexSML.cxx             |   30 +-
 plugins/scintilla/scintilla/LexSQL.cxx             |  540 +++++++--
 plugins/scintilla/scintilla/LexScriptol.cxx        |   21 +-
 plugins/scintilla/scintilla/LexSmalltalk.cxx       |   33 +-
 plugins/scintilla/scintilla/LexSorcus.cxx          |  135 +-
 plugins/scintilla/scintilla/LexSpecman.cxx         |   13 +-
 plugins/scintilla/scintilla/LexSpice.cxx           |   14 +-
 plugins/scintilla/scintilla/LexTACL.cxx            |   15 +-
 plugins/scintilla/scintilla/LexTADS3.cxx           |   27 +-
 plugins/scintilla/scintilla/LexTAL.cxx             |   17 +-
 plugins/scintilla/scintilla/LexTCL.cxx             |   29 +-
 plugins/scintilla/scintilla/LexTeX.cxx             |   55 +-
 plugins/scintilla/scintilla/LexTxt2tags.cxx        |  480 +++++++
 plugins/scintilla/scintilla/LexVB.cxx              |   15 +-
 plugins/scintilla/scintilla/LexVHDL.cxx            |   60 +-
 plugins/scintilla/scintilla/LexVerilog.cxx         |   40 +-
 plugins/scintilla/scintilla/LexYAML.cxx            |   17 +-
 plugins/scintilla/scintilla/LexerBase.cxx          |   92 ++
 plugins/scintilla/scintilla/LexerBase.h            |   41 +
 plugins/scintilla/scintilla/LexerModule.cxx        |  121 ++
 plugins/scintilla/scintilla/LexerModule.h          |   82 ++
 plugins/scintilla/scintilla/LexerNoExceptions.cxx  |   68 +
 plugins/scintilla/scintilla/LexerNoExceptions.h    |   32 +
 plugins/scintilla/scintilla/LexerSimple.cxx        |   57 +
 plugins/scintilla/scintilla/LexerSimple.h          |   30 +
 plugins/scintilla/scintilla/LineMarker.cxx         |  140 ++-
 plugins/scintilla/scintilla/LineMarker.h           |   13 +-
 plugins/scintilla/scintilla/Makefile.am            |   51 +-
 plugins/scintilla/scintilla/OptionSet.h            |  142 ++
 plugins/scintilla/scintilla/Partitioning.h         |    7 +-
 plugins/scintilla/scintilla/PerLine.cxx            |   19 +-
 plugins/scintilla/scintilla/PerLine.h              |    4 +-
 plugins/scintilla/scintilla/PlatGTK.cxx            |  855 +++++++-----
 plugins/scintilla/scintilla/PositionCache.cxx      |   93 +-
 plugins/scintilla/scintilla/PositionCache.h        |   29 +-
 .../scintilla/{PropSet.cxx => PropSetSimple.cxx}   |   27 +-
 plugins/scintilla/scintilla/PropSetSimple.h        |    4 +-
 plugins/scintilla/scintilla/RESearch.cxx           |   98 +-
 plugins/scintilla/scintilla/RunStyles.cxx          |    4 +-
 plugins/scintilla/scintilla/SVector.h              |   14 +-
 plugins/scintilla/scintilla/ScintillaBase.cxx      |  301 +++--
 plugins/scintilla/scintilla/ScintillaBase.h        |   17 +-
 plugins/scintilla/scintilla/ScintillaGTK.cxx       | 1460 ++++++++++----------
 plugins/scintilla/scintilla/Selection.cxx          |   13 +-
 plugins/scintilla/scintilla/Selection.h            |    9 +-
 plugins/scintilla/scintilla/SparseState.h          |  110 ++
 plugins/scintilla/scintilla/SplitVector.h          |   29 +-
 plugins/scintilla/scintilla/Style.cxx              |  133 +-
 plugins/scintilla/scintilla/Style.h                |   64 +-
 plugins/scintilla/scintilla/StyleContext.cxx       |    9 +-
 plugins/scintilla/scintilla/StyleContext.h         |   51 +-
 plugins/scintilla/scintilla/UniConversion.cxx      |   16 +-
 plugins/scintilla/scintilla/UniConversion.h        |    3 +-
 plugins/scintilla/scintilla/ViewStyle.cxx          |  157 ++-
 plugins/scintilla/scintilla/ViewStyle.h            |   22 +
 plugins/scintilla/scintilla/WindowAccessor.cxx     |  191 ---
 plugins/scintilla/scintilla/WordList.cxx           |  205 +++
 plugins/scintilla/scintilla/WordList.h             |   41 +
 plugins/scintilla/scintilla/XPM.cxx                |    8 +-
 plugins/scintilla/scintilla/XPM.h                  |   12 +-
 plugins/scintilla/scintilla/include/HFacer.py      |    1 +
 plugins/scintilla/scintilla/include/ILexer.h       |   69 +
 plugins/scintilla/scintilla/include/Platform.h     |   20 +-
 plugins/scintilla/scintilla/include/SciLexer.h     |   91 ++-
 plugins/scintilla/scintilla/include/Scintilla.h    |  104 +-
 .../scintilla/scintilla/include/Scintilla.iface    |  223 +++-
 .../scintilla/scintilla/include/ScintillaWidget.h  |   12 +-
 plugins/scintilla/scintilla/lexers.make            |   14 +
 plugins/scintilla/scintilla/test-scintilla.cxx     |   42 +-
 plugins/scintilla/style-editor.c                   |    4 +-
 plugins/scintilla/text_editor_cbs.c                |   15 +-
 171 files changed, 13135 insertions(+), 5605 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 1ab6372..f722a3b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,9 +3,9 @@ dnl Created by Anjuta application wizard.
 
 AC_PREREQ(2.59)
 
-m4_define(anjuta_major_version,  2)
-m4_define(anjuta_minor_version, 32)
-m4_define(anjuta_micro_version,  1)
+m4_define(anjuta_major_version,  3)
+m4_define(anjuta_minor_version,  0)
+m4_define(anjuta_micro_version,  0)
 m4_define(anjuta_nano_version,   0)
 m4_define(anjuta_version, anjuta_major_version.anjuta_minor_version.anjuta_micro_version.anjuta_nano_version)
 
@@ -29,7 +29,7 @@ AC_LANG_C
 ANJUTA_REQUIRED=anjuta_major_version.anjuta_minor_version.0
 BINUTILS_REQUIRED=2.15.92
 LIBGRAPHVIZ_REQUIRED=1.0
-GTK_REQUIRED=2.17.10
+GTK_REQUIRED=3.0.0
 GLIB_REQUIRED=2.16.0
 GCONF_REQUIRED=2.12.0
 GNOME_REQUIRED=2.12.0
@@ -102,7 +102,7 @@ dnl maintainer mode
 AM_MAINTAINER_MODE
 
 dnl Check for libanjuta
-PKG_CHECK_MODULES(LIBANJUTA, [libanjuta-1.0 >= $ANJUTA_REQUIRED])
+PKG_CHECK_MODULES(LIBANJUTA, [libanjuta-3.0 >= $ANJUTA_REQUIRED])
 
 dnl Check for libgnome
 PKG_CHECK_MODULES(GNOME, libgnomecanvas-2.0 >= $GNOME_REQUIRED)
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 4499e74..e49a311 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -1 +1,3 @@
-SUBDIRS = valgrind scratchbox profiler scintilla sample1
+#SUBDIRS = valgrind scratchbox profiler scintilla sample1
+# Only the following plugins are supported on Gtk+3
+SUBDIRS = scratchbox scintilla sample1
diff --git a/plugins/scintilla/aneditor-indent.cxx b/plugins/scintilla/aneditor-indent.cxx
index 5fbddb9..9983ac3 100644
--- a/plugins/scintilla/aneditor-indent.cxx
+++ b/plugins/scintilla/aneditor-indent.cxx
@@ -90,11 +90,13 @@ int AnEditor::GetLineIndentPosition(int line) {
 }
 
 bool AnEditor::RangeIsAllWhitespace(int start, int end) {
-	WindowAccessor acc(wEditor.GetID(), *props);
+	//FIXME WindowAccessor acc(wEditor.GetID(), *props);
+#if 0
 	for (int i = start;i < end;i++) {
 		if ((acc[i] != ' ') && (acc[i] != '\t'))
 			return false;
 	}
+#endif
 	return true;
 }
 
diff --git a/plugins/scintilla/aneditor-priv.h b/plugins/scintilla/aneditor-priv.h
index 6867b0a..b31da0c 100644
--- a/plugins/scintilla/aneditor-priv.h
+++ b/plugins/scintilla/aneditor-priv.h
@@ -41,7 +41,6 @@
 #include "Platform.h"
 #include "PropSet.h"
 #include "Accessor.h"
-#include "WindowAccessor.h"
 #include "KeyWords.h"
 #include "Scintilla.h"
 #include "ScintillaWidget.h"
diff --git a/plugins/scintilla/aneditor.cxx b/plugins/scintilla/aneditor.cxx
index b5b92c7..7246059 100644
--- a/plugins/scintilla/aneditor.cxx
+++ b/plugins/scintilla/aneditor.cxx
@@ -118,7 +118,7 @@ AnEditor::AnEditor(PropSetFile* p) {
 	
 	wEditor = scintilla_new();
 	g_object_ref (G_OBJECT (wEditor.GetID()));
-	gtk_object_sink (GTK_OBJECT (wEditor.GetID()));
+	g_object_ref_sink (G_OBJECT (wEditor.GetID()));
 	scintilla_set_id(SCINTILLA(wEditor.GetID()), 0);
 
 	fnEditor = reinterpret_cast<SciFnDirect>(Platform::SendScintilla(
@@ -541,7 +541,8 @@ bool AnEditor::FindMatchingBracePosition(bool editor, int &braceAtCaret, int &br
 	braceOpposite = -1;
 	char charBefore = '\0';
 	char styleBefore = '\0';
-	WindowAccessor acc(win.GetID(), *props);
+	//FIXME WindowAccessor acc(win.GetID(), *props);
+#if 0
 	if (caretPos > 0) {
 		charBefore = acc[caretPos - 1];
 		styleBefore = static_cast<char>(acc.StyleAt(caretPos - 1) & 31);
@@ -584,6 +585,7 @@ bool AnEditor::FindMatchingBracePosition(bool editor, int &braceAtCaret, int &br
 			isInside = !isAfter;
 		}
 	}
+#endif
 	return isInside;
 }
 
@@ -644,7 +646,8 @@ void AnEditor::SelectionWord(char *word, int len) {
 	int selStart = cr.cpMin;
 	int selEnd = cr.cpMax;
 	if (selStart == selEnd) {
-		WindowAccessor acc(wEditor.GetID(), *props);
+		//FIXME WindowAccessor acc(wEditor.GetID(), *props);
+#if 0
 		// Try and find a word at the caret
 		if (iswordcharforsel(acc[selStart])) {
 			while ((selStart > 0) && (iswordcharforsel(acc[selStart - 1])))
@@ -654,6 +657,7 @@ void AnEditor::SelectionWord(char *word, int len) {
 			if (selStart < selEnd)
 				selEnd++;   	// Because normal selections end one past
 		}
+#endif
 	}
 	word[0] = '\0';
 	if ((selStart < selEnd) && ((selEnd - selStart + 1) < len)) {
@@ -667,7 +671,8 @@ void AnEditor::WordSelect() {
 	int selEnd;
 	
 	selStart = selEnd = SendEditor(SCI_GETCURRENTPOS);
-	WindowAccessor acc(wEditor.GetID(), *props);
+	//FIXME WindowAccessor acc(wEditor.GetID(), *props);
+#if 0
 	if (iswordcharforsel(acc[selStart])) {
 			while ((selStart > 0) && (iswordcharforsel(acc[selStart - 1])))
 				selStart--;
@@ -676,6 +681,7 @@ void AnEditor::WordSelect() {
 			if (selStart < selEnd)
 				selEnd++;   	// Because normal selections end one past
 	}
+#endif
 	SetSelection(selStart, selEnd);
 }
 
diff --git a/plugins/scintilla/scintilla/Accessor.cxx b/plugins/scintilla/scintilla/Accessor.cxx
new file mode 100644
index 0000000..5adaaa2
--- /dev/null
+++ b/plugins/scintilla/scintilla/Accessor.cxx
@@ -0,0 +1,79 @@
+// Scintilla source code edit control
+/** @file KeyWords.cxx
+ ** Colourise for particular languages.
+ **/
+// 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 <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+Accessor::Accessor(IDocument *pAccess_, PropSetSimple *pprops_) : LexAccessor(pAccess_), pprops(pprops_) {
+}
+
+int Accessor::GetPropertyInt(const char *key, int defaultValue) {
+	return pprops->GetInt(key, defaultValue);
+}
+
+int Accessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
+	int end = Length();
+	int spaceFlags = 0;
+
+	// Determines the indentation level of the current line and also checks for consistent
+	// indentation compared to the previous line.
+	// Indentation is judged consistent when the indentation whitespace of each line lines
+	// the same or the indentation of one line is a prefix of the other.
+
+	int pos = LineStart(line);
+	char ch = (*this)[pos];
+	int indent = 0;
+	bool inPrevPrefix = line > 0;
+	int posPrev = inPrevPrefix ? LineStart(line-1) : 0;
+	while ((ch == ' ' || ch == '\t') && (pos < end)) {
+		if (inPrevPrefix) {
+			char chPrev = (*this)[posPrev++];
+			if (chPrev == ' ' || chPrev == '\t') {
+				if (chPrev != ch)
+					spaceFlags |= wsInconsistent;
+			} else {
+				inPrevPrefix = false;
+			}
+		}
+		if (ch == ' ') {
+			spaceFlags |= wsSpace;
+			indent++;
+		} else {	// Tab
+			spaceFlags |= wsTab;
+			if (spaceFlags & wsSpace)
+				spaceFlags |= wsSpaceTab;
+			indent = (indent / 8 + 1) * 8;
+		}
+		ch = (*this)[++pos];
+	}
+
+	*flags = spaceFlags;
+	indent += SC_FOLDLEVELBASE;
+	// if completely empty line or the start of a comment...
+	if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
+			(pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)))
+		return indent | SC_FOLDLEVELWHITEFLAG;
+	else
+		return indent;
+}
diff --git a/plugins/scintilla/scintilla/Accessor.h b/plugins/scintilla/scintilla/Accessor.h
new file mode 100644
index 0000000..2f28c1a
--- /dev/null
+++ b/plugins/scintilla/scintilla/Accessor.h
@@ -0,0 +1,35 @@
+// Scintilla source code edit control
+/** @file Accessor.h
+ ** Interfaces between Scintilla and lexers.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef ACCESSOR_H
+#define ACCESSOR_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8};
+
+class Accessor;
+class WordList;
+class PropSetSimple;
+
+typedef bool (*PFNIsCommentLeader)(Accessor &styler, int pos, int len);
+
+class Accessor : public LexAccessor {
+public:
+	PropSetSimple *pprops;
+	Accessor(IDocument *pAccess_, PropSetSimple *pprops_);
+	int GetPropertyInt(const char *, int defaultValue=0);
+	int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/AutoComplete.cxx b/plugins/scintilla/scintilla/AutoComplete.cxx
index 86c64df..f6a291f 100644
--- a/plugins/scintilla/scintilla/AutoComplete.cxx
+++ b/plugins/scintilla/scintilla/AutoComplete.cxx
@@ -8,10 +8,11 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <assert.h>
 
 #include "Platform.h"
 
-#include "CharClassify.h"
+#include "CharacterSet.h"
 #include "AutoComplete.h"
 
 #ifdef SCI_NAMESPACE
@@ -43,12 +44,12 @@ AutoComplete::~AutoComplete() {
 	}
 }
 
-bool AutoComplete::Active() {
+bool AutoComplete::Active() const {
 	return active;
 }
 
-void AutoComplete::Start(Window &parent, int ctrlID, 
-	int position, Point location, int startLen_, 
+void AutoComplete::Start(Window &parent, int ctrlID,
+	int position, Point location, int startLen_,
 	int lineHeight, bool unicodeMode) {
 	if (active) {
 		Cancel();
@@ -82,7 +83,7 @@ void AutoComplete::SetSeparator(char separator_) {
 	separator = separator_;
 }
 
-char AutoComplete::GetSeparator() {
+char AutoComplete::GetSeparator() const {
 	return separator;
 }
 
@@ -90,7 +91,7 @@ void AutoComplete::SetTypesep(char separator_) {
 	typesep = separator_;
 }
 
-char AutoComplete::GetTypesep() {
+char AutoComplete::GetTypesep() const {
 	return typesep;
 }
 
@@ -128,11 +129,11 @@ void AutoComplete::Select(const char *word) {
 	size_t lenWord = strlen(word);
 	int location = -1;
 	const int maxItemLen=1000;
-	char item[maxItemLen];
 	int start = 0; // lower bound of the api array block to search
 	int end = lb->Length() - 1; // upper bound of the api array block to search
 	while ((start <= end) && (location == -1)) { // Binary searching loop
 		int pivot = (start + end) / 2;
+		char item[maxItemLen];
 		lb->GetValue(pivot, item, maxItemLen);
 		int cond;
 		if (ignoreCase)
diff --git a/plugins/scintilla/scintilla/AutoComplete.h b/plugins/scintilla/scintilla/AutoComplete.h
index b10cdce..f48cb05 100644
--- a/plugins/scintilla/scintilla/AutoComplete.h
+++ b/plugins/scintilla/scintilla/AutoComplete.h
@@ -36,7 +36,7 @@ public:
 	~AutoComplete();
 
 	/// Is the auto completion list displayed?
-	bool Active();
+	bool Active() const;
 
 	/// Display the auto completion list positioned to be near a character position
 	void Start(Window &parent, int ctrlID, int position, Point location,
@@ -52,11 +52,11 @@ public:
 
 	/// The separator character is used when interpreting the list in SetList
 	void SetSeparator(char separator_);
-	char GetSeparator();
+	char GetSeparator() const;
 
 	/// The typesep character is used for seperating the word from the type
 	void SetTypesep(char separator_);
-	char GetTypesep();
+	char GetTypesep() const;
 
 	/// The list string contains a sequence of words separated by the separator character
 	void SetList(const char *list);
diff --git a/plugins/scintilla/scintilla/CallTip.cxx b/plugins/scintilla/scintilla/CallTip.cxx
index 3ea2d48..cdc30fc 100644
--- a/plugins/scintilla/scintilla/CallTip.cxx
+++ b/plugins/scintilla/scintilla/CallTip.cxx
@@ -29,6 +29,7 @@ CallTip::CallTip() {
 	rectUp = PRectangle(0,0,0,0);
 	rectDown = PRectangle(0,0,0,0);
 	lineHeight = 1;
+	offsetMain = 0;
 	startHighlight = 0;
 	endHighlight = 0;
 	tabSize = 0;
@@ -45,6 +46,8 @@ CallTip::CallTip() {
 	colourSel.desired = ColourDesired(0, 0, 0x80);
 	colourShade.desired = ColourDesired(0, 0, 0);
 	colourLight.desired = ColourDesired(0xc0, 0xc0, 0xc0);
+	codePage = 0;
+	clickPlace = 0;
 }
 
 CallTip::~CallTip() {
@@ -68,7 +71,7 @@ static bool IsArrowCharacter(char ch) {
 }
 
 // We ignore tabs unless a tab width has been set.
-bool CallTip::IsTabCharacter(char ch) {
+bool CallTip::IsTabCharacter(char ch) const {
 	return (tabSize > 0) && (ch == '\t');
 }
 
@@ -95,9 +98,9 @@ void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
 	int maxEnd = 0;
 	const int numEnds = 10;
 	int ends[numEnds + 2];
-	for (int i=0;i<len;i++) {
+	for (int i=0; i<len; i++) {
 		if ((maxEnd < numEnds) &&
-		        (IsArrowCharacter(s[i]) || IsTabCharacter(s[i])) ) {
+		        (IsArrowCharacter(s[i]) || IsTabCharacter(s[i]))) {
 			if (i > 0)
 				ends[maxEnd++] = i;
 			ends[maxEnd++] = i+1;
diff --git a/plugins/scintilla/scintilla/CallTip.h b/plugins/scintilla/scintilla/CallTip.h
index a64755f..a9ba82e 100644
--- a/plugins/scintilla/scintilla/CallTip.h
+++ b/plugins/scintilla/scintilla/CallTip.h
@@ -33,7 +33,7 @@ class CallTip {
 		int posStart, int posEnd, int ytext, PRectangle rcClient,
 		bool highlight, bool draw);
 	int PaintContents(Surface *surfaceWindow, bool draw);
-	bool IsTabCharacter(char c);
+	bool IsTabCharacter(char c) const;
 	int NextTabPos(int x);
 
 public:
@@ -61,7 +61,7 @@ public:
 
 	/// Setup the calltip and return a rectangle of the area required.
 	PRectangle CallTipStart(int pos, Point pt, const char *defn,
-		const char *faceName, int size, int codePage_, 
+		const char *faceName, int size, int codePage_,
 		int characterSet, Window &wParent);
 
 	void CallTipCancel();
diff --git a/plugins/scintilla/scintilla/Catalogue.cxx b/plugins/scintilla/scintilla/Catalogue.cxx
new file mode 100644
index 0000000..00785d5
--- /dev/null
+++ b/plugins/scintilla/scintilla/Catalogue.cxx
@@ -0,0 +1,186 @@
+// Scintilla source code edit control
+/** @file KeyWords.cxx
+ ** Colourise for particular languages.
+ **/
+// 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 <assert.h>
+
+#include <vector>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "LexerModule.h"
+#include "Catalogue.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static std::vector<LexerModule *> lexerCatalogue;
+static int nextLanguage = SCLEX_AUTOMATIC+1;
+
+const LexerModule *Catalogue::Find(int language) {
+	Scintilla_LinkLexers();
+	for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
+		it != lexerCatalogue.end(); ++it) {
+		if ((*it)->GetLanguage() == language) {
+			return *it;
+		}
+	}
+	return 0;
+}
+
+const LexerModule *Catalogue::Find(const char *languageName) {
+	Scintilla_LinkLexers();
+	if (languageName) {
+		for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
+			it != lexerCatalogue.end(); ++it) {
+			if ((*it)->languageName && (0 == strcmp((*it)->languageName, languageName))) {
+				return *it;
+			}
+		}
+	}
+	return 0;
+}
+
+void Catalogue::AddLexerModule(LexerModule *plm) {
+	if (plm->GetLanguage() == SCLEX_AUTOMATIC) {
+		plm->language = nextLanguage;
+		nextLanguage++;
+	}
+	lexerCatalogue.push_back(plm);
+}
+
+// Alternative historical name for Scintilla_LinkLexers
+int wxForceScintillaLexers(void) {
+	return Scintilla_LinkLexers();
+}
+
+// To add or remove a lexer, add or remove its file and run LexGen.py.
+
+// Force a reference to all of the Scintilla lexers so that the linker will
+// not remove the code of the lexers.
+int Scintilla_LinkLexers() {
+
+	static int initialised = 0;
+	if (initialised)
+		return 0;
+	initialised = 1;
+
+// Shorten the code that declares a lexer and ensures it is linked in by calling a method.
+#define LINK_LEXER(lexer) extern LexerModule lexer; Catalogue::AddLexerModule(&lexer);
+
+//++Autogenerated -- run src/LexGen.py to regenerate
+//**\(\tLINK_LEXER(\*);\n\)
+	LINK_LEXER(lmA68k);
+	LINK_LEXER(lmAbaqus);
+	LINK_LEXER(lmAda);
+	LINK_LEXER(lmAns1);
+	LINK_LEXER(lmAPDL);
+	LINK_LEXER(lmAsm);
+	LINK_LEXER(lmASY);
+	LINK_LEXER(lmAU3);
+	LINK_LEXER(lmAVE);
+	LINK_LEXER(lmBaan);
+	LINK_LEXER(lmBash);
+	LINK_LEXER(lmBatch);
+	LINK_LEXER(lmBlitzBasic);
+	LINK_LEXER(lmBullant);
+	LINK_LEXER(lmCaml);
+	LINK_LEXER(lmClw);
+	LINK_LEXER(lmClwNoCase);
+	LINK_LEXER(lmCmake);
+	LINK_LEXER(lmCOBOL);
+	LINK_LEXER(lmConf);
+	LINK_LEXER(lmCPP);
+	LINK_LEXER(lmCPPNoCase);
+	LINK_LEXER(lmCsound);
+	LINK_LEXER(lmCss);
+	LINK_LEXER(lmD);
+	LINK_LEXER(lmDiff);
+	LINK_LEXER(lmEiffel);
+	LINK_LEXER(lmEiffelkw);
+	LINK_LEXER(lmErlang);
+	LINK_LEXER(lmErrorList);
+	LINK_LEXER(lmESCRIPT);
+	LINK_LEXER(lmF77);
+	LINK_LEXER(lmFlagShip);
+	LINK_LEXER(lmForth);
+	LINK_LEXER(lmFortran);
+	LINK_LEXER(lmFreeBasic);
+	LINK_LEXER(lmGAP);
+	LINK_LEXER(lmGui4Cli);
+	LINK_LEXER(lmHaskell);
+	LINK_LEXER(lmHTML);
+	LINK_LEXER(lmInno);
+	LINK_LEXER(lmKix);
+	LINK_LEXER(lmLatex);
+	LINK_LEXER(lmLISP);
+	LINK_LEXER(lmLot);
+	LINK_LEXER(lmLout);
+	LINK_LEXER(lmLua);
+	LINK_LEXER(lmMagikSF);
+	LINK_LEXER(lmMake);
+	LINK_LEXER(lmMarkdown);
+	LINK_LEXER(lmMatlab);
+	LINK_LEXER(lmMETAPOST);
+	LINK_LEXER(lmMMIXAL);
+	LINK_LEXER(lmModula);
+	LINK_LEXER(lmMSSQL);
+	LINK_LEXER(lmMySQL);
+	LINK_LEXER(lmNimrod);
+	LINK_LEXER(lmNncrontab);
+	LINK_LEXER(lmNsis);
+	LINK_LEXER(lmNull);
+	LINK_LEXER(lmOctave);
+	LINK_LEXER(lmOpal);
+	LINK_LEXER(lmPascal);
+	LINK_LEXER(lmPB);
+	LINK_LEXER(lmPerl);
+	LINK_LEXER(lmPHPSCRIPT);
+	LINK_LEXER(lmPLM);
+	LINK_LEXER(lmPo);
+	LINK_LEXER(lmPOV);
+	LINK_LEXER(lmPowerPro);
+	LINK_LEXER(lmPowerShell);
+	LINK_LEXER(lmProgress);
+	LINK_LEXER(lmProps);
+	LINK_LEXER(lmPS);
+	LINK_LEXER(lmPureBasic);
+	LINK_LEXER(lmPython);
+	LINK_LEXER(lmR);
+	LINK_LEXER(lmREBOL);
+	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(lmTxt2tags);
+	LINK_LEXER(lmVB);
+	LINK_LEXER(lmVBScript);
+	LINK_LEXER(lmVerilog);
+	LINK_LEXER(lmVHDL);
+	LINK_LEXER(lmXML);
+	LINK_LEXER(lmYAML);
+
+//--Autogenerated -- end of automatically generated section
+
+	return 1;
+}
diff --git a/plugins/scintilla/scintilla/Catalogue.h b/plugins/scintilla/scintilla/Catalogue.h
new file mode 100644
index 0000000..7fea37d
--- /dev/null
+++ b/plugins/scintilla/scintilla/Catalogue.h
@@ -0,0 +1,26 @@
+// Scintilla source code edit control
+/** @file Catalogue.h
+ ** Lexer infrastructure.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef CATALOGUE_H
+#define CATALOGUE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class Catalogue {
+public:
+	static const LexerModule *Find(int language);
+	static const LexerModule *Find(const char *languageName);
+	static void AddLexerModule(LexerModule *plm);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/CellBuffer.cxx b/plugins/scintilla/scintilla/CellBuffer.cxx
index be04403..19f6670 100644
--- a/plugins/scintilla/scintilla/CellBuffer.cxx
+++ b/plugins/scintilla/scintilla/CellBuffer.cxx
@@ -44,9 +44,11 @@ void LineVector::InsertText(int line, int delta) {
 	starts.InsertText(line, delta);
 }
 
-void LineVector::InsertLine(int line, int position) {
+void LineVector::InsertLine(int line, int position, bool lineStart) {
 	starts.InsertPartition(line, position);
 	if (perLine) {
+		if ((line > 0) && lineStart)
+			line--;
 		perLine->InsertLine(line);
 	}
 }
@@ -197,7 +199,7 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng
 				// Insertions must be immediately after to coalesce
 				currentAction++;
 			} else if (at == removeAction) {
-				if ((lengthData == 1) || (lengthData == 2)){
+				if ((lengthData == 1) || (lengthData == 2)) {
 					if ((position + lengthData) == actPrevious->position) {
 						; // Backspace -> OK
 					} else if (position == actPrevious->position) {
@@ -339,7 +341,7 @@ char CellBuffer::CharAt(int position) const {
 	return substance.ValueAt(position);
 }
 
-void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) {
+void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) const {
 	if (lengthRetrieve < 0)
 		return;
 	if (position < 0)
@@ -349,17 +351,27 @@ void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) {
 		                      lengthRetrieve, substance.Length());
 		return;
 	}
-	
-	for (int i=0; i<lengthRetrieve; i++) {
-		*buffer++ = substance.ValueAt(position + i);
-	}
+	substance.GetRange(buffer, position, lengthRetrieve);
 }
 
-char CellBuffer::StyleAt(int position) {
+char CellBuffer::StyleAt(int position) const {
 	return style.ValueAt(position);
 }
 
-const char *CellBuffer::BufferPointer() { 
+void CellBuffer::GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const {
+	if (lengthRetrieve < 0)
+		return;
+	if (position < 0)
+		return;
+	if ((position + lengthRetrieve) > style.Length()) {
+		Platform::DebugPrintf("Bad GetStyleRange %d for %d of %d\n", position,
+		                      lengthRetrieve, style.Length());
+		return;
+	}
+	style.GetRange(reinterpret_cast<char *>(buffer), position, lengthRetrieve);
+}
+
+const char *CellBuffer::BufferPointer() {
 	return substance.BufferPointer();
 }
 
@@ -455,7 +467,7 @@ int CellBuffer::LineStart(int line) const {
 		return lv.LineStart(line);
 }
 
-bool CellBuffer::IsReadOnly() {
+bool CellBuffer::IsReadOnly() const {
 	return readOnly;
 }
 
@@ -473,8 +485,8 @@ bool CellBuffer::IsSavePoint() {
 
 // Without undo
 
-void CellBuffer::InsertLine(int line, int position) {
-	lv.InsertLine(line, position);
+void CellBuffer::InsertLine(int line, int position, bool lineStart) {
+	lv.InsertLine(line, position, lineStart);
 }
 
 void CellBuffer::RemoveLine(int line) {
@@ -490,27 +502,28 @@ void CellBuffer::BasicInsertString(int position, const char *s, int insertLength
 	style.InsertValue(position, insertLength, 0);
 
 	int lineInsert = lv.LineFromPosition(position) + 1;
+	bool atLineStart = lv.LineStart(lineInsert-1) == position;
 	// Point all the lines after the insertion point further along in the buffer
 	lv.InsertText(lineInsert-1, insertLength);
 	char chPrev = substance.ValueAt(position - 1);
 	char chAfter = substance.ValueAt(position + insertLength);
 	if (chPrev == '\r' && chAfter == '\n') {
 		// Splitting up a crlf pair at position
-		InsertLine(lineInsert, position);
+		InsertLine(lineInsert, position, false);
 		lineInsert++;
 	}
 	char ch = ' ';
 	for (int i = 0; i < insertLength; i++) {
 		ch = s[i];
 		if (ch == '\r') {
-			InsertLine(lineInsert, (position + i) + 1);
+			InsertLine(lineInsert, (position + i) + 1, atLineStart);
 			lineInsert++;
 		} else if (ch == '\n') {
 			if (chPrev == '\r') {
 				// Patch up what was end of line
 				lv.SetLineStart(lineInsert - 1, (position + i) + 1);
 			} else {
-				InsertLine(lineInsert, (position + i) + 1);
+				InsertLine(lineInsert, (position + i) + 1, atLineStart);
 				lineInsert++;
 			}
 		}
@@ -586,7 +599,7 @@ bool CellBuffer::SetUndoCollection(bool collectUndo) {
 	return collectingUndo;
 }
 
-bool CellBuffer::IsCollectingUndo() {
+bool CellBuffer::IsCollectingUndo() const {
 	return collectingUndo;
 }
 
diff --git a/plugins/scintilla/scintilla/CellBuffer.h b/plugins/scintilla/scintilla/CellBuffer.h
index 3381c19..a82a397 100644
--- a/plugins/scintilla/scintilla/CellBuffer.h
+++ b/plugins/scintilla/scintilla/CellBuffer.h
@@ -37,7 +37,7 @@ public:
 	void SetPerLine(PerLine *pl);
 
 	void InsertText(int line, int delta);
-	void InsertLine(int line, int position);
+	void InsertLine(int line, int position, bool lineStart);
 	void SetLineStart(int line, int position);
 	void RemoveLine(int line);
 	int Lines() const {
@@ -142,6 +142,10 @@ private:
 
 	LineVector lv;
 
+	/// Actions without undo
+	void BasicInsertString(int position, const char *s, int insertLength);
+	void BasicDeleteChars(int position, int deleteLength);
+
 public:
 
 	CellBuffer();
@@ -149,8 +153,9 @@ public:
 
 	/// Retrieving positions outside the range of the buffer works and returns 0
 	char CharAt(int position) const;
-	void GetCharRange(char *buffer, int position, int lengthRetrieve);
-	char StyleAt(int position);
+	void GetCharRange(char *buffer, int position, int lengthRetrieve) const;
+	char StyleAt(int position) const;
+	void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const;
 	const char *BufferPointer();
 
 	int Length() const;
@@ -159,7 +164,7 @@ public:
 	int Lines() const;
 	int LineStart(int line) const;
 	int LineFromPosition(int pos) const { return lv.LineFromPosition(pos); }
-	void InsertLine(int line, int position);
+	void InsertLine(int line, int position, bool lineStart);
 	void RemoveLine(int line);
 	const char *InsertString(int position, const char *s, int insertLength, bool &startSequence);
 
@@ -170,7 +175,7 @@ public:
 
 	const char *DeleteChars(int position, int deleteLength, bool &startSequence);
 
-	bool IsReadOnly();
+	bool IsReadOnly() const;
 	void SetReadOnly(bool set);
 
 	/// The save point is a marker in the undo stack where the container has stated that
@@ -178,12 +183,8 @@ public:
 	void SetSavePoint();
 	bool IsSavePoint();
 
-	/// Actions without undo
-	void BasicInsertString(int position, const char *s, int insertLength);
-	void BasicDeleteChars(int position, int deleteLength);
-
 	bool SetUndoCollection(bool collectUndo);
-	bool IsCollectingUndo();
+	bool IsCollectingUndo() const;
 	void BeginUndoAction();
 	void EndUndoAction();
 	void AddUndoAction(int token, bool mayCoalesce);
diff --git a/plugins/scintilla/scintilla/CharClassify.cxx b/plugins/scintilla/scintilla/CharClassify.cxx
index bbd25a0..c16af45 100644
--- a/plugins/scintilla/scintilla/CharClassify.cxx
+++ b/plugins/scintilla/scintilla/CharClassify.cxx
@@ -10,6 +10,10 @@
 
 #include "CharClassify.h"
 
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
 // Shut up annoying Visual C++ warnings:
 #ifdef _MSC_VER
 #pragma warning(disable: 4514)
@@ -42,37 +46,3 @@ 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 d746fe0..e8b798e 100644
--- a/plugins/scintilla/scintilla/CharClassify.h
+++ b/plugins/scintilla/scintilla/CharClassify.h
@@ -8,6 +8,10 @@
 #ifndef CHARCLASSIFY_H
 #define CHARCLASSIFY_H
 
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
 class CharClassify {
 public:
 	CharClassify();
@@ -23,15 +27,8 @@ private:
 	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');
+#ifdef SCI_NAMESPACE
 }
+#endif
 
 #endif
diff --git a/plugins/scintilla/scintilla/CharacterSet.cxx b/plugins/scintilla/scintilla/CharacterSet.cxx
new file mode 100644
index 0000000..35669df
--- /dev/null
+++ b/plugins/scintilla/scintilla/CharacterSet.cxx
@@ -0,0 +1,61 @@
+// Scintilla source code edit control
+/** @file CharacterSet.cxx
+ ** Simple case functions for ASCII.
+ ** Lexer infrastructure.
+ **/
+// Copyright 1998-2010 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 <assert.h>
+
+#include "CharacterSet.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+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;
+}
+
+#ifdef SCI_NAMESPACE
+}
+#endif
diff --git a/plugins/scintilla/scintilla/CharacterSet.h b/plugins/scintilla/scintilla/CharacterSet.h
index 4e8ffbd..ba42ea3 100644
--- a/plugins/scintilla/scintilla/CharacterSet.h
+++ b/plugins/scintilla/scintilla/CharacterSet.h
@@ -5,6 +5,13 @@
 // Copyright 2007 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
+#ifndef CHARACTERSET_H
+#define CHARACTERSET_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
 class CharacterSet {
 	int size;
 	bool valueAfter;
@@ -39,20 +46,103 @@ public:
 		size = 0;
 	}
 	void Add(int val) {
-		PLATFORM_ASSERT(val >= 0);
-		PLATFORM_ASSERT(val < size);
+		assert(val >= 0);
+		assert(val < size);
 		bset[val] = true;
 	}
-	void AddString(const char *CharacterSet) {
-		for (const char *cp=CharacterSet; *cp; cp++) {
+	void AddString(const char *setToAdd) {
+		for (const char *cp=setToAdd; *cp; cp++) {
 			int val = static_cast<unsigned char>(*cp);
-			PLATFORM_ASSERT(val >= 0);
-			PLATFORM_ASSERT(val < size);
+			assert(val >= 0);
+			assert(val < size);
 			bset[val] = true;
 		}
 	}
 	bool Contains(int val) const {
-		PLATFORM_ASSERT(val >= 0);
+		assert(val >= 0);
+		if (val < 0) return false;
 		return (val < size) ? bset[val] : valueAfter;
 	}
 };
+
+// Functions for classifying characters
+
+inline bool IsASpace(int ch) {
+    return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
+inline bool IsASpaceOrTab(int ch) {
+	return (ch == ' ') || (ch == '\t');
+}
+
+inline bool IsADigit(int ch) {
+	return (ch >= '0') && (ch <= '9');
+}
+
+inline bool IsADigit(int ch, int base) {
+	if (base <= 10) {
+		return (ch >= '0') && (ch < '0' + base);
+	} else {
+		return ((ch >= '0') && (ch <= '9')) ||
+		       ((ch >= 'A') && (ch < 'A' + base - 10)) ||
+		       ((ch >= 'a') && (ch < 'a' + base - 10));
+	}
+}
+
+inline bool IsASCII(int ch) {
+	return ch < 0x80;
+}
+
+inline bool IsAlphaNumeric(int ch) {
+	return
+		((ch >= '0') && (ch <= '9')) ||
+		((ch >= 'a') && (ch <= 'z')) ||
+		((ch >= 'A') && (ch <= 'Z'));
+}
+
+/**
+ * Check if a character is a space.
+ * This is ASCII specific but is safe with chars >= 0x80.
+ */
+inline bool isspacechar(int ch) {
+    return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
+inline bool iswordchar(int ch) {
+	return IsASCII(ch) && (IsAlphaNumeric(ch) || ch == '.' || ch == '_');
+}
+
+inline bool iswordstart(int ch) {
+	return IsASCII(ch) && (IsAlphaNumeric(ch) || ch == '_');
+}
+
+inline bool isoperator(int ch) {
+	if (IsASCII(ch) && IsAlphaNumeric(ch))
+		return false;
+	if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
+	        ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
+	        ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
+	        ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
+	        ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
+	        ch == '?' || ch == '!' || ch == '.' || ch == '~')
+		return true;
+	return false;
+}
+
+// Simple case functions for ASCII.
+
+inline char MakeUpperCase(char ch) {
+	if (ch < 'a' || ch > 'z')
+		return ch;
+	else
+		return static_cast<char>(ch - 'a' + 'A');
+}
+
+int CompareCaseInsensitive(const char *a, const char *b);
+int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/ContractionState.cxx b/plugins/scintilla/scintilla/ContractionState.cxx
index 08de5cf..8a1b486 100644
--- a/plugins/scintilla/scintilla/ContractionState.cxx
+++ b/plugins/scintilla/scintilla/ContractionState.cxx
@@ -193,6 +193,23 @@ bool ContractionState::SetExpanded(int lineDoc, bool expanded_) {
 	}
 }
 
+int ContractionState::ContractedNext(int lineDocStart) const {
+	if (OneToOne()) {
+		return -1;
+	} else {
+		Check();
+		if (!expanded->ValueAt(lineDocStart)) {
+			return lineDocStart;
+		} else {
+			int lineDocNextChange = expanded->EndRun(lineDocStart);
+			if (lineDocNextChange < LinesInDoc())
+				return lineDocNextChange;
+			else
+				return -1;
+		}
+	}
+}
+
 int ContractionState::GetHeight(int lineDoc) const {
 	if (OneToOne()) {
 		return 1;
@@ -232,11 +249,11 @@ void ContractionState::ShowAll() {
 
 void ContractionState::Check() const {
 #ifdef CHECK_CORRECTNESS
-	for (int vline = 0;vline < LinesDisplayed(); vline++) {
+	for (int vline = 0; vline < LinesDisplayed(); vline++) {
 		const int lineDoc = DocFromDisplay(vline);
 		PLATFORM_ASSERT(GetVisible(lineDoc));
 	}
-	for (int lineDoc = 0;lineDoc < LinesInDoc(); lineDoc++) {
+	for (int lineDoc = 0; lineDoc < LinesInDoc(); lineDoc++) {
 		const int displayThis = DisplayFromDoc(lineDoc);
 		const int displayNext = DisplayFromDoc(lineDoc + 1);
 		const int height = displayNext - displayThis;
diff --git a/plugins/scintilla/scintilla/ContractionState.h b/plugins/scintilla/scintilla/ContractionState.h
index ba62975..8e7b39b 100644
--- a/plugins/scintilla/scintilla/ContractionState.h
+++ b/plugins/scintilla/scintilla/ContractionState.h
@@ -51,6 +51,7 @@ public:
 
 	bool GetExpanded(int lineDoc) const;
 	bool SetExpanded(int lineDoc, bool expanded);
+	int ContractedNext(int lineDocStart) const;
 
 	int GetHeight(int lineDoc) const;
 	bool SetHeight(int lineDoc, int height);
diff --git a/plugins/scintilla/scintilla/Converter.h b/plugins/scintilla/scintilla/Converter.h
index d3038a2..8e7e3e9 100644
--- a/plugins/scintilla/scintilla/Converter.h
+++ b/plugins/scintilla/scintilla/Converter.h
@@ -3,12 +3,7 @@
 // Copyright 2004 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
-#include <iconv.h>
-#if GTK_MAJOR_VERSION >= 2
-	typedef GIConv ConverterHandle;
-#else
-	typedef iconv_t ConverterHandle;
-#endif
+typedef GIConv ConverterHandle;
 const ConverterHandle iconvhBad = (ConverterHandle)(-1);
 // Since various versions of iconv can not agree on whether the src argument
 // is char ** or const char ** provide a templatised adaptor.
@@ -24,11 +19,7 @@ size_t iconv_adaptor(size_t(*f_iconv)(ConverterHandle, T, size_t *, char **, siz
 class Converter {
 	ConverterHandle iconvh;
 	void OpenHandle(const char *fullDestination, const char *charSetSource) {
-#if GTK_MAJOR_VERSION >= 2
 		iconvh = g_iconv_open(fullDestination, charSetSource);
-#else
-		iconvh = iconv_open(fullDestination, charSetSource);
-#endif
 	}
 	bool Succeeded() const {
 		return iconvh != iconvhBad;
@@ -65,11 +56,7 @@ public:
 	}
 	void Close() {
 		if (Succeeded()) {
-#if GTK_MAJOR_VERSION >= 2
 			g_iconv_close(iconvh);
-#else
-			iconv_close(iconvh);
-#endif
 			iconvh = iconvhBad;
 		}
 	}
@@ -77,11 +64,7 @@ public:
 		if (!Succeeded()) {
 			return (size_t)(-1);
 		} else {
-#if GTK_MAJOR_VERSION >= 2
 			return iconv_adaptor(g_iconv, iconvh, src, srcleft, dst, dstleft);
-#else
-			return iconv_adaptor(iconv, iconvh, src, srcleft, dst, dstleft);
-#endif
 		}
 	}
 };
diff --git a/plugins/scintilla/scintilla/Decoration.h b/plugins/scintilla/scintilla/Decoration.h
index 2809641..fedff97 100644
--- a/plugins/scintilla/scintilla/Decoration.h
+++ b/plugins/scintilla/scintilla/Decoration.h
@@ -40,10 +40,10 @@ public:
 	~DecorationList();
 
 	void SetCurrentIndicator(int indicator);
-	int GetCurrentIndicator() { return currentIndicator; }
+	int GetCurrentIndicator() const { return currentIndicator; }
 
 	void SetCurrentValue(int value);
-	int GetCurrentValue() { return currentValue; }
+	int GetCurrentValue() const { return currentValue; }
 
 	// Returns true if some values may have changed
 	bool FillRange(int &position, int value, int &fillLength);
diff --git a/plugins/scintilla/scintilla/Document.cxx b/plugins/scintilla/scintilla/Document.cxx
index a5d1adb..7b718f2 100644
--- a/plugins/scintilla/scintilla/Document.cxx
+++ b/plugins/scintilla/scintilla/Document.cxx
@@ -2,26 +2,34 @@
 /** @file Document.cxx
  ** Text document that handles notifications, DBCS, styling, words and end of line.
  **/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 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 <stdio.h>
 #include <ctype.h>
+#include <assert.h>
+
+#include <string>
+#include <vector>
 
 #include "Platform.h"
 
+#include "ILexer.h"
 #include "Scintilla.h"
+
 #include "SplitVector.h"
 #include "Partitioning.h"
 #include "RunStyles.h"
 #include "CellBuffer.h"
 #include "PerLine.h"
 #include "CharClassify.h"
+#include "CharacterSet.h"
 #include "Decoration.h"
 #include "Document.h"
 #include "RESearch.h"
+#include "UniConversion.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -48,9 +56,38 @@ static inline bool IsUpperCase(char ch) {
 	return isascii(ch) && isupper(ch);
 }
 
+void LexInterface::Colourise(int start, int end) {
+	ElapsedTime et;
+	if (pdoc && instance && !performingStyle) {
+		// Protect against reentrance, which may occur, for example, when
+		// fold points are discovered while performing styling and the folding
+		// code looks for child lines which may trigger styling.
+		performingStyle = true;
+
+		int lengthDoc = pdoc->Length();
+		if (end == -1)
+			end = lengthDoc;
+		int len = end - start;
+
+		PLATFORM_ASSERT(len >= 0);
+		PLATFORM_ASSERT(start + len <= lengthDoc);
+
+		int styleStart = 0;
+		if (start > 0)
+			styleStart = pdoc->StyleAt(start - 1) & pdoc->stylingBitsMask;
+
+		if (len > 0) {
+			instance->Lex(start, len, styleStart, pdoc);
+			instance->Fold(start, len, styleStart, pdoc);
+		}
+
+		performingStyle = false;
+	}
+}
+
 Document::Document() {
 	refCount = 0;
-#ifdef unix
+#ifdef __unix__
 	eolMode = SC_EOL_LF;
 #else
 	eolMode = SC_EOL_CRLF;
@@ -83,6 +120,8 @@ Document::Document() {
 	perLineData[ldAnnotation] = new LineAnnotation();
 
 	cb.SetPerLine(this);
+
+	pli = 0;
 }
 
 Document::~Document() {
@@ -98,6 +137,8 @@ Document::~Document() {
 	lenWatchers = 0;
 	delete regex;
 	regex = 0;
+	delete pli;
+	pli = 0;
 }
 
 void Document::Init() {
@@ -140,13 +181,13 @@ void Document::SetSavePoint() {
 	NotifySavePoint(true);
 }
 
-int Document::GetMark(int line) { 
-	return static_cast<LineMarkers*>(perLineData[ldMarkers])->MarkValue(line); 
+int Document::GetMark(int line) {
+	return static_cast<LineMarkers *>(perLineData[ldMarkers])->MarkValue(line);
 }
 
 int Document::AddMark(int line, int markerNum) {
-	if (line <= LinesTotal()) {
-		int prev = static_cast<LineMarkers*>(perLineData[ldMarkers])->
+	if (line >= 0 && 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);
@@ -157,42 +198,49 @@ int Document::AddMark(int line, int markerNum) {
 }
 
 void Document::AddMarkSet(int line, int valueSet) {
+	if (line < 0 || line > LinesTotal()) {
+		return;
+	}
 	unsigned int m = valueSet;
 	for (int i = 0; m; i++, m >>= 1)
 		if (m & 1)
-			static_cast<LineMarkers*>(perLineData[ldMarkers])->
+			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) {
-	static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMark(line, markerNum, false);
+	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) {
-	static_cast<LineMarkers*>(perLineData[ldMarkers])->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) {
+	bool someChanges = false;
 	for (int line = 0; line < LinesTotal(); line++) {
-		static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMark(line, markerNum, true);
+		if (static_cast<LineMarkers *>(perLineData[ldMarkers])->DeleteMark(line, markerNum, true))
+			someChanges = true;
+	}
+	if (someChanges) {
+		DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
+		mh.line = -1;
+		NotifyModified(mh);
 	}
-	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::LineFromHandle(int markerHandle) {
+	return static_cast<LineMarkers *>(perLineData[ldMarkers])->LineFromHandle(markerHandle);
 }
 
-int Document::LineStart(int line) const {
+int SCI_METHOD Document::LineStart(int line) const {
 	return cb.LineStart(line);
 }
 
@@ -209,7 +257,14 @@ int Document::LineEnd(int line) const {
 	}
 }
 
-int Document::LineFromPosition(int pos) const {
+void SCI_METHOD Document::SetErrorStatus(int status) {
+	// Tell the watchers the lexer has changed.
+	for (int i = 0; i < lenWatchers; i++) {
+		watchers[i].watcher->NotifyErrorOccurred(this, watchers[i].userData, status);
+	}
+}
+
+int SCI_METHOD Document::LineFromPosition(int pos) const {
 	return cb.LineFromPosition(pos);
 }
 
@@ -226,7 +281,7 @@ int Document::VCHomePosition(int position) const {
 	int startPosition = LineStart(line);
 	int endLine = LineEnd(line);
 	int startText = startPosition;
-	while (startText < endLine && (cb.CharAt(startText) == ' ' || cb.CharAt(startText) == '\t' ) )
+	while (startText < endLine && (cb.CharAt(startText) == ' ' || cb.CharAt(startText) == '\t'))
 		startText++;
 	if (position == startText)
 		return startPosition;
@@ -234,8 +289,8 @@ int Document::VCHomePosition(int position) const {
 		return startText;
 }
 
-int Document::SetLevel(int line, int level) {
-	int prev = static_cast<LineLevels*>(perLineData[ldLevels])->SetLevel(line, level, LinesTotal());
+int SCI_METHOD Document::SetLevel(int line, int 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);
@@ -246,12 +301,12 @@ int Document::SetLevel(int line, int level) {
 	return prev;
 }
 
-int Document::GetLevel(int line) { 
-	return static_cast<LineLevels*>(perLineData[ldLevels])->GetLevel(line); 
+int SCI_METHOD Document::GetLevel(int line) const {
+	return static_cast<LineLevels *>(perLineData[ldLevels])->GetLevel(line);
 }
 
-void Document::ClearLevels() { 
-	static_cast<LineLevels*>(perLineData[ldLevels])->ClearLevels(); 
+void Document::ClearLevels() {
+	static_cast<LineLevels *>(perLineData[ldLevels])->ClearLevels();
 }
 
 static bool IsSubordinate(int levelStart, int levelTry) {
@@ -300,6 +355,110 @@ int Document::GetFoldParent(int line) {
 	}
 }
 
+void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, int line, int topLine, int bottomLine) {
+	int noNeedToParseBefore = Platform::Minimum(line, topLine) - 1;
+	int noNeedToParseAfter = Platform::Maximum(line, bottomLine) + 1;
+	int endLine = LineFromPosition(Length());
+	int beginFoldBlock = noNeedToParseBefore;
+	int endFoldBlock = -1;
+	int beginMarginCorrectlyDrawnZone = noNeedToParseBefore;
+	int endMarginCorrectlyDrawnZone = noNeedToParseAfter;
+	int endOfTailOfWhiteFlag = -1; //endOfTailOfWhiteFlag points the last SC_FOLDLEVELWHITEFLAG if follow a fold block. Otherwise endOfTailOfWhiteFlag points end of fold block.
+	int level = GetLevel(line);
+	int levelNumber = -1;
+	int lineLookLevel = 0;
+	int lineLookLevelNumber = -1;
+	int lineLook = line;
+	bool beginFoldBlockFound = false;
+	bool endFoldBlockFound = false;
+	bool beginMarginCorrectlyDrawnZoneFound = false;
+	bool endMarginCorrectlyDrawnZoneFound = false;
+
+	/*******************************************************************************/
+	/*      search backward (beginFoldBlock & beginMarginCorrectlyDrawnZone)       */
+	/*******************************************************************************/
+	for (endOfTailOfWhiteFlag = line; (lineLook > noNeedToParseBefore || (lineLookLevel & SC_FOLDLEVELWHITEFLAG)) && (!beginFoldBlockFound || !beginMarginCorrectlyDrawnZoneFound); --lineLook) {
+		lineLookLevel = GetLevel(lineLook);
+		if (levelNumber != -1) {
+			lineLookLevelNumber = lineLookLevel & SC_FOLDLEVELNUMBERMASK;
+			if (!beginMarginCorrectlyDrawnZoneFound && (lineLookLevelNumber > levelNumber)) {
+				beginMarginCorrectlyDrawnZoneFound = true;
+				beginMarginCorrectlyDrawnZone = endOfTailOfWhiteFlag;
+			}
+			//find the last space line (SC_FOLDLEVELWHITEFLAG).
+			if (!beginMarginCorrectlyDrawnZoneFound && !(lineLookLevel & SC_FOLDLEVELWHITEFLAG)) {
+				endOfTailOfWhiteFlag = lineLook - 1;
+			}
+			if (!beginFoldBlockFound && (lineLookLevelNumber < levelNumber)) {
+				beginFoldBlockFound = true;
+				beginFoldBlock = lineLook;
+				if (!beginMarginCorrectlyDrawnZoneFound) {
+					beginMarginCorrectlyDrawnZoneFound = true;
+					beginMarginCorrectlyDrawnZone = lineLook - 1;
+				}
+			} else 	if (!beginFoldBlockFound && lineLookLevelNumber == SC_FOLDLEVELBASE) {
+				beginFoldBlockFound = true;
+				beginFoldBlock = -1;
+			}
+		} else if (!(lineLookLevel & SC_FOLDLEVELWHITEFLAG)) {
+			endOfTailOfWhiteFlag = lineLook - 1;
+			levelNumber = lineLookLevel & SC_FOLDLEVELNUMBERMASK;
+			if (lineLookLevel & SC_FOLDLEVELHEADERFLAG &&
+			        //Managed the folding block when a fold header does not have any subordinate lines to fold away.
+			        (levelNumber < (GetLevel(lineLook + 1) & SC_FOLDLEVELNUMBERMASK))) {
+				beginFoldBlockFound = true;
+				beginFoldBlock = lineLook;
+				beginMarginCorrectlyDrawnZoneFound = true;
+				beginMarginCorrectlyDrawnZone = endOfTailOfWhiteFlag;
+				levelNumber = GetLevel(lineLook + 1) & SC_FOLDLEVELNUMBERMASK;;
+			}
+		}
+	}
+
+	/****************************************************************************/
+	/*       search forward (endStartBlock & endMarginCorrectlyDrawnZone)       */
+	/****************************************************************************/
+	if (level & SC_FOLDLEVELHEADERFLAG) {
+		//ignore this line because this line is on first one of block.
+		lineLook = line + 1;
+	} else {
+		lineLook = line;
+	}
+	for (; lineLook < noNeedToParseAfter && (!endFoldBlockFound || !endMarginCorrectlyDrawnZoneFound); ++lineLook) {
+		lineLookLevel = GetLevel(lineLook);
+		lineLookLevelNumber = lineLookLevel & SC_FOLDLEVELNUMBERMASK;
+		if (!endFoldBlockFound && !(lineLookLevel & SC_FOLDLEVELWHITEFLAG) && lineLookLevelNumber < levelNumber) {
+			endFoldBlockFound = true;
+			endFoldBlock = lineLook - 1;
+			if (!endMarginCorrectlyDrawnZoneFound) {
+				endMarginCorrectlyDrawnZoneFound = true;
+				endMarginCorrectlyDrawnZone = lineLook;
+			}
+		} else if (!endFoldBlockFound && lineLookLevel == SC_FOLDLEVELBASE) {
+			endFoldBlockFound = true;
+			endFoldBlock = -1;
+		}
+		if (!endMarginCorrectlyDrawnZoneFound && (lineLookLevel & SC_FOLDLEVELHEADERFLAG) &&
+		        //Managed the folding block when a fold header does not have any subordinate lines to fold away.
+		        (levelNumber < (GetLevel(lineLook + 1) & SC_FOLDLEVELNUMBERMASK))) {
+			endMarginCorrectlyDrawnZoneFound = true;
+			endMarginCorrectlyDrawnZone = lineLook;
+		}
+	}
+	if (!endFoldBlockFound && ((lineLook > endLine && lineLookLevelNumber < levelNumber) ||
+	        (levelNumber > SC_FOLDLEVELBASE))) {
+		//manage when endfold is incorrect or on last line.
+		endFoldBlock = lineLook - 1;
+		//useless to set endMarginCorrectlyDrawnZone.
+		//if endMarginCorrectlyDrawnZoneFound equals false then endMarginCorrectlyDrawnZone already equals to endLine + 1.
+	}
+
+	highlightDelimiter.beginFoldBlock = beginFoldBlock;
+	highlightDelimiter.endFoldBlock = endFoldBlock;
+	highlightDelimiter.beginMarginCorrectlyDrawnZone = beginMarginCorrectlyDrawnZone;
+	highlightDelimiter.endMarginCorrectlyDrawnZone = endMarginCorrectlyDrawnZone;
+}
+
 int Document::ClampPositionIntoDocument(int pos) {
 	return Platform::Clamp(pos, 0, Length());
 }
@@ -312,8 +471,6 @@ bool Document::IsCrLf(int pos) {
 	return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n');
 }
 
-static const int maxBytesInDBCSCharacter=5;
-
 int Document::LenChar(int pos) {
 	if (pos < 0) {
 		return 1;
@@ -334,13 +491,7 @@ int Document::LenChar(int pos) {
 		else
 			return len;
 	} else if (dbcsCodePage) {
-		char mbstr[maxBytesInDBCSCharacter+1];
-		int i;
-		for (i=0; i<Platform::DBCSCharMaxLength(); i++) {
-			mbstr[i] = cb.CharAt(pos+i);
-		}
-		mbstr[i] = '\0';
-		return Platform::DBCSCharLength(dbcsCodePage, mbstr);
+		return IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1;
 	} else {
 		return 1;
 	}
@@ -364,7 +515,7 @@ static int BytesFromLead(int leadByte) {
 	return 0;
 }
 
-bool Document::InGoodUTF8(int pos, int &start, int &end) {
+bool Document::InGoodUTF8(int pos, int &start, int &end) const {
 	int lead = pos;
 	while ((lead>0) && (pos-lead < 4) && IsTrailByte(static_cast<unsigned char>(cb.CharAt(lead-1))))
 		lead--;
@@ -416,8 +567,6 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
 			return pos - 1;
 	}
 
-	// Not between CR and LF
-
 	if (dbcsCodePage) {
 		if (SC_CP_UTF8 == dbcsCodePage) {
 			unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
@@ -433,16 +582,18 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
 		} else {
 			// Anchor DBCS calculations at start of line because start of line can
 			// not be a DBCS trail byte.
-			int posCheck = LineStart(LineFromPosition(pos));
-			while (posCheck < pos) {
-				char mbstr[maxBytesInDBCSCharacter+1];
-				int i;
-				for(i=0;i<Platform::DBCSCharMaxLength();i++) {
-					mbstr[i] = cb.CharAt(posCheck+i);
-				}
-				mbstr[i] = '\0';
+			int posStartLine = LineStart(LineFromPosition(pos));
+			if (pos == posStartLine)
+				return pos;
+
+			// Step back until a non-lead-byte is found.
+			int posCheck = pos;
+			while ((posCheck > posStartLine) && IsDBCSLeadByte(cb.CharAt(posCheck-1)))
+				posCheck--;
 
-				int mbsize = Platform::DBCSCharLength(dbcsCodePage, mbstr);
+			// Check from known start of character.
+			while (posCheck < pos) {
+				int mbsize = IsDBCSLeadByte(cb.CharAt(posCheck)) ? 2 : 1;
 				if (posCheck + mbsize == pos) {
 					return pos;
 				} else if (posCheck + mbsize > pos) {
@@ -460,6 +611,157 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
 	return pos;
 }
 
+// NextPosition moves between valid positions - it can not handle a position in the middle of a
+// multi-byte character. It is used to iterate through text more efficiently than MovePositionOutsideChar.
+// A \r\n pair is treated as two characters.
+int Document::NextPosition(int pos, int moveDir) const {
+	// If out of range, just return minimum/maximum value.
+	int increment = (moveDir > 0) ? 1 : -1;
+	if (pos + increment <= 0)
+		return 0;
+	if (pos + increment >= Length())
+		return Length();
+
+	if (dbcsCodePage) {
+		if (SC_CP_UTF8 == dbcsCodePage) {
+			pos += increment;
+			unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
+			int startUTF = pos;
+			int endUTF = pos;
+			if (IsTrailByte(ch) && InGoodUTF8(pos, startUTF, endUTF)) {
+				// ch is a trail byte within a UTF-8 character
+				if (moveDir > 0)
+					pos = endUTF;
+				else
+					pos = startUTF;
+			}
+		} else {
+			if (moveDir > 0) {
+				int mbsize = IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1;
+				pos += mbsize;
+				if (pos > Length())
+					pos = Length();
+			} else {
+				// Anchor DBCS calculations at start of line because start of line can
+				// not be a DBCS trail byte.
+				int posStartLine = LineStart(LineFromPosition(pos));
+				// See http://msdn.microsoft.com/en-us/library/cc194792%28v=MSDN.10%29.aspx
+				// http://msdn.microsoft.com/en-us/library/cc194790.aspx
+				if ((pos - 1) <= posStartLine) {
+					return pos - 1;
+				} else if (IsDBCSLeadByte(cb.CharAt(pos - 1))) {
+					// Must actually be trail byte
+					return pos - 2;
+				} else {
+					// Otherwise, step back until a non-lead-byte is found.
+					int posTemp = pos - 1;
+					while (posStartLine <= --posTemp && IsDBCSLeadByte(cb.CharAt(posTemp)))
+						;
+					// Now posTemp+1 must point to the beginning of a character,
+					// so figure out whether we went back an even or an odd
+					// number of bytes and go back 1 or 2 bytes, respectively.
+					return (pos - 1 - ((pos - posTemp) & 1));
+				}
+			}
+		}
+	} else {
+		pos += increment;
+	}
+
+	return pos;
+}
+
+bool Document::NextCharacter(int &pos, int moveDir) {
+	// Returns true if pos changed
+	int posNext = NextPosition(pos, moveDir);
+	if (posNext == pos) {
+		return false;
+	} else {
+		pos = posNext;
+		return true;
+	}
+}
+
+int SCI_METHOD Document::CodePage() const {
+	return dbcsCodePage;
+}
+
+bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
+	// Byte ranges found in Wikipedia articles with relevant search strings in each case
+	unsigned char uch = static_cast<unsigned char>(ch);
+	switch (dbcsCodePage) {
+		case 932:
+			// Shift_jis
+			return ((uch >= 0x81) && (uch <= 0x9F)) ||
+				((uch >= 0xE0) && (uch <= 0xEF));
+		case 936:
+			// GBK
+			return (uch >= 0x81) && (uch <= 0xFE);
+		case 949:
+			// Korean Wansung KS C-5601-1987
+			return (uch >= 0x81) && (uch <= 0xFE);
+		case 950:
+			// Big5
+			return (uch >= 0x81) && (uch <= 0xFE);
+		case 1361:
+			// Korean Johab KS C-5601-1992
+			return
+				((uch >= 0x84) && (uch <= 0xD3)) ||
+				((uch >= 0xD8) && (uch <= 0xDE)) ||
+				((uch >= 0xE0) && (uch <= 0xF9));
+	}
+	return false;
+}
+
+inline bool IsSpaceOrTab(int ch) {
+	return ch == ' ' || ch == '\t';
+}
+
+// Need to break text into segments near lengthSegment but taking into
+// account the encoding to not break inside a UTF-8 or DBCS character
+// and also trying to avoid breaking inside a pair of combining characters.
+// The segment length must always be long enough (more than 4 bytes)
+// so that there will be at least one whole character to make a segment.
+// For UTF-8, text must consist only of valid whole characters.
+// In preference order from best to worst:
+//   1) Break after space
+//   2) Break before punctuation
+//   3) Break after whole character
+
+int Document::SafeSegment(const char *text, int length, int lengthSegment) {
+	if (length <= lengthSegment)
+		return length;
+	int lastSpaceBreak = -1;
+	int lastPunctuationBreak = -1;
+	int lastEncodingAllowedBreak = -1;
+	for (int j=0; j < lengthSegment;) {
+		unsigned char ch = static_cast<unsigned char>(text[j]);
+		if (j > 0) {
+			if (IsSpaceOrTab(text[j - 1]) && !IsSpaceOrTab(text[j])) {
+				lastSpaceBreak = j;
+			}
+			if (ch < 'A') {
+				lastPunctuationBreak = j;
+			}
+		}
+		lastEncodingAllowedBreak = j;
+
+		if (dbcsCodePage == SC_CP_UTF8) {
+			j += (ch < 0x80) ? 1 : BytesFromLead(ch);
+		} else if (dbcsCodePage) {
+			j += IsDBCSLeadByte(ch) ? 2 : 1;
+		} else {
+			j++;
+		}
+	}
+	if (lastSpaceBreak >= 0) {
+		return lastSpaceBreak;
+	} else if (lastPunctuationBreak >= 0) {
+		return lastPunctuationBreak;
+	}
+	return lastEncodingAllowedBreak;
+}
+
 void Document::ModifiedAt(int pos) {
 	if (endStyled > pos)
 		endStyled = pos;
@@ -702,7 +1004,7 @@ void Document::DelCharBack(int pos) {
 	} else if (IsCrLf(pos - 2)) {
 		DeleteChars(pos - 2, 2);
 	} else if (dbcsCodePage) {
-		int startChar = MovePositionOutsideChar(pos - 1, -1, false);
+		int startChar = NextPosition(pos, -1);
 		DeleteChars(startChar, pos - startChar);
 	} else {
 		DeleteChars(pos - 1, 1);
@@ -734,12 +1036,12 @@ static void CreateIndentation(char *linebuf, int length, int indent, int tabSize
 	*linebuf = '\0';
 }
 
-int Document::GetLineIndentation(int line) {
+int SCI_METHOD Document::GetLineIndentation(int line) {
 	int indent = 0;
 	if ((line >= 0) && (line < LinesTotal())) {
 		int lineStart = LineStart(line);
 		int length = Length();
-		for (int i = lineStart;i < length;i++) {
+		for (int i = lineStart; i < length; i++) {
 			char ch = cb.CharAt(i);
 			if (ch == ' ')
 				indent++;
@@ -782,7 +1084,7 @@ int Document::GetColumn(int pos) {
 	int column = 0;
 	int line = LineFromPosition(pos);
 	if ((line >= 0) && (line < LinesTotal())) {
-		for (int i = LineStart(line);i < pos;) {
+		for (int i = LineStart(line); i < pos;) {
 			char ch = cb.CharAt(i);
 			if (ch == '\t') {
 				column = NextTab(column, tabInChars);
@@ -795,7 +1097,7 @@ int Document::GetColumn(int pos) {
 				return column;
 			} else {
 				column++;
-				i = MovePositionOutsideChar(i + 1, 1, false);
+				i = NextPosition(i, 1);
 			}
 		}
 	}
@@ -817,7 +1119,7 @@ int Document::FindColumn(int line, int column) {
 				return position;
 			} else {
 				columnCurrent++;
-				position = MovePositionOutsideChar(position + 1, 1, false);
+				position = NextPosition(position, 1);
 			}
 		}
 	}
@@ -969,7 +1271,7 @@ int Document::ExtendWordSelect(int pos, int delta, bool onlyWordCharacters) {
 		while (pos < (Length()) && (WordCharClass(cb.CharAt(pos)) == ccStart))
 			pos++;
 	}
-	return MovePositionOutsideChar(pos, delta);
+	return MovePositionOutsideChar(pos, delta, true);
 }
 
 /**
@@ -1074,79 +1376,199 @@ static inline char MakeLowerCase(char ch) {
 		return static_cast<char>(ch - 'A' + 'a');
 }
 
+static bool GoodTrailByte(int v) {
+	return (v >= 0x80) && (v < 0xc0);
+}
+
+size_t Document::ExtractChar(int pos, char *bytes) {
+	unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
+	size_t widthChar = UTF8CharLength(ch);
+	bytes[0] = ch;
+	for (size_t i=1; i<widthChar; i++) {
+		bytes[i] = cb.CharAt(pos+i);
+		if (!GoodTrailByte(static_cast<unsigned char>(bytes[i]))) { // Bad byte
+			widthChar = 1;
+		}
+	}
+	return widthChar;
+}
+
+CaseFolderTable::CaseFolderTable() {
+	for (size_t iChar=0; iChar<sizeof(mapping); iChar++) {
+		mapping[iChar] = static_cast<char>(iChar);
+	}
+}
+
+CaseFolderTable::~CaseFolderTable() {
+}
+
+size_t CaseFolderTable::Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
+	if (lenMixed > sizeFolded) {
+		return 0;
+	} else {
+		for (size_t i=0; i<lenMixed; i++) {
+			folded[i] = mapping[static_cast<unsigned char>(mixed[i])];
+		}
+		return lenMixed;
+	}
+}
+
+void CaseFolderTable::SetTranslation(char ch, char chTranslation) {
+	mapping[static_cast<unsigned char>(ch)] = chTranslation;
+}
+
+void CaseFolderTable::StandardASCII() {
+	for (size_t iChar=0; iChar<sizeof(mapping); iChar++) {
+		if (iChar >= 'A' && iChar <= 'Z') {
+			mapping[iChar] = static_cast<char>(iChar - 'A' + 'a');
+		} else {
+			mapping[iChar] = static_cast<char>(iChar);
+		}
+	}
+}
+
+bool Document::MatchesWordOptions(bool word, bool wordStart, int pos, int length) {
+	return (!word && !wordStart) ||
+			(word && IsWordAt(pos, pos + length)) ||
+			(wordStart && IsWordStartAt(pos));
+}
+
 /**
  * Find text in document, supporting both forward and backward
  * searches (just pass minPos > maxPos to do a backward search)
  * Has not been tested with backwards DBCS searches yet.
  */
-long Document::FindText(int minPos, int maxPos, const char *s,
+long Document::FindText(int minPos, int maxPos, const char *search,
                         bool caseSensitive, bool word, bool wordStart, bool regExp, int flags,
-                        int *length) {
+                        int *length, CaseFolder *pcf) {
+	if (*length <= 0)
+		return minPos;
 	if (regExp) {
 		if (!regex)
 			regex = CreateRegexSearch(&charClass);
-		return regex->FindText(this, minPos, maxPos, s, caseSensitive, word, wordStart, flags, length);
+		return regex->FindText(this, minPos, maxPos, search, caseSensitive, word, wordStart, flags, length);
 	} else {
 
-		bool forward = minPos <= maxPos;
-		int increment = forward ? 1 : -1;
+		const bool forward = minPos <= maxPos;
+		const int increment = forward ? 1 : -1;
 
 		// Range endpoints should not be inside DBCS characters, but just in case, move them.
-		int startPos = MovePositionOutsideChar(minPos, increment, false);
-		int endPos = MovePositionOutsideChar(maxPos, increment, false);
+		const int startPos = MovePositionOutsideChar(minPos, increment, false);
+		const int endPos = MovePositionOutsideChar(maxPos, increment, false);
 
 		// Compute actual search ranges needed
-		int lengthFind = *length;
-		if (lengthFind == -1)
-			lengthFind = static_cast<int>(strlen(s));
-		int endSearch = endPos;
-		if (startPos <= endPos) {
-			endSearch = endPos - lengthFind + 1;
-		}
+		const int lengthFind = (*length == -1) ? static_cast<int>(strlen(search)) : *length;
+		const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
+
 		//Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
-		char firstChar = s[0];
-		if (!caseSensitive)
-			firstChar = static_cast<char>(MakeUpperCase(firstChar));
-		int pos = forward ? startPos : (startPos - 1);
-		while (forward ? (pos < endSearch) : (pos >= endSearch)) {
-			char ch = CharAt(pos);
-			if (caseSensitive) {
-				if (ch == firstChar) {
-					bool found = true;
-					if (pos + lengthFind > Platform::Maximum(startPos, endPos)) found = false;
-					for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
-						ch = CharAt(pos + posMatch);
-						if (ch != s[posMatch])
-							found = false;
-					}
-					if (found) {
-						if ((!word && !wordStart) ||
-						        (word && IsWordAt(pos, pos + lengthFind)) ||
-						        (wordStart && IsWordStartAt(pos)))
-							return pos;
-					}
+		const int limitPos = Platform::Maximum(startPos, endPos);
+		int pos = startPos;
+		if (!forward) {
+			// Back all of a character
+			pos = NextPosition(pos, increment);
+		}
+		if (caseSensitive) {
+			while (forward ? (pos < endSearch) : (pos >= endSearch)) {
+				bool found = (pos + lengthFind) <= limitPos;
+				for (int indexSearch = 0; (indexSearch < lengthFind) && found; indexSearch++) {
+					found = CharAt(pos + indexSearch) == search[indexSearch];
 				}
-			} else {
-				if (MakeUpperCase(ch) == firstChar) {
-					bool found = true;
-					if (pos + lengthFind > Platform::Maximum(startPos, endPos)) found = false;
-					for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
-						ch = CharAt(pos + posMatch);
-						if (MakeUpperCase(ch) != MakeUpperCase(s[posMatch]))
-							found = false;
+				if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) {
+					return pos;
+				}
+				if (!NextCharacter(pos, increment))
+					break;
+			}
+		} else if (SC_CP_UTF8 == dbcsCodePage) {
+			const size_t maxBytesCharacter = 4;
+			const size_t maxFoldingExpansion = 4;
+			std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1);
+			const int lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
+			while (forward ? (pos < endSearch) : (pos >= endSearch)) {
+				int widthFirstCharacter = 0;
+				int indexDocument = 0;
+				int indexSearch = 0;
+				bool characterMatches = true;
+				while (characterMatches &&
+					((pos + indexDocument) < limitPos) &&
+					(indexSearch < lenSearch)) {
+					char bytes[maxBytesCharacter + 1];
+					bytes[maxBytesCharacter] = 0;
+					const int widthChar = ExtractChar(pos + indexDocument, bytes);
+					if (!widthFirstCharacter)
+						widthFirstCharacter = widthChar;
+					char folded[maxBytesCharacter * maxFoldingExpansion + 1];
+					const int lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar);
+					folded[lenFlat] = 0;
+					// Does folded match the buffer
+					characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
+					indexDocument += widthChar;
+					indexSearch += lenFlat;
+				}
+				if (characterMatches && (indexSearch == static_cast<int>(lenSearch))) {
+					if (MatchesWordOptions(word, wordStart, pos, indexDocument)) {
+						*length = indexDocument;
+						return pos;
 					}
-					if (found) {
-						if ((!word && !wordStart) ||
-						        (word && IsWordAt(pos, pos + lengthFind)) ||
-						        (wordStart && IsWordStartAt(pos)))
-							return pos;
+				}
+				if (forward) {
+					pos += widthFirstCharacter;
+				} else {
+					if (!NextCharacter(pos, increment))
+						break;
+				}
+			}
+		} else if (dbcsCodePage) {
+			const size_t maxBytesCharacter = 2;
+			const size_t maxFoldingExpansion = 4;
+			std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1);
+			const int lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
+			while (forward ? (pos < endSearch) : (pos >= endSearch)) {
+				int indexDocument = 0;
+				int indexSearch = 0;
+				bool characterMatches = true;
+				while (characterMatches &&
+					((pos + indexDocument) < limitPos) &&
+					(indexSearch < lenSearch)) {
+					char bytes[maxBytesCharacter + 1];
+					bytes[0] = cb.CharAt(pos + indexDocument);
+					const int widthChar = IsDBCSLeadByte(bytes[0]) ? 2 : 1;
+					if (widthChar == 2)
+						bytes[1] = cb.CharAt(pos + indexDocument + 1);
+					char folded[maxBytesCharacter * maxFoldingExpansion + 1];
+					const int lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar);
+					folded[lenFlat] = 0;
+					// Does folded match the buffer
+					characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
+					indexDocument += widthChar;
+					indexSearch += lenFlat;
+				}
+				if (characterMatches && (indexSearch == static_cast<int>(lenSearch))) {
+					if (MatchesWordOptions(word, wordStart, pos, indexDocument)) {
+						*length = indexDocument;
+						return pos;
 					}
 				}
+				if (!NextCharacter(pos, increment))
+					break;
 			}
-			pos += increment;
-			if (dbcsCodePage && (pos >= 0)) {
-				// Ensure trying to match from start of character
-				pos = MovePositionOutsideChar(pos, increment, false);
+		} else {
+			CaseFolderTable caseFolder;
+			std::vector<char> searchThing(lengthFind + 1);
+			pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
+			while (forward ? (pos < endSearch) : (pos >= endSearch)) {
+				bool found = (pos + lengthFind) <= limitPos;
+				for (int indexSearch = 0; (indexSearch < lengthFind) && found; indexSearch++) {
+					char ch = CharAt(pos + indexSearch);
+					char folded[2];
+					pcf->Fold(folded, sizeof(folded), &ch, 1);
+					found = folded[0] == searchThing[indexSearch];
+				}
+				if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) {
+					return pos;
+				}
+				if (!NextCharacter(pos, increment))
+					break;
 			}
 		}
 	}
@@ -1155,7 +1577,10 @@ long Document::FindText(int minPos, int maxPos, const char *s,
 }
 
 const char *Document::SubstituteByPosition(const char *text, int *length) {
-	return regex->SubstituteByPosition(this, text, length);
+	if (regex)
+		return regex->SubstituteByPosition(this, text, length);
+	else
+		return 0;
 }
 
 int Document::LinesTotal() const {
@@ -1194,12 +1619,12 @@ void Document::SetStylingBits(int bits) {
 	stylingBitsMask = (1 << stylingBits) - 1;
 }
 
-void Document::StartStyling(int position, char mask) {
+void SCI_METHOD Document::StartStyling(int position, char mask) {
 	stylingMask = mask;
 	endStyled = position;
 }
 
-bool Document::SetStyleFor(int length, char style) {
+bool SCI_METHOD Document::SetStyleFor(int length, char style) {
 	if (enteredStyling != 0) {
 		return false;
 	} else {
@@ -1217,7 +1642,7 @@ bool Document::SetStyleFor(int length, char style) {
 	}
 }
 
-bool Document::SetStyles(int length, const char *styles) {
+bool SCI_METHOD Document::SetStyles(int length, const char *styles) {
 	if (enteredStyling != 0) {
 		return false;
 	} else {
@@ -1248,75 +1673,93 @@ bool Document::SetStyles(int length, const char *styles) {
 void Document::EnsureStyledTo(int pos) {
 	if ((enteredStyling == 0) && (pos > GetEndStyled())) {
 		IncrementStyleClock();
-		// Ask the watchers to style, and stop as soon as one responds.
-		for (int i = 0; pos > GetEndStyled() && i < lenWatchers; i++) {
-			watchers[i].watcher->NotifyStyleNeeded(this, watchers[i].userData, pos);
+		if (pli && !pli->UseContainerLexing()) {
+			int lineEndStyled = LineFromPosition(GetEndStyled());
+			int endStyledTo = LineStart(lineEndStyled);
+			pli->Colourise(endStyledTo, pos);
+		} else {
+			// Ask the watchers to style, and stop as soon as one responds.
+			for (int i = 0; pos > GetEndStyled() && i < lenWatchers; i++) {
+				watchers[i].watcher->NotifyStyleNeeded(this, watchers[i].userData, pos);
+			}
 		}
 	}
 }
 
-int Document::SetLineState(int line, int state) {
-	int statePrevious = static_cast<LineState*>(perLineData[ldState])->SetLineState(line, state);
+void Document::LexerChanged() {
+	// Tell the watchers the lexer has changed.
+	for (int i = 0; i < lenWatchers; i++) {
+		watchers[i].watcher->NotifyLexerChanged(this, watchers[i].userData);
+	}
+}
+
+int SCI_METHOD Document::SetLineState(int line, int state) {
+	int statePrevious = static_cast<LineState *>(perLineData[ldState])->SetLineState(line, state);
 	if (state != statePrevious) {
-		DocModification mh(SC_MOD_CHANGELINESTATE, 0, 0, 0, 0, line);
+		DocModification mh(SC_MOD_CHANGELINESTATE, LineStart(line), 0, 0, 0, line);
 		NotifyModified(mh);
 	}
 	return statePrevious;
 }
 
-int Document::GetLineState(int line) { 
-	return static_cast<LineState*>(perLineData[ldState])->GetLineState(line); 
+int SCI_METHOD Document::GetLineState(int line) const {
+	return static_cast<LineState *>(perLineData[ldState])->GetLineState(line);
 }
 
-int Document::GetMaxLineState() { 
-	return static_cast<LineState*>(perLineData[ldState])->GetMaxLineState(); 
+int Document::GetMaxLineState() {
+	return static_cast<LineState *>(perLineData[ldState])->GetMaxLineState();
+}
+
+void SCI_METHOD Document::ChangeLexerState(int start, int end) {
+	DocModification mh(SC_MOD_LEXERSTATE, start, end-start, 0, 0, 0);
+	NotifyModified(mh);
 }
 
 StyledText Document::MarginStyledText(int line) {
-	LineAnnotation *pla = static_cast<LineAnnotation*>(perLineData[ldMargin]);
-	return StyledText(pla->Length(line), pla->Text(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); 
+	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); 
+	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); 
+	static_cast<LineAnnotation *>(perLineData[ldMargin])->SetStyles(line, styles);
 }
 
 int Document::MarginLength(int line) const {
-	return static_cast<LineAnnotation*>(perLineData[ldMargin])->Length(line);
+	return static_cast<LineAnnotation *>(perLineData[ldMargin])->Length(line);
 }
 
 void Document::MarginClearAll() {
 	int maxEditorLine = LinesTotal();
-	for (int l=0;l<maxEditorLine;l++)
+	for (int l=0; l<maxEditorLine; l++)
 		MarginSetText(l, 0);
 	// Free remaining data
-	static_cast<LineAnnotation*>(perLineData[ldMargin])->ClearAll();
+	static_cast<LineAnnotation *>(perLineData[ldMargin])->ClearAll();
 }
 
 bool Document::AnnotationAny() const {
-	return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->AnySet(); 
+	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), 
+	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); 
+	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;
@@ -1324,34 +1767,36 @@ void Document::AnnotationSetText(int line, const char *text) {
 }
 
 void Document::AnnotationSetStyle(int line, int style) {
-	static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetStyle(line, style); 
+	static_cast<LineAnnotation *>(perLineData[ldAnnotation])->SetStyle(line, style);
+	DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), 0, 0, 0, line);
+	NotifyModified(mh);
 }
 
 void Document::AnnotationSetStyles(int line, const unsigned char *styles) {
-	static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetStyles(line, styles); 
+	static_cast<LineAnnotation *>(perLineData[ldAnnotation])->SetStyles(line, styles);
 }
 
 int Document::AnnotationLength(int line) const {
-	return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->Length(line);
+	return static_cast<LineAnnotation *>(perLineData[ldAnnotation])->Length(line);
 }
 
 int Document::AnnotationLines(int line) const {
-	return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->Lines(line);
+	return static_cast<LineAnnotation *>(perLineData[ldAnnotation])->Lines(line);
 }
 
 void Document::AnnotationClearAll() {
 	int maxEditorLine = LinesTotal();
-	for (int l=0;l<maxEditorLine;l++)
+	for (int l=0; l<maxEditorLine; l++)
 		AnnotationSetText(l, 0);
 	// Free remaining data
-	static_cast<LineAnnotation*>(perLineData[ldAnnotation])->ClearAll();
+	static_cast<LineAnnotation *>(perLineData[ldAnnotation])->ClearAll();
 }
 
 void Document::IncrementStyleClock() {
 	styleClock = (styleClock + 1) % 0x100000;
 }
 
-void Document::DecorationFillRange(int position, int value, int fillLength) {
+void SCI_METHOD Document::DecorationFillRange(int position, int value, int fillLength) {
 	if (decorations.FillRange(position, value, fillLength)) {
 		DocModification mh(SC_MOD_CHANGEINDICATOR | SC_PERFORMED_USER,
 							position, fillLength);
@@ -1523,11 +1968,11 @@ bool IsLineEndChar(char c) {
 int Document::ExtendStyleRange(int pos, int delta, bool singleLine) {
 	int sStart = cb.StyleAt(pos);
 	if (delta < 0) {
-		while (pos > 0 && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos))) )
+		while (pos > 0 && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos))))
 			pos--;
 		pos++;
 	} else {
-		while (pos < (Length()) && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos))) )
+		while (pos < (Length()) && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos))))
 			pos++;
 	}
 	return pos;
@@ -1567,9 +2012,8 @@ int Document::BraceMatch(int position, int /*maxReStyle*/) {
 	if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
 		direction = 1;
 	int depth = 1;
-	position = position + direction;
+	position = NextPosition(position, direction);
 	while ((position >= 0) && (position < Length())) {
-		position = MovePositionOutsideChar(position, direction);
 		char chAtPos = CharAt(position);
 		char styAtPos = static_cast<char>(StyleAt(position) & stylingBitsMask);
 		if ((position > GetEndStyled()) || (styAtPos == styBrace)) {
@@ -1580,7 +2024,10 @@ int Document::BraceMatch(int position, int /*maxReStyle*/) {
 			if (depth == 0)
 				return position;
 		}
-		position = position + direction;
+		int positionBeforeMove = position;
+		position = NextPosition(position, direction);
+		if (position == positionBeforeMove)
+			break;
 	}
 	return - 1;
 }
@@ -1600,7 +2047,7 @@ public:
                         bool caseSensitive, bool word, bool wordStart, int flags,
                         int *length);
 
-	virtual const char *SubstituteByPosition(Document* doc, const char *text, int *length);
+	virtual const char *SubstituteByPosition(Document *doc, const char *text, int *length);
 
 private:
 	RESearch search;
@@ -1656,6 +2103,12 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
 		// the start position is at end of line or between line end characters.
 		lineRangeStart++;
 		startPos = doc->LineStart(lineRangeStart);
+	} else if ((increment == -1) &&
+	           (startPos <= doc->LineStart(lineRangeStart)) &&
+	           (lineRangeStart > lineRangeEnd)) {
+		// the start position is at beginning of line.
+		lineRangeStart--;
+		startPos = doc->LineEnd(lineRangeStart);
 	}
 	int pos = -1;
 	int lenRet = 0;
@@ -1693,7 +2146,8 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
 		if (success) {
 			pos = search.bopat[0];
 			lenRet = search.eopat[0] - search.bopat[0];
-			if (increment == -1) {
+			// There can be only one start of a line, so no need to look for last match in line
+			if ((increment == -1) && (s[0] != '^')) {
 				// Check for the last match on this line.
 				int repetitions = 1000;	// Break out of infinite loop
 				while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) {
@@ -1715,7 +2169,7 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
 	return pos;
 }
 
-const char *BuiltinRegex::SubstituteByPosition(Document* doc, const char *text, int *length) {
+const char *BuiltinRegex::SubstituteByPosition(Document *doc, const char *text, int *length) {
 	delete []substituted;
 	substituted = 0;
 	DocumentIndexer di(doc, doc->Length());
@@ -1737,6 +2191,7 @@ const char *BuiltinRegex::SubstituteByPosition(Document* doc, const char *text,
 				case 'r':
 				case 't':
 				case 'v':
+				case '\\':
 					i++;
 				}
 				lenResult++;
@@ -1780,6 +2235,9 @@ const char *BuiltinRegex::SubstituteByPosition(Document* doc, const char *text,
 				case 'v':
 					*o++ = '\v';
 					break;
+				case '\\':
+					*o++ = '\\';
+					break;
 				default:
 					*o++ = '\\';
 					j--;
diff --git a/plugins/scintilla/scintilla/Document.h b/plugins/scintilla/scintilla/Document.h
index 240d59e..7858db7 100644
--- a/plugins/scintilla/scintilla/Document.h
+++ b/plugins/scintilla/scintilla/Document.h
@@ -2,7 +2,7 @@
 /** @file Document.h
  ** Text document that handles notifications, DBCS, styling, words and end of line.
  **/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef DOCUMENT_H
@@ -32,10 +32,10 @@ public:
 
 	Range(Position pos=0) :
 		start(pos), end(pos) {
-	};
+	}
 	Range(Position start_, Position end_) :
 		start(start_), end(end_) {
-	};
+	}
 
 	bool Valid() const {
 		return (start != invalidPosition) && (end != invalidPosition);
@@ -81,17 +81,17 @@ class Document;
  */
 class RegexSearchBase {
 public:
-	virtual ~RegexSearchBase(){}
+	virtual ~RegexSearchBase() {}
 
-	virtual long FindText(Document* doc, int minPos, int maxPos, const char *s,
+	virtual long FindText(Document *doc, int minPos, int maxPos, const char *s,
                         bool caseSensitive, bool word, bool wordStart, int flags, int *length) = 0;
 
 	///@return String with the substitutions, must remain valid until the next call or destruction
-	virtual const char *SubstituteByPosition(Document* doc, const char *text, int *length) = 0;
+	virtual const char *SubstituteByPosition(Document *doc, const char *text, int *length) = 0;
 };
 
 /// Factory function for RegexSearchBase
-extern RegexSearchBase* CreateRegexSearch(CharClassify *charClassTable);
+extern RegexSearchBase *CreateRegexSearch(CharClassify *charClassTable);
 
 struct StyledText {
 	size_t length;
@@ -99,7 +99,7 @@ struct StyledText {
 	bool multipleStyles;
 	size_t style;
 	const unsigned char *styles;
-	StyledText(	size_t length_, const char *text_, bool multipleStyles_, int 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.
@@ -115,9 +115,86 @@ struct StyledText {
 	}
 };
 
+class HighlightDelimiter {
+public:
+	HighlightDelimiter() {
+		beginFoldBlock = -1;
+		endFoldBlock = -1;
+		beginMarginCorrectlyDrawnZone = -1;
+		endMarginCorrectlyDrawnZone = -1;
+		isEnabled = false;
+	}
+
+	bool NeedsDrawing(int line) {
+		return isEnabled && (line <= beginMarginCorrectlyDrawnZone || endMarginCorrectlyDrawnZone <= line);
+	}
+
+	bool isCurrentBlockHighlight(int line) {
+		return isEnabled && beginFoldBlock != -1 && beginFoldBlock <= line && line <= endFoldBlock;
+	}
+
+	bool isHeadBlockFold(int line) {
+		return beginFoldBlock == line && line < endFoldBlock;
+	}
+
+	bool isBodyBlockFold(int line) {
+		return beginFoldBlock != -1 && beginFoldBlock < line && line < endFoldBlock;
+	}
+
+	bool isTailBlockFold(int line) {
+		return beginFoldBlock != -1 && beginFoldBlock < line && line == endFoldBlock;
+	}
+
+	// beginFoldBlock : Begin of current fold block.
+	// endStartBlock : End of current fold block.
+	// beginMarginCorrectlyDrawnZone : Begin of zone where margin is correctly drawn.
+	// endMarginCorrectlyDrawnZone : End of zone where margin is correctly drawn.
+	int beginFoldBlock;
+	int endFoldBlock;
+	int beginMarginCorrectlyDrawnZone;
+	int endMarginCorrectlyDrawnZone;
+	bool isEnabled;
+};
+
+class CaseFolder {
+public:
+	virtual ~CaseFolder() {
+	}
+	virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) = 0;
+};
+
+class CaseFolderTable : public CaseFolder {
+protected:
+	char mapping[256];
+public:
+	CaseFolderTable();
+	virtual ~CaseFolderTable();
+	virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed);
+	void SetTranslation(char ch, char chTranslation);
+	void StandardASCII();
+};
+
+class Document;
+
+class LexInterface {
+protected:
+	Document *pdoc;
+	ILexer *instance;
+	bool performingStyle;	///< Prevent reentrance
+public:
+	LexInterface(Document *pdoc_) : pdoc(pdoc_), instance(0), performingStyle(false) {
+	}
+	virtual ~LexInterface() {
+	}
+	void Colourise(int start, int end);
+	bool UseContainerLexing() const {
+		return instance == 0;
+	}
+};
+
 /**
  */
-class Document : PerLine {
+class Document : PerLine, public IDocument {
 
 public:
 	/** Used to pair watcher pointer with user data. */
@@ -147,13 +224,16 @@ private:
 	int lenWatchers;
 
 	// ldSize is not real data - it is for dimensions and loops
-	enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldSize };	
+	enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldSize };
 	PerLine *perLineData[ldSize];
 
 	bool matchesValid;
-	RegexSearchBase* regex;
+	RegexSearchBase *regex;
 
 public:
+
+	LexInterface *pli;
+
 	int stylingBits;
 	int stylingBitsMask;
 
@@ -179,12 +259,23 @@ public:
 	virtual void InsertLine(int line);
 	virtual void RemoveLine(int line);
 
-	int LineFromPosition(int pos) const;
+	int SCI_METHOD Version() const {
+		return dvOriginal;
+	}
+
+	void SCI_METHOD SetErrorStatus(int status);
+
+	int SCI_METHOD LineFromPosition(int pos) const;
 	int ClampPositionIntoDocument(int pos);
 	bool IsCrLf(int pos);
 	int LenChar(int pos);
-	bool InGoodUTF8(int pos, int &start, int &end);
+	bool InGoodUTF8(int pos, int &start, int &end) const;
 	int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
+	int NextPosition(int pos, int moveDir) const;
+	bool NextCharacter(int &pos, int moveDir);	// Returns true if pos changed
+	int SCI_METHOD CodePage() const;
+	bool SCI_METHOD IsDBCSLeadByte(char ch) const;
+	int SafeSegment(const char *text, int length, int lengthSegment);
 
 	// Gateways to modifying document
 	void ModifiedAt(int pos);
@@ -205,9 +296,9 @@ public:
 	void AddUndoAction(int token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); }
 	void SetSavePoint();
 	bool IsSavePoint() { return cb.IsSavePoint(); }
-	const char *BufferPointer() { return cb.BufferPointer(); }
+	const char * SCI_METHOD BufferPointer() { return cb.BufferPointer(); }
 
-	int GetLineIndentation(int line);
+	int SCI_METHOD GetLineIndentation(int line);
 	void SetLineIndentation(int line, int indent);
 	int GetLineIndentPosition(int line) const;
 	int GetColumn(int position);
@@ -225,10 +316,13 @@ public:
 	void DelCharBack(int pos);
 
 	char CharAt(int position) { return cb.CharAt(position); }
-	void GetCharRange(char *buffer, int position, int lengthRetrieve) {
+	void SCI_METHOD GetCharRange(char *buffer, int position, int lengthRetrieve) const {
 		cb.GetCharRange(buffer, position, lengthRetrieve);
 	}
-	char StyleAt(int position) { return cb.StyleAt(position); }
+	char SCI_METHOD StyleAt(int position) const { return cb.StyleAt(position); }
+	void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const {
+		cb.GetStyleRange(buffer, position, lengthRetrieve);
+	}
 	int GetMark(int line);
 	int AddMark(int line, int markerNum);
 	void AddMarkSet(int line, int valueSet);
@@ -236,27 +330,29 @@ public:
 	void DeleteMarkFromHandle(int markerHandle);
 	void DeleteAllMarks(int markerNum);
 	int LineFromHandle(int markerHandle);
-	int LineStart(int line) const;
+	int SCI_METHOD LineStart(int line) const;
 	int LineEnd(int line) const;
 	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);
+	int SCI_METHOD SetLevel(int line, int level);
+	int SCI_METHOD GetLevel(int line) const;
 	void ClearLevels();
 	int GetLastChild(int lineParent, int level=-1);
 	int GetFoldParent(int line);
+	void GetHighlightDelimiters(HighlightDelimiter &hDelimiter, int line, int topLine, int bottomLine);
 
 	void Indent(bool forwards);
 	int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false);
 	int NextWordStart(int pos, int delta);
 	int NextWordEnd(int pos, int delta);
-	int Length() const { return cb.Length(); }
+	int SCI_METHOD Length() const { return cb.Length(); }
 	void Allocate(int newSize) { cb.Allocate(newSize); }
-	long FindText(int minPos, int maxPos, const char *s,
-		bool caseSensitive, bool word, bool wordStart, bool regExp, int flags, int *length);
-	long FindText(int iMessage, unsigned long wParam, long lParam);
+	size_t ExtractChar(int pos, char *bytes);
+	bool MatchesWordOptions(bool word, bool wordStart, int pos, int length);
+	long FindText(int minPos, int maxPos, const char *search, bool caseSensitive, bool word,
+		bool wordStart, bool regExp, int flags, int *length, CaseFolder *pcf);
 	const char *SubstituteByPosition(const char *text, int *length);
 	int LinesTotal() const;
 
@@ -265,18 +361,23 @@ public:
 	void SetDefaultCharClasses(bool includeWordClass);
 	void SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass);
 	void SetStylingBits(int bits);
-	void StartStyling(int position, char mask);
-	bool SetStyleFor(int length, char style);
-	bool SetStyles(int length, const char *styles);
+	void SCI_METHOD StartStyling(int position, char mask);
+	bool SCI_METHOD SetStyleFor(int length, char style);
+	bool SCI_METHOD SetStyles(int length, const char *styles);
 	int GetEndStyled() { return endStyled; }
 	void EnsureStyledTo(int pos);
+	void LexerChanged();
 	int GetStyleClock() { return styleClock; }
 	void IncrementStyleClock();
-	void DecorationFillRange(int position, int value, int fillLength);
+	void SCI_METHOD DecorationSetCurrentIndicator(int indicator) {
+		decorations.SetCurrentIndicator(indicator);
+	}
+	void SCI_METHOD DecorationFillRange(int position, int value, int fillLength);
 
-	int SetLineState(int line, int state);
-	int GetLineState(int line);
+	int SCI_METHOD SetLineState(int line, int state);
+	int SCI_METHOD GetLineState(int line) const;
 	int GetMaxLineState();
+	void SCI_METHOD ChangeLexerState(int start, int end);
 
 	StyledText MarginStyledText(int line);
 	void MarginSetStyle(int line, int style);
@@ -299,6 +400,7 @@ public:
 	const WatcherWithUserData *GetWatchers() const { return watchers; }
 	int GetLenWatchers() const { return lenWatchers; }
 
+	CharClassify::cc WordCharClass(unsigned char ch);
 	bool IsWordPartSeparator(char ch);
 	int WordPartLeft(int pos);
 	int WordPartRight(int pos);
@@ -310,7 +412,6 @@ public:
 	int BraceMatch(int position, int maxReStyle);
 
 private:
-	CharClassify::cc WordCharClass(unsigned char ch);
 	bool IsWordStartAt(int pos);
 	bool IsWordEndAt(int pos);
 	bool IsWordAt(int start, int end);
@@ -324,7 +425,7 @@ class UndoGroup {
 	Document *pdoc;
 	bool groupNeeded;
 public:
-	UndoGroup(Document *pdoc_, bool groupNeeded_=true) : 
+	UndoGroup(Document *pdoc_, bool groupNeeded_=true) :
 		pdoc(pdoc_), groupNeeded(groupNeeded_) {
 		if (groupNeeded) {
 			pdoc->BeginUndoAction();
@@ -398,6 +499,8 @@ public:
 	virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0;
 	virtual void NotifyDeleted(Document *doc, void *userData) = 0;
 	virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0;
+	virtual void NotifyLexerChanged(Document *doc, void *userData) = 0;
+	virtual void NotifyErrorOccurred(Document *doc, void *userData, int status) = 0;
 };
 
 #ifdef SCI_NAMESPACE
diff --git a/plugins/scintilla/scintilla/Editor.cxx b/plugins/scintilla/scintilla/Editor.cxx
index 9ec5994..d1d0e7f 100644
--- a/plugins/scintilla/scintilla/Editor.cxx
+++ b/plugins/scintilla/scintilla/Editor.cxx
@@ -2,28 +2,23 @@
 /** @file Editor.cxx
  ** Main code for the edit control.
  **/
-// Copyright 1998-2004 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 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 <stdio.h>
 #include <ctype.h>
+#include <assert.h>
 
 #include <string>
 #include <vector>
 #include <algorithm>
-
-// 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 <memory>
 
 #include "Platform.h"
 
+#include "ILexer.h"
 #include "Scintilla.h"
 
 #include "SplitVector.h"
@@ -52,7 +47,7 @@ using namespace Scintilla;
 	return whether this modification represents an operation that
 	may reasonably be deferred (not done now OR [possibly] at all)
 */
-static bool CanDeferToLastStep(const DocModification& mh) {
+static bool CanDeferToLastStep(const DocModification &mh) {
 	if (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE))
 		return true;	// CAN skip
 	if (!(mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO)))
@@ -62,7 +57,7 @@ static bool CanDeferToLastStep(const DocModification& mh) {
 	return false;		// PRESUMABLY must do
 }
 
-static bool CanEliminate(const DocModification& mh) {
+static bool CanEliminate(const DocModification &mh) {
 	return
 	    (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) != 0;
 }
@@ -71,7 +66,7 @@ static bool CanEliminate(const DocModification& mh) {
 	return whether this modification represents the FINAL step
 	in a [possibly lengthy] multi-step Undo/Redo sequence
 */
-static bool IsLastStep(const DocModification& mh) {
+static bool IsLastStep(const DocModification &mh) {
 	return
 	    (mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO)) != 0
 	    && (mh.modificationType & SC_MULTISTEPUNDOREDO) != 0
@@ -93,6 +88,15 @@ static inline bool IsControlCharacter(int ch) {
 	return ch >= 0 && ch < ' ';
 }
 
+static inline bool IsAllSpacesOrTabs(char *s, unsigned int len) {
+	for (unsigned int i = 0; i < len; i++) {
+		// This is safe because IsSpaceOrTab() will return false for null terminators
+		if (!IsSpaceOrTab(s[i]))
+			return false;
+	}
+	return true;
+}
+
 Editor::Editor() {
 	ctrlID = 0;
 
@@ -123,11 +127,15 @@ Editor::Editor() {
 	dropWentOutside = false;
 	posDrag = SelectionPosition(invalidPosition);
 	posDrop = SelectionPosition(invalidPosition);
+	hotSpotClickPos = INVALID_POSITION;
 	selectionType = selChar;
 
 	lastXChosen = 0;
 	lineAnchor = 0;
 	originalAnchorPos = 0;
+	wordSelectAnchorStartPos = 0;
+	wordSelectAnchorEndPos = 0;
+	wordSelectInitialCaretPos = -1;
 
 	primarySelection = true;
 
@@ -147,9 +155,10 @@ Editor::Editor() {
 	lineWidthMaxSeen = 0;
 	verticalScrollBarVisible = true;
 	endAtLastLine = true;
-	caretSticky = false;
+	caretSticky = SC_CARETSTICKY_OFF;
 	multipleSelection = false;
 	additionalSelectionTyping = false;
+	multiPasteMode = SC_MULTIPASTE_ONCE;
 	additionalCaretsBlink = true;
 	additionalCaretsVisible = true;
 	virtualSpaceOptions = SCVS_NONE;
@@ -169,7 +178,8 @@ Editor::Editor() {
 
 	lengthForEncode = -1;
 
-	needUpdateUI = true;
+	needUpdateUI = 0;
+	ContainerNeedsUpdate(SC_UPDATE_CONTENT);
 	braces[0] = invalidPosition;
 	braces[1] = invalidPosition;
 	bracesMatchStyle = STYLE_BRACEBAD;
@@ -428,7 +438,10 @@ int Editor::LineFromLocation(Point pt) {
 }
 
 void Editor::SetTopLine(int topLineNew) {
-	topLine = topLineNew;
+	if (topLine != topLineNew) {
+		topLine = topLineNew;
+		ContainerNeedsUpdate(SC_UPDATE_V_SCROLL);
+	}
 	posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine));
 }
 
@@ -621,7 +634,7 @@ void Editor::Redraw() {
 	//wMain.InvalidateAll();
 }
 
-void Editor::RedrawSelMargin(int line) {
+void Editor::RedrawSelMargin(int line, bool allAfter) {
 	if (!AbandonPaint()) {
 		if (vs.maskInLine) {
 			Redraw();
@@ -632,7 +645,8 @@ void Editor::RedrawSelMargin(int line) {
 				int position = pdoc->LineStart(line);
 				PRectangle rcLine = RectangleFromRange(position, position);
 				rcSelMargin.top = rcLine.top;
-				rcSelMargin.bottom = rcLine.bottom;
+				if (!allAfter)
+					rcSelMargin.bottom = rcLine.bottom;
 			}
 			wMain.InvalidateRectangle(rcSelMargin);
 		}
@@ -691,17 +705,17 @@ void Editor::SetRectangularRange() {
 		if (sel.selType == Selection::selThin) {
 			xCaret = xAnchor;
 		}
-		int lineAnchor = pdoc->LineFromPosition(sel.Rectangular().anchor.Position());
+		int lineAnchorRect = 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) {
+		int increment = (lineCaret > lineAnchorRect) ? 1 : -1;
+		for (int line=lineAnchorRect; line != lineCaret+increment; line += increment) {
 			SelectionRange range(SPositionFromLineX(line, xCaret), SPositionFromLineX(line, xAnchor));
 			if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) == 0)
 				range.ClearVirtualSpace();
-			if (line == lineAnchor)
+			if (line == lineAnchorRect)
 				sel.SetSelection(range);
 			else
-				sel.AddSelection(range);
+				sel.AddSelectionWithoutTrim(range);
 		}
 	}
 }
@@ -734,19 +748,36 @@ void Editor::InvalidateSelection(SelectionRange newMain, bool invalidateWholeSel
 			lastAffected = Platform::Maximum(lastAffected, sel.Range(r).anchor.Position());
 		}
 	}
-	needUpdateUI = true;
+	ContainerNeedsUpdate(SC_UPDATE_SELECTION);
 	InvalidateRange(firstAffected, lastAffected);
 }
 
 void Editor::SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_) {
-	SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_),
-		ClampPositionIntoDocument(anchor_));
+	currentPos_ = ClampPositionIntoDocument(currentPos_);
+	anchor_ = ClampPositionIntoDocument(anchor_);
+	int currentLine = pdoc->LineFromPosition(currentPos_.Position());
+	/* For Line selection - ensure the anchor and caret are always
+	   at the beginning and end of the region lines. */
+	if (sel.selType == Selection::selLines) {
+		if (currentPos_ > anchor_) {
+			anchor_ = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(anchor_.Position())));
+			currentPos_ = SelectionPosition(pdoc->LineEnd(pdoc->LineFromPosition(currentPos_.Position())));
+		} else {
+			currentPos_ = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(currentPos_.Position())));
+			anchor_ = SelectionPosition(pdoc->LineEnd(pdoc->LineFromPosition(anchor_.Position())));
+		}
+	}
+	SelectionRange rangeNew(currentPos_, anchor_);
 	if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) {
 		InvalidateSelection(rangeNew);
 	}
 	sel.RangeMain() = rangeNew;
 	SetRectangularRange();
 	ClaimSelection();
+
+	if (highlightDelimiter.NeedsDrawing(currentLine)) {
+		RedrawSelMargin();
+	}
 }
 
 void Editor::SetSelection(int currentPos_, int anchor_) {
@@ -756,6 +787,7 @@ void Editor::SetSelection(int currentPos_, int anchor_) {
 // Just move the caret on the main selection
 void Editor::SetSelection(SelectionPosition currentPos_) {
 	currentPos_ = ClampPositionIntoDocument(currentPos_);
+	int currentLine = pdoc->LineFromPosition(currentPos_.Position());
 	if (sel.Count() > 1 || !(sel.RangeMain().caret == currentPos_)) {
 		InvalidateSelection(SelectionRange(currentPos_));
 	}
@@ -768,6 +800,10 @@ void Editor::SetSelection(SelectionPosition currentPos_) {
 			SelectionRange(SelectionPosition(currentPos_), sel.RangeMain().anchor);
 	}
 	ClaimSelection();
+
+	if (highlightDelimiter.NeedsDrawing(currentLine)) {
+		RedrawSelMargin();
+	}
 }
 
 void Editor::SetSelection(int currentPos_) {
@@ -775,6 +811,7 @@ void Editor::SetSelection(int currentPos_) {
 }
 
 void Editor::SetEmptySelection(SelectionPosition currentPos_) {
+	int currentLine = pdoc->LineFromPosition(currentPos_.Position());
 	SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_));
 	if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) {
 		InvalidateSelection(rangeNew);
@@ -784,6 +821,9 @@ void Editor::SetEmptySelection(SelectionPosition currentPos_) {
 	SetRectangularRange();
 	ClaimSelection();
 
+	if (highlightDelimiter.NeedsDrawing(currentLine)) {
+		RedrawSelMargin();
+	}
 }
 
 void Editor::SetEmptySelection(int currentPos_) {
@@ -847,9 +887,18 @@ SelectionPosition Editor::MovePositionOutsideChar(SelectionPosition pos, int mov
 }
 
 int Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, bool ensureVisible) {
+	bool simpleCaret = (sel.Count() == 1) && sel.Empty();
+	SelectionPosition spCaret = sel.Last();
+
 	int delta = newPos.Position() - sel.MainCaret();
 	newPos = ClampPositionIntoDocument(newPos);
 	newPos = MovePositionOutsideChar(newPos, delta);
+	if (!multipleSelection && sel.IsRectangular() && (selt == Selection::selStream)) {
+		// Can't turn into multiple selection so clear additional selections
+		InvalidateSelection(SelectionRange(newPos), true);
+		SelectionRange rangeMain = sel.RangeMain();
+		sel.SetSelection(rangeMain);
+	}
 	if (!sel.IsRectangular() && (selt == Selection::selRectangle)) {
 		// Switching to rectangular
 		SelectionRange rangeMain = sel.RangeMain();
@@ -866,7 +915,20 @@ int Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, b
 	}
 	ShowCaretAtCurrentPosition();
 	if (ensureVisible) {
-		EnsureCaretVisible();
+		XYScrollPosition newXY = XYScrollToMakeVisible(true, true, true);
+		if (simpleCaret && (newXY.xOffset == xOffset)) {
+			// simple vertical scroll then invalidate
+			ScrollTo(newXY.topLine);
+			InvalidateSelection(SelectionRange(spCaret), true);
+		} else {
+			SetXYScroll(newXY);
+		}
+	}
+
+	int currentLine = pdoc->LineFromPosition(newPos.Position());
+
+	if (highlightDelimiter.NeedsDrawing(currentLine)) {
+		RedrawSelMargin();
 	}
 	return 0;
 }
@@ -908,18 +970,22 @@ Point Editor::PointMainCaret() {
  */
 void Editor::SetLastXChosen() {
 	Point pt = PointMainCaret();
-	lastXChosen = pt.x;
+	lastXChosen = pt.x + xOffset;
 }
 
 void Editor::ScrollTo(int line, bool moveThumb) {
 	int topLineNew = Platform::Clamp(line, 0, MaxScrollPos());
 	if (topLineNew != topLine) {
 		// Try to optimise small scrolls
+#ifndef UNDER_CE
 		int linesToMove = topLine - topLineNew;
+#endif
 		SetTopLine(topLineNew);
-		ShowCaretAtCurrentPosition();
-		// Perform redraw rather than scroll if many lines would be redrawn anyway.
+		// Optimize by styling the view as this will invalidate any needed area
+		// which could abort the initial paint if discovered later.
+		StyleToPositionInView(PositionAfterArea(GetClientRectangle()));
 #ifndef UNDER_CE
+		// Perform redraw rather than scroll if many lines would be redrawn anyway.
 		if ((abs(linesToMove) <= 10) && (paintState == notPainting)) {
 			ScrollText(linesToMove);
 		} else {
@@ -945,22 +1011,86 @@ void Editor::HorizontalScrollTo(int xPos) {
 		xPos = 0;
 	if ((wrapState == eWrapNone) && (xOffset != xPos)) {
 		xOffset = xPos;
+		ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
 		SetHorizontalScrollPos();
 		RedrawRect(GetClientRectangle());
 	}
 }
 
+void Editor::VerticalCentreCaret() {
+	int lineDoc = pdoc->LineFromPosition(sel.IsRectangular() ? sel.Rectangular().caret.Position() : sel.MainCaret());
+	int lineDisplay = cs.DisplayFromDoc(lineDoc);
+	int newTop = lineDisplay - (LinesOnScreen() / 2);
+	if (topLine != newTop) {
+		SetTopLine(newTop > 0 ? newTop : 0);
+		RedrawRect(GetClientRectangle());
+	}
+}
+
+void Editor::MoveSelectedLines(int lineDelta) {
+
+	// if selection doesn't start at the beginning of the line, set the new start
+	int selectionStart = SelectionStart().Position();
+	int startLine = pdoc->LineFromPosition(selectionStart);
+	int beginningOfStartLine = pdoc->LineStart(startLine);
+	selectionStart = beginningOfStartLine;
+
+	// if selection doesn't end at the beginning of a line greater than that of the start,
+	// then set it at the beginning of the next one
+	int selectionEnd = SelectionEnd().Position();
+	int endLine = pdoc->LineFromPosition(selectionEnd);
+	int beginningOfEndLine = pdoc->LineStart(endLine);
+	if (selectionEnd > beginningOfEndLine
+		|| selectionStart == selectionEnd) {
+		selectionEnd = pdoc->LineStart(endLine + 1);
+	}
+
+	// if there's nowhere for the selection to move
+	// (i.e. at the beginning going up or at the end going down),
+	// stop it right there!
+	if ((selectionStart == 0 && lineDelta < 0)
+		|| (selectionEnd == pdoc->Length() && lineDelta > 0)
+	        || selectionStart == selectionEnd) {
+		return;
+	}
+
+	UndoGroup ug(pdoc);
+
+	SetSelection(selectionStart, selectionEnd);
+
+	SelectionText selectedText;
+	CopySelectionRange(&selectedText);
+
+	int selectionLength = SelectionRange(selectionStart, selectionEnd).Length();
+	ClearSelection();
+
+	Point currentLocation = LocationFromPosition(CurrentPosition());
+	int currentLine = LineFromLocation(currentLocation);
+	GoToLine(currentLine + lineDelta);
+
+	pdoc->InsertCString(CurrentPosition(), selectedText.s);
+	SetSelection(CurrentPosition(), CurrentPosition() + selectionLength);
+}
+
+void Editor::MoveSelectedLinesUp() {
+	MoveSelectedLines(-1);
+}
+
+void Editor::MoveSelectedLinesDown() {
+	MoveSelectedLines(1);
+}
+
 void Editor::MoveCaretInsideView(bool ensureVisible) {
 	PRectangle rcClient = GetTextRectangle();
 	Point pt = PointMainCaret();
 	if (pt.y < rcClient.top) {
 		MovePositionTo(SPositionFromLocation(
-		            Point(lastXChosen, rcClient.top)),
+		            Point(lastXChosen - xOffset, rcClient.top)),
 					Selection::noSel, ensureVisible);
 	} else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) {
 		int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight;
 		MovePositionTo(SPositionFromLocation(
-		            Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)),
+		            Point(lastXChosen - xOffset, rcClient.top + yOfLastLineFullyDisplayed)),
 		        Selection::noSel, ensureVisible);
 	}
 }
@@ -1029,29 +1159,24 @@ slop | strict | jumps | even | Caret can go to the margin                 | When
   1  |   1    |   0   |   1  | No, kept out of UZ                         | moved by one position
   1  |   1    |   1   |   1  | No, kept out of UZ                         | moved to put caret at 3UZ of the margin
 */
-void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
-	//Platform::DebugPrintf("EnsureCaretVisible %d %s\n", xOffset, useMargin ? " margin" : " ");
+
+Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const bool useMargin, const bool vert, const bool horiz) {
 	PRectangle rcClient = GetTextRectangle();
-	//int rcClientFullWidth = rcClient.Width();
-	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.Position());
-	bool bSlop, bStrict, bJump, bEven;
+	const SelectionPosition posCaret = posDrag.IsValid() ? posDrag : sel.RangeMain().caret;
+	const Point pt = LocationFromPosition(posCaret);
+	const Point ptBottomCaret(pt.x, pt.y + vs.lineHeight - 1);
+	const int lineCaret = DisplayFromPosition(posCaret.Position());
+
+	XYScrollPosition newXY(xOffset, topLine);
 
 	// Vertical positioning
-	if (vert && (pt.y < rcClient.top || ptBottomCaret.y > rcClient.bottom || (caretYPolicy & CARET_STRICT) != 0)) {
-		int linesOnScreen = LinesOnScreen();
-		int halfScreen = Platform::Maximum(linesOnScreen - 1, 2) / 2;
-		int newTopLine = topLine;
-		bSlop = (caretYPolicy & CARET_SLOP) != 0;
-		bStrict = (caretYPolicy & CARET_STRICT) != 0;
-		bJump = (caretYPolicy & CARET_JUMPS) != 0;
-		bEven = (caretYPolicy & CARET_EVEN) != 0;
+	if (vert && (pt.y < rcClient.top || ptBottomCaret.y >= rcClient.bottom || (caretYPolicy & CARET_STRICT) != 0)) {
+		const int linesOnScreen = LinesOnScreen();
+		const int halfScreen = Platform::Maximum(linesOnScreen - 1, 2) / 2;
+		const bool bSlop = (caretYPolicy & CARET_SLOP) != 0;
+		const bool bStrict = (caretYPolicy & CARET_STRICT) != 0;
+		const bool bJump = (caretYPolicy & CARET_JUMPS) != 0;
+		const bool bEven = (caretYPolicy & CARET_EVEN) != 0;
 
 		// It should be possible to scroll the window to show the caret,
 		// but this fails to remove the caret on GTK+
@@ -1084,10 +1209,10 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
 				}
 				if (lineCaret < topLine + yMarginT) {
 					// Caret goes too high
-					newTopLine = lineCaret - yMoveT;
+					newXY.topLine = lineCaret - yMoveT;
 				} else if (lineCaret > topLine + linesOnScreen - 1 - yMarginB) {
 					// Caret goes too low
-					newTopLine = lineCaret - linesOnScreen + 1 + yMoveB;
+					newXY.topLine = lineCaret - linesOnScreen + 1 + yMoveB;
 				}
 			} else {	// Not strict
 				yMoveT = bJump ? caretYSlop * 3 : caretYSlop;
@@ -1099,10 +1224,10 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
 				}
 				if (lineCaret < topLine) {
 					// Caret goes too high
-					newTopLine = lineCaret - yMoveT;
+					newXY.topLine = lineCaret - yMoveT;
 				} else if (lineCaret > topLine + linesOnScreen - 1) {
 					// Caret goes too low
-					newTopLine = lineCaret - linesOnScreen + 1 + yMoveB;
+					newXY.topLine = lineCaret - linesOnScreen + 1 + yMoveB;
 				}
 			}
 		} else {	// No slop
@@ -1110,41 +1235,35 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
 				// Minimal move
 				if (lineCaret < topLine) {
 					// Caret goes too high
-					newTopLine = lineCaret;
+					newXY.topLine = lineCaret;
 				} else if (lineCaret > topLine + linesOnScreen - 1) {
 					// Caret goes too low
 					if (bEven) {
-						newTopLine = lineCaret - linesOnScreen + 1;
+						newXY.topLine = lineCaret - linesOnScreen + 1;
 					} else {
-						newTopLine = lineCaret;
+						newXY.topLine = lineCaret;
 					}
 				}
 			} else {	// Strict or going out of display
 				if (bEven) {
 					// Always center caret
-					newTopLine = lineCaret - halfScreen;
+					newXY.topLine = lineCaret - halfScreen;
 				} else {
 					// Always put caret on top of display
-					newTopLine = lineCaret;
+					newXY.topLine = lineCaret;
 				}
 			}
 		}
-		newTopLine = Platform::Clamp(newTopLine, 0, MaxScrollPos());
-		if (newTopLine != topLine) {
-			Redraw();
-			SetTopLine(newTopLine);
-			SetVerticalScrollPos();
-		}
+		newXY.topLine = Platform::Clamp(newXY.topLine, 0, MaxScrollPos());
 	}
 
 	// Horizontal positioning
 	if (horiz && (wrapState == eWrapNone)) {
-		int halfScreen = Platform::Maximum(rcClient.Width() - 4, 4) / 2;
-		int xOffsetNew = xOffset;
-		bSlop = (caretXPolicy & CARET_SLOP) != 0;
-		bStrict = (caretXPolicy & CARET_STRICT) != 0;
-		bJump = (caretXPolicy & CARET_JUMPS) != 0;
-		bEven = (caretXPolicy & CARET_EVEN) != 0;
+		const int halfScreen = Platform::Maximum(rcClient.Width() - 4, 4) / 2;
+		const bool bSlop = (caretXPolicy & CARET_SLOP) != 0;
+		const bool bStrict = (caretXPolicy & CARET_STRICT) != 0;
+		const bool bJump = (caretXPolicy & CARET_JUMPS) != 0;
+		const bool bEven = (caretXPolicy & CARET_EVEN) != 0;
 
 		if (bSlop) {	// A margin is defined
 			int xMoveL, xMoveR;
@@ -1173,18 +1292,18 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
 				if (pt.x < rcClient.left + xMarginL) {
 					// Caret is on the left of the display
 					if (bJump && bEven) {
-						xOffsetNew -= xMoveL;
+						newXY.xOffset -= xMoveL;
 					} else {
 						// Move just enough to allow to display the caret
-						xOffsetNew -= (rcClient.left + xMarginL) - pt.x;
+						newXY.xOffset -= (rcClient.left + xMarginL) - pt.x;
 					}
 				} else if (pt.x >= rcClient.right - xMarginR) {
 					// Caret is on the right of the display
 					if (bJump && bEven) {
-						xOffsetNew += xMoveR;
+						newXY.xOffset += xMoveR;
 					} else {
 						// Move just enough to allow to display the caret
-						xOffsetNew += pt.x - (rcClient.right - xMarginR) + 1;
+						newXY.xOffset += pt.x - (rcClient.right - xMarginR) + 1;
 					}
 				}
 			} else {	// Not strict
@@ -1197,10 +1316,10 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
 				}
 				if (pt.x < rcClient.left) {
 					// Caret is on the left of the display
-					xOffsetNew -= xMoveL;
+					newXY.xOffset -= xMoveL;
 				} else if (pt.x >= rcClient.right) {
 					// Caret is on the right of the display
-					xOffsetNew += xMoveR;
+					newXY.xOffset += xMoveR;
 				}
 			}
 		} else {	// No slop
@@ -1209,54 +1328,70 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
 				// Strict or going out of display
 				if (bEven) {
 					// Center caret
-					xOffsetNew += pt.x - rcClient.left - halfScreen;
+					newXY.xOffset += pt.x - rcClient.left - halfScreen;
 				} else {
 					// Put caret on right
-					xOffsetNew += pt.x - rcClient.right + 1;
+					newXY.xOffset += pt.x - rcClient.right + 1;
 				}
 			} else {
 				// Move just enough to allow to display the caret
 				if (pt.x < rcClient.left) {
 					// Caret is on the left of the display
 					if (bEven) {
-						xOffsetNew -= rcClient.left - pt.x;
+						newXY.xOffset -= rcClient.left - pt.x;
 					} else {
-						xOffsetNew += pt.x - rcClient.right + 1;
+						newXY.xOffset += pt.x - rcClient.right + 1;
 					}
 				} else if (pt.x >= rcClient.right) {
 					// Caret is on the right of the display
-					xOffsetNew += pt.x - rcClient.right + 1;
+					newXY.xOffset += pt.x - rcClient.right + 1;
 				}
 			}
 		}
 		// In case of a jump (find result) largely out of display, adjust the offset to display the caret
-		if (pt.x + xOffset < rcClient.left + xOffsetNew) {
-			xOffsetNew = pt.x + xOffset - rcClient.left;
-		} else if (pt.x + xOffset >= rcClient.right + xOffsetNew) {
-			xOffsetNew = pt.x + xOffset - rcClient.right + 1;
+		if (pt.x + xOffset < rcClient.left + newXY.xOffset) {
+			newXY.xOffset = pt.x + xOffset - rcClient.left;
+		} else if (pt.x + xOffset >= rcClient.right + newXY.xOffset) {
+			newXY.xOffset = pt.x + xOffset - rcClient.right + 1;
 			if (vs.caretStyle == CARETSTYLE_BLOCK) {
 				// Ensure we can see a good portion of the block caret
-				xOffsetNew += vs.aveCharWidth;
+				newXY.xOffset += vs.aveCharWidth;
 			}
 		}
-		if (xOffsetNew < 0) {
-			xOffsetNew = 0;
+		if (newXY.xOffset < 0) {
+			newXY.xOffset = 0;
+		}
+	}
+
+	return newXY;
+}
+
+void Editor::SetXYScroll(XYScrollPosition newXY) {
+	if ((newXY.topLine != topLine) || (newXY.xOffset != xOffset)) {
+		if (newXY.topLine != topLine) {
+			SetTopLine(newXY.topLine);
+			SetVerticalScrollPos();
 		}
-		if (xOffset != xOffsetNew) {
-			xOffset = xOffsetNew;
-			if (xOffsetNew > 0) {
+		if (newXY.xOffset != xOffset) {
+			xOffset = newXY.xOffset;
+			ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
+			if (newXY.xOffset > 0) {
 				PRectangle rcText = GetTextRectangle();
 				if (horizontalScrollBarVisible &&
-				        rcText.Width() + xOffset > scrollWidth) {
+					rcText.Width() + xOffset > scrollWidth) {
 					scrollWidth = xOffset + rcText.Width();
 					SetScrollBars();
 				}
 			}
 			SetHorizontalScrollPos();
-			Redraw();
 		}
+		Redraw();
+		UpdateSystemCaret();
 	}
-	UpdateSystemCaret();
+}
+
+void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
+	SetXYScroll(XYScrollToMakeVisible(useMargin, vert, horiz));
 }
 
 void Editor::ShowCaretAtCurrentPosition() {
@@ -1369,8 +1504,6 @@ bool Editor::WrapLines(bool fullWrap, int priorityWrapLineStart) {
 			rcTextArea.left = vs.fixedColumnWidth;
 			rcTextArea.right -= vs.rightMarginWidth;
 			wrapWidth = rcTextArea.Width();
-			// Ensure all of the document is styled.
-			pdoc->EnsureStyledTo(pdoc->Length());
 			RefreshStyleData();
 			AutoSurface surface(this);
 			if (surface) {
@@ -1391,6 +1524,9 @@ bool Editor::WrapLines(bool fullWrap, int priorityWrapLineStart) {
 						lastLineToWrap = wrapEnd;
 				} // else do a fullWrap.
 
+				// Ensure all lines being wrapped are styled.
+				pdoc->EnsureStyledTo(pdoc->LineEnd(lastLineToWrap));
+
 				// Platform::DebugPrintf("Wraplines: full = %d, priorityStart = %d (wrapping: %d to %d)\n", fullWrap, priorityWrapLineStart, lineToWrap, lastLineToWrap);
 				// Platform::DebugPrintf("Pending wraps: %d to %d\n", wrapStart, wrapEnd);
 				while (lineToWrap < lastLineToWrap) {
@@ -1495,7 +1631,7 @@ static int istrlen(const char *s) {
 
 bool ValidStyledText(ViewStyle &vs, size_t styleOffset, const StyledText &st) {
 	if (st.multipleStyles) {
-		for (size_t iStyle=0;iStyle<st.length; iStyle++) {
+		for (size_t iStyle=0; iStyle<st.length; iStyle++) {
 			if (!vs.ValidStyle(styleOffset + st.styles[iStyle]))
 				return false;
 		}
@@ -1629,7 +1765,6 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
 
 			int visibleLine = topLine;
 			int yposScreen = 0;
-
 			// Work out whether the top line is whitespace located after a
 			// lessening of fold level which implies a 'fold tail' but which should not
 			// be displayed until the last of a sequence of whitespace.
@@ -1647,6 +1782,11 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
 						needWhiteClosure = true;
 				}
 			}
+			if (highlightDelimiter.isEnabled && (vs.ms[margin].mask & SC_MASK_FOLDERS)) {
+				int lineBack = cs.DocFromDisplay(topLine);
+				int lineFront = cs.DocFromDisplay(((rcMargin.bottom - rcMargin.top) / vs.lineHeight) + topLine) + 1;
+				pdoc->GetHighlightDelimiters(highlightDelimiter, pdoc->LineFromPosition(CurrentPosition()), lineBack, lineFront);
+			}
 
 			// Old code does not know about new markers needed to distinguish all cases
 			int folderOpenMid = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEROPENMID,
@@ -1657,10 +1797,10 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
 			while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rcMargin.bottom) {
 
 				PLATFORM_ASSERT(visibleLine < cs.LinesDisplayed());
-
 				int lineDoc = cs.DocFromDisplay(visibleLine);
 				PLATFORM_ASSERT(cs.GetVisible(lineDoc));
 				bool firstSubLine = visibleLine == cs.DisplayFromDoc(lineDoc);
+				bool lastSubLine = visibleLine == (cs.DisplayFromDoc(lineDoc + 1) - 1);
 
 				// Decide which fold indicator should be displayed
 				level = pdoc->GetLevel(lineDoc);
@@ -1672,19 +1812,31 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
 				int levelNextNum = levelNext & SC_FOLDLEVELNUMBERMASK;
 				if (level & SC_FOLDLEVELHEADERFLAG) {
 					if (firstSubLine) {
-						if (cs.GetExpanded(lineDoc)) {
-							if (levelNum == SC_FOLDLEVELBASE)
-								marks |= 1 << SC_MARKNUM_FOLDEROPEN;
-							else
-								marks |= 1 << folderOpenMid;
-						} else {
-							if (levelNum == SC_FOLDLEVELBASE)
-								marks |= 1 << SC_MARKNUM_FOLDER;
-							else
-								marks |= 1 << folderEnd;
-						}
+						if (levelNum < levelNextNum) {
+							if (cs.GetExpanded(lineDoc)) {
+								if (levelNum == SC_FOLDLEVELBASE)
+									marks |= 1 << SC_MARKNUM_FOLDEROPEN;
+								else
+									marks |= 1 << folderOpenMid;
+							} else {
+								if (levelNum == SC_FOLDLEVELBASE)
+									marks |= 1 << SC_MARKNUM_FOLDER;
+								else
+									marks |= 1 << folderEnd;
+							}
+						} else if (levelNum > SC_FOLDLEVELBASE) {
+							marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ 						}
 					} else {
-						marks |= 1 << SC_MARKNUM_FOLDERSUB;
+						if (levelNum < levelNextNum) {
+							if (cs.GetExpanded(lineDoc)) {
+								marks |= 1 << SC_MARKNUM_FOLDERSUB;
+							} else if (levelNum > SC_FOLDLEVELBASE) {
+								marks |= 1 << SC_MARKNUM_FOLDERSUB;
+							}
+						} else if (levelNum > SC_FOLDLEVELBASE) {
+							marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ 						}
 					}
 					needWhiteClosure = false;
 				} else if (level & SC_FOLDLEVELWHITEFLAG) {
@@ -1715,16 +1867,19 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
 						if (levelNext & SC_FOLDLEVELWHITEFLAG) {
 							marks |= 1 << SC_MARKNUM_FOLDERSUB;
 							needWhiteClosure = true;
-						} else if (levelNextNum > SC_FOLDLEVELBASE) {
-							marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL;
+						} else if (lastSubLine) {
+							if (levelNextNum > SC_FOLDLEVELBASE) {
+								marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL;
+							} else {
+								marks |= 1 << SC_MARKNUM_FOLDERTAIL;
+							}
 						} else {
-							marks |= 1 << SC_MARKNUM_FOLDERTAIL;
+							marks |= 1 << SC_MARKNUM_FOLDERSUB;
 						}
 					} else {
 						marks |= 1 << SC_MARKNUM_FOLDERSUB;
 					}
 				}
-
 				marks &= vs.ms[margin].mask;
 				PRectangle rcMarker = rcSelMargin;
 				rcMarker.top = yposScreen;
@@ -1771,7 +1926,20 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
 				if (marks) {
 					for (int markBit = 0; (markBit < 32) && marks; markBit++) {
 						if (marks & 1) {
-							vs.markers[markBit].Draw(surface, rcMarker, vs.styles[STYLE_LINENUMBER].font);
+							LineMarker::typeOfFold tFold;
+							if (!highlightDelimiter.isCurrentBlockHighlight(lineDoc)) {
+								tFold = LineMarker::undefined;
+							} else if (highlightDelimiter.isBodyBlockFold(lineDoc)) {
+								tFold = LineMarker::body;
+							} else if (highlightDelimiter.isHeadBlockFold(lineDoc)) {
+								tFold = LineMarker::head;
+							} else if (highlightDelimiter.isTailBlockFold(lineDoc)) {
+								tFold = LineMarker::tail;
+							} else {
+								//Normally, this branch is never used. But I prefer to manage it anyway.
+								tFold = LineMarker::undefined;
+							}
+							vs.markers[markBit].Draw(surface, rcMarker, vs.styles[STYLE_LINENUMBER].font, tFold);
 						}
 						marks >>= 1;
 					}
@@ -1824,6 +1992,7 @@ static bool GoodTrailByte(int v) {
 }
 
 bool BadUTF(const char *s, int len, int &trailBytes) {
+	// For the rules: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
 	if (trailBytes) {
 		trailBytes--;
 		return false;
@@ -1840,6 +2009,23 @@ bool BadUTF(const char *s, int len, int &trailBytes) {
 		if (len < 4)
 			return true;
 		if (GoodTrailByte(us[1]) && GoodTrailByte(us[2]) && GoodTrailByte(us[3])) {
+			if (*us == 0xf4) {
+				// Check if encoding a value beyond the last Unicode character 10FFFF
+				if (us[1] > 0x8f) {
+					return true;
+				} else if (us[1] == 0x8f) {
+					if (us[2] > 0xbf) {
+						return true;
+					} else if (us[2] == 0xbf) {
+						if (us[3] > 0xbf) {
+							return true;
+						}
+					}
+				}
+			} else if ((*us == 0xf0) && ((us[1] & 0xf0) == 0x80)) {
+				// Overlong
+				return true;
+			}
 			trailBytes = 3;
 			return false;
 		} else {
@@ -1850,6 +2036,22 @@ bool BadUTF(const char *s, int len, int &trailBytes) {
 		if (len < 3)
 			return true;
 		if (GoodTrailByte(us[1]) && GoodTrailByte(us[2])) {
+			if ((*us == 0xe0) && ((us[1] & 0xe0) == 0x80)) {
+				// Overlong
+				return true;
+			}
+			if ((*us == 0xed) && ((us[1] & 0xe0) == 0xa0)) {
+				// Surrogate
+				return true;
+			}
+			if ((*us == 0xef) && (us[1] == 0xbf) && (us[2] == 0xbe)) {
+				// U+FFFE
+				return true;
+			}
+			if ((*us == 0xef) && (us[1] == 0xbf) && (us[2] == 0xbf)) {
+				// U+FFFF
+				return true;
+			}
 			trailBytes = 2;
 			return false;
 		} else {
@@ -1939,8 +2141,6 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
 	if (ll->validity == LineLayout::llInvalid) {
 		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) {
@@ -1950,25 +2150,32 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
 			ll->edgeColumn = -1;
 		}
 
-		char styleByte = 0;
-		int styleMask = pdoc->stylingBitsMask;
+		char styleByte;
+		const int styleMask = pdoc->stylingBitsMask;
 		ll->styleBitsSet = 0;
 		// Fill base line layout
-		for (int charInDoc = posLineStart; charInDoc < posLineEnd; charInDoc++) {
-			char chDoc = pdoc->CharAt(charInDoc);
-			styleByte = pdoc->StyleAt(charInDoc);
+		const int lineLength = posLineEnd - posLineStart;
+		pdoc->GetCharRange(ll->chars, posLineStart, lineLength);
+		pdoc->GetStyleRange(ll->styles, posLineStart, lineLength);
+		int numCharsBeforeEOL = lineLength;
+		while ((numCharsBeforeEOL > 0) && IsEOLChar(ll->chars[numCharsBeforeEOL-1])) {
+			numCharsBeforeEOL--;
+		}
+		const int numCharsInLine = (vstyle.viewEOL) ? lineLength : numCharsBeforeEOL;
+		for (int styleInLine = 0; styleInLine < numCharsInLine; styleInLine++) {
+			styleByte = ll->styles[styleInLine];
 			ll->styleBitsSet |= styleByte;
-			if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
-				ll->chars[numCharsInLine] = chDoc;
-				ll->styles[numCharsInLine] = static_cast<char>(styleByte & styleMask);
-				ll->indicators[numCharsInLine] = static_cast<char>(styleByte & ~styleMask);
-				if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper)
-					ll->chars[numCharsInLine] = static_cast<char>(toupper(chDoc));
-				else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
-					ll->chars[numCharsInLine] = static_cast<char>(tolower(chDoc));
-				numCharsInLine++;
-				if (!IsEOLChar(chDoc))
-					numCharsBeforeEOL++;
+			ll->styles[styleInLine] = static_cast<char>(styleByte & styleMask);
+			ll->indicators[styleInLine] = static_cast<char>(styleByte & ~styleMask);
+		}
+		styleByte = static_cast<char>(((lineLength > 0) ? ll->styles[lineLength-1] : 0) & styleMask);
+		if (vstyle.someStylesForceCase) {
+			for (int charInLine = 0; charInLine<lineLength; charInLine++) {
+				char chDoc = ll->chars[charInLine];
+				if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseUpper)
+					ll->chars[charInLine] = static_cast<char>(toupper(chDoc));
+				else if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseLower)
+					ll->chars[charInLine] = static_cast<char>(tolower(chDoc));
 			}
 		}
 		ll->xHighlightGuide = 0;
@@ -2018,8 +2225,8 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
 						}
 						lastSegItalics = false;
 					} else if (isBadUTF) {
-						char hexits[3];
-						sprintf(hexits, "%2X", ll->chars[charInLine] & 0xff);
+						char hexits[4];
+						sprintf(hexits, "x%2X", ll->chars[charInLine] & 0xff);
 						ll->positions[charInLine + 1] =
 						    surface->WidthText(ctrlCharsFont, hexits, istrlen(hexits)) + 3;
 					} else {	// Regular character
@@ -2031,7 +2238,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
 						} else {
 							lastSegItalics = vstyle.styles[ll->styles[charInLine]].italic;
 							posCache.MeasureWidths(surface, vstyle, ll->styles[charInLine], ll->chars + startseg,
-							        lenSeg, ll->positions + startseg + 1);
+							        lenSeg, ll->positions + startseg + 1, pdoc);
 						}
 					}
 				} else {    // invisible
@@ -2342,6 +2549,8 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
 
 	// Fill the remainder of the line
 	rcSegment.left = xEol + xStart + virtualSpace + blobsWidth + vsDraw.aveCharWidth;
+	if (rcSegment.left < rcLine.left)
+		rcSegment.left = rcLine.left;
 	rcSegment.right = rcLine.right;
 
 	if (!hideSelection && vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) {
@@ -2374,12 +2583,22 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
 	}
 }
 
+void Editor::DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw,
+		int xStart, PRectangle rcLine, LineLayout *ll, int subLine) {
+	const int subLineStart = ll->positions[ll->LineStart(subLine)];
+	PRectangle rcIndic(
+		ll->positions[startPos] + xStart - subLineStart,
+		rcLine.top + vsDraw.maxAscent,
+		ll->positions[endPos] + xStart - subLineStart,
+		rcLine.top + vsDraw.maxAscent + 3);
+	vsDraw.indicators[indicNum].Draw(surface, rcIndic, rcLine);
+}
+
 void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
         PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under) {
 	// Draw decorators
 	const int posLineStart = pdoc->LineStart(line);
 	const int lineStart = ll->LineStart(subLine);
-	const int subLineStart = ll->positions[lineStart];
 	const int posLineEnd = posLineStart + lineEnd;
 
 	if (!under) {
@@ -2404,12 +2623,7 @@ void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int x
 					// IN indicator run, looking for END
 					if (indicPos >= lineEnd || !(ll->indicators[indicPos] & mask)) {
 						// AT end of indicator run, DRAW it!
-						PRectangle rcIndic(
-						    ll->positions[startPos] + xStart - subLineStart,
-						    rcLine.top + vsDraw.maxAscent,
-						    ll->positions[indicPos] + xStart - subLineStart,
-						    rcLine.top + vsDraw.maxAscent + 3);
-						vsDraw.indicators[indicnum].Draw(surface, rcIndic, rcLine);
+						DrawIndicator(indicnum, startPos, indicPos, surface, vsDraw, xStart, rcLine, ll, subLine);
 						// RESET control var
 						startPos = -1;
 					}
@@ -2429,16 +2643,33 @@ void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int x
 				int endPos = deco->rs.EndRun(startPos);
 				if (endPos > posLineEnd)
 					endPos = posLineEnd;
-				PRectangle rcIndic(
-				    ll->positions[startPos - posLineStart] + xStart - subLineStart,
-				    rcLine.top + vsDraw.maxAscent,
-				    ll->positions[endPos - posLineStart] + xStart - subLineStart,
-				    rcLine.top + vsDraw.maxAscent + 3);
-				vsDraw.indicators[deco->indicator].Draw(surface, rcIndic, rcLine);
+				DrawIndicator(deco->indicator, startPos - posLineStart, endPos - posLineStart,
+					surface, vsDraw, xStart, rcLine, ll, subLine);
 				startPos = deco->rs.EndRun(endPos);
 			}
 		}
 	}
+
+	// Use indicators to highlight matching braces
+	if ((vs.braceHighlightIndicatorSet && (bracesMatchStyle == STYLE_BRACELIGHT)) ||
+		(vs.braceBadLightIndicatorSet && (bracesMatchStyle == STYLE_BRACEBAD))) {
+		int braceIndicator = (bracesMatchStyle == STYLE_BRACELIGHT) ? vs.braceHighlightIndicator : vs.braceBadLightIndicator;
+		if (under == vsDraw.indicators[braceIndicator].under) {
+			Range rangeLine(posLineStart + lineStart, posLineEnd);
+			if (rangeLine.ContainsCharacter(braces[0])) {
+				int braceOffset = braces[0] - posLineStart;
+				if (braceOffset < ll->numCharsInLine) {
+					DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, xStart, rcLine, ll, subLine);
+				}
+			}
+			if (rangeLine.ContainsCharacter(braces[1])) {
+				int braceOffset = braces[1] - posLineStart;
+				if (braceOffset < ll->numCharsInLine) {
+					DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, xStart, rcLine, ll, subLine);
+				}
+			}
+		}
+	}
 }
 
 void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
@@ -2481,7 +2712,7 @@ void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int x
 			surface->LineTo(rcSegment.left, rcSegment.bottom);
 			surface->MoveTo(rcSegment.right, rcSegment.top);
 			surface->LineTo(rcSegment.right, rcSegment.bottom);
-			if (subLine == ll->lines){
+			if (subLine == ll->lines) {
 				surface->MoveTo(rcSegment.left, rcSegment.top);
 				surface->LineTo(rcSegment.right, rcSegment.top);
 			}
@@ -2623,7 +2854,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 
 	ll->psel = &sel;
 
-	BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible, selBackDrawn);
+	BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, xStartVisible, selBackDrawn, pdoc);
 	int next = bfBack.First();
 
 	// Background drawing loop
@@ -2713,8 +2944,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 
 	inIndentation = subLine == 0;	// Do not handle indentation except on first subline.
 	// Foreground drawing loop
-	BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible,
-		((!twoPhaseDraw && selBackDrawn) || vsDraw.selforeset));
+	BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, xStartVisible,
+		((!twoPhaseDraw && selBackDrawn) || vsDraw.selforeset), pdoc);
 	next = bfFore.First();
 
 	while (next < lineEnd) {
@@ -2787,8 +3018,9 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 					        cc, 1, textBack, textFore);
 				}
 			} else if ((i == startseg) && (static_cast<unsigned char>(ll->chars[i]) >= 0x80) && IsUnicodeMode()) {
-				char hexits[3];
-				sprintf(hexits, "%2X", ll->chars[i] & 0xff);
+				// A single byte >= 0x80 in UTF-8 is a bad byte and is displayed as its hex value
+				char hexits[4];
+				sprintf(hexits, "x%2X", ll->chars[i] & 0xff);
 				DrawTextBlob(surface, vsDraw, rcSegment, hexits, textBack, textFore, twoPhaseDraw);
 			} else {
 				// Normal text display
@@ -2840,7 +3072,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 					}
 				}
 			}
-			if (ll->hsStart != -1 && vsDraw.hotspotUnderline && iDoc >= ll->hsStart && iDoc < ll->hsEnd ) {
+			if (ll->hsStart != -1 && vsDraw.hotspotUnderline && iDoc >= ll->hsStart && iDoc < ll->hsEnd) {
 				PRectangle rcUL = rcSegment;
 				rcUL.top = rcUL.top + vsDraw.maxAscent + 1;
 				rcUL.bottom = rcUL.top + 1;
@@ -2893,7 +3125,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 			lineNextWithText++;
 		}
 		if (lineNextWithText > line) {
-			// This line is empty, so use indentation of last line with text
+			xStartText = 100000;	// Don't limit to visible indentation on empty line
+			// This line is empty, so use indentation of first next line with text
 			indentSpace = Platform::Maximum(indentSpace,
 			        pdoc->GetLineIndentation(lineNextWithText));
 		}
@@ -2941,7 +3174,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
 	}
 
 	// Draw any translucent whole line states
-	rcSegment.left = xStart;
+	rcSegment.left = 0;
 	rcSegment.right = rcLine.right - 1;
 	if (caret.active && vsDraw.showCaretLineBackground && ll->containsCaret) {
 		SimpleAlphaRectangle(surface, rcSegment, vsDraw.caretLineBackground.allocated, vsDraw.caretLineAlpha);
@@ -3063,11 +3296,11 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) {
 		}
 
 		pixmapSelPattern->FillRectangle(rcPattern, colourFMFill);
-		pixmapSelPattern->PenColour(colourFMStripes);
-		for (int stripe = 0; stripe < patternSize; stripe++) {
-			// Alternating 1 pixel stripes is same as checkerboard.
-			pixmapSelPattern->MoveTo(0, stripe * 2);
-			pixmapSelPattern->LineTo(patternSize, stripe * 2 - patternSize);
+		for (int y = 0; y < patternSize; y++) {
+			for (int x = y % 2; x < patternSize; x+=2) {
+				PRectangle rcPixel(x, y, x+1, y+1);
+				pixmapSelPattern->FillRectangle(rcPixel, colourFMStripes);
+			}
 		}
 	}
 
@@ -3081,10 +3314,9 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) {
 		pixmapIndentGuideHighlight->FillRectangle(rcIG, vs.styles[STYLE_BRACELIGHT].back.allocated);
 		pixmapIndentGuideHighlight->PenColour(vs.styles[STYLE_BRACELIGHT].fore.allocated);
 		for (int stripe = 1; stripe < vs.lineHeight + 1; stripe += 2) {
-			pixmapIndentGuide->MoveTo(0, stripe);
-			pixmapIndentGuide->LineTo(2, stripe);
-			pixmapIndentGuideHighlight->MoveTo(0, stripe);
-			pixmapIndentGuideHighlight->LineTo(2, stripe);
+			PRectangle rcPixel(0, stripe, 1, stripe+1);
+			pixmapIndentGuide->FillRectangle(rcPixel, vs.styles[STYLE_INDENTGUIDE].fore.allocated);
+			pixmapIndentGuideHighlight->FillRectangle(rcPixel, vs.styles[STYLE_BRACELIGHT].fore.allocated);
 		}
 	}
 
@@ -3186,6 +3418,8 @@ 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);
 
+	StyleToPositionInView(PositionAfterArea(rcArea));
+
 	pixmapLine->Release();
 	RefreshStyleData();
 	RefreshPixMaps(surfaceWindow);
@@ -3198,13 +3432,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 	pixmapLine->SetPalette(&palette, !hasFocus);
 
 	int screenLinePaintFirst = rcArea.top / vs.lineHeight;
-	// The area to be painted plus one extra line is styled.
-	// The extra line is to determine when a style change, such as starting a comment flows on to other lines.
-	int lineStyleLast = topLine + (rcArea.bottom - 1) / vs.lineHeight + 1;
-	//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);
 
 	int xStart = vs.fixedColumnWidth - xOffset;
 	int ypos = 0;
@@ -3212,8 +3439,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 		ypos += screenLinePaintFirst * vs.lineHeight;
 	int yposScreen = screenLinePaintFirst * vs.lineHeight;
 
-	// Ensure we are styled as far as we are painting.
-	pdoc->EnsureStyledTo(endPosPaint);
 	bool paintAbandonedByStyling = paintState == paintAbandoned;
 	if (needUpdateUI) {
 		// Deselect palette by selecting a temporary palette
@@ -3221,7 +3446,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 		surfaceWindow->SetPalette(&palTemp, true);
 
 		NotifyUpdateUI();
-		needUpdateUI = false;
+		needUpdateUI = 0;
 
 		RefreshStyleData();
 		RefreshPixMaps(surfaceWindow);
@@ -3245,12 +3470,14 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 	}
 	PLATFORM_ASSERT(pixmapSelPattern->Initialised());
 
-	PaintSelMargin(surfaceWindow, rcArea);
+	if (paintState != paintAbandoned) {
+		PaintSelMargin(surfaceWindow, rcArea);
 
-	PRectangle rcRightMargin = rcClient;
-	rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth;
-	if (rcArea.Intersects(rcRightMargin)) {
-		surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back.allocated);
+		PRectangle rcRightMargin = rcClient;
+		rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth;
+		if (rcArea.Intersects(rcRightMargin)) {
+			surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back.allocated);
+		}
 	}
 
 	if (paintState == paintAbandoned) {
@@ -3331,34 +3558,40 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 				rcLine.top = ypos;
 				rcLine.bottom = ypos + vs.lineHeight;
 
+				bool bracesIgnoreStyle = false;
+				if ((vs.braceHighlightIndicatorSet && (bracesMatchStyle == STYLE_BRACELIGHT)) ||
+					(vs.braceBadLightIndicatorSet && (bracesMatchStyle == STYLE_BRACEBAD))) {
+					bracesIgnoreStyle = true;
+				}
 				Range rangeLine(pdoc->LineStart(lineDoc), pdoc->LineStart(lineDoc + 1));
 				// Highlight the current braces if any
 				ll->SetBracesHighlight(rangeLine, braces, static_cast<char>(bracesMatchStyle),
-				        highlightGuideColumn * vs.spaceWidth);
+				        highlightGuideColumn * vs.spaceWidth, bracesIgnoreStyle);
 
 				// Draw the line
 				DrawLine(surface, vs, lineDoc, visibleLine, xStart, rcLine, ll, subLine);
 				//durPaint += et.Duration(true);
 
 				// Restore the previous styles for the brace highlights in case layout is in cache.
-				ll->RestoreBracesHighlight(rangeLine, braces);
+				ll->RestoreBracesHighlight(rangeLine, braces, bracesIgnoreStyle);
 
 				bool expanded = cs.GetExpanded(lineDoc);
-				// 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) {
+				const int level = pdoc->GetLevel(lineDoc);
+				const int levelNext = pdoc->GetLevel(lineDoc + 1);
+				if ((level & SC_FOLDLEVELHEADERFLAG) &&
+					((level & SC_FOLDLEVELNUMBERMASK) < (levelNext & SC_FOLDLEVELNUMBERMASK))) {
+					// Paint the line above the fold
+					if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED))
+						||
+						(!expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) {
 						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) {
+					// Paint the line below the fold
+					if ((expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED))
+						||
+						(!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
 						PRectangle rcFoldLine = rcLine;
 						rcFoldLine.top = rcFoldLine.bottom - 1;
 						surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
@@ -3472,9 +3705,12 @@ long Editor::FormatRange(bool draw, Sci_RangeToFormat *pfr) {
 	vsPrint.whitespaceBackgroundSet = false;
 	vsPrint.whitespaceForegroundSet = false;
 	vsPrint.showCaretLineBackground = false;
+	// Don't highlight matching braces using indicators
+	vsPrint.braceHighlightIndicatorSet = false;
+	vsPrint.braceBadLightIndicatorSet = false;
 
 	// Set colours for printing according to users settings
-	for (size_t sty = 0;sty < vsPrint.stylesSize;sty++) {
+	for (size_t sty = 0; sty < vsPrint.stylesSize; sty++) {
 		if (printColourMode == SC_PRINT_INVERTLIGHT) {
 			vsPrint.styles[sty].fore.desired = InvertedLight(vsPrint.styles[sty].fore.desired);
 			vsPrint.styles[sty].back.desired = InvertedLight(vsPrint.styles[sty].back.desired);
@@ -3529,7 +3765,7 @@ long Editor::FormatRange(bool draw, Sci_RangeToFormat *pfr) {
 
 	int nPrintPos = pfr->chrg.cpMin;
 	int visibleLine = 0;
-	int widthPrint = pfr->rc.Width() - vsPrint.fixedColumnWidth;
+	int widthPrint = pfr->rc.right - pfr->rc.left - vsPrint.fixedColumnWidth;
 	if (printWrapState == eWrapNone)
 		widthPrint = LineLayout::wrapWidthInfinite;
 
@@ -3727,7 +3963,11 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
 				if (wrapState != eWrapNone) {
 					AutoSurface surface(this);
 					if (surface) {
-						WrapOneLine(surface, pdoc->LineFromPosition(positionInsert));
+						if (WrapOneLine(surface, pdoc->LineFromPosition(positionInsert))) {
+							SetScrollBars();
+							SetVerticalScrollPos();
+							Redraw();
+						}
 					}
 				}
 			}
@@ -3741,7 +3981,8 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
 	EnsureCaretVisible();
 	// Avoid blinking during rapid typing:
 	ShowCaretAtCurrentPosition();
-	if (!caretSticky) {
+	if ((caretSticky == SC_CARETSTICKY_OFF) ||
+		((caretSticky == SC_CARETSTICKY_WHITESPACE) && !IsAllSpacesOrTabs(s, len))) {
 		SetLastXChosen();
 	}
 
@@ -3787,8 +4028,40 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
 	}
 }
 
-void Editor::ClearSelection() {
-	if (!sel.IsRectangular())
+void Editor::InsertPaste(SelectionPosition selStart, const char *text, int len) {
+	if (multiPasteMode == SC_MULTIPASTE_ONCE) {
+		selStart = SelectionPosition(InsertSpace(selStart.Position(), selStart.VirtualSpace()));
+		if (pdoc->InsertString(selStart.Position(), text, len)) {
+			SetEmptySelection(selStart.Position() + len);
+		}
+	} else {
+		// SC_MULTIPASTE_EACH
+		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();
+					}
+				}
+				positionInsert = InsertSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
+				if (pdoc->InsertString(positionInsert, text, len)) {
+					sel.Range(r).caret.SetPosition(positionInsert + len);
+					sel.Range(r).anchor.SetPosition(positionInsert + len);
+				}
+				sel.Range(r).ClearVirtualSpace();
+			}
+		}
+	}
+}
+
+void Editor::ClearSelection(bool retainMultipleSelections) {
+	if (!sel.IsRectangular() && !retainMultipleSelections)
 		FilterSelections();
 	UndoGroup ug(pdoc);
 	for (size_t r=0; r<sel.Count(); r++) {
@@ -3902,9 +4175,9 @@ bool Editor::CanPaste() {
 }
 
 void Editor::Clear() {
-	UndoGroup ug(pdoc);
 	// If multiple selections, don't delete EOLS
 	if (sel.Empty()) {
+		UndoGroup ug(pdoc, sel.Count() > 1);
 		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).Start().VirtualSpace()) {
@@ -4014,10 +4287,17 @@ void Editor::NotifyStyleToNeeded(int endStyleNeeded) {
 	NotifyParent(scn);
 }
 
-void Editor::NotifyStyleNeeded(Document*, void *, int endStyleNeeded) {
+void Editor::NotifyStyleNeeded(Document *, void *, int endStyleNeeded) {
 	NotifyStyleToNeeded(endStyleNeeded);
 }
 
+void Editor::NotifyLexerChanged(Document *, void *) {
+}
+
+void Editor::NotifyErrorOccurred(Document *, void *, int status) {
+	errorStatus = status;
+}
+
 void Editor::NotifyChar(int ch) {
 	SCNotification scn = {0};
 	scn.nmhdr.code = SCN_CHARADDED;
@@ -4069,9 +4349,19 @@ void Editor::NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt)
 	NotifyParent(scn);
 }
 
+void Editor::NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt) {
+	SCNotification scn = {0};
+	scn.nmhdr.code = SCN_HOTSPOTRELEASECLICK;
+	scn.position = position;
+	scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
+	        (alt ? SCI_ALT : 0);
+	NotifyParent(scn);
+}
+
 void Editor::NotifyUpdateUI() {
 	SCNotification scn = {0};
 	scn.nmhdr.code = SCN_UPDATEUI;
+	scn.updated = needUpdateUI;
 	NotifyParent(scn);
 }
 
@@ -4139,12 +4429,12 @@ void Editor::NotifyZoom() {
 }
 
 // Notifications from document
-void Editor::NotifyModifyAttempt(Document*, void *) {
+void Editor::NotifyModifyAttempt(Document *, void *) {
 	//Platform::DebugPrintf("** Modify Attempt\n");
 	NotifyModifyAttempt();
 }
 
-void Editor::NotifySavePoint(Document*, void *, bool atSavePoint) {
+void Editor::NotifySavePoint(Document *, void *, bool atSavePoint) {
 	//Platform::DebugPrintf("** Save Point %s\n", atSavePoint ? "On" : "Off");
 	NotifySavePoint(atSavePoint);
 }
@@ -4187,8 +4477,8 @@ static inline int MovePositionForDeletion(int position, int startDeletion, int l
 	}
 }
 
-void Editor::NotifyModified(Document*, DocModification mh, void *) {
-	needUpdateUI = true;
+void Editor::NotifyModified(Document *, DocModification mh, void *) {
+	ContainerNeedsUpdate(SC_UPDATE_CONTENT);
 	if (paintState == painting) {
 		CheckForChangeOutsidePaint(Range(mh.position, mh.position + mh.length));
 	}
@@ -4201,6 +4491,14 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
 			Redraw();
 		}
 	}
+	if (mh.modificationType & SC_MOD_LEXERSTATE) {
+		if (paintState == painting) {
+			CheckForChangeOutsidePaint(
+			    Range(mh.position, mh.position + mh.length));
+		} else {
+			Redraw();
+		}
+	}
 	if (mh.modificationType & (SC_MOD_CHANGESTYLE | SC_MOD_CHANGEINDICATOR)) {
 		if (mh.modificationType & SC_MOD_CHANGESTYLE) {
 			pdoc->IncrementStyleClock();
@@ -4231,7 +4529,16 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
 			// Some lines are hidden so may need shown.
 			// TODO: check if the modified area is hidden.
 			if (mh.modificationType & SC_MOD_BEFOREINSERT) {
-				NotifyNeedShown(mh.position, 0);
+				int lineOfPos = pdoc->LineFromPosition(mh.position);
+				bool insertingNewLine = false;
+				for (int i=0; i < mh.length; i++) {
+					if ((mh.text[i] == '\n') || (mh.text[i] == '\r'))
+						insertingNewLine = true;
+				}
+				if (insertingNewLine && (mh.position != pdoc->LineStart(lineOfPos)))
+					NotifyNeedShown(mh.position, pdoc->LineStart(lineOfPos+1) - mh.position);
+				else
+					NotifyNeedShown(mh.position, 0);
 			} else if (mh.modificationType & SC_MOD_BEFOREDELETE) {
 				NotifyNeedShown(mh.position, mh.length);
 			}
@@ -4250,6 +4557,7 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
 			int lineDoc = pdoc->LineFromPosition(mh.position);
 			if (vs.annotationVisible) {
 				cs.SetHeight(lineDoc, cs.GetHeight(lineDoc) + mh.annotationLinesAdded);
+				Redraw();
 			}
 		}
 		CheckModificationForWrap(mh);
@@ -4267,12 +4575,14 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
 			// TODO: could invalidate from mh.startModification to end of screen
 			//InvalidateRange(mh.position, mh.position + mh.length);
 			if (paintState == notPainting && !CanDeferToLastStep(mh)) {
+				QueueStyling(pdoc->Length());
 				Redraw();
 			}
 		} else {
 			//Platform::DebugPrintf("** %x Line Changed %d .. %d\n", this,
 			//	mh.position, mh.position + mh.length);
 			if (paintState == notPainting && mh.length && !CanEliminate(mh)) {
+				QueueStyling(mh.position + mh.length);
 				InvalidateRange(mh.position, mh.position + mh.length);
 			}
 		}
@@ -4286,7 +4596,7 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
 		if ((paintState == notPainting) || !PaintContainsMargin()) {
 			if (mh.modificationType & SC_MOD_CHANGEFOLD) {
 				// Fold changes can affect the drawing of following lines so redraw whole margin
-				RedrawSelMargin();
+				RedrawSelMargin(mh.line-1, true);
 			} else {
 				RedrawSelMargin(mh.line);
 			}
@@ -4430,6 +4740,9 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
 	case SCI_PAGEDOWNRECTEXTEND:
 	case SCI_SELECTIONDUPLICATE:
 	case SCI_COPYALLOWLINE:
+	case SCI_VERTICALCENTRECARET:
+	case SCI_MOVESELECTEDLINESUP:
+	case SCI_MOVESELECTEDLINESDOWN:
 		break;
 
 		// Filter out all others like display changes. Also, newlines are redundant
@@ -4449,6 +4762,11 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
 	NotifyParent(scn);
 }
 
+// Something has changed that the container should know about
+void Editor::ContainerNeedsUpdate(int flags) {
+	needUpdateUI |= flags;
+}
+
 /**
  * Force scroll and keep position relative to top of window.
  *
@@ -4456,51 +4774,76 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
  * If stuttered = true and already at first/last row, scroll as normal.
  */
 void Editor::PageMove(int direction, Selection::selTypes selt, bool stuttered) {
-	int topLineNew, newPos;
+	int topLineNew;
+	SelectionPosition newPos;
 
-	// I consider only the caretYSlop, and ignore the caretYPolicy-- is that a problem?
 	int currentLine = pdoc->LineFromPosition(sel.MainCaret());
 	int topStutterLine = topLine + caretYSlop;
 	int bottomStutterLine =
 	    pdoc->LineFromPosition(PositionFromLocation(
-	                Point(lastXChosen, direction * vs.lineHeight * LinesToScroll())))
+	                Point(lastXChosen - xOffset, direction * vs.lineHeight * LinesToScroll())))
 	    - caretYSlop - 1;
 
 	if (stuttered && (direction < 0 && currentLine > topStutterLine)) {
 		topLineNew = topLine;
-		newPos = PositionFromLocation(Point(lastXChosen, vs.lineHeight * caretYSlop));
+		newPos = SPositionFromLocation(Point(lastXChosen - xOffset, vs.lineHeight * caretYSlop),
+			false, false, UserVirtualSpace());
 
 	} else if (stuttered && (direction > 0 && currentLine < bottomStutterLine)) {
 		topLineNew = topLine;
-		newPos = PositionFromLocation(Point(lastXChosen, vs.lineHeight * (LinesToScroll() - caretYSlop)));
+		newPos = SPositionFromLocation(Point(lastXChosen - xOffset, vs.lineHeight * (LinesToScroll() - caretYSlop)),
+			false, false, UserVirtualSpace());
 
 	} else {
 		Point pt = LocationFromPosition(sel.MainCaret());
 
 		topLineNew = Platform::Clamp(
 		            topLine + direction * LinesToScroll(), 0, MaxScrollPos());
-		newPos = PositionFromLocation(
-		            Point(lastXChosen, pt.y + direction * (vs.lineHeight * LinesToScroll())));
+		newPos = SPositionFromLocation(
+			Point(lastXChosen - xOffset, pt.y + direction * (vs.lineHeight * LinesToScroll())),
+			false, false, UserVirtualSpace());
 	}
 
 	if (topLineNew != topLine) {
 		SetTopLine(topLineNew);
-		MovePositionTo(SelectionPosition(newPos), selt);
+		MovePositionTo(newPos, selt);
 		Redraw();
 		SetVerticalScrollPos();
 	} else {
-		MovePositionTo(SelectionPosition(newPos), selt);
+		MovePositionTo(newPos, selt);
 	}
 }
 
-void Editor::ChangeCaseOfSelection(bool makeUpperCase) {
+void Editor::ChangeCaseOfSelection(int caseMapping) {
 	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;
+		SelectionRange currentNoVS = current;
+		currentNoVS.ClearVirtualSpace();
+		char *text = CopyRange(currentNoVS.Start().Position(), currentNoVS.End().Position());
+		size_t rangeBytes = currentNoVS.Length();
+		if (rangeBytes > 0) {
+			std::string sText(text, rangeBytes);
+
+			std::string sMapped = CaseMapString(sText, caseMapping);
+
+			if (sMapped != sText) {
+				size_t firstDifference = 0;
+				while (sMapped[firstDifference] == sText[firstDifference])
+					firstDifference++;
+				size_t lastDifference = sMapped.size() - 1;
+				while (sMapped[lastDifference] == sText[lastDifference])
+					lastDifference--;
+				size_t endSame = sMapped.size() - 1 - lastDifference;
+				pdoc->DeleteChars(currentNoVS.Start().Position() + firstDifference,
+					rangeBytes - firstDifference - endSame);
+				pdoc->InsertString(currentNoVS.Start().Position() + firstDifference,
+					sMapped.c_str() + firstDifference, lastDifference - firstDifference + 1);
+				// Automatic movement changes selection so reset to exactly the same as it was.
+				sel.Range(r) = current;
+			}
+		}
+		delete []text;
 	}
 }
 
@@ -4531,7 +4874,6 @@ void Editor::Duplicate(bool forLine) {
 		forLine = true;
 	}
 	UndoGroup ug(pdoc, sel.Count() > 1);
-	SelectionPosition last;
 	const char *eol = "";
 	int eolLen = 0;
 	if (forLine) {
@@ -4613,10 +4955,10 @@ void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) {
 	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());
+	            Point(lastXChosen - xOffset, 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());
+	            Point(lastXChosen - xOffset, pt.y + (commentLines + 1) * vs.lineHeight), false, false, UserVirtualSpace());
 	}
 	if (direction < 0) {
 		// Line wrapping may lead to a location on the same line, so
@@ -4935,6 +5277,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
 		inOverstrike = !inOverstrike;
 		DropCaret();
 		ShowCaretAtCurrentPosition();
+		ContainerNeedsUpdate(SC_UPDATE_CONTENT);
 		NotifyUpdateUI();
 		break;
 	case SCI_CANCEL:            	// Cancel any modes - handled in subclass
@@ -4943,21 +5286,21 @@ int Editor::KeyCommand(unsigned int iMessage) {
 		break;
 	case SCI_DELETEBACK:
 		DelCharBack(true);
-		if (!caretSticky) {
+		if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) {
 			SetLastXChosen();
 		}
 		EnsureCaretVisible();
 		break;
 	case SCI_DELETEBACKNOTLINE:
 		DelCharBack(false);
-		if (!caretSticky) {
+		if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) {
 			SetLastXChosen();
 		}
 		EnsureCaretVisible();
 		break;
 	case SCI_TAB:
 		Indent(true);
-		if (!caretSticky) {
+		if (caretSticky == SC_CARETSTICKY_OFF) {
 			SetLastXChosen();
 		}
 		EnsureCaretVisible();
@@ -4965,7 +5308,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
 		break;
 	case SCI_BACKTAB:
 		Indent(false);
-		if (!caretSticky) {
+		if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) {
 			SetLastXChosen();
 		}
 		EnsureCaretVisible();
@@ -5034,6 +5377,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
 			UndoGroup ug(pdoc);
 			sel.RangeMain().caret = SelectionPosition(
 				InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace()));
+			sel.RangeMain().anchor = sel.RangeMain().caret;
 			int endWord = pdoc->NextWordStart(sel.MainCaret(), 1);
 			pdoc->DeleteChars(sel.MainCaret(), endWord - sel.MainCaret());
 		}
@@ -5094,10 +5438,10 @@ int Editor::KeyCommand(unsigned int iMessage) {
 		Duplicate(false);
 		break;
 	case SCI_LOWERCASE:
-		ChangeCaseOfSelection(false);
+		ChangeCaseOfSelection(cmLower);
 		break;
 	case SCI_UPPERCASE:
-		ChangeCaseOfSelection(true);
+		ChangeCaseOfSelection(cmUpper);
 		break;
 	case SCI_WORDPARTLEFT:
 		MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(sel.MainCaret()), -1));
@@ -5205,7 +5549,7 @@ void Editor::Indent(bool forwards) {
 					int indentation = pdoc->GetLineIndentation(lineCurrentPos);
 					int indentationStep = pdoc->IndentSize();
 					pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
-					SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
+					sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos));
 				} else {
 					int newColumn = ((pdoc->GetColumn(caretPosition) - 1) / pdoc->tabInChars) *
 							pdoc->tabInChars;
@@ -5244,6 +5588,31 @@ void Editor::Indent(bool forwards) {
 	}
 }
 
+class CaseFolderASCII : public CaseFolderTable {
+public:
+	CaseFolderASCII() {
+		StandardASCII();
+	}
+	~CaseFolderASCII() {
+	}
+	virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
+		if (lenMixed > sizeFolded) {
+			return 0;
+		} else {
+			for (size_t i=0; i<lenMixed; i++) {
+				folded[i] = mapping[static_cast<unsigned char>(mixed[i])];
+			}
+			return lenMixed;
+		}
+	}
+};
+
+
+CaseFolder *Editor::CaseFolderForEncoding() {
+	// Simple default that only maps ASCII upper case to lower case.
+	return new CaseFolderASCII();
+}
+
 /**
  * Search of a text in the document, in the given range.
  * @return The position of the found text, -1 if not found.
@@ -5255,13 +5624,15 @@ long Editor::FindText(
 
 	Sci_TextToFind *ft = reinterpret_cast<Sci_TextToFind *>(lParam);
 	int lengthFound = istrlen(ft->lpstrText);
+	std::auto_ptr<CaseFolder> pcf(CaseFolderForEncoding());
 	int pos = pdoc->FindText(ft->chrg.cpMin, ft->chrg.cpMax, ft->lpstrText,
 	        (wParam & SCFIND_MATCHCASE) != 0,
 	        (wParam & SCFIND_WHOLEWORD) != 0,
 	        (wParam & SCFIND_WORDSTART) != 0,
 	        (wParam & SCFIND_REGEXP) != 0,
 	        wParam,
-	        &lengthFound);
+	        &lengthFound,
+			pcf.get());
 	if (pos != -1) {
 		ft->chrgText.cpMin = pos;
 		ft->chrgText.cpMax = pos + lengthFound;
@@ -5298,6 +5669,7 @@ long Editor::SearchText(
 	const char *txt = reinterpret_cast<char *>(lParam);
 	int pos;
 	int lengthFound = istrlen(txt);
+	std::auto_ptr<CaseFolder> pcf(CaseFolderForEncoding());
 	if (iMessage == SCI_SEARCHNEXT) {
 		pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt,
 		        (wParam & SCFIND_MATCHCASE) != 0,
@@ -5305,7 +5677,8 @@ long Editor::SearchText(
 		        (wParam & SCFIND_WORDSTART) != 0,
 		        (wParam & SCFIND_REGEXP) != 0,
 		        wParam,
-		        &lengthFound);
+		        &lengthFound,
+				pcf.get());
 	} else {
 		pos = pdoc->FindText(searchAnchor, 0, txt,
 		        (wParam & SCFIND_MATCHCASE) != 0,
@@ -5313,9 +5686,9 @@ long Editor::SearchText(
 		        (wParam & SCFIND_WORDSTART) != 0,
 		        (wParam & SCFIND_REGEXP) != 0,
 		        wParam,
-		        &lengthFound);
+		        &lengthFound,
+				pcf.get());
 	}
-
 	if (pos != -1) {
 		SetSelection(pos, pos + lengthFound);
 	}
@@ -5323,19 +5696,39 @@ long Editor::SearchText(
 	return pos;
 }
 
+std::string Editor::CaseMapString(const std::string &s, int caseMapping) {
+	std::string ret(s);
+	for (size_t i=0; i<ret.size(); i++) {
+		switch (caseMapping) {
+			case cmUpper:
+				if (ret[i] >= 'a' && ret[i] <= 'z')
+					ret[i] = static_cast<char>(ret[i] - 'a' + 'A');
+				break;
+			case cmLower:
+				if (ret[i] >= 'A' && ret[i] <= 'Z')
+					ret[i] = static_cast<char>(ret[i] - 'A' + 'a');
+				break;
+		}
+	}
+	return ret;
+}
+
 /**
  * Search for text in the target range of the document.
  * @return The position of the found text, -1 if not found.
  */
 long Editor::SearchInTarget(const char *text, int length) {
 	int lengthFound = length;
+
+	std::auto_ptr<CaseFolder> pcf(CaseFolderForEncoding());
 	int pos = pdoc->FindText(targetStart, targetEnd, text,
 	        (searchFlags & SCFIND_MATCHCASE) != 0,
 	        (searchFlags & SCFIND_WHOLEWORD) != 0,
 	        (searchFlags & SCFIND_WORDSTART) != 0,
 	        (searchFlags & SCFIND_REGEXP) != 0,
 	        searchFlags,
-	        &lengthFound);
+	        &lengthFound,
+			pcf.get());
 	if (pos != -1) {
 		targetStart = pos;
 		targetEnd = pos + lengthFound;
@@ -5591,6 +5984,16 @@ bool Editor::PointInSelMargin(Point pt) {
 	}
 }
 
+Window::Cursor Editor::GetMarginCursor(Point pt) {
+	int x = 0;
+	for (int margin = 0; margin < ViewStyle::margins; margin++) {
+		if ((pt.x >= x) && (pt.x < x + vs.ms[margin].width))
+			return static_cast<Window::Cursor>(vs.ms[margin].cursor);
+		x += vs.ms[margin].width;
+	}
+	return Window::cursorReverseArrow;
+}
+
 void Editor::LineSelection(int lineCurrent_, int lineAnchor_) {
 	if (lineAnchor_ < lineCurrent_) {
 		SetSelection(pdoc->LineStart(lineCurrent_ + 1),
@@ -5604,6 +6007,30 @@ void Editor::LineSelection(int lineCurrent_, int lineAnchor_) {
 	}
 }
 
+void Editor::WordSelection(int pos) {
+	if (pos < wordSelectAnchorStartPos) {
+		// Extend backward to the word containing pos.
+		// Skip ExtendWordSelect if the line is empty or if pos is after the last character.
+		// This ensures that a series of empty lines isn't counted as a single "word".
+		if (!pdoc->IsLineEndPosition(pos))
+			pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos + 1, 1), -1);
+		SetSelection(pos, wordSelectAnchorEndPos);
+	} else if (pos > wordSelectAnchorEndPos) {
+		// Extend forward to the word containing the character to the left of pos.
+		// Skip ExtendWordSelect if the line is empty or if pos is the first position on the line.
+		// This ensures that a series of empty lines isn't counted as a single "word".
+		if (pos > pdoc->LineStart(pdoc->LineFromPosition(pos)))
+			pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos - 1, -1), 1);
+		SetSelection(pos, wordSelectAnchorStartPos);
+	} else {
+		// Select only the anchored word
+		if (pos >= originalAnchorPos)
+			SetSelection(wordSelectAnchorEndPos, wordSelectAnchorStartPos);
+		else
+			SetSelection(wordSelectAnchorStartPos, wordSelectAnchorEndPos);
+	}
+}
+
 void Editor::DwellEnd(bool mouseMoved) {
 	if (mouseMoved)
 		ticksToDwell = dwellDelay;
@@ -5615,7 +6042,15 @@ void Editor::DwellEnd(bool mouseMoved) {
 	}
 }
 
-static bool AllowVirtualSpace(int	virtualSpaceOptions, bool rectangular) {
+void Editor::MouseLeave() {
+	SetHotSpotRange(NULL);
+	if (!HaveMouseCapture()) {
+		ptMouseLast = Point(-1,-1);
+		DwellEnd(true);
+	}
+}
+
+static bool AllowVirtualSpace(int virtualSpaceOptions, bool rectangular) {
 	return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0)
 		|| (rectangular && ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) != 0));
 }
@@ -5657,13 +6092,33 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
 		}
 
 		if (selectionType == selWord) {
-			if (sel.MainCaret() >= originalAnchorPos) {	// Moved forward
-				SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), 1),
-				        pdoc->ExtendWordSelect(originalAnchorPos, -1));
-			} else {	// Moved backward
-				SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), -1),
-				        pdoc->ExtendWordSelect(originalAnchorPos, 1));
+			int charPos = originalAnchorPos;
+			if (sel.MainCaret() == originalAnchorPos) {
+				charPos = PositionFromLocation(pt, false, true);
+				charPos = MovePositionOutsideChar(charPos, -1);
+			}
+
+			int startWord, endWord;
+			if ((sel.MainCaret() >= originalAnchorPos) && !pdoc->IsLineEndPosition(charPos)) {
+				startWord = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(charPos + 1, 1), -1);
+				endWord = pdoc->ExtendWordSelect(charPos, 1);
+			} else {
+				// Selecting backwards, or anchor beyond last character on line. In these cases,
+				// we select the word containing the character to the *left* of the anchor.
+				if (charPos > pdoc->LineStart(pdoc->LineFromPosition(charPos))) {
+					startWord = pdoc->ExtendWordSelect(charPos, -1);
+					endWord = pdoc->ExtendWordSelect(startWord, 1);
+				} else {
+					// Anchor at start of line; select nothing to begin with.
+					startWord = charPos;
+					endWord = charPos;
+				}
 			}
+
+			wordSelectAnchorStartPos = startWord;
+			wordSelectAnchorEndPos = endWord;
+			wordSelectInitialCaretPos = sel.MainCaret();
+			WordSelection(wordSelectInitialCaretPos);
 		} else if (selectionType == selLine) {
 			lineAnchor = LineFromLocation(pt);
 			SetSelection(pdoc->LineStart(lineAnchor + 1), pdoc->LineStart(lineAnchor));
@@ -5708,6 +6163,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
 		} else {
 			if (PointIsHotspot(pt)) {
 				NotifyHotSpotClicked(newPos.Position(), shift, ctrl, alt);
+				hotSpotClickPos = PositionFromLocation(pt,true,false);
 			}
 			if (!shift) {
 				if (PointInSelection(pt) && !SelectionEmpty())
@@ -5727,7 +6183,8 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
 						InvalidateSelection(SelectionRange(newPos), true);
 						if (sel.Count() > 1)
 							Redraw();
-						sel.Clear();
+						if ((sel.Count() > 1) || (sel.selType != Selection::selStream))
+							sel.Clear();
 						sel.selType = alt ? Selection::selRectangle : Selection::selStream;
 						SetSelection(newPos, newPos);
 					}
@@ -5745,7 +6202,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
 		}
 	}
 	lastClickTime = curTime;
-	lastXChosen = pt.x;
+	lastXChosen = pt.x + xOffset;
 	ShowCaretAtCurrentPosition();
 }
 
@@ -5793,7 +6250,7 @@ void Editor::SetHotSpotRange(Point *pt) {
 	}
 }
 
-void Editor::GetHotSpotRange(int& hsStart_, int& hsEnd_) {
+void Editor::GetHotSpotRange(int &hsStart_, int &hsEnd_) {
 	hsStart_ = hsStart;
 	hsEnd_ = hsEnd;
 }
@@ -5844,7 +6301,7 @@ void Editor::ButtonMove(Point pt) {
 				}
 			} else if (selectionType == selWord) {
 				// Continue selecting by word
-				if (movePos.Position() == originalAnchorPos) {	// Didn't move
+				if (movePos.Position() == wordSelectInitialCaretPos) {  // 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
@@ -5854,12 +6311,9 @@ 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.Position() > originalAnchorPos) {	// Moved forward
-					SetSelection(pdoc->ExtendWordSelect(movePos.Position(), 1),
-					        pdoc->ExtendWordSelect(originalAnchorPos, -1));
-				} else {	// Moved backward
-					SetSelection(pdoc->ExtendWordSelect(movePos.Position(), -1),
-					        pdoc->ExtendWordSelect(originalAnchorPos, 1));
+				} else {
+					wordSelectInitialCaretPos = -1;
+					WordSelection(movePos.Position());
 				}
 			} else {
 				// Continue selecting by line
@@ -5887,10 +6341,18 @@ void Editor::ButtonMove(Point pt) {
 		if (hsStart != -1 && !PositionIsHotspot(movePos.Position()))
 			SetHotSpotRange(NULL);
 
+		if (hotSpotClickPos != INVALID_POSITION && PositionFromLocation(pt,true,false) != hotSpotClickPos) {
+			if (inDragDrop == ddNone) {
+				DisplayCursor(Window::cursorText);
+			}
+			hotSpotClickPos = INVALID_POSITION;
+		}
+
 	} else {
 		if (vs.fixedColumnWidth > 0) {	// There is a margin
 			if (PointInSelMargin(pt)) {
-				DisplayCursor(Window::cursorReverseArrow);
+				DisplayCursor(GetMarginCursor(pt));
+				SetHotSpotRange(NULL);
 				return; 	// No need to test for selection
 			}
 		}
@@ -5915,10 +6377,16 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
 	if (inDragDrop == ddInitial) {
 		inDragDrop = ddNone;
 		SetEmptySelection(newPos.Position());
+		selectionType = selChar;
+		originalAnchorPos = sel.MainCaret();
+	}
+	if (hotSpotClickPos != INVALID_POSITION && PointIsHotspot(pt)) {
+		hotSpotClickPos = INVALID_POSITION;
+		NotifyHotSpotReleaseClick(newPos.Position(), false, ctrl, false);
 	}
 	if (HaveMouseCapture()) {
 		if (PointInSelMargin(pt)) {
-			DisplayCursor(Window::cursorReverseArrow);
+			DisplayCursor(GetMarginCursor(pt));
 		} else {
 			DisplayCursor(Window::cursorText);
 			SetHotSpotRange(NULL);
@@ -5968,7 +6436,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
 		SetRectangularRange();
 		lastClickTime = curTime;
 		lastClick = pt;
-		lastXChosen = pt.x;
+		lastXChosen = pt.x + xOffset;
 		if (sel.selType == Selection::selStream) {
 			SetLastXChosen();
 		}
@@ -6000,7 +6468,8 @@ void Editor::Tick() {
 	}
 	if ((dwellDelay < SC_TIME_FOREVER) &&
 	        (ticksToDwell > 0) &&
-	        (!HaveMouseCapture())) {
+	        (!HaveMouseCapture()) &&
+	        (ptMouseLast.y >= 0)) {
 		ticksToDwell -= timer.tickSize;
 		if (ticksToDwell <= 0) {
 			dwelling = true;
@@ -6044,6 +6513,48 @@ void Editor::SetFocusState(bool focusState) {
 	}
 }
 
+int Editor::PositionAfterArea(PRectangle rcArea) {
+	// The start of the document line after the display line after the area
+	// This often means that the line after a modification is restyled which helps
+	// detect multiline comment additions and heals single line comments
+	int lineAfter = topLine + (rcArea.bottom - 1) / vs.lineHeight + 1;
+	if (lineAfter < cs.LinesDisplayed())
+		return pdoc->LineStart(cs.DocFromDisplay(lineAfter) + 1);
+	else
+		return pdoc->Length();
+}
+
+// Style to a position within the view. If this causes a change at end of last line then
+// affects later lines so style all the viewed text.
+void Editor::StyleToPositionInView(Position pos) {
+	int endWindow = PositionAfterArea(GetClientRectangle());
+	if (pos > endWindow)
+		pos = endWindow;
+	int styleAtEnd = pdoc->StyleAt(pos-1);
+	pdoc->EnsureStyledTo(pos);
+	if ((endWindow > pos) && (styleAtEnd != pdoc->StyleAt(pos-1))) {
+		// Style at end of line changed so is multi-line change like starting a comment
+		// so require rest of window to be styled.
+		pdoc->EnsureStyledTo(endWindow);
+	}
+}
+
+void Editor::IdleStyling() {
+	// Style the line after the modification as this allows modifications that change just the
+	// line of the modification to heal instead of propagating to the rest of the window.
+	StyleToPositionInView(pdoc->LineStart(pdoc->LineFromPosition(styleNeeded.upTo) + 2));
+
+	if (needUpdateUI) {
+		NotifyUpdateUI();
+		needUpdateUI = 0;
+	}
+	styleNeeded.Reset();
+}
+
+void Editor::QueueStyling(int upTo) {
+	styleNeeded.NeedUpTo(upTo);
+}
+
 bool Editor::PaintContains(PRectangle rc) {
 	if (rc.Empty()) {
 		return true;
@@ -6150,6 +6661,7 @@ void Editor::SetAnnotationVisible(int visible) {
 				}
 			}
 		}
+		Redraw();
 	}
 }
 
@@ -6185,8 +6697,8 @@ void Editor::ToggleContraction(int line) {
 
 		if (cs.GetExpanded(line)) {
 			int lineMaxSubord = pdoc->GetLastChild(line);
-			cs.SetExpanded(line, 0);
 			if (lineMaxSubord > line) {
+				cs.SetExpanded(line, 0);
 				cs.SetVisible(line + 1, lineMaxSubord, false);
 
 				int lineCurrent = pdoc->LineFromPosition(sel.MainCaret());
@@ -6212,6 +6724,18 @@ void Editor::ToggleContraction(int line) {
 	}
 }
 
+int Editor::ContractedFoldNext(int lineStart) {
+	for (int line = lineStart; line<pdoc->LinesTotal();) {
+		if (!cs.GetExpanded(line) && (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG))
+			return line;
+		line = cs.ContractedNext(line+1);
+		if (line < 0)
+			return -1;
+	}
+
+	return -1;
+}
+
 /**
  * Recurse up from this line to find any folds that prevent this line from being visible
  * and unfold them all.
@@ -6257,6 +6781,24 @@ void Editor::EnsureLineVisible(int lineDoc, bool enforcePolicy) {
 	}
 }
 
+int Editor::GetTag(char *tagValue, int tagNumber) {
+	char name[3] = "\\?";
+	const char *text = 0;
+	int length = 0;
+	if ((tagNumber >= 1) && (tagNumber <= 9)) {
+		name[1] = static_cast<char>(tagNumber + '0');
+		length = 2;
+		text = pdoc->SubstituteByPosition(name, &length);
+	}
+	if (tagValue) {
+		if (text)
+			memcpy(tagValue, text, length + 1);
+		else
+			*tagValue = '\0';
+	}
+	return length;
+}
+
 int Editor::ReplaceTarget(bool replacePatterns, const char *text, int length) {
 	UndoGroup ug(pdoc);
 	if (length == -1)
@@ -6303,11 +6845,11 @@ void Editor::AddStyledText(char *buffer, int appendLength) {
 	size_t textLength = appendLength / 2;
 	char *text = new char[textLength];
 	size_t i;
-	for (i = 0;i < textLength;i++) {
+	for (i = 0; i < textLength; i++) {
 		text[i] = buffer[i*2];
 	}
 	pdoc->InsertString(CurrentPosition(), text, textLength);
-	for (i = 0;i < textLength;i++) {
+	for (i = 0; i < textLength; i++) {
 		text[i] = buffer[i*2+1];
 	}
 	pdoc->StartStyling(CurrentPosition(), static_cast<char>(0xff));
@@ -6466,6 +7008,18 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		CopyAllowLine();
 		break;
 
+	case SCI_VERTICALCENTRECARET:
+		VerticalCentreCaret();
+		break;
+
+	case SCI_MOVESELECTEDLINESUP:
+		MoveSelectedLinesUp();
+		break;
+
+	case SCI_MOVESELECTEDLINESDOWN:
+		MoveSelectedLinesDown();
+		break;
+
 	case SCI_COPYRANGE:
 		CopyRangeToClipboard(wParam, lParam);
 		break;
@@ -6476,7 +7030,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
 	case SCI_PASTE:
 		Paste();
-		if (!caretSticky) {
+		if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) {
 			SetLastXChosen();
 		}
 		EnsureCaretVisible();
@@ -6641,6 +7195,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	case SCI_GETSEARCHFLAGS:
 		return searchFlags;
 
+	case SCI_GETTAG:
+		return GetTag(CharPtrFromSPtr(lParam), wParam);
+
 	case SCI_POSITIONBEFORE:
 		return pdoc->MovePositionOutsideChar(wParam - 1, -1, true);
 
@@ -6654,6 +7211,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 
 	case SCI_SETXOFFSET:
 		xOffset = wParam;
+		ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
 		SetHorizontalScrollPos();
 		Redraw();
 		break;
@@ -6861,14 +7419,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		break;
 
 	case SCI_GETSELECTIONSTART:
-		return Platform::Minimum(sel.MainAnchor(), sel.MainCaret());
+		return sel.LimitsForRectangularElseMain().start.Position();
 
 	case SCI_SETSELECTIONEND:
 		SetSelection(wParam, Platform::Minimum(sel.MainAnchor(), wParam));
 		break;
 
 	case SCI_GETSELECTIONEND:
-		return Platform::Maximum(sel.MainAnchor(), sel.MainCaret());
+		return sel.LimitsForRectangularElseMain().end.Position();
 
 	case SCI_SETPRINTMAGNIFICATION:
 		printMagnification = wParam;
@@ -6968,7 +7526,6 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	case SCI_GOTOPOS:
 		SetEmptySelection(wParam);
 		EnsureCaretVisible();
-		Redraw();
 		break;
 
 	case SCI_GETCURLINE: {
@@ -7119,6 +7676,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 			break;
 		}
 		xOffset = 0;
+		ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
 		InvalidateStyleRedraw();
 		ReconfigureScrollBars();
 		break;
@@ -7127,9 +7685,11 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		return wrapState;
 
 	case SCI_SETWRAPVISUALFLAGS:
-		wrapVisualFlags = wParam;
-		InvalidateStyleRedraw();
-		ReconfigureScrollBars();
+		if (wrapVisualFlags != static_cast<int>(wParam)) {
+			wrapVisualFlags = wParam;
+			InvalidateStyleRedraw();
+			ReconfigureScrollBars();
+		}
 		break;
 
 	case SCI_GETWRAPVISUALFLAGS:
@@ -7144,18 +7704,22 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		return wrapVisualFlagsLocation;
 
 	case SCI_SETWRAPSTARTINDENT:
-		wrapVisualStartIndent = wParam;
-		InvalidateStyleRedraw();
-		ReconfigureScrollBars();
+		if (wrapVisualStartIndent != static_cast<int>(wParam)) {
+			wrapVisualStartIndent = wParam;
+			InvalidateStyleRedraw();
+			ReconfigureScrollBars();
+		}
 		break;
 
 	case SCI_GETWRAPSTARTINDENT:
 		return wrapVisualStartIndent;
 
 	case SCI_SETWRAPINDENTMODE:
-		wrapIndentMode = wParam;
-		InvalidateStyleRedraw();
-		ReconfigureScrollBars();
+		if (wrapIndentMode != static_cast<int>(wParam)) {
+			wrapIndentMode = wParam;
+			InvalidateStyleRedraw();
+			ReconfigureScrollBars();
+		}
 		break;
 
 	case SCI_GETWRAPINDENTMODE:
@@ -7222,9 +7786,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		return endAtLastLine;
 
 	case SCI_SETCARETSTICKY:
-		PLATFORM_ASSERT((wParam == 0) || (wParam == 1));
-		if (caretSticky != (wParam != 0)) {
-			caretSticky = wParam != 0;
+		PLATFORM_ASSERT((wParam >= SC_CARETSTICKY_OFF) && (wParam <= SC_CARETSTICKY_WHITESPACE));
+		if ((wParam >= SC_CARETSTICKY_OFF) && (wParam <= SC_CARETSTICKY_WHITESPACE)) {
+			caretSticky = wParam;
 		}
 		break;
 
@@ -7322,6 +7886,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		InvalidateStyleData();
 		RedrawSelMargin();
 		break;
+	case SCI_MARKERSETBACKSELECTED:
+		if (wParam <= MARKER_MAX)
+			vs.markers[wParam].backSelected.desired = ColourDesired(lParam);
+		InvalidateStyleRedraw();
+		break;
+	case SCI_MARKERENABLEHIGHLIGHT:
+		highlightDelimiter.isEnabled = wParam == 1;
+		InvalidateStyleRedraw();
+		break;
 	case SCI_MARKERSETBACK:
 		if (wParam <= MARKER_MAX)
 			vs.markers[wParam].back.desired = ColourDesired(lParam);
@@ -7433,6 +8006,17 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		else
 			return 0;
 
+	case SCI_SETMARGINCURSORN:
+		if (ValidMargin(wParam))
+			vs.ms[wParam].cursor = lParam;
+		break;
+
+	case SCI_GETMARGINCURSORN:
+		if (ValidMargin(wParam))
+			return vs.ms[wParam].cursor;
+		else
+			return 0;
+
 	case SCI_STYLECLEARALL:
 		vs.ClearStyles();
 		InvalidateStyleRedraw();
@@ -7570,6 +8154,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		ToggleContraction(wParam);
 		break;
 
+	case SCI_CONTRACTEDFOLDNEXT:
+		return ContractedFoldNext(wParam);
+
 	case SCI_ENSUREVISIBLE:
 		EnsureLineVisible(wParam, false);
 		break;
@@ -7725,7 +8312,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		return (wParam <= INDIC_MAX) ? vs.indicators[wParam].under : 0;
 
 	case SCI_INDICSETALPHA:
-		if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 100) {
+		if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 255) {
 			vs.indicators[wParam].fillAlpha = lParam;
 			InvalidateStyleRedraw();
 		}
@@ -7734,6 +8321,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	case SCI_INDICGETALPHA:
 		return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fillAlpha : 0;
 
+	case SCI_INDICSETOUTLINEALPHA:
+		if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 255) {
+			vs.indicators[wParam].outlineAlpha = lParam;
+			InvalidateStyleRedraw();
+		}
+		break;
+
+	case SCI_INDICGETOUTLINEALPHA:
+		return (wParam <= INDIC_MAX) ? vs.indicators[wParam].outlineAlpha : 0;
+
 	case SCI_SETINDICATORCURRENT:
 		pdoc->decorations.SetCurrentIndicator(wParam);
 		break;
@@ -7859,10 +8456,24 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		SetBraceHighlight(static_cast<int>(wParam), lParam, STYLE_BRACELIGHT);
 		break;
 
+	case SCI_BRACEHIGHLIGHTINDICATOR:
+		if (lParam >= 0 && lParam <= INDIC_MAX) {
+			vs.braceHighlightIndicatorSet = wParam != 0;
+			vs.braceHighlightIndicator = lParam;
+		}
+		break;
+
 	case SCI_BRACEBADLIGHT:
 		SetBraceHighlight(static_cast<int>(wParam), -1, STYLE_BRACEBAD);
 		break;
 
+	case SCI_BRACEBADLIGHTINDICATOR:
+		if (lParam >= 0 && lParam <= INDIC_MAX) {
+			vs.braceBadLightIndicatorSet = wParam != 0;
+			vs.braceBadLightIndicator = lParam;
+		}
+		break;
+
 	case SCI_BRACEMATCH:
 		// wParam is position of char to find brace for,
 		// lParam is maximum amount of text to restyle to find it
@@ -8261,6 +8872,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	case SCI_GETADDITIONALSELECTIONTYPING:
 		return additionalSelectionTyping;
 
+	case SCI_SETMULTIPASTE:
+		multiPasteMode = wParam;
+		break;
+
+	case SCI_GETMULTIPASTE:
+		return multiPasteMode;
+
 	case SCI_SETADDITIONALCARETSBLINK:
 		additionalCaretsBlink = wParam != 0;
 		InvalidateCaret();
@@ -8441,6 +9059,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 		sel.RangeMain() = SelectionRange(sel.RangeMain().anchor, sel.RangeMain().caret);
 		break;
 
+	case SCI_CHANGELEXERSTATE:
+		pdoc->ChangeLexerState(wParam, lParam);
+		break;
+
 	default:
 		return DefWndProc(iMessage, wParam, lParam);
 	}
diff --git a/plugins/scintilla/scintilla/Editor.h b/plugins/scintilla/scintilla/Editor.h
index 92dcfb1..5c01ee8 100644
--- a/plugins/scintilla/scintilla/Editor.h
+++ b/plugins/scintilla/scintilla/Editor.h
@@ -2,7 +2,7 @@
 /** @file Editor.h
  ** Defines the main editor class.
  **/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef EDITOR_H
@@ -46,6 +46,26 @@ public:
 };
 
 /**
+ * When platform has a way to generate an event before painting,
+ * accumulate needed styling range in StyleNeeded to avoid unnecessary work.
+ */
+class StyleNeeded {
+public:
+	bool active;
+	Position upTo;
+
+	StyleNeeded() : active(false), upTo(0) {}
+	void Reset() {
+		active = false;
+		upTo = 0;
+	}
+	void NeedUpTo(Position pos) {
+		if (upTo < pos)
+			upTo = pos;
+	}
+};
+
+/**
  * Hold a piece of text selected for copying or dragging.
  * The text is expected to hold a terminating '\0' and this is counted in len.
  */
@@ -119,6 +139,9 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	int cursorMode;
 	int controlCharSymbol;
 
+	// Highlight current folding block
+	HighlightDelimiter highlightDelimiter;
+
 	bool hasFocus;
 	bool hideSelection;
 	bool inOverstrike;
@@ -139,9 +162,10 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	int lineWidthMaxSeen;
 	bool verticalScrollBarVisible;
 	bool endAtLastLine;
-	bool caretSticky;
+	int caretSticky;
 	bool multipleSelection;
 	bool additionalSelectionTyping;
+	int multiPasteMode;
 	bool additionalCaretsBlink;
 	bool additionalCaretsVisible;
 
@@ -176,9 +200,13 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	bool dropWentOutside;
 	SelectionPosition posDrag;
 	SelectionPosition posDrop;
+	int hotSpotClickPos;
 	int lastXChosen;
 	int lineAnchor;
 	int originalAnchorPos;
+	int wordSelectAnchorStartPos;
+	int wordSelectAnchorEndPos;
+	int wordSelectInitialCaretPos;
 	int targetStart;
 	int targetEnd;
 	int searchFlags;
@@ -186,7 +214,7 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	int posTopLine;
 	int lengthForEncode;
 
-	bool needUpdateUI;
+	int needUpdateUI;
 	Position braces[2];
 	int bracesMatchStyle;
 	int highlightGuideColumn;
@@ -196,6 +224,7 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	enum { notPainting, painting, paintAbandoned } paintState;
 	PRectangle rcPaint;
 	bool paintingAllText;
+	StyleNeeded styleNeeded;
 
 	int modEventMask;
 
@@ -271,7 +300,7 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	bool AbandonPaint();
 	void RedrawRect(PRectangle rc);
 	void Redraw();
-	void RedrawSelMargin(int line=-1);
+	void RedrawSelMargin(int line=-1, bool allAfter=false);
 	PRectangle RectangleFromRange(int start, int end);
 	void InvalidateRange(int start, int end);
 
@@ -305,8 +334,20 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	void ScrollTo(int line, bool moveThumb=true);
 	virtual void ScrollText(int linesToMove);
 	void HorizontalScrollTo(int xPos);
+	void VerticalCentreCaret();
+	void MoveSelectedLines(int lineDelta);
+	void MoveSelectedLinesUp();
+	void MoveSelectedLinesDown();
 	void MoveCaretInsideView(bool ensureVisible=true);
 	int DisplayFromPosition(int pos);
+
+	struct XYScrollPosition {
+		int xOffset;
+		int topLine;
+		XYScrollPosition(int xOffset_, int topLine_) : xOffset(xOffset_), topLine(topLine_) {}
+	};
+	XYScrollPosition XYScrollToMakeVisible(const bool useMargin, const bool vert, const bool horiz);
+	void SetXYScroll(XYScrollPosition newXY);
 	void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true);
 	void ShowCaretAtCurrentPosition();
 	void DropCaret();
@@ -332,13 +373,15 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 		int line, int lineEnd, int xStart, int subLine, int subLineStart,
 		bool overrideBackground, ColourAllocated background,
 		bool drawWrapMark, ColourAllocated wrapColour);
+	void DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw,
+		int xStart, PRectangle rcLine, LineLayout *ll, int subLine);
 	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);
-	void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, 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);
@@ -358,7 +401,8 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	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 InsertPaste(SelectionPosition selStart, const char *text, int len);
+	void ClearSelection(bool retainMultipleSelections=false);
 	void ClearAll();
 	void ClearDocumentStyle();
 	void Cut();
@@ -386,6 +430,7 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt);
 	void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt);
 	void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt);
+	void NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt);
 	void NotifyUpdateUI();
 	void NotifyPainted();
 	void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt);
@@ -400,10 +445,15 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	void NotifyModified(Document *document, DocModification mh, void *userData);
 	void NotifyDeleted(Document *document, void *userData);
 	void NotifyStyleNeeded(Document *doc, void *userData, int endPos);
+	void NotifyLexerChanged(Document *doc, void *userData);
+	void NotifyErrorOccurred(Document *doc, void *userData, int status);
 	void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
 
+	void ContainerNeedsUpdate(int flags);
 	void PageMove(int direction, Selection::selTypes sel=Selection::noSel, bool stuttered = false);
-	void ChangeCaseOfSelection(bool makeUpperCase);
+	enum { cmSame, cmUpper, cmLower } caseMap;
+	virtual std::string CaseMapString(const std::string &s, int caseMapping);
+	void ChangeCaseOfSelection(int caseMapping);
 	void LineTranspose();
 	void Duplicate(bool forLine);
 	virtual void CancelModes();
@@ -420,6 +470,7 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 
 	void Indent(bool forwards);
 
+	virtual CaseFolder *CaseFolderForEncoding();
 	long FindText(uptr_t wParam, sptr_t lParam);
 	void SearchAnchor();
 	long SearchText(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
@@ -440,8 +491,11 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	bool PositionInSelection(int pos);
 	bool PointInSelection(Point pt);
 	bool PointInSelMargin(Point pt);
+	Window::Cursor GetMarginCursor(Point pt);
 	void LineSelection(int lineCurrent_, int lineAnchor_);
+	void WordSelection(int pos);
 	void DwellEnd(bool mouseMoved);
+	void MouseLeave();
 	virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
 	void ButtonMove(Point pt);
 	void ButtonUp(Point pt, unsigned int curTime, bool ctrl);
@@ -454,6 +508,11 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	virtual bool HaveMouseCapture() = 0;
 	void SetFocusState(bool focusState);
 
+	int PositionAfterArea(PRectangle rcArea);
+	void StyleToPositionInView(Position pos);
+	void IdleStyling();
+	virtual void QueueStyling(int upTo);
+
 	virtual bool PaintContains(PRectangle rc);
 	bool PaintContainsMargin();
 	void CheckForChangeOutsidePaint(Range r);
@@ -461,18 +520,20 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 
 	void SetAnnotationHeights(int start, int end);
 	void SetDocPointer(Document *document);
-	
+
 	void SetAnnotationVisible(int visible);
 
 	void Expand(int &line, bool doExpand);
 	void ToggleContraction(int line);
+	int ContractedFoldNext(int lineStart);
 	void EnsureLineVisible(int lineDoc, bool enforcePolicy);
+	int GetTag(char *tagValue, int tagNumber);
 	int ReplaceTarget(bool replacePatterns, const char *text, int length=-1);
 
 	bool PositionIsHotspot(int position);
 	bool PointIsHotspot(Point pt);
 	void SetHotSpotRange(Point *pt);
-	void GetHotSpotRange(int& hsStart, int& hsEnd);
+	void GetHotSpotRange(int &hsStart, int &hsEnd);
 
 	int CodePage() const;
 	virtual bool ValidCodePage(int /* codePage */) const { return true; }
diff --git a/plugins/scintilla/scintilla/ExternalLexer.cxx b/plugins/scintilla/scintilla/ExternalLexer.cxx
index 098df4d..bb48464 100644
--- a/plugins/scintilla/scintilla/ExternalLexer.cxx
+++ b/plugins/scintilla/scintilla/ExternalLexer.cxx
@@ -9,18 +9,18 @@
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
+#include <assert.h>
 
 #include <string>
 
 #include "Platform.h"
 
+#include "ILexer.h"
 #include "Scintilla.h"
-
 #include "SciLexer.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "DocumentAccessor.h"
-#include "KeyWords.h"
+
+#include "LexerModule.h"
+#include "Catalogue.h"
 #include "ExternalLexer.h"
 
 #ifdef SCI_NAMESPACE
@@ -35,77 +35,9 @@ LexerManager *LexerManager::theInstance = NULL;
 //
 //------------------------------------------
 
-char **WordListsToStrings(WordList *val[]) {
-	int dim = 0;
-	while (val[dim])
-		dim++;
-	char **wls = new char * [dim + 1];
-	for (int i = 0;i < dim;i++) {
-		std::string words;
-		words = "";
-		for (int n = 0; n < val[i]->len; n++) {
-			words += val[i]->words[n];
-			if (n != val[i]->len - 1)
-				words += " ";
-		}
-		wls[i] = new char[words.length() + 1];
-		strcpy(wls[i], words.c_str());
-	}
-	wls[dim] = 0;
-	return wls;
-}
-
-void DeleteWLStrings(char *strs[]) {
-	int dim = 0;
-	while (strs[dim]) {
-		delete strs[dim];
-		dim++;
-	}
-	delete [] strs;
-}
-
-void ExternalLexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
-                              WordList *keywordlists[], Accessor &styler) const {
-	if (!fneLexer)
-		return ;
-
-	char **kwds = WordListsToStrings(keywordlists);
-	char *ps = styler.GetProperties();
-
-	// The accessor passed in is always a DocumentAccessor so this cast and the subsequent
-	// access will work. Can not use the stricter dynamic_cast as that requires RTTI.
-	DocumentAccessor &da = static_cast<DocumentAccessor &>(styler);
-	WindowID wID = da.GetWindow();
-
-	fneLexer(externalLanguage, startPos, lengthDoc, initStyle, kwds, wID, ps);
-
-	delete ps;
-	DeleteWLStrings(kwds);
-}
-
-void ExternalLexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
-                               WordList *keywordlists[], Accessor &styler) const {
-	if (!fneFolder)
-		return ;
-
-	char **kwds = WordListsToStrings(keywordlists);
-	char *ps = styler.GetProperties();
-
-	// The accessor passed in is always a DocumentAccessor so this cast and the subsequent
-	// access will work. Can not use the stricter dynamic_cast as that requires RTTI.
-	DocumentAccessor &da = static_cast<DocumentAccessor &>(styler);
-	WindowID wID = da.GetWindow();
-
-	fneFolder(externalLanguage, startPos, lengthDoc, initStyle, kwds, wID, ps);
-
-	delete ps;
-	DeleteWLStrings(kwds);
-}
-
-void ExternalLexerModule::SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index) {
-	fneLexer = fLexer;
-	fneFolder = fFolder;
-	externalLanguage = index;
+void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) {
+	fneFactory = fFactory;
+	fnFactory = fFactory(index);
 }
 
 //------------------------------------------
@@ -114,7 +46,7 @@ void ExternalLexerModule::SetExternal(ExtLexerFunction fLexer, ExtFoldFunction f
 //
 //------------------------------------------
 
-LexerLibrary::LexerLibrary(const char* ModuleName) {
+LexerLibrary::LexerLibrary(const char *ModuleName) {
 	// Initialise some members...
 	first = NULL;
 	last = NULL;
@@ -132,8 +64,7 @@ LexerLibrary::LexerLibrary(const char* ModuleName) {
 
 			// Find functions in the DLL
 			GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName");
-			ExtLexerFunction Lexer = (ExtLexerFunction)(sptr_t)lib->FindFunction("Lex");
-			ExtFoldFunction Folder = (ExtFoldFunction)(sptr_t)lib->FindFunction("Fold");
+			GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory");
 
 			// Assign a buffer for the lexer name.
 			char lexname[100];
@@ -144,6 +75,7 @@ LexerLibrary::LexerLibrary(const char* ModuleName) {
 			for (int i = 0; i < nl; i++) {
 				GetLexerName(i, lexname, 100);
 				lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL);
+				Catalogue::AddLexerModule(lex);
 
 				// Create a LexerMinder so we don't leak the ExternalLexerModule...
 				lm = new LexerMinder;
@@ -158,8 +90,8 @@ LexerLibrary::LexerLibrary(const char* ModuleName) {
 				}
 
 				// The external lexer needs to know how to call into its DLL to
-				// do its lexing and folding, we tell it here. Folder may be null.
-				lex->SetExternal(Lexer, Folder, i);
+				// do its lexing and folding, we tell it here.
+				lex->SetExternal(fnFactory, i);
 			}
 		}
 	}
@@ -172,7 +104,6 @@ LexerLibrary::~LexerLibrary() {
 }
 
 void LexerLibrary::Release() {
-	//TODO maintain a list of lexers created, and delete them!
 	LexerMinder *lm;
 	LexerMinder *lmNext;
 	lm = first;
@@ -195,18 +126,15 @@ void LexerLibrary::Release() {
 
 /// Return the single LexerManager instance...
 LexerManager *LexerManager::GetInstance() {
-	if(!theInstance)
+	if (!theInstance)
 		theInstance = new LexerManager;
 	return theInstance;
 }
 
 /// Delete any LexerManager instance...
-void LexerManager::DeleteInstance()
-{
-	if(theInstance) {
-		delete theInstance;
-		theInstance = NULL;
-	}
+void LexerManager::DeleteInstance() {
+	delete theInstance;
+	theInstance = NULL;
 }
 
 /// protected constructor - this is a singleton...
@@ -219,13 +147,15 @@ LexerManager::~LexerManager() {
 	Clear();
 }
 
-void LexerManager::Load(const char* path)
-{
+void LexerManager::Load(const char *path) {
 	LoadLexerLibrary(path);
 }
 
-void LexerManager::LoadLexerLibrary(const char* module)
-{
+void LexerManager::LoadLexerLibrary(const char *module) {
+	for (LexerLibrary *ll = first; ll; ll= ll->next) {
+		if (strcmp(ll->m_sModuleName.c_str(), module) == 0)
+			return;
+	}
 	LexerLibrary *lib = new LexerLibrary(module);
 	if (NULL != first) {
 		last->next = lib;
@@ -236,8 +166,7 @@ void LexerManager::LoadLexerLibrary(const char* module)
 	}
 }
 
-void LexerManager::Clear()
-{
+void LexerManager::Clear() {
 	if (NULL != first) {
 		LexerLibrary *cur = first;
 		LexerLibrary *next;
@@ -257,8 +186,7 @@ void LexerManager::Clear()
 //
 //------------------------------------------
 
-LMMinder::~LMMinder()
-{
+LMMinder::~LMMinder() {
 	LexerManager::DeleteInstance();
 }
 
diff --git a/plugins/scintilla/scintilla/ExternalLexer.h b/plugins/scintilla/scintilla/ExternalLexer.h
index 29f42cc..bf175a6 100644
--- a/plugins/scintilla/scintilla/ExternalLexer.h
+++ b/plugins/scintilla/scintilla/ExternalLexer.h
@@ -18,36 +18,26 @@
 namespace Scintilla {
 #endif
 
-// External Lexer function definitions...
-typedef void (EXT_LEXER_DECL *ExtLexerFunction)(unsigned int lexer, unsigned int startPos, int length, int initStyle,
-                  char *words[], WindowID window, char *props);
-typedef void (EXT_LEXER_DECL *ExtFoldFunction)(unsigned int lexer, unsigned int startPos, int length, int initStyle,
-                  char *words[], WindowID window, char *props);
-typedef void* (EXT_LEXER_DECL *GetLexerFunction)(unsigned int Index);
+typedef void*(EXT_LEXER_DECL *GetLexerFunction)(unsigned int Index);
 typedef int (EXT_LEXER_DECL *GetLexerCountFn)();
 typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength);
-
-//class DynamicLibrary;
+typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned int Index);
 
 /// Sub-class of LexerModule to use an external lexer.
-class ExternalLexerModule : protected LexerModule {
+class ExternalLexerModule : public LexerModule {
 protected:
-	ExtLexerFunction fneLexer;
-	ExtFoldFunction fneFolder;
-	int externalLanguage;
+	GetLexerFactoryFunction fneFactory;
 	char name[100];
 public:
-	ExternalLexerModule(int language_, LexerFunction fnLexer_, 
-		const char *languageName_=0, LexerFunction fnFolder_=0) : LexerModule(language_, fnLexer_, 0, fnFolder_){
+	ExternalLexerModule(int language_, LexerFunction fnLexer_,
+		const char *languageName_=0, LexerFunction fnFolder_=0) :
+		LexerModule(language_, fnLexer_, 0, fnFolder_),
+		fneFactory(0) {
 		strncpy(name, languageName_, sizeof(name));
 		name[sizeof(name)-1] = '\0';
 		languageName = name;
-	};
-	virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle,
-					WordList *keywordlists[], Accessor &styler) const;
-	virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle,
-					WordList *keywordlists[], Accessor &styler) const;
-	virtual void SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index);
+	}
+	virtual void SetExternal(GetLexerFactoryFunction fFactory, int index);
 };
 
 /// LexerMinder points to an ExternalLexerModule - so we don't leak them.
@@ -64,10 +54,10 @@ class LexerLibrary {
 	LexerMinder		*last;
 
 public:
-	LexerLibrary(const char* ModuleName);
+	LexerLibrary(const char *ModuleName);
 	~LexerLibrary();
 	void Release();
-	
+
 	LexerLibrary	*next;
 	std::string			m_sModuleName;
 };
@@ -76,18 +66,18 @@ public:
 class LexerManager {
 public:
 	~LexerManager();
-	
+
 	static LexerManager *GetInstance();
 	static void DeleteInstance();
-	
-	void Load(const char* path);
+
+	void Load(const char *path);
 	void Clear();
 
 private:
 	LexerManager();
 	static LexerManager *theInstance;
 
-	void LoadLexerLibrary(const char* module);
+	void LoadLexerLibrary(const char *module);
 	LexerLibrary *first;
 	LexerLibrary *last;
 };
diff --git a/plugins/scintilla/scintilla/Indicator.cxx b/plugins/scintilla/scintilla/Indicator.cxx
index da95312..5c352bf 100644
--- a/plugins/scintilla/scintilla/Indicator.cxx
+++ b/plugins/scintilla/scintilla/Indicator.cxx
@@ -67,12 +67,12 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
 		surface->LineTo(rc.right, rcLine.top+1);
 		surface->LineTo(rc.left, rcLine.top+1);
 		surface->LineTo(rc.left, ymid+1);
-	} else if (style == INDIC_ROUNDBOX) {
+	} else if (style == INDIC_ROUNDBOX || style == INDIC_STRAIGHTBOX) {
 		PRectangle rcBox = rcLine;
 		rcBox.top = rcLine.top + 1;
 		rcBox.left = rc.left;
 		rcBox.right = rc.right;
-		surface->AlphaRectangle(rcBox, 1, fore.allocated, fillAlpha, fore.allocated, 50, 0);
+		surface->AlphaRectangle(rcBox, (style == INDIC_ROUNDBOX) ? 1 : 0, fore.allocated, fillAlpha, fore.allocated, outlineAlpha, 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 42b56f0..e787b59 100644
--- a/plugins/scintilla/scintilla/Indicator.h
+++ b/plugins/scintilla/scintilla/Indicator.h
@@ -20,7 +20,8 @@ public:
 	bool under;
 	ColourPair fore;
 	int fillAlpha;
-	Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30) {
+	int outlineAlpha;
+	Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30), outlineAlpha(50) {
 	}
 	void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine);
 };
diff --git a/plugins/scintilla/scintilla/LexA68k.cxx b/plugins/scintilla/scintilla/LexA68k.cxx
new file mode 100644
index 0000000..970e429
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexA68k.cxx
@@ -0,0 +1,318 @@
+// Scintilla source code edit control
+/** @file LexA68k.cxx
+ ** Lexer for Assembler, just for the MASM syntax
+ ** Written by Martial Demolins AKA Folco
+ **/
+// Copyright 2010 Martial Demolins <mdemolins(a)gmail.com>
+// The License.txt file describes the conditions under which this software
+// may be distributed.
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+
+// Return values for GetOperatorType
+#define NO_OPERATOR     0
+#define OPERATOR_1CHAR  1
+#define OPERATOR_2CHAR  2
+
+
+/**
+ *  IsIdentifierStart
+ *
+ *  Return true if the given char is a valid identifier first char
+ */
+
+static inline bool IsIdentifierStart (const int ch)
+{
+    return (isalpha(ch) || (ch == '_') || (ch == '\\'));
+}
+
+
+/**
+ *  IsIdentifierChar
+ *
+ *  Return true if the given char is a valid identifier char
+ */
+
+static inline bool IsIdentifierChar (const int ch)
+{
+    return (isalnum(ch) || (ch == '_') || (ch == '@') || (ch == ':') || (ch == '.'));
+}
+
+
+/**
+ *  GetOperatorType
+ *
+ *  Return:
+ *  NO_OPERATOR     if char is not an operator
+ *  OPERATOR_1CHAR  if the operator is one char long
+ *  OPERATOR_2CHAR  if the operator is two chars long
+ */
+
+static inline int GetOperatorType (const int ch1, const int ch2)
+{
+    int OpType = NO_OPERATOR;
+
+    if ((ch1 == '+') || (ch1 == '-') || (ch1 == '*') || (ch1 == '/') || (ch1 == '#') ||
+        (ch1 == '(') || (ch1 == ')') || (ch1 == '~') || (ch1 == '&') || (ch1 == '|') || (ch1 == ','))
+        OpType = OPERATOR_1CHAR;
+
+    else if ((ch1 == ch2) && (ch1 == '<' || ch1 == '>'))
+        OpType = OPERATOR_2CHAR;
+
+    return OpType;
+}
+
+
+/**
+ *  IsBin
+ *
+ *  Return true if the given char is 0 or 1
+ */
+
+static inline bool IsBin (const int ch)
+{
+    return (ch == '0') || (ch == '1');
+}
+
+
+/**
+ *  IsDoxygenChar
+ *
+ *  Return true if the char may be part of a Doxygen keyword
+ */
+
+static inline bool IsDoxygenChar (const int ch)
+{
+    return isalpha(ch) || (ch == '$') || (ch == '[') || (ch == ']') || (ch == '{') || (ch == '}');
+}
+
+
+/**
+ *  ColouriseA68kDoc
+ *
+ *  Main function, which colourises a 68k source
+ */
+
+static void ColouriseA68kDoc (unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler)
+{
+
+    // Get references to keywords lists
+    WordList &cpuInstruction = *keywordlists[0];
+    WordList &registers = *keywordlists[1];
+    WordList &directive = *keywordlists[2];
+    WordList &extInstruction = *keywordlists[3];
+    WordList &commentSpecial = *keywordlists[4];
+    WordList &doxygenKeyword = *keywordlists[5];
+
+
+    // Instanciate a context for our source
+    StyleContext sc(startPos, length, initStyle, styler);
+
+
+    /************************************************************
+    *
+    *   Parse the text
+    *
+    ************************************************************/
+
+    for ( ; sc.More(); sc.Forward())
+    {
+        char Buffer[100];
+        int OpType;
+
+        // Reset style at beginning of line
+        if (sc.atLineStart)
+            sc.SetState(SCE_A68K_DEFAULT);
+
+
+        /************************************************************
+        *
+        *   Handle current state if we are not in the "default style"
+        *
+        ************************************************************/
+
+        if (sc.state != SCE_A68K_DEFAULT)
+        {
+            // Check if current style continue.
+            // If this case, we loop because there is nothing else to do
+            if (((sc.state == SCE_A68K_NUMBER_DEC) && isdigit(sc.ch))                                       // Decimal number
+                || ((sc.state == SCE_A68K_NUMBER_BIN) && IsBin(sc.ch))                                      // Binary number
+                || ((sc.state == SCE_A68K_NUMBER_HEX) && isxdigit(sc.ch))                                   // Hexa number
+                || ((sc.state == SCE_A68K_MACRO_ARG)  && isdigit(sc.ch))                                    // Arg of macro
+                || ((sc.state == SCE_A68K_STRING1)    && (sc.ch != '\''))                                   // String single-quoted
+                || ((sc.state == SCE_A68K_STRING2)    && (sc.ch != '\"'))                                   // String double-quoted
+                || ((sc.state == SCE_A68K_MACRO_ARG)  && isdigit(sc.ch))                                    // Macro argument
+                // Label. ' ' and '\t' are needed to handle macro declarations
+                || ((sc.state == SCE_A68K_LABEL)      && (sc.ch != ':') && (sc.ch != ' ') && (sc.ch != '\t'))
+                || ((sc.state == SCE_A68K_IDENTIFIER) && (sc.ch < 0x80) && IsIdentifierChar(sc.ch))         // Identifier
+                || ((sc.state == SCE_A68K_COMMENT_DOXYGEN) && (sc.ch < 0x80) && IsDoxygenChar(sc.ch))       // Doxygen keyword
+                || ((sc.state == SCE_A68K_COMMENT_WORD) && (sc.ch < 0x80) && isalpha(sc.ch)))               // Comment current word
+            {
+                continue;
+            }
+
+            // Check if some states terminate at the current char:
+            // we must include this char in the current style context
+            else if (((sc.state == SCE_A68K_STRING1)    && (sc.ch < 0x80) && (sc.ch == '\''))       // String single-quoted
+                     || ((sc.state == SCE_A68K_STRING2) && (sc.ch < 0x80) && (sc.ch == '\"'))       // String double-quoted
+                     || ((sc.state == SCE_A68K_LABEL)   && (sc.ch < 0x80) && (sc.ch == ':')))       // Label
+            {
+                sc.ForwardSetState(SCE_A68K_DEFAULT);
+            }
+
+            // Check for special words or Doxygen keywords in comments
+            else if (sc.state == SCE_A68K_COMMENT)
+            {
+                if (sc.ch == '\\') {
+                    sc.SetState(SCE_A68K_COMMENT_DOXYGEN);
+                }
+                else if ((sc.ch < 0x80) && isalpha(sc.ch)) {
+                    sc.SetState(SCE_A68K_COMMENT_WORD);
+                }
+                continue;
+            }
+
+            // Check for special words in comment
+            else if ((sc.state == SCE_A68K_COMMENT_WORD) && (sc.ch < 0x80) && !isalpha(sc.ch))
+            {
+                sc.GetCurrent(Buffer, sizeof(Buffer));
+                if (commentSpecial.InList(Buffer)) {
+                    sc.ChangeState(SCE_A68K_COMMENT_SPECIAL);
+                }
+                else {
+                    sc.ChangeState(SCE_A68K_COMMENT);
+                }
+                sc.SetState(SCE_A68K_COMMENT);
+                continue;
+            }
+
+            // Check for Doxygen keywords
+            else if ((sc.state == SCE_A68K_COMMENT_DOXYGEN) && (sc.ch < 0x80) && !IsDoxygenChar(sc.ch))
+            {
+                sc.GetCurrentLowered(Buffer, sizeof(Buffer));                           // Buffer the string of the current context
+                if (!doxygenKeyword.InList(Buffer)) {
+                    sc.ChangeState(SCE_A68K_COMMENT);
+                }
+                sc.SetState(SCE_A68K_COMMENT);
+                continue;
+            }
+
+            // Check if we are in the case of a label which terminates without ':'
+            // It should be a macro declaration, not a label
+            else if ((sc.state == SCE_A68K_LABEL) && (sc.ch < 0x80) && ((sc.ch == ' ') || (sc.ch == '\t')))
+            {
+                sc.ChangeState(SCE_A68K_MACRO_DECLARATION);
+            }
+
+            // Check if we are at the end of an identifier
+            // In this case, colourise it if was a keyword.
+            else if ((sc.state == SCE_A68K_IDENTIFIER) && !IsIdentifierChar(sc.ch))
+            {
+                sc.GetCurrentLowered(Buffer, sizeof(Buffer));                           // Buffer the string of the current context
+                if (cpuInstruction.InList(Buffer)) {                                    // And check if it belongs to a keyword list
+                    sc.ChangeState(SCE_A68K_CPUINSTRUCTION);
+                }
+                else if (extInstruction.InList(Buffer)) {
+                    sc.ChangeState(SCE_A68K_EXTINSTRUCTION);
+                }
+                else if (registers.InList(Buffer)) {
+                    sc.ChangeState(SCE_A68K_REGISTER);
+                }
+                else if (directive.InList(Buffer)) {
+                    sc.ChangeState(SCE_A68K_DIRECTIVE);
+                }
+            }
+
+            // All special contexts are now handled.Come back to default style
+            sc.SetState(SCE_A68K_DEFAULT);
+        }
+
+
+        /************************************************************
+        *
+        *   Check if we must enter a new state
+        *
+        ************************************************************/
+
+        // Label and macro identifiers start at the beginning of a line
+        // We set both as a label, but if it wasn't one (no ':' at the end),
+        // it will be changed as a macro identifier.
+        if (sc.atLineStart && (sc.ch < 0x80) && IsIdentifierStart(sc.ch)) {
+            sc.SetState(SCE_A68K_LABEL);
+        }
+        else if ((sc.ch < 0x80) && (sc.ch == ';')) {                            // Comment
+            sc.SetState(SCE_A68K_COMMENT);
+        }
+        else if ((sc.ch < 0x80) && isdigit(sc.ch)) {                            // Decimal numbers haven't prefix
+            sc.SetState(SCE_A68K_NUMBER_DEC);
+        }
+        else if ((sc.ch < 0x80) && (sc.ch == '%')) {                            // Binary numbers are prefixed with '%'
+            sc.SetState(SCE_A68K_NUMBER_BIN);
+        }
+        else if ((sc.ch < 0x80) && (sc.ch == '$')) {                            // Hexadecimal numbers are prefixed with '$'
+            sc.SetState(SCE_A68K_NUMBER_HEX);
+        }
+        else if ((sc.ch < 0x80) && (sc.ch == '\'')) {                           // String (single-quoted)
+            sc.SetState(SCE_A68K_STRING1);
+        }
+        else if ((sc.ch < 0x80) && (sc.ch == '\"')) {                           // String (double-quoted)
+            sc.SetState(SCE_A68K_STRING2);
+        }
+        else if ((sc.ch < 0x80) && (sc.ch == '\\') && (isdigit(sc.chNext))) {   // Replacement symbols in macro
+            sc.SetState(SCE_A68K_MACRO_ARG);
+        }
+        else if ((sc.ch < 0x80) && IsIdentifierStart(sc.ch)) {                  // An identifier: constant, label, etc...
+            sc.SetState(SCE_A68K_IDENTIFIER);
+        }
+        else {
+            if (sc.ch < 0x80) {
+                OpType = GetOperatorType(sc.ch, sc.chNext);                     // Check if current char is an operator
+                if (OpType != NO_OPERATOR) {
+                    sc.SetState(SCE_A68K_OPERATOR);
+                    if (OpType == OPERATOR_2CHAR) {                             // Check if the operator is 2 bytes long
+                        sc.ForwardSetState(SCE_A68K_OPERATOR);                  // (>> or <<)
+                    }
+                }
+            }
+        }
+    }                                                                           // End of for()
+    sc.Complete();
+}
+
+
+// Names of the keyword lists
+
+static const char * const a68kWordListDesc[] =
+{
+    "CPU instructions",
+    "Registers",
+    "Directives",
+    "Extended instructions",
+    "Comment special words",
+    "Doxygen keywords",
+    0
+};
+
+LexerModule lmA68k(SCLEX_A68K, ColouriseA68kDoc, "a68k", 0, a68kWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexAPDL.cxx b/plugins/scintilla/scintilla/LexAPDL.cxx
index 7bf597b..7d65a56 100644
--- a/plugins/scintilla/scintilla/LexAPDL.cxx
+++ b/plugins/scintilla/scintilla/LexAPDL.cxx
@@ -8,18 +8,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexASY.cxx b/plugins/scintilla/scintilla/LexASY.cxx
index 5bf979f..9e3470c 100644
--- a/plugins/scintilla/scintilla/LexASY.cxx
+++ b/plugins/scintilla/scintilla/LexASY.cxx
@@ -4,25 +4,26 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
 #include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-static void ColouriseAsyDoc(unsigned int startPos, int length, int initStyle, 
+static void ColouriseAsyDoc(unsigned int startPos, int length, int initStyle,
 		WordList *keywordlists[], Accessor &styler) {
 
 	WordList &keywords = *keywordlists[0];
@@ -118,7 +119,7 @@ static void ColouriseAsyDoc(unsigned int startPos, int length, int initStyle,
 				sc.SetState(SCE_ASY_IDENTIFIER);
 			} else if (sc.Match('/', '*')) {
 				sc.SetState(SCE_ASY_COMMENT);
-				sc.Forward();	// 
+				sc.Forward();	//
 			} else if (sc.Match('/', '/')) {
 				sc.SetState(SCE_ASY_COMMENTLINE);
 			} else if (sc.ch == '\"') {
@@ -162,14 +163,14 @@ static int ParseASYWord(unsigned int pos, Accessor &styler, char *word)
           length++;
           ch=styler.SafeGetCharAt(pos+length);
   }
-  word[length]=0;   
+  word[length]=0;
   return length;
 }
 
 static bool IsASYDrawingLine(int line, Accessor &styler) {
 	int pos = styler.LineStart(line);
 	int eol_pos = styler.LineStart(line + 1) - 1;
-	
+
 	int startpos = pos;
 	char buffer[100]="";
 
@@ -181,11 +182,11 @@ static bool IsASYDrawingLine(int line, Accessor &styler) {
 		if (!drawcommands && ch!=' ') return false;
 		else if (drawcommands) return true;
 		startpos++;
-	}		
+	}
 	return false;
 }
 
-static void FoldAsyDoc(unsigned int startPos, int length, int initStyle, 
+static void FoldAsyDoc(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;
@@ -236,7 +237,7 @@ static void FoldAsyDoc(unsigned int startPos, int length, int initStyle,
 			else if (lineCurrent!=0 && IsASYDrawingLine(lineCurrent - 1, styler) &&
 				!IsASYDrawingLine(lineCurrent+1, styler))
 				levelNext--;
-		}	
+		}
 
 		if (atEOL) {
 			int levelUse = levelCurrent;
diff --git a/plugins/scintilla/scintilla/LexAU3.cxx b/plugins/scintilla/scintilla/LexAU3.cxx
index cfff927..72c918f 100644
--- a/plugins/scintilla/scintilla/LexAU3.cxx
+++ b/plugins/scintilla/scintilla/LexAU3.cxx
@@ -1,15 +1,15 @@
 // Scintilla source code edit control
 // @file LexAU3.cxx
 // Lexer for AutoIt3  http://www.hiddensoft.com/autoit3
-// by Jos van der Zande, jvdzande yahoo com 
+// by Jos van der Zande, jvdzande yahoo com
 //
 // Changes:
 // March 28, 2004 - Added the standard Folding code
 // April 21, 2004 - Added Preprosessor Table + Syntax Highlighting
 //                  Fixed Number highlighting
 //                  Changed default isoperator to IsAOperator to have a better match to AutoIt3
-//                  Fixed "#comments_start" -> "#comments-start"  
-//                  Fixed "#comments_end" -> "#comments-end"  
+//                  Fixed "#comments_start" -> "#comments-start"
+//                  Fixed "#comments_end" -> "#comments-end"
 //                  Fixed Sendkeys in Strings when not terminated with }
 //                  Added support for Sendkey strings that have second parameter e.g. {UP 5} or {a down}
 // April 26, 2004 - Fixed # pre-processor statement inside of comment block would invalidly change the color.
@@ -25,9 +25,9 @@
 //                  Added fold.compact support set with fold.compact=1
 //                  Changed folding inside of #cs-#ce. Default is no keyword folding inside comment blocks when fold.comment=1
 //                        it will now only happen when fold.comment=2.
-// Sep 5, 2004    - Added logic to handle colourizing words on the last line. 
+// Sep 5, 2004    - Added logic to handle colourizing words on the last line.
 //                        Typed Characters now show as "default" till they match any table.
-// Oct 10, 2004   - Added logic to show Comments in "Special" directives. 
+// Oct 10, 2004   - Added logic to show Comments in "Special" directives.
 // Nov  1, 2004   - Added better testing for Numbers supporting x and e notation.
 // Nov 28, 2004   - Added logic to handle continuation lines for syntax highlighting.
 // Jan 10, 2005   - Added Abbreviations Keyword used for expansion
@@ -52,18 +52,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -127,7 +130,7 @@ static int GetSendKey(const char *szLine, char *szKey)
 			}
 			else if (cTemp == ' ')
 			{
-				// skip other spaces 
+				// skip other spaces
 			}
 			else if (nFlag == 0)
 			{
@@ -139,7 +142,7 @@ static int GetSendKey(const char *szLine, char *szKey)
 				// Save second portion into var...
 				szSpecial[nSpecPos++] = cTemp;
 				// check if Second portion is all numbers for repeat fuction
-				if (isdigit(cTemp) == false) {nSpecNum = 0;} 
+				if (isdigit(cTemp) == false) {nSpecNum = 0;}
 			}
 		}
 		nPos++;									// skip to next char
@@ -151,7 +154,7 @@ static int GetSendKey(const char *szLine, char *szKey)
 	szKey[nKeyPos] = '\0';
 	szSpecial[nSpecPos] = '\0';
 	if (strcmp(szSpecial,"down")== 0    || strcmp(szSpecial,"up")== 0  ||
-		strcmp(szSpecial,"on")== 0      || strcmp(szSpecial,"off")== 0 || 
+		strcmp(szSpecial,"on")== 0      || strcmp(szSpecial,"off")== 0 ||
 		strcmp(szSpecial,"toggle")== 0  || nSpecNum == 1 )
 	{
 		nFlag = 0;
@@ -160,13 +163,13 @@ static int GetSendKey(const char *szLine, char *szKey)
 	{
 		nFlag = 1;
 	}
-	return nFlag;  // 1 is bad, 0 is good 
+	return nFlag;  // 1 is bad, 0 is good
 
-} // GetSendKey() 
+} // GetSendKey()
 
 //
 // Routine to check the last "none comment" character on a line to see if its a continuation
-// 
+//
 static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
 {
 	int nsPos = styler.LineStart(szLine);
@@ -192,7 +195,7 @@ static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
 
 //
 // syntax highlighting logic
-static void ColouriseAU3Doc(unsigned int startPos, 
+static void ColouriseAU3Doc(unsigned int startPos,
 							int length, int initStyle,
 							WordList *keywordlists[],
 							Accessor &styler) {
@@ -214,19 +217,19 @@ static void ColouriseAU3Doc(unsigned int startPos,
 			   (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
 			lineCurrent--;
 			startPos = styler.LineStart(lineCurrent); // get start position
-			initStyle =  0;                           // reset the start style to 0 
+			initStyle =  0;                           // reset the start style to 0
 		}
 	}
 	// Set the new length to include it from the start and set the start position
 	length = length + s_startPos - startPos;      // correct the total length to process
     styler.StartAt(startPos);
-	
+
     StyleContext sc(startPos, length, initStyle, styler);
 	char si;     // string indicator "=1 '=2
 	char ni;     // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 Enot=3
-	char ci;     // comment indicator 0=not linecomment(;) 
+	char ci;     // comment indicator 0=not linecomment(;)
 	char s_save[100];
-	si=0;  
+	si=0;
 	ni=0;
 	ci=0;
 	//$$$
@@ -234,8 +237,8 @@ static void ColouriseAU3Doc(unsigned int startPos,
 		char s[100];
 		sc.GetCurrentLowered(s, sizeof(s));
 		// **********************************************
-		// save the total current word for eof processing 
-		if (IsAWordChar(sc.ch) || sc.ch == '}') 
+		// save the total current word for eof processing
+		if (IsAWordChar(sc.ch) || sc.ch == '}')
 		{
 			strcpy(s_save,s);
 			int tp = strlen(s_save);
@@ -254,9 +257,9 @@ static void ColouriseAU3Doc(unsigned int startPos,
 				if (sc.atLineEnd) {
 					ci=0;
 					if (strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0) {
-						if (sc.atLineEnd) 
+						if (sc.atLineEnd)
 							sc.SetState(SCE_AU3_DEFAULT);
-						else	
+						else
 							sc.SetState(SCE_AU3_COMMENTBLOCK);
 					}
 					break;
@@ -267,9 +270,9 @@ static void ColouriseAU3Doc(unsigned int startPos,
 					sc.SetState(SCE_AU3_COMMENTBLOCK);
 				}
 				// skip rest of the line
-				if (ci==2) 
+				if (ci==2)
 					break;
-				// check when first character is detected on the line 
+				// check when first character is detected on the line
 				if (ci==0) {
 					if (IsAWordStart(static_cast<char>(sc.ch)) || IsAOperator(static_cast<char>(sc.ch))) {
 						ci=1;
@@ -292,10 +295,10 @@ static void ColouriseAU3Doc(unsigned int startPos,
             }
             case SCE_AU3_OPERATOR:
             {
-                // check if its a COMobject 
+                // check if its a COMobject
 				if (sc.chPrev == '.' && IsAWordChar(sc.ch)) {
 					sc.SetState(SCE_AU3_COMOBJ);
-				}	
+				}
 				else {
 					sc.SetState(SCE_AU3_DEFAULT);
 				}
@@ -360,7 +363,7 @@ static void ColouriseAU3Doc(unsigned int startPos,
 							sc.SetState(SCE_AU3_DEFAULT);
 						}
 					}
-				}	
+				}
                 if (sc.atLineEnd) {
 					sc.SetState(SCE_AU3_DEFAULT);}
                 break;
@@ -433,7 +436,7 @@ static void ColouriseAU3Doc(unsigned int startPos,
             case SCE_AU3_STRING:
             {
 				// check for " to end a double qouted string or
-				// check for ' to end a single qouted string 
+				// check for ' to end a single qouted string
 	            if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\'') || (si == 3 && sc.ch == '>'))
 				{
 					sc.ForwardSetState(SCE_AU3_DEFAULT);
@@ -445,7 +448,7 @@ static void ColouriseAU3Doc(unsigned int startPos,
 					si=0;
 					// at line end and not found a continuation char then reset to default
 					int lineCurrent = styler.GetLine(sc.currentPos);
-					if (!IsContinuationLine(lineCurrent,styler)) 
+					if (!IsContinuationLine(lineCurrent,styler))
 					{
 						sc.SetState(SCE_AU3_DEFAULT);
 						break;
@@ -456,27 +459,27 @@ static void ColouriseAU3Doc(unsigned int startPos,
 					sc.SetState(SCE_AU3_SENT);}
 				break;
             }
-            
+
             case SCE_AU3_SENT:
             {
-				// Send key string ended 
-				if (sc.chPrev == '}' && sc.ch != '}') 
+				// Send key string ended
+				if (sc.chPrev == '}' && sc.ch != '}')
 				{
 					// set color to SENDKEY when valid sendkey .. else set back to regular string
 					char sk[100];
 					// split {111 222} and return {111} and check if 222 is valid.
 					// if return code = 1 then invalid 222 so must be string
-					if (GetSendKey(s,sk))   
+					if (GetSendKey(s,sk))
 					{
 						sc.ChangeState(SCE_AU3_STRING);
 					}
 					// if single char between {?} then its ok as sendkey for a single character
-					else if (strlen(sk) == 3)  
+					else if (strlen(sk) == 3)
 					{
 						sc.ChangeState(SCE_AU3_SENT);
 					}
 					// if sendkey {111} is in table then ok as sendkey
-					else if (keywords4.InList(sk)) 
+					else if (keywords4.InList(sk))
 					{
 						sc.ChangeState(SCE_AU3_SENT);
 					}
@@ -492,9 +495,9 @@ static void ColouriseAU3Doc(unsigned int startPos,
 					int		nPos	= 0;
 					int		nState	= 1;
 					char	cTemp;
-					while (!(nState == 2) && ((cTemp = s[nPos]) != '\0')) 
+					while (!(nState == 2) && ((cTemp = s[nPos]) != '\0'))
 					{
-						if (cTemp == '{' && nState == 1) 
+						if (cTemp == '{' && nState == 1)
 						{
 							nState = 2;
 						}
@@ -509,14 +512,14 @@ static void ColouriseAU3Doc(unsigned int startPos,
 						sc.ChangeState(SCE_AU3_STRING);
 						sc.SetState(SCE_AU3_STRING);
 					}
-					// If invalid character found then assume its a regular string	
+					// If invalid character found then assume its a regular string
 					if (nState == 0) {
 						sc.ChangeState(SCE_AU3_STRING);
 						sc.SetState(SCE_AU3_STRING);
 					}
 				}
 				// check if next portion is again a sendkey
-				if (sc.atLineEnd) 
+				if (sc.atLineEnd)
 				{
 					sc.ChangeState(SCE_AU3_STRING);
 					sc.SetState(SCE_AU3_DEFAULT);
@@ -547,14 +550,14 @@ static void ColouriseAU3Doc(unsigned int startPos,
             else if (sc.ch == '.' && !IsADigit(sc.chNext)) {sc.SetState(SCE_AU3_OPERATOR);}
             else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);}
             //else if (sc.ch == '_') {sc.SetState(SCE_AU3_KEYWORD);}
-            else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);}  // string after #include 
+            else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);}  // string after #include
             else if (sc.ch == '\"') {
 				sc.SetState(SCE_AU3_STRING);
 				si = 1;	}
             else if (sc.ch == '\'') {
 				sc.SetState(SCE_AU3_STRING);
 				si = 2;	}
-            else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) 
+            else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
 			{
 				sc.SetState(SCE_AU3_NUMBER);
 				ni = 0;
@@ -566,7 +569,7 @@ static void ColouriseAU3Doc(unsigned int startPos,
     }      //for (; sc.More(); sc.Forward())
 
 	//*************************************
-	// Colourize the last word correctly 
+	// Colourize the last word correctly
 	//*************************************
 	if (sc.state == SCE_AU3_KEYWORD)
 		{
@@ -610,24 +613,24 @@ static void ColouriseAU3Doc(unsigned int startPos,
 	}
 	if (sc.state == SCE_AU3_SENT)
     {
-		// Send key string ended 
-		if (sc.chPrev == '}' && sc.ch != '}') 
+		// Send key string ended
+		if (sc.chPrev == '}' && sc.ch != '}')
 		{
 			// set color to SENDKEY when valid sendkey .. else set back to regular string
 			char sk[100];
 			// split {111 222} and return {111} and check if 222 is valid.
 			// if return code = 1 then invalid 222 so must be string
-			if (GetSendKey(s_save,sk))   
+			if (GetSendKey(s_save,sk))
 			{
 				sc.ChangeState(SCE_AU3_STRING);
 			}
 			// if single char between {?} then its ok as sendkey for a single character
-			else if (strlen(sk) == 3)  
+			else if (strlen(sk) == 3)
 			{
 				sc.ChangeState(SCE_AU3_SENT);
 			}
 			// if sendkey {111} is in table then ok as sendkey
-			else if (keywords4.InList(sk)) 
+			else if (keywords4.InList(sk))
 			{
 				sc.ChangeState(SCE_AU3_SENT);
 			}
@@ -638,7 +641,7 @@ static void ColouriseAU3Doc(unsigned int startPos,
 			sc.SetState(SCE_AU3_STRING);
 		}
 		// check if next portion is again a sendkey
-		if (sc.atLineEnd) 
+		if (sc.atLineEnd)
 		{
 			sc.ChangeState(SCE_AU3_STRING);
 			sc.SetState(SCE_AU3_DEFAULT);
@@ -655,7 +658,7 @@ static bool IsStreamCommentStyle(int style) {
 
 //
 // Routine to find first none space on the current line and return its Style
-// needed for comment lines not starting on pos 1 
+// needed for comment lines not starting on pos 1
 static int GetStyleFirstWord(unsigned int szLine, Accessor &styler)
 {
 	int nsPos = styler.LineStart(szLine);
@@ -687,7 +690,7 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
 			startPos = styler.LineStart(lineCurrent);
 		}
 	}
-	// vars for style of previous/current/next lines 
+	// 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
@@ -712,7 +715,7 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
 	if (lineCurrent > 0)
 		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
 	int levelNext = levelCurrent;
-	//  
+	//
 	int	visibleChars = 0;
 	char chNext = styler.SafeGetCharAt(startPos);
 	char chPrev = ' ';
@@ -737,7 +740,7 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
 				}
 			}
 		}
-		// start the capture of the first word 
+		// start the capture of the first word
 		if (!(FirstWordStart)) {
 			if (IsAWordChar(ch) || IsAWordStart(ch) || ch == ';') {
 				FirstWordStart = true;
@@ -749,7 +752,7 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
 			if (ThenFoundLast) {
 				if (IsAWordChar(ch)) {
 					ThenFoundLast = false;
-				}		
+				}
 			}
 			// find out if the word "then" is the last on a "if" line
 			if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
@@ -770,21 +773,21 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
 				}
 			}
 		}
-		// End of Line found so process the information 
+		// 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 == '_')) && 
+			if (szKeywordlen > 0 && (!(chPrev == '_')) &&
 				((!(IsStreamCommentStyle(style)) || foldInComment)) ) {
 				szKeyword[szKeywordlen] = '\0';
 				// only fold "if" last keyword is "then"  (else its a one line if)
 				if (strcmp(szKeyword,"if") == 0  && ThenFoundLast) {
 						levelNext++;
 				}
-				// create new fold for these words 
+				// create new fold for these words
 				if (strcmp(szKeyword,"do") == 0   || strcmp(szKeyword,"for") == 0 ||
 					strcmp(szKeyword,"func") == 0 || strcmp(szKeyword,"while") == 0||
 					strcmp(szKeyword,"with") == 0 || strcmp(szKeyword,"#region") == 0 ) {
@@ -797,12 +800,12 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
 				}
 				// end the fold for these words before the current line
 				if (strcmp(szKeyword,"endfunc") == 0 || strcmp(szKeyword,"endif") == 0 ||
-					strcmp(szKeyword,"next") == 0    || strcmp(szKeyword,"until") == 0 || 
+					strcmp(szKeyword,"next") == 0    || strcmp(szKeyword,"until") == 0 ||
 					strcmp(szKeyword,"endwith") == 0 ||strcmp(szKeyword,"wend") == 0){
 						levelNext--;
 						levelCurrent--;
 				}
-				// end the fold for these words before the current line and Start new fold 
+				// end the fold for these words before the current line and Start new fold
 				if (strcmp(szKeyword,"case") == 0      || strcmp(szKeyword,"else") == 0 ||
 					strcmp(szKeyword,"elseif") == 0 ) {
 						levelCurrent--;
@@ -841,16 +844,16 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
 				// 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) 
+				else if (IsStreamCommentStyle(stylePrev)
 						&& !(styleNext == SCE_AU3_COMMENT)
-						&& stylePrev == SCE_AU3_COMMENT 
+						&& stylePrev == SCE_AU3_COMMENT
 						&& style == SCE_AU3_COMMENT) {
 					levelNext--;
 				}
 				// fold till the one but last line for Blockcomment lines
-				else if (IsStreamCommentStyle(stylePrev) 
+				else if (IsStreamCommentStyle(stylePrev)
 						&& !(styleNext == SCE_AU3_COMMENTBLOCK)
 						&& style == SCE_AU3_COMMENTBLOCK) {
 					levelNext--;
diff --git a/plugins/scintilla/scintilla/LexAVE.cxx b/plugins/scintilla/scintilla/LexAVE.cxx
index 2b7029b..373173c 100644
--- a/plugins/scintilla/scintilla/LexAVE.cxx
+++ b/plugins/scintilla/scintilla/LexAVE.cxx
@@ -9,18 +9,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
 #include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -42,7 +45,7 @@ inline bool IsAWordStart(const int ch) {
 }
 
 inline bool isAveOperator(char ch) {
-	if (isalnum(ch))
+	if (isascii(ch) && isalnum(ch))
 		return false;
 	// '.' left out as it is used to make up numbers
 	if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
diff --git a/plugins/scintilla/scintilla/LexAbaqus.cxx b/plugins/scintilla/scintilla/LexAbaqus.cxx
index 10e8b76..1341700 100644
--- a/plugins/scintilla/scintilla/LexAbaqus.cxx
+++ b/plugins/scintilla/scintilla/LexAbaqus.cxx
@@ -10,18 +10,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexAccessor.h b/plugins/scintilla/scintilla/LexAccessor.h
new file mode 100644
index 0000000..dccf31e
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexAccessor.h
@@ -0,0 +1,175 @@
+// Scintilla source code edit control
+/** @file LexAccessor.h
+ ** Interfaces between Scintilla and lexers.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXACCESSOR_H
+#define LEXACCESSOR_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class LexAccessor {
+private:
+	IDocument *pAccess;
+	enum {extremePosition=0x7FFFFFFF};
+	/** @a bufferSize is a trade off between time taken to copy the characters
+	 * and retrieval overhead.
+	 * @a slopSize positions the buffer before the desired position
+	 * in case there is some backtracking. */
+	enum {bufferSize=4000, slopSize=bufferSize/8};
+	char buf[bufferSize+1];
+	int startPos;
+	int endPos;
+	int codePage;
+	int lenDoc;
+	int mask;
+	char styleBuf[bufferSize];
+	int validLen;
+	char chFlags;
+	char chWhile;
+	unsigned int startSeg;
+	int startPosStyling;
+
+	void Fill(int position) {
+		startPos = position - slopSize;
+		if (startPos + bufferSize > lenDoc)
+			startPos = lenDoc - bufferSize;
+		if (startPos < 0)
+			startPos = 0;
+		endPos = startPos + bufferSize;
+		if (endPos > lenDoc)
+			endPos = lenDoc;
+
+		pAccess->GetCharRange(buf, startPos, endPos-startPos);
+		buf[endPos-startPos] = '\0';
+	}
+
+public:
+	LexAccessor(IDocument *pAccess_) :
+		pAccess(pAccess_), startPos(extremePosition), endPos(0),
+		codePage(pAccess->CodePage()), lenDoc(pAccess->Length()),
+		mask(127), validLen(0), chFlags(0), chWhile(0),
+		startSeg(0), startPosStyling(0) {
+	}
+	char operator[](int position) {
+		if (position < startPos || position >= endPos) {
+			Fill(position);
+		}
+		return buf[position - startPos];
+	}
+	/** Safe version of operator[], returning a defined value for invalid position. */
+	char SafeGetCharAt(int position, char chDefault=' ') {
+		if (position < startPos || position >= endPos) {
+			Fill(position);
+			if (position < startPos || position >= endPos) {
+				// Position is outside range of document
+				return chDefault;
+			}
+		}
+		return buf[position - startPos];
+	}
+	bool IsLeadByte(char ch) {
+		return pAccess->IsDBCSLeadByte(ch);
+	}
+
+	bool Match(int pos, const char *s) {
+		for (int i=0; *s; i++) {
+			if (*s != SafeGetCharAt(pos+i))
+				return false;
+			s++;
+		}
+		return true;
+	}
+	char StyleAt(int position) {
+		return static_cast<char>(pAccess->StyleAt(position) & mask);
+	}
+	int GetLine(int position) {
+		return pAccess->LineFromPosition(position);
+	}
+	int LineStart(int line) {
+		return pAccess->LineStart(line);
+	}
+	int LevelAt(int line) {
+		return pAccess->GetLevel(line);
+	}
+	int Length() const {
+		return lenDoc;
+	}
+	void Flush() {
+		startPos = extremePosition;
+		if (validLen > 0) {
+			pAccess->SetStyles(validLen, styleBuf);
+			startPosStyling += validLen;
+			validLen = 0;
+		}
+	}
+	int GetLineState(int line) {
+		return pAccess->GetLineState(line);
+	}
+	int SetLineState(int line, int state) {
+		return pAccess->SetLineState(line, state);
+	}
+	// Style setting
+	void StartAt(unsigned int start, char chMask=31) {
+		// Store the mask specified for use with StyleAt.
+		mask = chMask;
+		pAccess->StartStyling(start, chMask);
+		startPosStyling = start;
+	}
+	void SetFlags(char chFlags_, char chWhile_) {
+		chFlags = chFlags_;
+		chWhile = chWhile_;
+	}
+	unsigned int GetStartSegment() const {
+		return startSeg;
+	}
+	void StartSegment(unsigned int pos) {
+		startSeg = pos;
+	}
+	void ColourTo(unsigned int pos, int chAttr) {
+		// Only perform styling if non empty range
+		if (pos != startSeg - 1) {
+			assert(pos >= startSeg);
+			if (pos < startSeg) {
+				return;
+			}
+
+			if (validLen + (pos - startSeg + 1) >= bufferSize)
+				Flush();
+			if (validLen + (pos - startSeg + 1) >= bufferSize) {
+				// Too big for buffer so send directly
+				pAccess->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
+			} else {
+				if (chAttr != chWhile)
+					chFlags = 0;
+				chAttr |= chFlags;
+				for (unsigned int i = startSeg; i <= pos; i++) {
+					assert((startPosStyling + validLen) < Length());
+					styleBuf[validLen++] = static_cast<char>(chAttr);
+				}
+			}
+		}
+		startSeg = pos+1;
+	}
+	void SetLevel(int line, int level) {
+		pAccess->SetLevel(line, level);
+	}
+	void IndicatorFill(int start, int end, int indicator, int value) {
+		pAccess->DecorationSetCurrentIndicator(indicator);
+		pAccess->DecorationFillRange(start, value, end - start);
+	}
+
+	void ChangeLexerState(int start, int end) {
+		pAccess->ChangeLexerState(start, end);
+	}
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/LexAda.cxx b/plugins/scintilla/scintilla/LexAda.cxx
old mode 100755
new mode 100644
index 654bfbe..e109514
--- a/plugins/scintilla/scintilla/LexAda.cxx
+++ b/plugins/scintilla/scintilla/LexAda.cxx
@@ -6,19 +6,23 @@
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
-#include <ctype.h>
 #include <string.h>
 #include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
 
 #include <string>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "PropSet.h"
-#include "KeyWords.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexAsm.cxx b/plugins/scintilla/scintilla/LexAsm.cxx
index 17c9384..946d47a 100644
--- a/plugins/scintilla/scintilla/LexAsm.cxx
+++ b/plugins/scintilla/scintilla/LexAsm.cxx
@@ -4,25 +4,37 @@
  ** Written by The Black Horus
  ** Enhancements and NASM stuff by Kein-Hong Man, 2003-10
  ** SCE_ASM_COMMENTBLOCK and SCE_ASM_CHARACTER are for future GNU as colouring
+ ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
  **/
 // 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>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
 
-#include "Platform.h"
+#include <string>
+#include <map>
+#include <set>
 
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
@@ -50,15 +62,184 @@ static inline bool IsAsmOperator(const int ch) {
 	return false;
 }
 
-static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                            Accessor &styler) {
+static bool IsStreamCommentStyle(int style) {
+	return style == SCE_ASM_COMMENTDIRECTIVE || style == SCE_ASM_COMMENTBLOCK;
+}
+
+static inline int LowerCase(int c) {
+	if (c >= 'A' && c <= 'Z')
+		return 'a' + c - 'A';
+	return c;
+}
+
+// An individual named option for use in an OptionSet
 
-	WordList &cpuInstruction = *keywordlists[0];
-	WordList &mathInstruction = *keywordlists[1];
-	WordList &registers = *keywordlists[2];
-	WordList &directive = *keywordlists[3];
-	WordList &directiveOperand = *keywordlists[4];
-	WordList &extInstruction = *keywordlists[5];
+// Options used for LexerAsm
+struct OptionsAsm {
+	std::string delimiter;
+	bool fold;
+	bool foldSyntaxBased;
+	bool foldCommentMultiline;
+	bool foldCommentExplicit;
+	std::string foldExplicitStart;
+	std::string foldExplicitEnd;
+	bool foldExplicitAnywhere;
+	bool foldCompact;
+	OptionsAsm() {
+		delimiter = "";
+		fold = false;
+		foldSyntaxBased = true;
+		foldCommentMultiline = false;
+		foldCommentExplicit = false;
+		foldExplicitStart = "";
+		foldExplicitEnd   = "";
+		foldExplicitAnywhere = false;
+		foldCompact = true;
+	}
+};
+
+static const char * const asmWordListDesc[] = {
+	"CPU instructions",
+	"FPU instructions",
+	"Registers",
+	"Directives",
+	"Directive operands",
+	"Extended instructions",
+	"Directives4Foldstart",
+	"Directives4Foldend",
+	0
+};
+
+struct OptionSetAsm : public OptionSet<OptionsAsm> {
+	OptionSetAsm() {
+		DefineProperty("lexer.asm.comment.delimiter", &OptionsAsm::delimiter,
+			"Character used for COMMENT directive's delimiter, replacing the standard \"~\".");
+
+		DefineProperty("fold", &OptionsAsm::fold);
+
+		DefineProperty("fold.asm.syntax.based", &OptionsAsm::foldSyntaxBased,
+			"Set this property to 0 to disable syntax based folding.");
+
+		DefineProperty("fold.asm.comment.multiline", &OptionsAsm::foldCommentMultiline,
+			"Set this property to 1 to enable folding multi-line comments.");
+
+		DefineProperty("fold.asm.comment.explicit", &OptionsAsm::foldCommentExplicit,
+			"This option enables folding explicit fold points when using the Asm 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.");
+
+		DefineProperty("fold.asm.explicit.start", &OptionsAsm::foldExplicitStart,
+			"The string to use for explicit fold start points, replacing the standard ;{.");
+
+		DefineProperty("fold.asm.explicit.end", &OptionsAsm::foldExplicitEnd,
+			"The string to use for explicit fold end points, replacing the standard ;}.");
+
+		DefineProperty("fold.asm.explicit.anywhere", &OptionsAsm::foldExplicitAnywhere,
+			"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+		DefineProperty("fold.compact", &OptionsAsm::foldCompact);
+
+		DefineWordListSets(asmWordListDesc);
+	}
+};
+
+class LexerAsm : public ILexer {
+	WordList cpuInstruction;
+	WordList mathInstruction;
+	WordList registers;
+	WordList directive;
+	WordList directiveOperand;
+	WordList extInstruction;
+	WordList directives4foldstart;
+	WordList directives4foldend;
+	OptionsAsm options;
+	OptionSetAsm osAsm;
+public:
+	LexerAsm() {
+	}
+	~LexerAsm() {
+	}
+	void SCI_METHOD Release() {
+		delete this;
+	}
+	int SCI_METHOD Version() const {
+		return lvOriginal;
+	}
+	const char * SCI_METHOD PropertyNames() {
+		return osAsm.PropertyNames();
+	}
+	int SCI_METHOD PropertyType(const char *name) {
+		return osAsm.PropertyType(name);
+	}
+	const char * SCI_METHOD DescribeProperty(const char *name) {
+		return osAsm.DescribeProperty(name);
+	}
+	int SCI_METHOD PropertySet(const char *key, const char *val);
+	const char * SCI_METHOD DescribeWordListSets() {
+		return osAsm.DescribeWordListSets();
+	}
+	int SCI_METHOD WordListSet(int n, const char *wl);
+	void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+	void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+
+	void * SCI_METHOD PrivateCall(int, void *) {
+		return 0;
+	}
+
+	static ILexer *LexerFactoryAsm() {
+		return new LexerAsm();
+	}
+};
+
+int SCI_METHOD LexerAsm::PropertySet(const char *key, const char *val) {
+	if (osAsm.PropertySet(&options, key, val)) {
+		return 0;
+	}
+	return -1;
+}
+
+int SCI_METHOD LexerAsm::WordListSet(int n, const char *wl) {
+	WordList *wordListN = 0;
+	switch (n) {
+	case 0:
+		wordListN = &cpuInstruction;
+		break;
+	case 1:
+		wordListN = &mathInstruction;
+		break;
+	case 2:
+		wordListN = &registers;
+		break;
+	case 3:
+		wordListN = &directive;
+		break;
+	case 4:
+		wordListN = &directiveOperand;
+		break;
+	case 5:
+		wordListN = &extInstruction;
+		break;
+	case 6:
+		wordListN = &directives4foldstart;
+		break;
+	case 7:
+		wordListN = &directives4foldend;
+		break;
+	}
+	int firstModification = -1;
+	if (wordListN) {
+		WordList wlNew;
+		wlNew.Set(wl);
+		if (*wordListN != wlNew) {
+			wordListN->Set(wl);
+			firstModification = 0;
+		}
+	}
+	return firstModification;
+}
+
+void SCI_METHOD LexerAsm::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+	LexAccessor styler(pAccess);
 
 	// Do not leak onto next line
 	if (initStyle == SCE_ASM_STRINGEOL)
@@ -92,7 +273,7 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
 			if (!IsAsmOperator(sc.ch)) {
 			    sc.SetState(SCE_ASM_DEFAULT);
 			}
-		}else if (sc.state == SCE_ASM_NUMBER) {
+		} else if (sc.state == SCE_ASM_NUMBER) {
 			if (!IsAWordChar(sc.ch)) {
 				sc.SetState(SCE_ASM_DEFAULT);
 			}
@@ -100,6 +281,7 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
 			if (!IsAWordChar(sc.ch) ) {
 				char s[100];
 				sc.GetCurrentLowered(s, sizeof(s));
+				bool IsDirective = false;
 
 				if (cpuInstruction.InList(s)) {
 					sc.ChangeState(SCE_ASM_CPUINSTRUCTION);
@@ -109,15 +291,32 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
 					sc.ChangeState(SCE_ASM_REGISTER);
 				}  else if (directive.InList(s)) {
 					sc.ChangeState(SCE_ASM_DIRECTIVE);
+					IsDirective = true;
 				} else if (directiveOperand.InList(s)) {
 					sc.ChangeState(SCE_ASM_DIRECTIVEOPERAND);
 				} else if (extInstruction.InList(s)) {
 					sc.ChangeState(SCE_ASM_EXTINSTRUCTION);
 				}
 				sc.SetState(SCE_ASM_DEFAULT);
+				if (IsDirective && !strcmp(s, "comment")) {
+					char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
+					while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) {
+						sc.ForwardSetState(SCE_ASM_DEFAULT);
+					}
+					if (sc.ch == delimiter) {
+						sc.SetState(SCE_ASM_COMMENTDIRECTIVE);
+					}
+				}
 			}
-		}
-		else if (sc.state == SCE_ASM_COMMENT ) {
+		} else if (sc.state == SCE_ASM_COMMENTDIRECTIVE) {
+			char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
+			if (sc.ch == delimiter) {
+				while (!sc.atLineEnd) {
+					sc.Forward();
+				}
+				sc.SetState(SCE_ASM_DEFAULT);
+			}
+		} else if (sc.state == SCE_ASM_COMMENT ) {
 			if (sc.atLineEnd) {
 				sc.SetState(SCE_ASM_DEFAULT);
 			}
@@ -166,15 +365,100 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
 	sc.Complete();
 }
 
-static const char * const asmWordListDesc[] = {
-	"CPU instructions",
-	"FPU instructions",
-	"Registers",
-	"Directives",
-	"Directive operands",
-	"Extended instructions",
-	0
-};
+// 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".
+
+void SCI_METHOD LexerAsm::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+
+	if (!options.fold)
+		return;
+
+	LexAccessor styler(pAccess);
+
+	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 levelNext = levelCurrent;
+	char chNext = styler[startPos];
+	int styleNext = styler.StyleAt(startPos);
+	int style = initStyle;
+	char word[100];
+	int wordlen = 0;
+	const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
+	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 (options.foldCommentMultiline && 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 (options.foldCommentExplicit && ((style == SCE_ASM_COMMENT) || options.foldExplicitAnywhere)) {
+			if (userDefinedFoldMarkers) {
+				if (styler.Match(i, options.foldExplicitStart.c_str())) {
+ 					levelNext++;
+				} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
+ 					levelNext--;
+ 				}
+			} else {
+				if (ch == ';') {
+					if (chNext == '{') {
+						levelNext++;
+					} else if (chNext == '}') {
+						levelNext--;
+					}
+				}
+ 			}
+ 		}
+		if (options.foldSyntaxBased && (style == SCE_ASM_DIRECTIVE)) {
+			word[wordlen++] = static_cast<char>(LowerCase(ch));
+			if (wordlen == 100) {                   // prevent overflow
+				word[0] = '\0';
+				wordlen = 1;
+			}
+			if (styleNext != SCE_ASM_DIRECTIVE) {   // reading directive ready
+				word[wordlen] = '\0';
+				wordlen = 0;
+				if (directives4foldstart.InList(word)) {
+					levelNext++;
+				} else if (directives4foldend.InList(word)){
+					levelNext--;
+				}
+			}
+		}
+		if (!IsASpace(ch))
+			visibleChars++;
+		if (atEOL || (i == endPos-1)) {
+			int levelUse = levelCurrent;
+			int lev = levelUse | levelNext << 16;
+			if (visibleChars == 0 && options.foldCompact)
+				lev |= SC_FOLDLEVELWHITEFLAG;
+			if (levelUse < levelNext)
+				lev |= SC_FOLDLEVELHEADERFLAG;
+			if (lev != styler.LevelAt(lineCurrent)) {
+				styler.SetLevel(lineCurrent, lev);
+			}
+			lineCurrent++;
+			levelCurrent = levelNext;
+			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;
+		}
+	}
+}
 
-LexerModule lmAsm(SCLEX_ASM, ColouriseAsmDoc, "asm", 0, asmWordListDesc);
+LexerModule lmAsm(SCLEX_ASM, LexerAsm::LexerFactoryAsm, "asm", asmWordListDesc);
 
diff --git a/plugins/scintilla/scintilla/LexAsn1.cxx b/plugins/scintilla/scintilla/LexAsn1.cxx
index 36f1d5d..3545b3f 100644
--- a/plugins/scintilla/scintilla/LexAsn1.cxx
+++ b/plugins/scintilla/scintilla/LexAsn1.cxx
@@ -5,20 +5,23 @@
 // Copyright 2004 by Herr Pfarrer rpfarrer <at> yahoo <dot> de
 // Last Updated: 20/07/2004
 // 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 <assert.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexBaan.cxx b/plugins/scintilla/scintilla/LexBaan.cxx
index a6847db..3784f3c 100644
--- a/plugins/scintilla/scintilla/LexBaan.cxx
+++ b/plugins/scintilla/scintilla/LexBaan.cxx
@@ -8,18 +8,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexBash.cxx b/plugins/scintilla/scintilla/LexBash.cxx
index 5801278..165e104 100644
--- a/plugins/scintilla/scintilla/LexBash.cxx
+++ b/plugins/scintilla/scintilla/LexBash.cxx
@@ -2,44 +2,53 @@
 /** @file LexBash.cxx
  ** Lexer for Bash.
  **/
-// Copyright 2004-2008 by Neil Hodgson <neilh scintilla org>
+// Copyright 2004-2010 by Neil Hodgson <neilh scintilla org>
 // Adapted from LexPerl by Kein-Hong Man 2004
 // 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 <assert.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
 #include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-#define HERE_DELIM_MAX 256
+#define HERE_DELIM_MAX			256
 
 // define this if you want 'invalid octals' to be marked as errors
 // usually, this is not a good idea, permissive lexing is better
 #undef PEDANTIC_OCTAL
 
-#define BASH_BASE_ERROR		65
-#define BASH_BASE_DECIMAL	66
-#define BASH_BASE_HEX		67
+#define BASH_BASE_ERROR			65
+#define BASH_BASE_DECIMAL		66
+#define BASH_BASE_HEX			67
 #ifdef PEDANTIC_OCTAL
-#define BASH_BASE_OCTAL		68
-#define BASH_BASE_OCTAL_ERROR	69
+#define BASH_BASE_OCTAL			68
+#define	BASH_BASE_OCTAL_ERROR	69
 #endif
 
+// state constants for parts of a bash command segment
+#define	BASH_CMD_BODY			0
+#define BASH_CMD_START			1
+#define BASH_CMD_WORD			2
+#define BASH_CMD_TEST			3
+#define BASH_CMD_ARITH			4
+#define BASH_CMD_DELIM			5
+
 static inline int translateBashDigit(int ch) {
 	if (ch >= '0' && ch <= '9') {
 		return ch - '0';
@@ -80,11 +89,15 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
 							 WordList *keywordlists[], Accessor &styler) {
 
 	WordList &keywords = *keywordlists[0];
+	WordList cmdDelimiter, bashStruct, bashStruct_in;
+	cmdDelimiter.Set("| || |& & && ; ;; ( ) { }");
+	bashStruct.Set("if elif fi while until else then do done esac eval");
+	bashStruct_in.Set("for case select");
 
 	CharacterSet setWordStart(CharacterSet::setAlpha, "_");
 	// note that [+-] are often parts of identifiers in shell scripts
 	CharacterSet setWord(CharacterSet::setAlphaNum, "._+-");
-	CharacterSet setBashOperator(CharacterSet::setNone, "^&\\%()-+=|{}[]:;>,*/<?!.~@");
+	CharacterSet setBashOperator(CharacterSet::setNone, "^&%()-+=|{}[]:;>,*/<?!.~@");
 	CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn");
 	CharacterSet setParam(CharacterSet::setAlphaNum, "$_");
 	CharacterSet setHereDoc(CharacterSet::setAlpha, "_\\-+!");
@@ -144,46 +157,115 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
 	int numBase = 0;
 	int digit;
 	unsigned int endPos = startPos + length;
+	int cmdState = BASH_CMD_START;
+	int testExprType = 0;
 
-	// Backtrack to beginning of style if required...
-	// If in a long distance lexical state, backtrack to find quote characters
-	if (initStyle == SCE_SH_HERE_Q) {
-		while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_SH_HERE_DELIM)) {
-			startPos--;
-		}
-		startPos = styler.LineStart(styler.GetLine(startPos));
-		initStyle = styler.StyleAt(startPos - 1);
-	}
-	// Bash strings can be multi-line with embedded newlines, so backtrack.
-	// Bash numbers have additional state during lexing, so backtrack too.
-	if (initStyle == SCE_SH_STRING
-	 || initStyle == SCE_SH_BACKTICKS
-	 || initStyle == SCE_SH_CHARACTER
-	 || initStyle == SCE_SH_NUMBER
-	 || initStyle == SCE_SH_IDENTIFIER
-	 || initStyle == SCE_SH_COMMENTLINE) {
-		while ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) {
-			startPos--;
-		}
-		initStyle = SCE_SH_DEFAULT;
+	// Always backtracks to the start of a line that is not a continuation
+	// of the previous line (i.e. start of a bash command segment)
+	int ln = styler.GetLine(startPos);
+	for (;;) {
+		startPos = styler.LineStart(ln);
+		if (ln == 0 || styler.GetLineState(ln) == BASH_CMD_START)
+			break;
+		ln--;
 	}
+	initStyle = SCE_SH_DEFAULT;
 
 	StyleContext sc(startPos, endPos - startPos, initStyle, styler);
 
 	for (; sc.More(); sc.Forward()) {
 
+		// handle line continuation, updates per-line stored state
+		if (sc.atLineStart) {
+			ln = styler.GetLine(sc.currentPos);
+			if (sc.state == SCE_SH_STRING
+			 || sc.state == SCE_SH_BACKTICKS
+			 || sc.state == SCE_SH_CHARACTER
+			 || sc.state == SCE_SH_HERE_Q
+			 || sc.state == SCE_SH_COMMENTLINE
+			 || sc.state == SCE_SH_PARAM) {
+				// force backtrack while retaining cmdState
+				styler.SetLineState(ln, BASH_CMD_BODY);
+			} else {
+				if (ln > 0) {
+					if ((sc.GetRelative(-3) == '\\' && sc.GetRelative(-2) == '\r' && sc.chPrev == '\n')
+					 || sc.GetRelative(-2) == '\\') {	// handle '\' line continuation
+						// retain last line's state
+					} else
+						cmdState = BASH_CMD_START;
+				}
+				styler.SetLineState(ln, cmdState);
+			}
+		}
+
+		// controls change of cmdState at the end of a non-whitespace element
+		// states BODY|TEST|ARITH persist until the end of a command segment
+		// state WORD persist, but ends with 'in' or 'do' construct keywords
+		int cmdStateNew = BASH_CMD_BODY;
+		if (cmdState == BASH_CMD_TEST || cmdState == BASH_CMD_ARITH || cmdState == BASH_CMD_WORD)
+			cmdStateNew = cmdState;
+		int stylePrev = sc.state;
+
 		// Determine if the current state should terminate.
 		switch (sc.state) {
 			case SCE_SH_OPERATOR:
 				sc.SetState(SCE_SH_DEFAULT);
+				if (cmdState == BASH_CMD_DELIM)		// if command delimiter, start new command
+					cmdStateNew = BASH_CMD_START;
+				else if (sc.chPrev == '\\')			// propagate command state if line continued
+					cmdStateNew = cmdState;
 				break;
 			case SCE_SH_WORD:
 				// "." never used in Bash variable names but used in file names
 				if (!setWord.Contains(sc.ch)) {
-					char s[1000];
+					char s[500];
+					char s2[10];
 					sc.GetCurrent(s, sizeof(s));
-					if (s[0] != '-' &&	// for file operators
-						!keywords.InList(s)) {
+					// allow keywords ending in a whitespace or command delimiter
+					s2[0] = static_cast<char>(sc.ch);
+					s2[1] = '\0';
+					bool keywordEnds = IsASpace(sc.ch) || cmdDelimiter.InList(s2);
+					// 'in' or 'do' may be construct keywords
+					if (cmdState == BASH_CMD_WORD) {
+						if (strcmp(s, "in") == 0 && keywordEnds)
+							cmdStateNew = BASH_CMD_BODY;
+						else if (strcmp(s, "do") == 0 && keywordEnds)
+							cmdStateNew = BASH_CMD_START;
+						else
+							sc.ChangeState(SCE_SH_IDENTIFIER);
+						sc.SetState(SCE_SH_DEFAULT);
+						break;
+					}
+					// a 'test' keyword starts a test expression
+					if (strcmp(s, "test") == 0) {
+						if (cmdState == BASH_CMD_START && keywordEnds) {
+							cmdStateNew = BASH_CMD_TEST;
+							testExprType = 0;
+						} else
+							sc.ChangeState(SCE_SH_IDENTIFIER);
+					}
+					// detect bash construct keywords
+					else if (bashStruct.InList(s)) {
+						if (cmdState == BASH_CMD_START && keywordEnds)
+							cmdStateNew = BASH_CMD_START;
+						else
+							sc.ChangeState(SCE_SH_IDENTIFIER);
+					}
+					// 'for'|'case'|'select' needs 'in'|'do' to be highlighted later
+					else if (bashStruct_in.InList(s)) {
+						if (cmdState == BASH_CMD_START && keywordEnds)
+							cmdStateNew = BASH_CMD_WORD;
+						else
+							sc.ChangeState(SCE_SH_IDENTIFIER);
+					}
+					// disambiguate option items and file test operators
+					else if (s[0] == '-') {
+						if (cmdState != BASH_CMD_TEST)
+							sc.ChangeState(SCE_SH_IDENTIFIER);
+					}
+					// disambiguate keywords and identifiers
+					else if (cmdState != BASH_CMD_START
+						  || !(keywords.InList(s) && keywordEnds)) {
 						sc.ChangeState(SCE_SH_IDENTIFIER);
 					}
 					sc.SetState(SCE_SH_DEFAULT);
@@ -248,14 +330,8 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
 				sc.SetState(SCE_SH_DEFAULT);
 				break;
 			case SCE_SH_COMMENTLINE:
-				if (sc.ch == '\\' && (sc.chNext == '\r' || sc.chNext == '\n')) {
-					// comment continuation
-					sc.Forward();
-					if (sc.ch == '\r' && sc.chNext == '\n') {
-						sc.Forward();
-					}
-				} else if (sc.atLineEnd) {
-					sc.ForwardSetState(SCE_SH_DEFAULT);
+				if (sc.atLineEnd && sc.chPrev != '\\') {
+					sc.SetState(SCE_SH_DEFAULT);
 				}
 				break;
 			case SCE_SH_HERE_DELIM:
@@ -294,23 +370,14 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
 						HereDoc.State = 1;
 					}
 				} else if (HereDoc.State == 1) { // collect the delimiter
-					if (HereDoc.Quoted) { // a quoted here-doc delimiter
-						if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
-							sc.ForwardSetState(SCE_SH_DEFAULT);
-						} else {
-							if (sc.ch == '\\' && sc.chNext == HereDoc.Quote) { // escaped quote
-								sc.Forward();
-							}
-							HereDoc.Append(sc.ch);
-						}
-					} else { // an unquoted here-doc delimiter
-						if (setHereDoc2.Contains(sc.ch)) {
-							HereDoc.Append(sc.ch);
-						} else if (sc.ch == '\\') {
-							// skip escape prefix
-						} else {
-							sc.SetState(SCE_SH_DEFAULT);
-						}
+					if (setHereDoc2.Contains(sc.ch) || sc.chPrev == '\\') {
+						HereDoc.Append(sc.ch);
+					} else if (HereDoc.Quoted && sc.ch == HereDoc.Quote) {	// closing quote => end of delimiter
+						sc.ForwardSetState(SCE_SH_DEFAULT);
+					} else if (sc.ch == '\\') {
+						// skip escape prefix
+					} else {
+						sc.SetState(SCE_SH_DEFAULT);
 					}
 					if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {	// force blowup
 						sc.SetState(SCE_SH_ERROR);
@@ -339,8 +406,8 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
 					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)) {
+						if ((prefixws == 0) ||	// indentation rule
+							(prefixws > 0 && HereDoc.Indent)) {
 							sc.SetState(SCE_SH_DEFAULT);
 							break;
 						}
@@ -391,10 +458,17 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
 			sc.SetState(SCE_SH_HERE_Q);
 		}
 
+		// update cmdState about the current command segment
+		if (stylePrev != SCE_SH_DEFAULT && sc.state == SCE_SH_DEFAULT) {
+			cmdState = cmdStateNew;
+		}
 		// Determine if a new state should be entered.
 		if (sc.state == SCE_SH_DEFAULT) {
-			if (sc.ch == '\\') {	// escaped character
+			if (sc.ch == '\\') {
+				// Bash can escape any non-newline as a literal
 				sc.SetState(SCE_SH_IDENTIFIER);
+				if (sc.chNext == '\r' || sc.chNext == '\n')
+					sc.SetState(SCE_SH_OPERATOR);
 			} else if (IsADigit(sc.ch)) {
 				sc.SetState(SCE_SH_NUMBER);
 				numBase = BASH_BASE_DECIMAL;
@@ -424,6 +498,10 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
 				sc.SetState(SCE_SH_BACKTICKS);
 				Quote.Start(sc.ch);
 			} else if (sc.ch == '$') {
+				if (sc.Match("$((")) {
+					sc.SetState(SCE_SH_OPERATOR);	// handle '((' later
+					continue;
+				}
 				sc.SetState(SCE_SH_SCALAR);
 				sc.Forward();
 				if (sc.ch == '{') {
@@ -434,9 +512,6 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
 					sc.ChangeState(SCE_SH_STRING);
 				} else if (sc.ch == '(' || sc.ch == '`') {
 					sc.ChangeState(SCE_SH_BACKTICKS);
-					if (sc.chNext == '(') {	// $(( is lexed as operator
-						sc.ChangeState(SCE_SH_OPERATOR);
-					}
 				} else {
 					continue;	// scalar has no delimiter pair
 				}
@@ -453,9 +528,66 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
 				sc.SetState(SCE_SH_WORD);
 				sc.Forward();
 			} else if (setBashOperator.Contains(sc.ch)) {
+				char s[10];
+				bool isCmdDelim = false;
 				sc.SetState(SCE_SH_OPERATOR);
+				// handle opening delimiters for test/arithmetic expressions - ((,[[,[
+				if (cmdState == BASH_CMD_START
+				 || cmdState == BASH_CMD_BODY) {
+					if (sc.Match('(', '(')) {
+						cmdState = BASH_CMD_ARITH;
+						sc.Forward();
+					} else if (sc.Match('[', '[') && IsASpace(sc.GetRelative(2))) {
+						cmdState = BASH_CMD_TEST;
+						testExprType = 1;
+						sc.Forward();
+					} else if (sc.ch == '[' && IsASpace(sc.chNext)) {
+						cmdState = BASH_CMD_TEST;
+						testExprType = 2;
+					}
+				}
+				// special state -- for ((x;y;z)) in ... looping
+				if (cmdState == BASH_CMD_WORD && sc.Match('(', '(')) {
+					cmdState = BASH_CMD_ARITH;
+					sc.Forward();
+					continue;
+				}
+				// handle command delimiters in command START|BODY|WORD state, also TEST if 'test'
+				if (cmdState == BASH_CMD_START
+				 || cmdState == BASH_CMD_BODY
+				 || cmdState == BASH_CMD_WORD
+				 || (cmdState == BASH_CMD_TEST && testExprType == 0)) {
+					s[0] = static_cast<char>(sc.ch);
+					if (setBashOperator.Contains(sc.chNext)) {
+						s[1] = static_cast<char>(sc.chNext);
+						s[2] = '\0';
+						isCmdDelim = cmdDelimiter.InList(s);
+						if (isCmdDelim)
+							sc.Forward();
+					}
+					if (!isCmdDelim) {
+						s[1] = '\0';
+						isCmdDelim = cmdDelimiter.InList(s);
+					}
+					if (isCmdDelim) {
+						cmdState = BASH_CMD_DELIM;
+						continue;
+					}
+				}
+				// handle closing delimiters for test/arithmetic expressions - )),]],]
+				if (cmdState == BASH_CMD_ARITH && sc.Match(')', ')')) {
+					cmdState = BASH_CMD_BODY;
+					sc.Forward();
+				} else if (cmdState == BASH_CMD_TEST && IsASpace(sc.chPrev)) {
+					if (sc.Match(']', ']') && testExprType == 1) {
+						sc.Forward();
+						cmdState = BASH_CMD_BODY;
+					} else if (sc.ch == ']' && testExprType == 2) {
+						cmdState = BASH_CMD_BODY;
+					}
+				}
 			}
-		}
+		}// sc.state
 	}
 	sc.Complete();
 }
@@ -507,6 +639,14 @@ static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
 				levelCurrent--;
 			}
 		}
+		// Here Document folding
+		if (style == SCE_SH_HERE_DELIM) {
+			if (ch == '<' && chNext == '<') {
+				levelCurrent++;
+			}
+		} else if (style == SCE_SH_HERE_Q && styler.StyleAt(i+1) == SCE_PL_DEFAULT) {
+			levelCurrent--;
+		}
 		if (atEOL) {
 			int lev = levelPrev;
 			if (visibleChars == 0 && foldCompact)
diff --git a/plugins/scintilla/scintilla/LexBasic.cxx b/plugins/scintilla/scintilla/LexBasic.cxx
index 1c5d7b4..55641ed 100644
--- a/plugins/scintilla/scintilla/LexBasic.cxx
+++ b/plugins/scintilla/scintilla/LexBasic.cxx
@@ -1,6 +1,7 @@
 // Scintilla source code edit control
 /** @file LexBasic.cxx
  ** Lexer for BlitzBasic and PureBasic.
+ ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
  **/
 // Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
@@ -19,18 +20,28 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
-#include <ctype.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
 
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include <string>
+#include <map>
+
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
@@ -86,8 +97,213 @@ static int LowerCase(int c)
 	return c;
 }
 
-static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
-                           WordList *keywordlists[], Accessor &styler, char comment_char) {
+static int CheckBlitzFoldPoint(char const *token, int &level) {
+	if (!strcmp(token, "function") ||
+		!strcmp(token, "type")) {
+		level |= SC_FOLDLEVELHEADERFLAG;
+		return 1;
+	}
+	if (!strcmp(token, "end function") ||
+		!strcmp(token, "end type")) {
+		return -1;
+	}
+	return 0;
+}
+
+static int CheckPureFoldPoint(char const *token, int &level) {
+	if (!strcmp(token, "procedure") ||
+		!strcmp(token, "enumeration") ||
+		!strcmp(token, "interface") ||
+		!strcmp(token, "structure")) {
+		level |= SC_FOLDLEVELHEADERFLAG;
+		return 1;
+	}
+	if (!strcmp(token, "endprocedure") ||
+		!strcmp(token, "endenumeration") ||
+		!strcmp(token, "endinterface") ||
+		!strcmp(token, "endstructure")) {
+		return -1;
+	}
+	return 0;
+}
+
+static int CheckFreeFoldPoint(char const *token, int &level) {
+	if (!strcmp(token, "function") ||
+		!strcmp(token, "sub") ||
+		!strcmp(token, "type")) {
+		level |= SC_FOLDLEVELHEADERFLAG;
+		return 1;
+	}
+	if (!strcmp(token, "end function") ||
+		!strcmp(token, "end sub") ||
+		!strcmp(token, "end type")) {
+		return -1;
+	}
+	return 0;
+}
+
+// An individual named option for use in an OptionSet
+
+// Options used for LexerBasic
+struct OptionsBasic {
+	bool fold;
+	bool foldSyntaxBased;
+	bool foldCommentExplicit;
+	std::string foldExplicitStart;
+	std::string foldExplicitEnd;
+	bool foldExplicitAnywhere;
+	bool foldCompact;
+	OptionsBasic() {
+		fold = false;
+		foldSyntaxBased = true;
+		foldCommentExplicit = false;
+		foldExplicitStart = "";
+		foldExplicitEnd   = "";
+		foldExplicitAnywhere = false;
+		foldCompact = true;
+	}
+};
+
+static const char * const blitzbasicWordListDesc[] = {
+	"BlitzBasic Keywords",
+	"user1",
+	"user2",
+	"user3",
+	0
+};
+
+static const char * const purebasicWordListDesc[] = {
+	"PureBasic Keywords",
+	"PureBasic PreProcessor Keywords",
+	"user defined 1",
+	"user defined 2",
+	0
+};
+
+static const char * const freebasicWordListDesc[] = {
+	"FreeBasic Keywords",
+	"FreeBasic PreProcessor Keywords",
+	"user defined 1",
+	"user defined 2",
+	0
+};
+
+struct OptionSetBasic : public OptionSet<OptionsBasic> {
+	OptionSetBasic(const char * const wordListDescriptions[]) {
+		DefineProperty("fold", &OptionsBasic::fold);
+
+		DefineProperty("fold.basic.syntax.based", &OptionsBasic::foldSyntaxBased,
+			"Set this property to 0 to disable syntax based folding.");
+
+		DefineProperty("fold.basic.comment.explicit", &OptionsBasic::foldCommentExplicit,
+			"This option enables folding explicit fold points when using the Basic lexer. "
+			"Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start "
+			"and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded.");
+
+		DefineProperty("fold.basic.explicit.start", &OptionsBasic::foldExplicitStart,
+			"The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB).");
+
+		DefineProperty("fold.basic.explicit.end", &OptionsBasic::foldExplicitEnd,
+			"The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB).");
+
+		DefineProperty("fold.basic.explicit.anywhere", &OptionsBasic::foldExplicitAnywhere,
+			"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+		DefineProperty("fold.compact", &OptionsBasic::foldCompact);
+
+		DefineWordListSets(wordListDescriptions);
+	}
+};
+
+class LexerBasic : public ILexer {
+	char comment_char;
+	int (*CheckFoldPoint)(char const *, int &);
+	WordList keywordlists[4];
+	OptionsBasic options;
+	OptionSetBasic osBasic;
+public:
+	LexerBasic(char comment_char_, int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) :
+	           comment_char(comment_char_),
+	           CheckFoldPoint(CheckFoldPoint_),
+	           osBasic(wordListDescriptions) {
+	}
+	~LexerBasic() {
+	}
+	void SCI_METHOD Release() {
+		delete this;
+	}
+	int SCI_METHOD Version() const {
+		return lvOriginal;
+	}
+	const char * SCI_METHOD PropertyNames() {
+		return osBasic.PropertyNames();
+	}
+	int SCI_METHOD PropertyType(const char *name) {
+		return osBasic.PropertyType(name);
+	}
+	const char * SCI_METHOD DescribeProperty(const char *name) {
+		return osBasic.DescribeProperty(name);
+	}
+	int SCI_METHOD PropertySet(const char *key, const char *val);
+	const char * SCI_METHOD DescribeWordListSets() {
+		return osBasic.DescribeWordListSets();
+	}
+	int SCI_METHOD WordListSet(int n, const char *wl);
+	void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+	void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+
+	void * SCI_METHOD PrivateCall(int, void *) {
+		return 0;
+	}
+	static ILexer *LexerFactoryBlitzBasic() {
+		return new LexerBasic(';', CheckBlitzFoldPoint, blitzbasicWordListDesc);
+	}
+	static ILexer *LexerFactoryPureBasic() {
+		return new LexerBasic(';', CheckPureFoldPoint, purebasicWordListDesc);
+	}
+	static ILexer *LexerFactoryFreeBasic() {
+		return new LexerBasic('\'', CheckFreeFoldPoint, freebasicWordListDesc );
+	}
+};
+
+int SCI_METHOD LexerBasic::PropertySet(const char *key, const char *val) {
+	if (osBasic.PropertySet(&options, key, val)) {
+		return 0;
+	}
+	return -1;
+}
+
+int SCI_METHOD LexerBasic::WordListSet(int n, const char *wl) {
+	WordList *wordListN = 0;
+	switch (n) {
+	case 0:
+		wordListN = &keywordlists[0];
+		break;
+	case 1:
+		wordListN = &keywordlists[1];
+		break;
+	case 2:
+		wordListN = &keywordlists[2];
+		break;
+	case 3:
+		wordListN = &keywordlists[3];
+		break;
+	}
+	int firstModification = -1;
+	if (wordListN) {
+		WordList wlNew;
+		wlNew.Set(wl);
+		if (*wordListN != wlNew) {
+			wordListN->Set(wl);
+			firstModification = 0;
+		}
+	}
+	return firstModification;
+}
+
+void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+	LexAccessor styler(pAccess);
+
 	bool wasfirst = true, isfirst = true; // true if first token in a line
 	styler.StartAt(startPos);
 
@@ -111,7 +327,7 @@ static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
 					};
 					sc.GetCurrentLowered(s, sizeof(s));
 					for (int i = 0; i < 4; i++) {
-						if (keywordlists[i]->InList(s)) {
+						if (keywordlists[i].InList(s)) {
 							sc.ChangeState(kstates[i]);
 						}
 					}
@@ -202,66 +418,30 @@ static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
 	sc.Complete();
 }
 
-static int CheckBlitzFoldPoint(char const *token, int &level) {
-	if (!strcmp(token, "function") ||
-		!strcmp(token, "type")) {
-		level |= SC_FOLDLEVELHEADERFLAG;
-		return 1;
-	}
-	if (!strcmp(token, "end function") ||
-		!strcmp(token, "end type")) {
-		return -1;
-	}
-	return 0;
-}
 
-static int CheckPureFoldPoint(char const *token, int &level) {
-	if (!strcmp(token, "procedure") ||
-		!strcmp(token, "enumeration") ||
-		!strcmp(token, "interface") ||
-		!strcmp(token, "structure")) {
-		level |= SC_FOLDLEVELHEADERFLAG;
-		return 1;
-	}
-	if (!strcmp(token, "endprocedure") ||
-		!strcmp(token, "endenumeration") ||
-		!strcmp(token, "endinterface") ||
-		!strcmp(token, "endstructure")) {
-		return -1;
-	}
-	return 0;
-}
+void SCI_METHOD LexerBasic::Fold(unsigned int startPos, int length, int /* initStyle */, IDocument *pAccess) {
 
-static int CheckFreeFoldPoint(char const *token, int &level) {
-	if (!strcmp(token, "function") ||
-		!strcmp(token, "sub") ||
-		!strcmp(token, "type")) {
-		level |= SC_FOLDLEVELHEADERFLAG;
-		return 1;
-	}
-	if (!strcmp(token, "end function") ||
-		!strcmp(token, "end sub") ||
-		!strcmp(token, "end type")) {
-		return -1;
-	}
-	return 0;
-}
+	if (!options.fold)
+		return;
+
+	LexAccessor styler(pAccess);
 
-static void FoldBasicDoc(unsigned int startPos, int length,
-	Accessor &styler, int (*CheckFoldPoint)(char const *, int &)) {
 	int line = styler.GetLine(startPos);
 	int level = styler.LevelAt(line);
 	int go = 0, done = 0;
 	int endPos = startPos + length;
 	char word[256];
 	int wordlen = 0;
-	int i;
-        bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+	const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
+	int cNext = styler[startPos];
+
 	// Scan for tokens at the start of the line (they may include
 	// whitespace, for tokens like "End Function"
-	for (i = startPos; i < endPos; i++) {
-		int c = styler.SafeGetCharAt(i);
-		if (!done && !go) {
+	for (int i = startPos; i < endPos; i++) {
+		int c = cNext;
+		cNext = styler.SafeGetCharAt(i + 1);
+		bool atEOL = (c == '\r' && cNext != '\n') || (c == '\n');
+		if (options.foldSyntaxBased && !done && !go) {
 			if (wordlen) { // are we scanning a token already?
 				word[wordlen] = static_cast<char>(LowerCase(c));
 				if (!IsIdentifier(c)) { // done with token
@@ -291,8 +471,27 @@ static void FoldBasicDoc(unsigned int startPos, int length,
 				}
 			}
 		}
-		if (c == '\n') { // line end
-			if (!done && wordlen == 0 && foldCompact) // line was only space
+		if (options.foldCommentExplicit && ((styler.StyleAt(i) == SCE_B_COMMENT) || options.foldExplicitAnywhere)) {
+			if (userDefinedFoldMarkers) {
+				if (styler.Match(i, options.foldExplicitStart.c_str())) {
+ 					level |= SC_FOLDLEVELHEADERFLAG;
+					go = 1;
+				} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
+ 					go = -1;
+ 				}
+			} else {
+				if (c == comment_char) {
+					if (cNext == '{') {
+						level |= SC_FOLDLEVELHEADERFLAG;
+						go = 1;
+					} else if (cNext == '}') {
+						go = -1;
+					}
+				}
+ 			}
+ 		}
+		if (atEOL) { // line end
+			if (!done && wordlen == 0 && options.foldCompact) // line was only space
 				level |= SC_FOLDLEVELWHITEFLAG;
 			if (level != styler.LevelAt(line))
 				styler.SetLevel(line, level);
@@ -308,66 +507,8 @@ static void FoldBasicDoc(unsigned int startPos, int length,
 	}
 }
 
-static void ColouriseBlitzBasicDoc(unsigned int startPos, int length, int initStyle,
-                           WordList *keywordlists[], Accessor &styler) {
-	ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
-}
-
-static void ColourisePureBasicDoc(unsigned int startPos, int length, int initStyle,
-                           WordList *keywordlists[], Accessor &styler) {
-	ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
-}
-
-static void ColouriseFreeBasicDoc(unsigned int startPos, int length, int initStyle,
-                           WordList *keywordlists[], Accessor &styler) {
-	ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, '\'');
-}
-
-static void FoldBlitzBasicDoc(unsigned int startPos, int length, int,
-	WordList *[], Accessor &styler) {
-	FoldBasicDoc(startPos, length, styler, CheckBlitzFoldPoint);
-}
-
-static void FoldPureBasicDoc(unsigned int startPos, int length, int,
-	WordList *[], Accessor &styler) {
-	FoldBasicDoc(startPos, length, styler, CheckPureFoldPoint);
-}
-
-static void FoldFreeBasicDoc(unsigned int startPos, int length, int,
-	WordList *[], Accessor &styler) {
-	FoldBasicDoc(startPos, length, styler, CheckFreeFoldPoint);
-}
-
-static const char * const blitzbasicWordListDesc[] = {
-	"BlitzBasic Keywords",
-	"user1",
-	"user2",
-	"user3",
-	0
-};
-
-static const char * const purebasicWordListDesc[] = {
-	"PureBasic Keywords",
-	"PureBasic PreProcessor Keywords",
-	"user defined 1",
-	"user defined 2",
-	0
-};
-
-static const char * const freebasicWordListDesc[] = {
-	"FreeBasic Keywords",
-	"FreeBasic PreProcessor Keywords",
-	"user defined 1",
-	"user defined 2",
-	0
-};
-
-LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, ColouriseBlitzBasicDoc, "blitzbasic",
-	FoldBlitzBasicDoc, blitzbasicWordListDesc);
-
-LexerModule lmPureBasic(SCLEX_PUREBASIC, ColourisePureBasicDoc, "purebasic",
-	FoldPureBasicDoc, purebasicWordListDesc);
+LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, LexerBasic::LexerFactoryBlitzBasic, "blitzbasic", blitzbasicWordListDesc);
 
-LexerModule lmFreeBasic(SCLEX_FREEBASIC, ColouriseFreeBasicDoc, "freebasic",
-	FoldFreeBasicDoc, freebasicWordListDesc);
+LexerModule lmPureBasic(SCLEX_PUREBASIC, LexerBasic::LexerFactoryPureBasic, "purebasic", purebasicWordListDesc);
 
+LexerModule lmFreeBasic(SCLEX_FREEBASIC, LexerBasic::LexerFactoryFreeBasic, "freebasic", freebasicWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexBullant.cxx b/plugins/scintilla/scintilla/LexBullant.cxx
index cc60cd2..bb5c9c4 100644
--- a/plugins/scintilla/scintilla/LexBullant.cxx
+++ b/plugins/scintilla/scintilla/LexBullant.cxx
@@ -3,24 +3,29 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
 static int classifyWordBullant(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
 	char s[100];
+	s[0] = '\0';
 	for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
 		s[i] = static_cast<char>(tolower(styler[start + i]));
 		s[i + 1] = '\0';
@@ -111,7 +116,7 @@ static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle
 			}
 			blockChange=0;
 */		}
-		if (!isspace(ch))
+		if (!(isascii(ch) && isspace(ch)))
 			visibleChars++;
 
 		if (styler.IsLeadByte(ch)) {
diff --git a/plugins/scintilla/scintilla/LexCLW.cxx b/plugins/scintilla/scintilla/LexCLW.cxx
index 624ef0f..c1dea60 100644
--- a/plugins/scintilla/scintilla/LexCLW.cxx
+++ b/plugins/scintilla/scintilla/LexCLW.cxx
@@ -10,16 +10,19 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
 #include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -60,10 +63,10 @@ inline bool IsALabelStart(const int iChar) {
 // Is a label character
 inline bool IsALabelCharacter(const int iChar) {
 
-	return(isalnum(iChar) || iChar == '_' || iChar == ':'); 
+	return(isalnum(iChar) || iChar == '_' || iChar == ':');
 }
 
-// Is the character is a ! and the the next character is not a ! 
+// Is the character is a ! and the the next character is not a !
 inline bool IsACommentStart(const int iChar) {
 
 	return(iChar == '!');
@@ -126,7 +129,7 @@ inline bool SetNumericConstantState(StyleContext &scDoc) {
 				break;
 			default :
 				break;
-		}	
+		}
 	}
 	// If points found (can be more than one for improper formatted number
 	if (iPoints > 0) {
@@ -186,12 +189,12 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
 	WordList &wlLabelReservedWords = *wlKeywords[7];		// Clarion Reserved Keywords (Labels)
 	WordList &wlProcLabelReservedWords = *wlKeywords[8];	// Clarion Reserved Keywords (Procedure Labels)
 
-	const char wlProcReservedKeywordList[] = 
+	const char wlProcReservedKeywordList[] =
 	"PROCEDURE FUNCTION";
 	WordList wlProcReservedKeywords;
 	wlProcReservedKeywords.Set(wlProcReservedKeywordList);
 
-	const char wlCompilerKeywordList[] = 
+	const char wlCompilerKeywordList[] =
 	"COMPILE OMIT";
 	WordList wlCompilerKeywords;
 	wlCompilerKeywords.Set(wlCompilerKeywordList);
@@ -243,7 +246,7 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
 						// change the label to error state
 						scDoc.ChangeState(SCE_CLW_ERROR);
 					}
-					// Else if UPPERCASE label string is 
+					// Else if UPPERCASE label string is
 					else if (wlProcLabelReservedWords.InList(cLabel) && iColumn1Label) {
 						char cWord[512];	// Word buffer
 						// Get the next word from the current position
@@ -368,13 +371,13 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
 				// Increment the parenthese level
 				iParenthesesLevel++;
 			}
-			// Else if the character is a ) (close parenthese) 
+			// Else if the character is a ) (close parenthese)
 			else if (scDoc.ch == ')') {
 				// If the parenthese level is set to zero
 				// parentheses matched
 				if (!iParenthesesLevel) {
 					scDoc.SetState(SCE_CLW_DEFAULT);
-				} 
+				}
 				// Else parenthese level is greater than zero
 				// still looking for matching parentheses
 				else {
@@ -399,7 +402,7 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
 			|| IsAHexCharacter(scDoc.ch, bCaseSensitive)
 			|| scDoc.ch == '.'
 			|| IsANumericBaseCharacter(scDoc.ch, bCaseSensitive))) {
-				// If the number was a real 
+				// If the number was a real
 				if (SetNumericConstantState(scDoc)) {
 					// Colour the matched string to the real constant state
 					scDoc.ChangeState(SCE_CLW_REAL_CONSTANT);
@@ -461,7 +464,7 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
 		}
 		// Default Handling
 		else {
-			// If in default state 
+			// If in default state
 			if (scDoc.state == SCE_CLW_DEFAULT) {
 				// If is a letter could be a possible statement
 				if (isalpha(scDoc.ch)) {
@@ -477,10 +480,10 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
 				else if (IsACommentStart(scDoc.ch) || scDoc.ch == '|') {
 					// then set the state to comment.
 					scDoc.SetState(SCE_CLW_COMMENT);
-				}		
+				}
 				// else if the character is a ' (single quote)
 				else if (scDoc.ch == '\'') {
-					// If the character is also a ' (single quote) 
+					// If the character is also a ' (single quote)
 					// Embedded Apostrophe
 					if (scDoc.chNext == '\'') {
 						// Move forward colouring it as default state
@@ -490,7 +493,7 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
 						// move to the next character and then set the state to comment.
 						scDoc.ForwardSetState(SCE_CLW_STRING);
 					}
-				}		
+				}
 				// else the character is an @ (ampersand)
 				else if (scDoc.ch == '@') {
 					// Case insensitive.
@@ -509,7 +512,7 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
 							scDoc.SetState(SCE_CLW_PICTURE_STRING);
 						}
 					}
-				}		
+				}
 			}
 		}
 	}
@@ -616,7 +619,7 @@ static void FoldClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle,
 		iStyle = iStyleNext;
 		iStyleNext = accStyler.StyleAt(uiPos + 1);
 		bool bEOL = (chChar == '\r' && chNext != '\n') || (chChar == '\n');
-	
+
 		if (iStylePrev == SCE_CLW_DEFAULT) {
 			if (iStyle == SCE_CLW_KEYWORD || iStyle == SCE_CLW_STRUCTURE_DATA_TYPE) {
 				// Store last word start point.
@@ -647,7 +650,7 @@ static void FoldClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle,
 			iLevelPrev = iLevelCurrent;
 			iVisibleChars = 0;
 		}
-		
+
 		if (!isspacechar(chChar))
 			iVisibleChars++;
 	}
diff --git a/plugins/scintilla/scintilla/LexCOBOL.cxx b/plugins/scintilla/scintilla/LexCOBOL.cxx
index d061d5c..a9a8f55 100644
--- a/plugins/scintilla/scintilla/LexCOBOL.cxx
+++ b/plugins/scintilla/scintilla/LexCOBOL.cxx
@@ -10,18 +10,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
 #include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -90,11 +93,11 @@ static int classifyWordCOBOL(unsigned int start, unsigned int end, /*WordList &k
     getRange(start, end, styler, s, sizeof(s));
 
     char chAttr = SCE_C_IDENTIFIER;
-    if (isdigit(s[0]) || (s[0] == '.')) {
+    if (isdigit(s[0]) || (s[0] == '.') || (s[0] == 'v')) {
         chAttr = SCE_C_NUMBER;
 		char *p = s + 1;
 		while (*p) {
-			if (!isdigit(*p) && isCOBOLwordchar(*p)) {
+			if ((!isdigit(*p) && (*p) != 'v') && isCOBOLwordchar(*p)) {
 				chAttr = SCE_C_IDENTIFIER;
 			    break;
 			}
@@ -202,7 +205,7 @@ static void ColouriseCOBOLDoc(unsigned int startPos, int length, int initStyle,
         }
 
         if (state == SCE_C_DEFAULT) {
-            if (isCOBOLwordstart(ch) || (ch == '$' && isalpha(chNext))) {
+            if (isCOBOLwordstart(ch) || (ch == '$' && isascii(chNext) && isalpha(chNext))) {
                 ColourTo(styler, i-1, state);
                 state = SCE_C_IDENTIFIER;
             } else if (column == 0 && ch == '*' && chNext != '*') {
diff --git a/plugins/scintilla/scintilla/LexCPP.cxx b/plugins/scintilla/scintilla/LexCPP.cxx
index 9577afb..22477c3 100644
--- a/plugins/scintilla/scintilla/LexCPP.cxx
+++ b/plugins/scintilla/scintilla/LexCPP.cxx
@@ -1,6 +1,7 @@
 // Scintilla source code edit control
 /** @file LexCPP.cxx
  ** Lexer for C++, C, Java, and JavaScript.
+ ** Further folding features and configuration properties added by "Udo Lechner" <dlchnr(at)gmx(dot)net>
  **/
 // Copyright 1998-2005 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
@@ -10,16 +11,29 @@
 #include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
 
-#include "Platform.h"
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
 
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include <string>
+#include <vector>
+#include <map>
+#include <algorithm>
+
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
 #include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
+#include "SparseState.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -39,7 +53,7 @@ static bool IsSpaceEquiv(int state) {
 // a = b+++/ptn/...
 // Putting a space between the '++' post-inc operator and the '+' binary op
 // fixes this, and is highly recommended for readability anyway.
-static bool FollowsPostfixOperator(StyleContext &sc, Accessor &styler) {
+static bool FollowsPostfixOperator(StyleContext &sc, LexAccessor &styler) {
 	int pos = (int) sc.currentPos;
 	while (--pos > 0) {
 		char ch = styler[pos];
@@ -50,18 +64,384 @@ static bool FollowsPostfixOperator(StyleContext &sc, Accessor &styler) {
 	return false;
 }
 
-static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                            Accessor &styler, bool caseSensitive) {
+static bool followsReturnKeyword(StyleContext &sc, LexAccessor &styler) {
+	// Don't look at styles, so no need to flush.
+	int pos = (int) sc.currentPos;
+	int currentLine = styler.GetLine(pos);
+	int lineStartPos = styler.LineStart(currentLine);
+	char ch;
+	while (--pos > lineStartPos) {
+		ch = styler.SafeGetCharAt(pos);
+		if (ch != ' ' && ch != '\t') {
+			break;
+		}
+	}
+	const char *retBack = "nruter";
+	const char *s = retBack;
+	while (*s
+		&& pos >= lineStartPos
+		&& styler.SafeGetCharAt(pos) == *s) {
+		s++;
+		pos--;
+	}
+	return !*s;
+}
+
+static std::string GetRestOfLine(LexAccessor &styler, int start, bool allowSpace) {
+	std::string restOfLine;
+	int i =0;
+	char ch = styler.SafeGetCharAt(start + i, '\n');
+	while ((ch != '\r') && (ch != '\n')) {
+		if (allowSpace || (ch != ' '))
+			restOfLine += ch;
+		i++;
+		ch = styler.SafeGetCharAt(start + i, '\n');
+	}
+	return restOfLine;
+}
+
+static bool IsStreamCommentStyle(int style) {
+	return style == SCE_C_COMMENT ||
+		style == SCE_C_COMMENTDOC ||
+		style == SCE_C_COMMENTDOCKEYWORD ||
+		style == SCE_C_COMMENTDOCKEYWORDERROR;
+}
+
+static std::vector<std::string> Tokenize(const std::string &s) {
+	// Break into space separated tokens
+	std::string word;
+	std::vector<std::string> tokens;
+	for (const char *cp = s.c_str(); *cp; cp++) {
+		if ((*cp == ' ') || (*cp == '\t')) {
+			if (!word.empty()) {
+				tokens.push_back(word);
+				word = "";
+			}
+		} else {
+			word += *cp;
+		}
+	}
+	if (!word.empty()) {
+		tokens.push_back(word);
+	}
+	return tokens;
+}
+
+struct PPDefinition {
+	int line;
+	std::string key;
+	std::string value;
+	PPDefinition(int line_, const std::string &key_, const std::string &value_) :
+		line(line_), key(key_), value(value_) {
+	}
+};
 
-	WordList &keywords = *keywordlists[0];
-	WordList &keywords2 = *keywordlists[1];
-	WordList &keywords3 = *keywordlists[2];
-	WordList &keywords4 = *keywordlists[3];
+class LinePPState {
+	int state;
+	int ifTaken;
+	int level;
+	bool ValidLevel() const {
+		return level >= 0 && level < 32;
+	}
+	int maskLevel() const {
+		return 1 << level;
+	}
+public:
+	LinePPState() : state(0), ifTaken(0), level(-1) {
+	}
+	bool IsInactive() const {
+		return state != 0;
+	}
+	bool CurrentIfTaken() {
+		return (ifTaken & maskLevel()) != 0;
+	}
+	void StartSection(bool on) {
+		level++;
+		if (ValidLevel()) {
+			if (on) {
+				state &= ~maskLevel();
+				ifTaken |= maskLevel();
+			} else {
+				state |= maskLevel();
+				ifTaken &= ~maskLevel();
+			}
+		}
+	}
+	void EndSection() {
+		if (ValidLevel()) {
+			state &= ~maskLevel();
+			ifTaken &= ~maskLevel();
+		}
+		level--;
+	}
+	void InvertCurrentLevel() {
+		if (ValidLevel()) {
+			state ^= maskLevel();
+			ifTaken |= maskLevel();
+		}
+	}
+};
+
+// Hold the preprocessor state for each line seen.
+// Currently one entry per line but could become sparse with just one entry per preprocessor line.
+class PPStates {
+	std::vector<LinePPState> vlls;
+public:
+	LinePPState ForLine(int line) {
+		if ((line > 0) && (vlls.size() > static_cast<size_t>(line))) {
+			return vlls[line];
+		} else {
+			return LinePPState();
+		}
+	}
+	void Add(int line, LinePPState lls) {
+		vlls.resize(line+1);
+		vlls[line] = lls;
+	}
+};
 
-	// 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;
+// An individual named option for use in an OptionSet
+
+// Options used for LexerCPP
+struct OptionsCPP {
+	bool stylingWithinPreprocessor;
+	bool identifiersAllowDollars;
+	bool trackPreprocessor;
+	bool updatePreprocessor;
+	bool triplequotedStrings;
+	bool fold;
+	bool foldSyntaxBased;
+	bool foldComment;
+	bool foldCommentMultiline;
+	bool foldCommentExplicit;
+	std::string foldExplicitStart;
+	std::string foldExplicitEnd;
+	bool foldExplicitAnywhere;
+	bool foldPreprocessor;
+	bool foldCompact;
+	bool foldAtElse;
+	OptionsCPP() {
+		stylingWithinPreprocessor = false;
+		identifiersAllowDollars = true;
+		trackPreprocessor = true;
+		updatePreprocessor = true;
+		triplequotedStrings = false;
+		fold = false;
+		foldSyntaxBased = true;
+		foldComment = false;
+		foldCommentMultiline = true;
+		foldCommentExplicit = true;
+		foldExplicitStart = "";
+		foldExplicitEnd = "";
+		foldExplicitAnywhere = false;
+		foldPreprocessor = false;
+		foldCompact = false;
+		foldAtElse = false;
+	}
+};
+
+static const char *const cppWordLists[] = {
+            "Primary keywords and identifiers",
+            "Secondary keywords and identifiers",
+            "Documentation comment keywords",
+            "Global classes and typedefs",
+            "Preprocessor definitions",
+            0,
+};
+
+struct OptionSetCPP : public OptionSet<OptionsCPP> {
+	OptionSetCPP() {
+		DefineProperty("styling.within.preprocessor", &OptionsCPP::stylingWithinPreprocessor,
+			"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).");
+
+		DefineProperty("lexer.cpp.allow.dollars", &OptionsCPP::identifiersAllowDollars,
+			"Set to 0 to disallow the '$' character in identifiers with the cpp lexer.");
+
+		DefineProperty("lexer.cpp.track.preprocessor", &OptionsCPP::trackPreprocessor,
+			"Set to 1 to interpret #if/#else/#endif to grey out code that is not active.");
+
+		DefineProperty("lexer.cpp.update.preprocessor", &OptionsCPP::updatePreprocessor,
+			"Set to 1 to update preprocessor definitions when #define found.");
+
+		DefineProperty("lexer.cpp.triplequoted.strings", &OptionsCPP::triplequotedStrings,
+			"Set to 1 to enable highlighting of triple-quoted strings.");
+
+		DefineProperty("fold", &OptionsCPP::fold);
+
+		DefineProperty("fold.cpp.syntax.based", &OptionsCPP::foldSyntaxBased,
+			"Set this property to 0 to disable syntax based folding.");
+
+		DefineProperty("fold.comment", &OptionsCPP::foldComment,
+			"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.");
+
+		DefineProperty("fold.cpp.comment.multiline", &OptionsCPP::foldCommentMultiline,
+			"Set this property to 0 to disable folding multi-line comments when fold.comment=1.");
+
+		DefineProperty("fold.cpp.comment.explicit", &OptionsCPP::foldCommentExplicit,
+			"Set this property to 0 to disable folding explicit fold points when fold.comment=1.");
+
+		DefineProperty("fold.cpp.explicit.start", &OptionsCPP::foldExplicitStart,
+			"The string to use for explicit fold start points, replacing the standard //{.");
+
+		DefineProperty("fold.cpp.explicit.end", &OptionsCPP::foldExplicitEnd,
+			"The string to use for explicit fold end points, replacing the standard //}.");
+
+		DefineProperty("fold.cpp.explicit.anywhere", &OptionsCPP::foldExplicitAnywhere,
+			"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+		DefineProperty("fold.preprocessor", &OptionsCPP::foldPreprocessor,
+			"This option enables folding preprocessor directives when using the C++ lexer. "
+			"Includes C#'s explicit #region and #endregion folding directives.");
+
+		DefineProperty("fold.compact", &OptionsCPP::foldCompact);
+
+		DefineProperty("fold.at.else", &OptionsCPP::foldAtElse,
+			"This option enables C++ folding on a \"} else {\" line of an if statement.");
+
+		DefineWordListSets(cppWordLists);
+	}
+};
+
+class LexerCPP : public ILexer {
+	bool caseSensitive;
+	CharacterSet setWord;
+	CharacterSet setNegationOp;
+	CharacterSet setArithmethicOp;
+	CharacterSet setRelOp;
+	CharacterSet setLogicalOp;
+	PPStates vlls;
+	std::vector<PPDefinition> ppDefineHistory;
+	WordList keywords;
+	WordList keywords2;
+	WordList keywords3;
+	WordList keywords4;
+	WordList ppDefinitions;
+	std::map<std::string, std::string> preprocessorDefinitionsStart;
+	OptionsCPP options;
+	OptionSetCPP osCPP;
+	SparseState<std::string> rawStringTerminators;
+	enum { activeFlag = 0x40 };
+public:
+	LexerCPP(bool caseSensitive_) :
+		caseSensitive(caseSensitive_),
+		setWord(CharacterSet::setAlphaNum, "._", 0x80, true),
+		setNegationOp(CharacterSet::setNone, "!"),
+		setArithmethicOp(CharacterSet::setNone, "+-/*%"),
+		setRelOp(CharacterSet::setNone, "=!<>"),
+		setLogicalOp(CharacterSet::setNone, "|&") {
+	}
+	~LexerCPP() {
+	}
+	void SCI_METHOD Release() {
+		delete this;
+	}
+	int SCI_METHOD Version() const {
+		return lvOriginal;
+	}
+	const char * SCI_METHOD PropertyNames() {
+		return osCPP.PropertyNames();
+	}
+	int SCI_METHOD PropertyType(const char *name) {
+		return osCPP.PropertyType(name);
+	}
+	const char * SCI_METHOD DescribeProperty(const char *name) {
+		return osCPP.DescribeProperty(name);
+	}
+	int SCI_METHOD PropertySet(const char *key, const char *val);
+	const char * SCI_METHOD DescribeWordListSets() {
+		return osCPP.DescribeWordListSets();
+	}
+	int SCI_METHOD WordListSet(int n, const char *wl);
+	void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+	void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+
+	void * SCI_METHOD PrivateCall(int, void *) {
+		return 0;
+	}
+
+	static ILexer *LexerFactoryCPP() {
+		return new LexerCPP(true);
+	}
+	static ILexer *LexerFactoryCPPInsensitive() {
+		return new LexerCPP(false);
+	}
+	static int MaskActive(int style) {
+		return style & ~activeFlag;
+	}
+	void EvaluateTokens(std::vector<std::string> &tokens);
+	bool EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions);
+};
+
+int SCI_METHOD LexerCPP::PropertySet(const char *key, const char *val) {
+	if (osCPP.PropertySet(&options, key, val)) {
+		return 0;
+	}
+	return -1;
+}
+
+int SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
+	WordList *wordListN = 0;
+	switch (n) {
+	case 0:
+		wordListN = &keywords;
+		break;
+	case 1:
+		wordListN = &keywords2;
+		break;
+	case 2:
+		wordListN = &keywords3;
+		break;
+	case 3:
+		wordListN = &keywords4;
+		break;
+	case 4:
+		wordListN = &ppDefinitions;
+		break;
+	}
+	int firstModification = -1;
+	if (wordListN) {
+		WordList wlNew;
+		wlNew.Set(wl);
+		if (*wordListN != wlNew) {
+			wordListN->Set(wl);
+			firstModification = 0;
+			if (n == 4) {
+				// Rebuild preprocessorDefinitions
+				preprocessorDefinitionsStart.clear();
+				for (int nDefinition = 0; nDefinition < ppDefinitions.len; nDefinition++) {
+					char *cpDefinition = ppDefinitions.words[nDefinition];
+					char *cpEquals = strchr(cpDefinition, '=');
+					if (cpEquals) {
+						std::string name(cpDefinition, cpEquals - cpDefinition);
+						std::string val(cpEquals+1);
+						preprocessorDefinitionsStart[name] = val;
+					} else {
+						std::string name(cpDefinition);
+						std::string val("1");
+						preprocessorDefinitionsStart[name] = val;
+					}
+				}
+			}
+		}
+	}
+	return firstModification;
+}
+
+// Functor used to truncate history
+struct After {
+	int line;
+	After(int line_) : line(line_) {}
+	bool operator()(PPDefinition &p) const {
+		return p.line > line;
+	}
+};
+
+void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+	LexAccessor styler(pAccess);
 
 	CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
 	CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-");
@@ -69,11 +449,8 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 	CharacterSet setDoxygen(CharacterSet::setAlpha, "$ \\&<>#{}[]");
 
 	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) {
+	if (options.identifiersAllowDollars) {
 		setWordStart.Add('$');
 		setWord.Add('$');
 	}
@@ -85,9 +462,11 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 	bool continuationLine = false;
 	bool isIncludePreprocessor = false;
 
-	if (initStyle == SCE_C_PREPROCESSOR) {
+	int lineCurrent = styler.GetLine(startPos);
+	if ((initStyle == SCE_C_PREPROCESSOR) ||
+      (initStyle == SCE_C_COMMENTLINE) ||
+      (initStyle == SCE_C_COMMENTLINEDOC)) {
 		// Set continuationLine if last character of previous line is '\'
-		int lineCurrent = styler.GetLine(startPos);
 		if (lineCurrent > 0) {
 			int chBack = styler.SafeGetCharAt(startPos-1, 0);
 			int chBack2 = styler.SafeGetCharAt(startPos-2, 0);
@@ -111,21 +490,64 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 		}
 	}
 
-	StyleContext sc(startPos, length, initStyle, styler);
+	StyleContext sc(startPos, length, initStyle, styler, 0x7f);
+	LinePPState preproc = vlls.ForLine(lineCurrent);
+
+	bool definitionsChanged = false;
+
+	// Truncate ppDefineHistory before current line
+
+	if (!options.updatePreprocessor)
+		ppDefineHistory.clear();
+
+	std::vector<PPDefinition>::iterator itInvalid = std::find_if(ppDefineHistory.begin(), ppDefineHistory.end(), After(lineCurrent-1));
+	if (itInvalid != ppDefineHistory.end()) {
+		ppDefineHistory.erase(itInvalid, ppDefineHistory.end());
+		definitionsChanged = true;
+	}
+
+	std::map<std::string, std::string> preprocessorDefinitions = preprocessorDefinitionsStart;
+	for (std::vector<PPDefinition>::iterator itDef = ppDefineHistory.begin(); itDef != ppDefineHistory.end(); ++itDef) {
+		preprocessorDefinitions[itDef->key] = itDef->value;
+	}
+
+	std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
+	SparseState<std::string> rawSTNew(lineCurrent);
+
+	int activitySet = preproc.IsInactive() ? activeFlag : 0;
 
 	for (; sc.More(); sc.Forward()) {
 
 		if (sc.atLineStart) {
-			if (sc.state == SCE_C_STRING) {
+			if ((sc.state == SCE_C_STRING) || (sc.state == SCE_C_CHARACTER)) {
 				// Prevent SCE_C_STRINGEOL from leaking back to previous line which
 				// ends with a line continuation by locking in the state upto this position.
-				sc.SetState(SCE_C_STRING);
+				sc.SetState(sc.state);
 			}
 			// Reset states to begining of colourise so no surprises
 			// if different sets of lines lexed.
 			visibleChars = 0;
 			lastWordWasUUID = false;
 			isIncludePreprocessor = false;
+			if (preproc.IsInactive()) {
+				activitySet = activeFlag;
+				sc.SetState(sc.state | activitySet);
+			}
+			if (activitySet) {
+				if (sc.ch == '#') {
+					if (sc.Match("#else") || sc.Match("#end") || sc.Match("#if")) {
+						//activitySet = 0;
+					}
+				}
+			}
+		}
+
+		if (sc.atLineEnd) {
+			lineCurrent++;
+			vlls.Add(lineCurrent, preproc);
+			if (rawStringTerminator != "") {
+				rawSTNew.Set(lineCurrent-1, rawStringTerminator);
+			}
 		}
 
 		// Handle line continuation generically.
@@ -140,15 +562,17 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 			}
 		}
 
+		const bool atLineEndBeforeSwitch = sc.atLineEnd;
+
 		// Determine if the current state should terminate.
-		switch (sc.state) {
+		switch (MaskActive(sc.state)) {
 			case SCE_C_OPERATOR:
-				sc.SetState(SCE_C_DEFAULT);
+				sc.SetState(SCE_C_DEFAULT|activitySet);
 				break;
 			case SCE_C_NUMBER:
 				// We accept almost anything because of hex. and number suffixes
-				if (!setWord.Contains(sc.ch)) {
-					sc.SetState(SCE_C_DEFAULT);
+				if (!(setWord.Contains(sc.ch) || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
+					sc.SetState(SCE_C_DEFAULT|activitySet);
 				}
 				break;
 			case SCE_C_IDENTIFIER:
@@ -161,59 +585,76 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 					}
 					if (keywords.InList(s)) {
 						lastWordWasUUID = strcmp(s, "uuid") == 0;
-						sc.ChangeState(SCE_C_WORD);
+						sc.ChangeState(SCE_C_WORD|activitySet);
 					} else if (keywords2.InList(s)) {
-						sc.ChangeState(SCE_C_WORD2);
+						sc.ChangeState(SCE_C_WORD2|activitySet);
 					} else if (keywords4.InList(s)) {
-						sc.ChangeState(SCE_C_GLOBALCLASS);
+						sc.ChangeState(SCE_C_GLOBALCLASS|activitySet);
+					}
+					const bool literalString = sc.ch == '\"';
+					if (literalString || sc.ch == '\'') {
+						size_t lenS = strlen(s);
+						const bool raw = literalString && sc.chPrev == 'R';
+						if (raw)
+							s[lenS--] = '\0';
+						bool valid =
+							(lenS == 0) ||
+							((lenS == 1) && ((s[0] == 'L') || (s[0] == 'u') || (s[0] == 'U'))) ||
+							((lenS == 2) && literalString && (s[0] == 'u') && (s[1] == '8'));
+						if (valid) {
+							if (literalString)
+								sc.ChangeState((raw ? SCE_C_STRINGRAW : SCE_C_STRING)|activitySet);
+							else
+								sc.ChangeState(SCE_C_CHARACTER|activitySet);
+						}
 					}
-					sc.SetState(SCE_C_DEFAULT);
+					sc.SetState(SCE_C_DEFAULT|activitySet);
 				}
 				break;
 			case SCE_C_PREPROCESSOR:
 				if (sc.atLineStart && !continuationLine) {
-					sc.SetState(SCE_C_DEFAULT);
-				} else if (stylingWithinPreprocessor) {
+					sc.SetState(SCE_C_DEFAULT|activitySet);
+				} else if (options.stylingWithinPreprocessor) {
 					if (IsASpace(sc.ch)) {
-						sc.SetState(SCE_C_DEFAULT);
+						sc.SetState(SCE_C_DEFAULT|activitySet);
 					}
 				} else {
 					if (sc.Match('/', '*') || sc.Match('/', '/')) {
-						sc.SetState(SCE_C_DEFAULT);
+						sc.SetState(SCE_C_DEFAULT|activitySet);
 					}
 				}
 				break;
 			case SCE_C_COMMENT:
 				if (sc.Match('*', '/')) {
 					sc.Forward();
-					sc.ForwardSetState(SCE_C_DEFAULT);
+					sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
 				}
 				break;
 			case SCE_C_COMMENTDOC:
 				if (sc.Match('*', '/')) {
 					sc.Forward();
-					sc.ForwardSetState(SCE_C_DEFAULT);
+					sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
 				} 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_C_COMMENTDOC;
-						sc.SetState(SCE_C_COMMENTDOCKEYWORD);
+						sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet);
 					}
 				}
 				break;
 			case SCE_C_COMMENTLINE:
-				if (sc.atLineStart) {
-					sc.SetState(SCE_C_DEFAULT);
+				if (sc.atLineStart && !continuationLine) {
+					sc.SetState(SCE_C_DEFAULT|activitySet);
 				}
 				break;
 			case SCE_C_COMMENTLINEDOC:
-				if (sc.atLineStart) {
-					sc.SetState(SCE_C_DEFAULT);
+				if (sc.atLineStart && !continuationLine) {
+					sc.SetState(SCE_C_DEFAULT|activitySet);
 				} 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_C_COMMENTLINEDOC;
-						sc.SetState(SCE_C_COMMENTDOCKEYWORD);
+						sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet);
 					}
 				}
 				break;
@@ -221,7 +662,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 				if ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) {
 					sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
 					sc.Forward();
-					sc.ForwardSetState(SCE_C_DEFAULT);
+					sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
 				} else if (!setDoxygen.Contains(sc.ch)) {
 					char s[100];
 					if (caseSensitive) {
@@ -230,17 +671,17 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 						sc.GetCurrentLowered(s, sizeof(s));
 					}
 					if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
-						sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
+						sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet);
 					}
 					sc.SetState(styleBeforeDCKeyword);
 				}
 				break;
 			case SCE_C_STRING:
 				if (sc.atLineEnd) {
-					sc.ChangeState(SCE_C_STRINGEOL);
+					sc.ChangeState(SCE_C_STRINGEOL|activitySet);
 				} else if (isIncludePreprocessor) {
 					if (sc.ch == '>') {
-						sc.ForwardSetState(SCE_C_DEFAULT);
+						sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
 						isIncludePreprocessor = false;
 					}
 				} else if (sc.ch == '\\') {
@@ -248,28 +689,36 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 						sc.Forward();
 					}
 				} else if (sc.ch == '\"') {
-					sc.ForwardSetState(SCE_C_DEFAULT);
+					sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
+				}
+				break;
+			case SCE_C_STRINGRAW:
+				if (sc.Match(rawStringTerminator.c_str())) {
+					for (size_t termPos=rawStringTerminator.size(); termPos; termPos--)
+						sc.Forward();
+					sc.SetState(SCE_C_DEFAULT|activitySet);
+					rawStringTerminator = "";
 				}
 				break;
 			case SCE_C_CHARACTER:
 				if (sc.atLineEnd) {
-					sc.ChangeState(SCE_C_STRINGEOL);
+					sc.ChangeState(SCE_C_STRINGEOL|activitySet);
 				} else if (sc.ch == '\\') {
 					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 						sc.Forward();
 					}
 				} else if (sc.ch == '\'') {
-					sc.ForwardSetState(SCE_C_DEFAULT);
+					sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
 				}
 				break;
 			case SCE_C_REGEX:
 				if (sc.atLineStart) {
-					sc.SetState(SCE_C_DEFAULT);
+					sc.SetState(SCE_C_DEFAULT|activitySet);
 				} else if (sc.ch == '/') {
 					sc.Forward();
 					while ((sc.ch < 0x80) && islower(sc.ch))
 						sc.Forward();    // gobble regex flags
-					sc.SetState(SCE_C_DEFAULT);
+					sc.SetState(SCE_C_DEFAULT|activitySet);
 				} else if (sc.ch == '\\') {
 					// Gobble up the quoted character
 					if (sc.chNext == '\\' || sc.chNext == '/') {
@@ -279,7 +728,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 				break;
 			case SCE_C_STRINGEOL:
 				if (sc.atLineStart) {
-					sc.SetState(SCE_C_DEFAULT);
+					sc.SetState(SCE_C_DEFAULT|activitySet);
 				}
 				break;
 			case SCE_C_VERBATIM:
@@ -287,72 +736,170 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 					if (sc.chNext == '\"') {
 						sc.Forward();
 					} else {
-						sc.ForwardSetState(SCE_C_DEFAULT);
+						sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
 					}
 				}
 				break;
+			case SCE_C_TRIPLEVERBATIM:
+				if (sc.Match("\"\"\"")) {
+					while (sc.Match('"')) {
+						sc.Forward();
+					}
+					sc.SetState(SCE_C_DEFAULT|activitySet);
+				}
+				break;
 			case SCE_C_UUID:
 				if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
-					sc.SetState(SCE_C_DEFAULT);
+					sc.SetState(SCE_C_DEFAULT|activitySet);
 				}
 		}
 
+		if (sc.atLineEnd && !atLineEndBeforeSwitch) {
+			// State exit processing consumed characters up to end of line.
+			lineCurrent++;
+			vlls.Add(lineCurrent, preproc);
+		}
+
 		// Determine if a new state should be entered.
-		if (sc.state == SCE_C_DEFAULT) {
+		if (MaskActive(sc.state) == SCE_C_DEFAULT) {
 			if (sc.Match('@', '\"')) {
-				sc.SetState(SCE_C_VERBATIM);
+				sc.SetState(SCE_C_VERBATIM|activitySet);
 				sc.Forward();
+			} else if (options.triplequotedStrings && sc.Match("\"\"\"")) {
+				sc.SetState(SCE_C_TRIPLEVERBATIM|activitySet);
+				sc.Forward(2);
 			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
 				if (lastWordWasUUID) {
-					sc.SetState(SCE_C_UUID);
+					sc.SetState(SCE_C_UUID|activitySet);
 					lastWordWasUUID = false;
 				} else {
-					sc.SetState(SCE_C_NUMBER);
+					sc.SetState(SCE_C_NUMBER|activitySet);
 				}
 			} else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
 				if (lastWordWasUUID) {
-					sc.SetState(SCE_C_UUID);
+					sc.SetState(SCE_C_UUID|activitySet);
 					lastWordWasUUID = false;
 				} else {
-					sc.SetState(SCE_C_IDENTIFIER);
+					sc.SetState(SCE_C_IDENTIFIER|activitySet);
 				}
 			} else if (sc.Match('/', '*')) {
 				if (sc.Match("/**") || sc.Match("/*!")) {	// Support of Qt/Doxygen doc. style
-					sc.SetState(SCE_C_COMMENTDOC);
+					sc.SetState(SCE_C_COMMENTDOC|activitySet);
 				} else {
-					sc.SetState(SCE_C_COMMENT);
+					sc.SetState(SCE_C_COMMENT|activitySet);
 				}
 				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_C_COMMENTLINEDOC);
+					sc.SetState(SCE_C_COMMENTLINEDOC|activitySet);
 				else
-					sc.SetState(SCE_C_COMMENTLINE);
-			} else if (sc.ch == '/' && setOKBeforeRE.Contains(chPrevNonWhite) &&
-				(!setCouldBePostOp.Contains(chPrevNonWhite) || !FollowsPostfixOperator(sc, styler))) {
-				sc.SetState(SCE_C_REGEX);	// JavaScript's RegEx
+					sc.SetState(SCE_C_COMMENTLINE|activitySet);
+			} else if (sc.ch == '/'
+				   && (setOKBeforeRE.Contains(chPrevNonWhite)
+				       || followsReturnKeyword(sc, styler))
+				   && (!setCouldBePostOp.Contains(chPrevNonWhite)
+				       || !FollowsPostfixOperator(sc, styler))) {
+				sc.SetState(SCE_C_REGEX|activitySet);	// JavaScript's RegEx
 			} else if (sc.ch == '\"') {
-				sc.SetState(SCE_C_STRING);
+				if (sc.chPrev == 'R') {
+					sc.SetState(SCE_C_STRINGRAW|activitySet);
+					rawStringTerminator = ")";
+					for (int termPos = sc.currentPos + 1;; termPos++) {
+						char chTerminator = styler.SafeGetCharAt(termPos, '(');
+						if (chTerminator == '(')
+							break;
+						rawStringTerminator += chTerminator;
+					}
+					rawStringTerminator += '\"';
+				} else {
+					sc.SetState(SCE_C_STRING|activitySet);
+				}
 				isIncludePreprocessor = false;	// ensure that '>' won't end the string
 			} else if (isIncludePreprocessor && sc.ch == '<') {
-				sc.SetState(SCE_C_STRING);
+				sc.SetState(SCE_C_STRING|activitySet);
 			} else if (sc.ch == '\'') {
-				sc.SetState(SCE_C_CHARACTER);
+				sc.SetState(SCE_C_CHARACTER|activitySet);
 			} else if (sc.ch == '#' && visibleChars == 0) {
 				// Preprocessor commands are alone on their line
-				sc.SetState(SCE_C_PREPROCESSOR);
+				sc.SetState(SCE_C_PREPROCESSOR|activitySet);
 				// Skip whitespace between # and preprocessor word
 				do {
 					sc.Forward();
 				} while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
 				if (sc.atLineEnd) {
-					sc.SetState(SCE_C_DEFAULT);
+					sc.SetState(SCE_C_DEFAULT|activitySet);
 				} else if (sc.Match("include")) {
 					isIncludePreprocessor = true;
+				} else {
+					if (options.trackPreprocessor) {
+						if (sc.Match("ifdef") || sc.Match("ifndef")) {
+							bool isIfDef = sc.Match("ifdef");
+							int i = isIfDef ? 5 : 6;
+							std::string restOfLine = GetRestOfLine(styler, sc.currentPos + i + 1, false);
+							bool foundDef = preprocessorDefinitions.find(restOfLine) != preprocessorDefinitions.end();
+							preproc.StartSection(isIfDef == foundDef);
+						} else if (sc.Match("if")) {
+							std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 2, true);
+							bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
+							preproc.StartSection(ifGood);
+						} else if (sc.Match("else")) {
+							if (!preproc.CurrentIfTaken()) {
+								preproc.InvertCurrentLevel();
+								activitySet = preproc.IsInactive() ? activeFlag : 0;
+								if (!activitySet)
+									sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+							} else if (!preproc.IsInactive()) {
+								preproc.InvertCurrentLevel();
+								activitySet = preproc.IsInactive() ? activeFlag : 0;
+								if (!activitySet)
+									sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+							}
+						} else if (sc.Match("elif")) {
+							// Ensure only one chosen out of #if .. #elif .. #elif .. #else .. #endif
+							if (!preproc.CurrentIfTaken()) {
+								// Similar to #if
+								std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 2, true);
+								bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
+								if (ifGood) {
+									preproc.InvertCurrentLevel();
+									activitySet = preproc.IsInactive() ? activeFlag : 0;
+									if (!activitySet)
+										sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+								}
+							} else if (!preproc.IsInactive()) {
+								preproc.InvertCurrentLevel();
+								activitySet = preproc.IsInactive() ? activeFlag : 0;
+								if (!activitySet)
+									sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+							}
+						} else if (sc.Match("endif")) {
+							preproc.EndSection();
+							activitySet = preproc.IsInactive() ? activeFlag : 0;
+							sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+						} else if (sc.Match("define")) {
+							if (options.updatePreprocessor && !preproc.IsInactive()) {
+								std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 6, true);
+								if (restOfLine.find(")") == std::string::npos) {	// Don't handle macros with arguments
+									std::vector<std::string> tokens = Tokenize(restOfLine);
+									std::string key;
+									std::string value("1");
+									if (tokens.size() >= 1) {
+										key = tokens[0];
+										if (tokens.size() >= 2) {
+											value = tokens[1];
+										}
+										preprocessorDefinitions[key] = value;
+										ppDefineHistory.push_back(PPDefinition(lineCurrent, key, value));
+										definitionsChanged = true;
+									}
+								}
+							}
+						}
+					}
 				}
 			} else if (isoperator(static_cast<char>(sc.ch))) {
-				sc.SetState(SCE_C_OPERATOR);
+				sc.SetState(SCE_C_OPERATOR|activitySet);
 			}
 		}
 
@@ -362,38 +909,22 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
 		}
 		continuationLine = false;
 	}
+	const bool rawStringsChanged = rawStringTerminators.Merge(rawSTNew, lineCurrent);
+	if (definitionsChanged || rawStringsChanged)
+		styler.ChangeLexerState(startPos, startPos + length);
 	sc.Complete();
 }
 
-static bool IsStreamCommentStyle(int style) {
-	return style == SCE_C_COMMENT ||
-		style == SCE_C_COMMENTDOC ||
-		style == SCE_C_COMMENTDOCKEYWORD ||
-		style == SCE_C_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 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;
+void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
 
-	// 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;
+	if (!options.fold)
+		return;
 
-	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;
+	LexAccessor styler(pAccess);
 
 	unsigned int endPos = startPos + length;
 	int visibleChars = 0;
@@ -404,16 +935,17 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
 	int levelMinCurrent = levelCurrent;
 	int levelNext = levelCurrent;
 	char chNext = styler[startPos];
-	int styleNext = styler.StyleAt(startPos);
-	int style = initStyle;
+	int styleNext = MaskActive(styler.StyleAt(startPos));
+	int style = MaskActive(initStyle);
+	const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
 	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);
+		styleNext = MaskActive(styler.StyleAt(i + 1));
 		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-		if (foldComment && IsStreamCommentStyle(style)) {
+		if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
 			if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {
 				levelNext++;
 			} else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_C_COMMENTLINEDOC) && !atEOL) {
@@ -421,17 +953,25 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
 				levelNext--;
 			}
 		}
-		if (foldComment && (style == SCE_C_COMMENTLINE)) {
-			if ((ch == '/') && (chNext == '/')) {
-				char chNext2 = styler.SafeGetCharAt(i + 2);
-				if (chNext2 == '{') {
+		if (options.foldComment && options.foldCommentExplicit && ((style == SCE_C_COMMENTLINE) || options.foldExplicitAnywhere)) {
+			if (userDefinedFoldMarkers) {
+				if (styler.Match(i, options.foldExplicitStart.c_str())) {
 					levelNext++;
-				} else if (chNext2 == '}') {
+				} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
 					levelNext--;
 				}
+			} else {
+				if ((ch == '/') && (chNext == '/')) {
+					char chNext2 = styler.SafeGetCharAt(i + 2);
+					if (chNext2 == '{') {
+						levelNext++;
+					} else if (chNext2 == '}') {
+						levelNext--;
+					}
+				}
 			}
 		}
-		if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
+		if (options.foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
 			if (ch == '#') {
 				unsigned int j = i + 1;
 				while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
@@ -444,7 +984,7 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
 				}
 			}
 		}
-		if (style == SCE_C_OPERATOR) {
+		if (options.foldSyntaxBased && (style == SCE_C_OPERATOR)) {
 			if (ch == '{') {
 				// Measure the minimum before a '{' to allow
 				// folding on "} else {"
@@ -460,11 +1000,11 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
 			visibleChars++;
 		if (atEOL || (i == endPos-1)) {
 			int levelUse = levelCurrent;
-			if (foldAtElse) {
+			if (options.foldSyntaxBased && options.foldAtElse) {
 				levelUse = levelMinCurrent;
 			}
 			int lev = levelUse | levelNext << 16;
-			if (visibleChars == 0 && foldCompact)
+			if (visibleChars == 0 && options.foldCompact)
 				lev |= SC_FOLDLEVELWHITEFLAG;
 			if (levelUse < levelNext)
 				lev |= SC_FOLDLEVELHEADERFLAG;
@@ -483,24 +1023,154 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
 	}
 }
 
-static const char * const cppWordLists[] = {
-            "Primary keywords and identifiers",
-            "Secondary keywords and identifiers",
-            "Documentation comment keywords",
-            "Unused",
-            "Global classes and typedefs",
-            0,
-        };
+void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens) {
 
-static void ColouriseCppDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                                     Accessor &styler) {
-	ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, true);
+	// Evaluate defined() statements to either 0 or 1
+	for (size_t i=0; (i+2)<tokens.size();) {
+		if ((tokens[i] == "defined") && (tokens[i+1] == "(")) {
+			const char *val = "0";
+			if (tokens[i+2] == ")") {
+				// defined()
+				tokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 3);
+			} else if (((i+2)<tokens.size()) && (tokens[i+3] == ")")) {
+				// defined(<int>)
+				tokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 4);
+				val = "1";
+			}
+			tokens[i] = val;
+		} else {
+			i++;
+		}
+	}
+
+	// Find bracketed subexpressions and recurse on them
+	std::vector<std::string>::iterator itBracket = std::find(tokens.begin(), tokens.end(), "(");
+	std::vector<std::string>::iterator itEndBracket = std::find(tokens.begin(), tokens.end(), ")");
+	while ((itBracket != tokens.end()) && (itEndBracket != tokens.end()) && (itEndBracket > itBracket)) {
+		std::vector<std::string> inBracket(itBracket + 1, itEndBracket);
+		EvaluateTokens(inBracket);
+
+		// The insertion is done before the removal because there were failures with the opposite approach
+		tokens.insert(itBracket, inBracket.begin(), inBracket.end());
+		itBracket = std::find(tokens.begin(), tokens.end(), "(");
+		itEndBracket = std::find(tokens.begin(), tokens.end(), ")");
+		tokens.erase(itBracket, itEndBracket + 1);
+
+		itBracket = std::find(tokens.begin(), tokens.end(), "(");
+		itEndBracket = std::find(tokens.begin(), tokens.end(), ")");
+	}
+
+	// Evaluate logical negations
+	for (size_t j=0; (j+1)<tokens.size();) {
+		if (setNegationOp.Contains(tokens[j][0])) {
+			int isTrue = atoi(tokens[j+1].c_str());
+			if (tokens[j] == "!")
+				isTrue = !isTrue;
+			std::vector<std::string>::iterator itInsert =
+				tokens.erase(tokens.begin() + j, tokens.begin() + j + 2);
+			tokens.insert(itInsert, isTrue ? "1" : "0");
+		} else {
+			j++;
+		}
+	}
+
+	// Evaluate expressions in precedence order
+	enum precedence { precArithmetic, precRelative, precLogical };
+	for (int prec=precArithmetic; prec <= precLogical; prec++) {
+		// Looking at 3 tokens at a time so end at 2 before end
+		for (size_t k=0; (k+2)<tokens.size();) {
+			char chOp = tokens[k+1][0];
+			if (
+				((prec==precArithmetic) && setArithmethicOp.Contains(chOp)) ||
+				((prec==precRelative) && setRelOp.Contains(chOp)) ||
+				((prec==precLogical) && setLogicalOp.Contains(chOp))
+				) {
+				int valA = atoi(tokens[k].c_str());
+				int valB = atoi(tokens[k+2].c_str());
+				int result = 0;
+				if (tokens[k+1] == "+")
+					result = valA + valB;
+				else if (tokens[k+1] == "-")
+					result = valA - valB;
+				else if (tokens[k+1] == "*")
+					result = valA * valB;
+				else if (tokens[k+1] == "/")
+					result = valA / (valB ? valB : 1);
+				else if (tokens[k+1] == "%")
+					result = valA % (valB ? valB : 1);
+				else if (tokens[k+1] == "<")
+					result = valA < valB;
+				else if (tokens[k+1] == "<=")
+					result = valA <= valB;
+				else if (tokens[k+1] == ">")
+					result = valA > valB;
+				else if (tokens[k+1] == ">=")
+					result = valA >= valB;
+				else if (tokens[k+1] == "==")
+					result = valA == valB;
+				else if (tokens[k+1] == "!=")
+					result = valA != valB;
+				else if (tokens[k+1] == "||")
+					result = valA || valB;
+				else if (tokens[k+1] == "&&")
+					result = valA && valB;
+				char sResult[30];
+				sprintf(sResult, "%d", result);
+				std::vector<std::string>::iterator itInsert =
+					tokens.erase(tokens.begin() + k, tokens.begin() + k + 3);
+				tokens.insert(itInsert, sResult);
+			} else {
+				k++;
+			}
+		}
+	}
 }
 
-static void ColouriseCppDocInsensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                                       Accessor &styler) {
-	ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, false);
+bool LexerCPP::EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions) {
+	// Break into tokens, replacing with definitions
+	std::string word;
+	std::vector<std::string> tokens;
+	const char *cp = expr.c_str();
+	for (;;) {
+		if (setWord.Contains(*cp)) {
+			word += *cp;
+		} else {
+			std::map<std::string, std::string>::const_iterator it = preprocessorDefinitions.find(word);
+			if (it != preprocessorDefinitions.end()) {
+				tokens.push_back(it->second);
+			} else if (!word.empty() && ((word[0] >= '0' && word[0] <= '9') || (word == "defined"))) {
+				tokens.push_back(word);
+			}
+			word = "";
+			if (!*cp) {
+				break;
+			}
+			if ((*cp != ' ') && (*cp != '\t')) {
+				std::string op(cp, 1);
+				if (setRelOp.Contains(*cp)) {
+					if (setRelOp.Contains(cp[1])) {
+						op += cp[1];
+						cp++;
+					}
+				} else if (setLogicalOp.Contains(*cp)) {
+					if (setLogicalOp.Contains(cp[1])) {
+						op += cp[1];
+						cp++;
+					}
+				}
+				tokens.push_back(op);
+			}
+		}
+		cp++;
+	}
+
+	EvaluateTokens(tokens);
+
+	// "0" or "" -> false else true
+	bool isFalse = tokens.empty() ||
+		((tokens.size() == 1) && ((tokens[0] == "") || tokens[0] == "0"));
+	return !isFalse;
 }
 
-LexerModule lmCPP(SCLEX_CPP, ColouriseCppDocSensitive, "cpp", FoldCppDoc, cppWordLists);
-LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, ColouriseCppDocInsensitive, "cppnocase", FoldCppDoc, cppWordLists);
+LexerModule lmCPP(SCLEX_CPP, LexerCPP::LexerFactoryCPP, "cpp", cppWordLists);
+LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, LexerCPP::LexerFactoryCPPInsensitive, "cppnocase", cppWordLists);
diff --git a/plugins/scintilla/scintilla/LexCSS.cxx b/plugins/scintilla/scintilla/LexCSS.cxx
index 3b139cd..8fbca38 100644
--- a/plugins/scintilla/scintilla/LexCSS.cxx
+++ b/plugins/scintilla/scintilla/LexCSS.cxx
@@ -9,18 +9,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -62,6 +65,7 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
 
 	int lastState = -1; // before operator
 	int lastStateC = -1; // before comment
+	int lastStateS = -1; // before single-quoted/double-quoted string
 	int op = ' '; // last operator
 	int opPrev = ' '; // last operator
 
@@ -105,7 +109,7 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
 				i--;
 			if ((sc.currentPos - i) % 2 == 1)
 				continue;
-			sc.ForwardSetState(SCE_CSS_VALUE);
+			sc.ForwardSetState(lastStateS);
 		}
 
 		if (sc.state == SCE_CSS_OPERATOR) {
@@ -140,9 +144,9 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
 					sc.SetState(SCE_CSS_TAG);
 				break;
 			case '{':
-				if (lastState == SCE_CSS_DIRECTIVE)
+				if (lastState == SCE_CSS_MEDIA)
 					sc.SetState(SCE_CSS_DEFAULT);
-				else if (lastState == SCE_CSS_TAG)
+				else if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DIRECTIVE)
 					sc.SetState(SCE_CSS_IDENTIFIER);
 				break;
 			case '}':
@@ -219,7 +223,8 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
 			sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||
 			sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||
 			sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
-			sc.state == SCE_CSS_IMPORTANT
+			sc.state == SCE_CSS_IMPORTANT ||
+			sc.state == SCE_CSS_DIRECTIVE
 		)) {
 			char s[100];
 			sc.GetCurrentLowered(s, sizeof(s));
@@ -263,6 +268,10 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
 				if (strcmp(s2, "important") != 0)
 					sc.ChangeState(SCE_CSS_VALUE);
 				break;
+			case SCE_CSS_DIRECTIVE:
+				if (op == '@' && strcmp(s2, "media") == 0)
+					sc.ChangeState(SCE_CSS_MEDIA);
+				break;
 			}
 		}
 
@@ -280,12 +289,14 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
 			lastStateC = sc.state;
 			sc.SetState(SCE_CSS_COMMENT);
 			sc.Forward();
-		} else if (sc.state == SCE_CSS_VALUE && (sc.ch == '\"' || sc.ch == '\'')) {
+		} else if ((sc.state == SCE_CSS_VALUE || sc.state == SCE_CSS_ATTRIBUTE)
+			&& (sc.ch == '\"' || sc.ch == '\'')) {
+			lastStateS = sc.state;
 			sc.SetState((sc.ch == '\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING));
 		} else if (IsCssOperator(sc.ch)
 			&& (sc.state != SCE_CSS_ATTRIBUTE || sc.ch == ']')
 			&& (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!')
-			&& (sc.state != SCE_CSS_DIRECTIVE || sc.ch == ';' || sc.ch == '{')
+			&& ((sc.state != SCE_CSS_DIRECTIVE && sc.state != SCE_CSS_MEDIA) || sc.ch == ';' || sc.ch == '{')
 		) {
 			if (sc.state != SCE_CSS_OPERATOR)
 				lastState = sc.state;
diff --git a/plugins/scintilla/scintilla/LexCaml.cxx b/plugins/scintilla/scintilla/LexCaml.cxx
index 0d11622..f576e3e 100644
--- a/plugins/scintilla/scintilla/LexCaml.cxx
+++ b/plugins/scintilla/scintilla/LexCaml.cxx
@@ -20,19 +20,22 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
 #include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 //	Since the Microsoft __iscsym[f] funcs are not ANSI...
 inline int  iscaml(int c) {return isalnum(c) || c == '_';}
@@ -51,9 +54,13 @@ using namespace Scintilla;
 /*
 	(actually seems to work!)
 */
+#include <string>
 #include "WindowAccessor.h"
 #include "ExternalLexer.h"
 
+#undef EXT_LEXER_DECL
+#define EXT_LEXER_DECL __declspec( dllexport ) __stdcall
+
 #if PLAT_WIN
 #include <windows.h>
 #endif
@@ -430,13 +437,11 @@ void ColouriseCamlDoc(
 static
 #endif	/* BUILD_AS_EXTERNAL_LEXER */
 void FoldCamlDoc(
-	unsigned int startPos, int length,
-	int initStyle,
-	WordList *keywordlists[],
-	Accessor &styler)
+	unsigned int, int,
+	int,
+	WordList *[],
+	Accessor &)
 {
-	// below useless evaluation(s) to supress "not used" warnings
-	startPos || length || initStyle || keywordlists[0] || styler.Length();
 }
 
 static const char * const camlWordListDesc[] = {
diff --git a/plugins/scintilla/scintilla/LexCmake.cxx b/plugins/scintilla/scintilla/LexCmake.cxx
index 1f51f47..70e9dee 100644
--- a/plugins/scintilla/scintilla/LexCmake.cxx
+++ b/plugins/scintilla/scintilla/LexCmake.cxx
@@ -5,21 +5,25 @@
 // Copyright 2007 by Cristian Adam <cristian [dot] adam [at] gmx [dot] net>
 // based on the NSIS lexer
 // 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 <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "CharClassify.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
diff --git a/plugins/scintilla/scintilla/LexConf.cxx b/plugins/scintilla/scintilla/LexConf.cxx
index 969275f..5e1bd19 100644
--- a/plugins/scintilla/scintilla/LexConf.cxx
+++ b/plugins/scintilla/scintilla/LexConf.cxx
@@ -11,18 +11,22 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
@@ -70,17 +74,17 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
 				} else if( ch == '"') {
 					state = SCE_CONF_STRING;
 					styler.ColourTo(i,SCE_CONF_STRING);
-				} else if( ispunct(ch) ) {
+				} else if( isascii(ch) && ispunct(ch) ) {
 					// signals an operator...
 					// no state jump necessary for this
 					// simple case...
 					styler.ColourTo(i,SCE_CONF_OPERATOR);
-				} else if( isalpha(ch) ) {
+				} else if( isascii(ch) && isalpha(ch) ) {
 					// signals the start of an identifier
 					bufferCount = 0;
 					buffer[bufferCount++] = static_cast<char>(tolower(ch));
 					state = SCE_CONF_IDENTIFIER;
-				} else if( isdigit(ch) ) {
+				} else if( isascii(ch) && isdigit(ch) ) {
 					// signals the start of a number
 					bufferCount = 0;
 					buffer[bufferCount++] = ch;
@@ -107,7 +111,7 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
 				// if we find a non-alphanumeric char,
 				// we simply go to default state
 				// else we're still dealing with an extension...
-				if( isalnum(ch) || (ch == '_') ||
+				if( (isascii(ch) && isalnum(ch)) || (ch == '_') ||
 					(ch == '-') || (ch == '$') ||
 					(ch == '/') || (ch == '.') || (ch == '*') )
 				{
@@ -129,7 +133,7 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
 
 			case SCE_CONF_IDENTIFIER:
 				// stay  in CONF_IDENTIFIER state until we find a non-alphanumeric
-				if( isalnum(ch) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
+				if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
 					buffer[bufferCount++] = static_cast<char>(tolower(ch));
 				} else {
 					state = SCE_CONF_DEFAULT;
@@ -154,7 +158,7 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
 
 			case SCE_CONF_NUMBER:
 				// stay  in CONF_NUMBER state until we find a non-numeric
-				if( isdigit(ch) || ch == '.') {
+				if( (isascii(ch) && isdigit(ch)) || ch == '.') {
 					buffer[bufferCount++] = ch;
 				} else {
 					state = SCE_CONF_DEFAULT;
diff --git a/plugins/scintilla/scintilla/LexCrontab.cxx b/plugins/scintilla/scintilla/LexCrontab.cxx
old mode 100755
new mode 100644
index 62044c3..08abc71
--- a/plugins/scintilla/scintilla/LexCrontab.cxx
+++ b/plugins/scintilla/scintilla/LexCrontab.cxx
@@ -9,18 +9,22 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
@@ -94,12 +98,12 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi
 					// signals an asterisk
 					// no state jump necessary for this simple case...
 					styler.ColourTo(i,SCE_NNCRONTAB_ASTERISK);
-				} else if( isalpha(ch) || ch == '<' ) {
+				} else if( (isascii(ch) && isalpha(ch)) || ch == '<' ) {
 					// signals the start of an identifier
 					bufferCount = 0;
 					buffer[bufferCount++] = ch;
 					state = SCE_NNCRONTAB_IDENTIFIER;
-				} else if( isdigit(ch) ) {
+				} else if( isascii(ch) && isdigit(ch) ) {
 					// signals the start of a number
 					bufferCount = 0;
 					buffer[bufferCount++] = ch;
@@ -167,7 +171,7 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi
 
 			case SCE_NNCRONTAB_IDENTIFIER:
 				// stay  in CONF_IDENTIFIER state until we find a non-alphanumeric
-				if( isalnum(ch) || (ch == '_') || (ch == '-') || (ch == '/') ||
+				if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') ||
 					(ch == '$') || (ch == '.') || (ch == '<') || (ch == '>') ||
 					(ch == '@') ) {
 					buffer[bufferCount++] = ch;
@@ -196,7 +200,7 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi
 
 			case SCE_NNCRONTAB_NUMBER:
 				// stay  in CONF_NUMBER state until we find a non-numeric
-				if( isdigit(ch) /* || ch == '.' */ ) {
+				if( isascii(ch) && isdigit(ch) /* || ch == '.' */ ) {
 					buffer[bufferCount++] = ch;
 				} else {
 					state = SCE_NNCRONTAB_DEFAULT;
diff --git a/plugins/scintilla/scintilla/LexCsound.cxx b/plugins/scintilla/scintilla/LexCsound.cxx
index 4162c9b..8e5880c 100644
--- a/plugins/scintilla/scintilla/LexCsound.cxx
+++ b/plugins/scintilla/scintilla/LexCsound.cxx
@@ -8,18 +8,22 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
-#include "Platform.h"
+#include <assert.h>
+#include <ctype.h>
 
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
@@ -35,7 +39,7 @@ static inline bool IsAWordStart(const int ch) {
 }
 
 static inline bool IsCsoundOperator(char ch) {
-	if (isalnum(ch))
+	if (isascii(ch) && isalnum(ch))
 		return false;
 	// '.' left out as it is used to make up numbers
 	if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
@@ -72,7 +76,7 @@ static void ColouriseCsoundDoc(unsigned int startPos, int length, int initStyle,
 				continue;
 			}
 		}
-              
+
 		// Determine if the current state should terminate.
 		if (sc.state == SCE_CSOUND_OPERATOR) {
 			if (!IsCsoundOperator(static_cast<char>(sc.ch))) {
@@ -119,7 +123,7 @@ static void ColouriseCsoundDoc(unsigned int startPos, int length, int initStyle,
 				sc.SetState(SCE_CSOUND_DEFAULT);
 			}
 		}
-		
+
 		// Determine if a new state should be entered.
 		if (sc.state == SCE_CSOUND_DEFAULT) {
 			if (sc.ch == ';'){
@@ -146,7 +150,7 @@ static void ColouriseCsoundDoc(unsigned int startPos, int length, int initStyle,
 	sc.Complete();
 }
 
-static void FoldCsoundInstruments(unsigned int startPos, int length, int /* initStyle */, WordList *[], 
+static void FoldCsoundInstruments(unsigned int startPos, int length, int /* initStyle */, WordList *[],
 		Accessor &styler) {
 	unsigned int lengthDoc = startPos + length;
 	int visibleChars = 0;
diff --git a/plugins/scintilla/scintilla/LexD.cxx b/plugins/scintilla/scintilla/LexD.cxx
index 4c4bcb3..5b8f9e7 100644
--- a/plugins/scintilla/scintilla/LexD.cxx
+++ b/plugins/scintilla/scintilla/LexD.cxx
@@ -2,25 +2,36 @@
  ** Lexer for D.
  **
  ** Copyright (c) 2006 by Waldemar Augustyn <waldemar wdmsys com>
+ ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
  **/
 // 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 <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
 
-#include "Platform.h"
+#include <string>
+#include <map>
 
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
@@ -55,17 +66,187 @@ static bool IsStringSuffix(int ch) {
 	return ch == 'c' || ch == 'w' || ch == 'd';
 }
 
+static bool IsStreamCommentStyle(int style) {
+	return style == SCE_D_COMMENT ||
+		style == SCE_D_COMMENTDOC ||
+		style == SCE_D_COMMENTDOCKEYWORD ||
+		style == SCE_D_COMMENTDOCKEYWORDERROR;
+}
 
-static void ColouriseDoc(unsigned int startPos, int length, int initStyle,
-	WordList *keywordlists[], Accessor &styler, bool caseSensitive) {
+// An individual named option for use in an OptionSet
 
-	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];
+// Options used for LexerD
+struct OptionsD {
+	bool fold;
+	bool foldSyntaxBased;
+	bool foldComment;
+	bool foldCommentMultiline;
+	bool foldCommentExplicit;
+	std::string foldExplicitStart;
+	std::string foldExplicitEnd;
+	bool foldExplicitAnywhere;
+	bool foldCompact;
+	int  foldAtElseInt;
+	bool foldAtElse;
+	OptionsD() {
+		fold = false;
+		foldSyntaxBased = true;
+		foldComment = false;
+		foldCommentMultiline = true;
+		foldCommentExplicit = true;
+		foldExplicitStart = "";
+		foldExplicitEnd   = "";
+		foldExplicitAnywhere = false;
+		foldCompact = true;
+		foldAtElseInt = -1;
+		foldAtElse = false;
+	}
+};
+
+static const char * const dWordLists[] = {
+			"Primary keywords and identifiers",
+			"Secondary keywords and identifiers",
+			"Documentation comment keywords",
+			"Type definitions and aliases",
+			"Keywords 5",
+			"Keywords 6",
+			"Keywords 7",
+			0,
+		};
+
+struct OptionSetD : public OptionSet<OptionsD> {
+	OptionSetD() {
+		DefineProperty("fold", &OptionsD::fold);
+
+		DefineProperty("fold.d.syntax.based", &OptionsD::foldSyntaxBased,
+			"Set this property to 0 to disable syntax based folding.");
+
+		DefineProperty("fold.comment", &OptionsD::foldComment);
+
+		DefineProperty("fold.d.comment.multiline", &OptionsD::foldCommentMultiline,
+			"Set this property to 0 to disable folding multi-line comments when fold.comment=1.");
+
+		DefineProperty("fold.d.comment.explicit", &OptionsD::foldCommentExplicit,
+			"Set this property to 0 to disable folding explicit fold points when fold.comment=1.");
+
+		DefineProperty("fold.d.explicit.start", &OptionsD::foldExplicitStart,
+			"The string to use for explicit fold start points, replacing the standard //{.");
+
+		DefineProperty("fold.d.explicit.end", &OptionsD::foldExplicitEnd,
+			"The string to use for explicit fold end points, replacing the standard //}.");
+
+		DefineProperty("fold.d.explicit.anywhere", &OptionsD::foldExplicitAnywhere,
+			"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+		DefineProperty("fold.compact", &OptionsD::foldCompact);
+
+		DefineProperty("lexer.d.fold.at.else", &OptionsD::foldAtElseInt,
+			"This option enables D folding on a \"} else {\" line of an if statement.");
+
+		DefineProperty("fold.at.else", &OptionsD::foldAtElse);
+
+		DefineWordListSets(dWordLists);
+	}
+};
+
+class LexerD : public ILexer {
+	bool caseSensitive;
+	WordList keywords;
+	WordList keywords2;
+	WordList keywords3;
+	WordList keywords4;
+	WordList keywords5;
+	WordList keywords6;
+	WordList keywords7;
+	OptionsD options;
+	OptionSetD osD;
+public:
+	LexerD(bool caseSensitive_) :
+		caseSensitive(caseSensitive_) {
+	}
+	~LexerD() {
+	}
+	void SCI_METHOD Release() {
+		delete this;
+	}
+	int SCI_METHOD Version() const {
+		return lvOriginal;
+	}
+	const char * SCI_METHOD PropertyNames() {
+		return osD.PropertyNames();
+	}
+	int SCI_METHOD PropertyType(const char *name) {
+		return osD.PropertyType(name);
+	}
+	const char * SCI_METHOD DescribeProperty(const char *name) {
+		return osD.DescribeProperty(name);
+	}
+	int SCI_METHOD PropertySet(const char *key, const char *val);
+	const char * SCI_METHOD DescribeWordListSets() {
+		return osD.DescribeWordListSets();
+	}
+	int SCI_METHOD WordListSet(int n, const char *wl);
+	void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+	void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+
+	void * SCI_METHOD PrivateCall(int, void *) {
+		return 0;
+	}
+
+	static ILexer *LexerFactoryD() {
+		return new LexerD(true);
+	}
+	static ILexer *LexerFactoryDInsensitive() {
+		return new LexerD(false);
+	}
+};
+
+int SCI_METHOD LexerD::PropertySet(const char *key, const char *val) {
+	if (osD.PropertySet(&options, key, val)) {
+		return 0;
+	}
+	return -1;
+}
+
+int SCI_METHOD LexerD::WordListSet(int n, const char *wl) {
+	WordList *wordListN = 0;
+	switch (n) {
+	case 0:
+		wordListN = &keywords;
+		break;
+	case 1:
+		wordListN = &keywords2;
+		break;
+	case 2:
+		wordListN = &keywords3;
+		break;
+	case 3:
+		wordListN = &keywords4;
+		break;
+	case 4:
+		wordListN = &keywords5;
+		break;
+	case 5:
+		wordListN = &keywords6;
+		break;
+	case 6:
+		wordListN = &keywords7;
+		break;
+	}
+	int firstModification = -1;
+	if (wordListN) {
+		WordList wlNew;
+		wlNew.Set(wl);
+		if (*wordListN != wlNew) {
+			wordListN->Set(wl);
+			firstModification = 0;
+		}
+	}
+	return firstModification;
+}
+
+void SCI_METHOD LexerD::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+	LexAccessor styler(pAccess);
 
 	int styleBeforeDCKeyword = SCE_D_DEFAULT;
 
@@ -290,24 +471,17 @@ static void ColouriseDoc(unsigned int startPos, int length, int initStyle,
 	sc.Complete();
 }
 
-static bool IsStreamCommentStyle(int style) {
-	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;
-
-	// 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;
+
+void SCI_METHOD LexerD::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+
+	if (!options.fold)
+		return;
+
+	LexAccessor styler(pAccess);
+
 	unsigned int endPos = startPos + length;
 	int visibleChars = 0;
 	int lineCurrent = styler.GetLine(startPos);
@@ -319,6 +493,8 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
 	char chNext = styler[startPos];
 	int styleNext = styler.StyleAt(startPos);
 	int style = initStyle;
+	bool foldAtElse = options.foldAtElseInt >= 0 ? options.foldAtElseInt != 0 : options.foldAtElse;
+	const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
 	for (unsigned int i = startPos; i < endPos; i++) {
 		char ch = chNext;
 		chNext = styler.SafeGetCharAt(i + 1);
@@ -326,7 +502,7 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
 		style = styleNext;
 		styleNext = styler.StyleAt(i + 1);
 		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-		if (foldComment && IsStreamCommentStyle(style)) {
+		if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
 			if (!IsStreamCommentStyle(stylePrev)) {
 				levelNext++;
 			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
@@ -334,7 +510,25 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
 				levelNext--;
 			}
 		}
-		if (style == SCE_D_OPERATOR) {
+		if (options.foldComment && options.foldCommentExplicit && ((style == SCE_D_COMMENTLINE) || options.foldExplicitAnywhere)) {
+			if (userDefinedFoldMarkers) {
+				if (styler.Match(i, options.foldExplicitStart.c_str())) {
+ 					levelNext++;
+				} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
+ 					levelNext--;
+ 				}
+			} else {
+				if ((ch == '/') && (chNext == '/')) {
+					char chNext2 = styler.SafeGetCharAt(i + 2);
+					if (chNext2 == '{') {
+						levelNext++;
+					} else if (chNext2 == '}') {
+						levelNext--;
+					}
+				}
+ 			}
+ 		}
+		if (options.foldSyntaxBased && (style == SCE_D_OPERATOR)) {
 			if (ch == '{') {
 				// Measure the minimum before a '{' to allow
 				// folding on "} else {"
@@ -346,19 +540,19 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
 				levelNext--;
 			}
 		}
-		if (atEOL) {
-			if (foldComment) {  // Handle nested comments
+		if (atEOL || (i == endPos-1)) {
+			if (options.foldComment && options.foldCommentMultiline) {  // Handle nested comments
 				int nc;
 				nc =  styler.GetLineState(lineCurrent);
 				nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;
 				levelNext += nc;
 			}
 			int levelUse = levelCurrent;
-			if (foldAtElse) {
+			if (options.foldSyntaxBased && foldAtElse) {
 				levelUse = levelMinCurrent;
 			}
 			int lev = levelUse | levelNext << 16;
-			if (visibleChars == 0 && foldCompact)
+			if (visibleChars == 0 && options.foldCompact)
 				lev |= SC_FOLDLEVELWHITEFLAG;
 			if (levelUse < levelNext)
 				lev |= SC_FOLDLEVELHEADERFLAG;
@@ -375,25 +569,4 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
 	}
 }
 
-static void FoldDDoc(unsigned int startPos, int length, int initStyle,
-	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",
-			"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);
-}
-
-LexerModule lmD(SCLEX_D, ColouriseDDoc, "d", FoldDDoc, dWordLists);
+LexerModule lmD(SCLEX_D, LexerD::LexerFactoryD, "d", dWordLists);
diff --git a/plugins/scintilla/scintilla/LexEScript.cxx b/plugins/scintilla/scintilla/LexEScript.cxx
index 295aaec..9a7560e 100644
--- a/plugins/scintilla/scintilla/LexEScript.cxx
+++ b/plugins/scintilla/scintilla/LexEScript.cxx
@@ -9,15 +9,18 @@
 #include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -198,7 +201,7 @@ static void FoldESCRIPTDoc(unsigned int startPos, int length, int initStyle, Wor
 		styleNext = styler.StyleAt(i + 1);
 		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 
-            
+
 		if (foldComment && IsStreamCommentStyle(style)) {
 			if (!IsStreamCommentStyle(stylePrev)) {
 				levelCurrent++;
diff --git a/plugins/scintilla/scintilla/LexEiffel.cxx b/plugins/scintilla/scintilla/LexEiffel.cxx
old mode 100755
new mode 100644
index 03dea5e..067801c
--- a/plugins/scintilla/scintilla/LexEiffel.cxx
+++ b/plugins/scintilla/scintilla/LexEiffel.cxx
@@ -7,18 +7,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
 #include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexErlang.cxx b/plugins/scintilla/scintilla/LexErlang.cxx
index 45577bd..5f52258 100644
--- a/plugins/scintilla/scintilla/LexErlang.cxx
+++ b/plugins/scintilla/scintilla/LexErlang.cxx
@@ -4,24 +4,28 @@
 /** @file LexErlang.cxx
  ** Lexer for Erlang.
  ** Enhanced by Etienne 'Lenain' Girondel (lenaing gmail com)
- ** Originally wrote by Peter-Henry Mander, 
+ ** Originally wrote by Peter-Henry Mander,
  ** based on Matlab lexer by José Fonseca.
  **/
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
@@ -152,7 +156,7 @@ static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
 						// Try to match documentation comment
 						sc.GetCurrent(cur, sizeof(cur));
 
-						if (parse_state == COMMENT_DOC_MACRO 
+						if (parse_state == COMMENT_DOC_MACRO
 							&& erlangDocMacro.InList(cur)) {
 								sc.ChangeState(SCE_ERLANG_COMMENT_DOC_MACRO);
 								while (sc.ch != '}' && !sc.atLineEnd)
@@ -340,7 +344,7 @@ static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
 				case NUMERAL_BASE_VALUE : {
 					if (!is_radix(radix_digits,sc.ch)) {
 						radix_digits = 0;
-				
+
 						if (!isalnum(sc.ch))
 							sc.ChangeState(SCE_ERLANG_NUMBER);
 
@@ -380,7 +384,7 @@ static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
 			/* Preprocessor --------------------------------------------------*/
 				case PREPROCESSOR : {
 					if (!IsAWordChar(sc.ch)) {
-						
+
 						sc.GetCurrent(cur, sizeof(cur));
 						if (erlangPreproc.InList(cur)) {
 							style = SCE_ERLANG_PREPROC;
@@ -421,7 +425,7 @@ static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
 				} break;
 				case SCE_ERLANG_OPERATOR : {
 					if (sc.chPrev == '.') {
-						if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' 
+						if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\'
 							|| sc.ch == '^') {
 							sc.ForwardSetState(SCE_ERLANG_DEFAULT);
 						} else if (sc.ch == '\'') {
diff --git a/plugins/scintilla/scintilla/LexFlagship.cxx b/plugins/scintilla/scintilla/LexFlagship.cxx
index baf2941..b8568b0 100644
--- a/plugins/scintilla/scintilla/LexFlagship.cxx
+++ b/plugins/scintilla/scintilla/LexFlagship.cxx
@@ -1,169 +1,299 @@
 // Scintilla source code edit control
 /** @file LexFlagShip.cxx
- ** Lexer for FlagShip 
- ** (Syntactically compatible to other XBase dialects, like dBase, Clipper, Fox etc.)
+ ** Lexer for Harbour and FlagShip.
+ ** (Syntactically compatible to other xBase dialects, like Clipper, dBase, Clip, FoxPro etc.)
  **/
 // Copyright 2005 by Randy Butler
+// Copyright 2010 by Xavi <jarabal/at/gmail.com> (Harbour)
 // 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>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-static bool IsFlagShipComment(Accessor &styler, int pos, int len) {
-	return len>0 && styler[pos]=='\'';
-}
-
-static inline bool IsTypeCharacter(int ch) {
-	return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$';
-}
-
 // Extended to accept accented characters
-static inline bool IsAWordChar(int ch) {
+static inline bool IsAWordChar(int ch)
+{
 	return ch >= 0x80 ||
-	       (isalnum(ch) || ch == '.' || ch == '_');
-}
-
-static inline bool IsAWordStart(int ch) {
-	return ch >= 0x80 ||
-	       (isalnum(ch) || ch == '_');
-}
-
-static inline bool IsADateCharacter(const int ch) {
-	return (ch < 0x80) &&
-		(isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t');
+				(isalnum(ch) || ch == '_');
 }
 
-
 static void ColouriseFlagShipDoc(unsigned int startPos, int length, int initStyle,
-                           WordList *keywordlists[], Accessor &styler) {
+                                 WordList *keywordlists[], Accessor &styler)
+{
 
-	//bool FSScriptSyntax = true;
 	WordList &keywords = *keywordlists[0];
 	WordList &keywords2 = *keywordlists[1];
 	WordList &keywords3 = *keywordlists[2];
 	WordList &keywords4 = *keywordlists[3];
+	WordList &keywords5 = *keywordlists[4];
+
+	// property lexer.flagship.styling.within.preprocessor
+	//	For Harbour code, determines whether all preprocessor code is styled in the preprocessor style (0) or only from the
+	//	initial # to the end of the command word(1, the default). It also determines how to present text, dump, and disabled code.
+	bool stylingWithinPreprocessor = styler.GetPropertyInt("lexer.flagship.styling.within.preprocessor", 1) != 0;
 
-	styler.StartAt(startPos);
+	CharacterSet setDoxygen(CharacterSet::setAlpha, "$ \\&<>#{}[]");
 
 	int visibleChars = 0;
+	int closeStringChar = 0;
+	int styleBeforeDCKeyword = SCE_FS_DEFAULT;
+	bool bEnableCode = initStyle < SCE_FS_DISABLEDCODE;
 
 	StyleContext sc(startPos, length, initStyle, styler);
 
 	for (; sc.More(); sc.Forward()) {
 
-		if (sc.state == SCE_FS_OPERATOR) {
-			sc.SetState(SCE_FS_DEFAULT);
-		} else if (sc.state == SCE_FS_IDENTIFIER) {
-			if (!IsAWordChar(sc.ch)) {
-				char s[100];
-				sc.GetCurrentLowered(s, sizeof(s));
-				if (keywords.InList(s)) {
-					sc.ChangeState(SCE_FS_KEYWORD);
-				} else if (keywords2.InList(s)) {
-					sc.ChangeState(SCE_FS_KEYWORD2);
-				} else if (keywords3.InList(s)) {
-					sc.ChangeState(SCE_FS_KEYWORD3);
-				} else if (keywords4.InList(s)) {
-					sc.ChangeState(SCE_FS_KEYWORD4);
-				}// Else, it is really an identifier...
-				sc.SetState(SCE_FS_DEFAULT);
-			}
-		} else if (sc.state == SCE_FS_NUMBER) {
-			if (!IsAWordChar(sc.ch)) {
-				sc.SetState(SCE_FS_DEFAULT);
-			}
-		} else if (sc.state == SCE_FS_STRING) {
-			// VB doubles quotes to preserve them, so just end this string
-			// state now as a following quote will start again
-			if (sc.ch == '\"') {
-				if (tolower(sc.chNext) == 'c') {
+		// Determine if the current state should terminate.
+		switch (sc.state) {
+			case SCE_FS_OPERATOR:
+			case SCE_FS_OPERATOR_C:
+			case SCE_FS_WORDOPERATOR:
+				sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+				break;
+			case SCE_FS_IDENTIFIER:
+			case SCE_FS_IDENTIFIER_C:
+				if (!IsAWordChar(sc.ch)) {
+					char s[64];
+					sc.GetCurrentLowered(s, sizeof(s));
+					if (keywords.InList(s)) {
+						sc.ChangeState(bEnableCode ? SCE_FS_KEYWORD : SCE_FS_KEYWORD_C);
+					} else if (keywords2.InList(s)) {
+						sc.ChangeState(bEnableCode ? SCE_FS_KEYWORD2 : SCE_FS_KEYWORD2_C);
+					} else if (bEnableCode && keywords3.InList(s)) {
+						sc.ChangeState(SCE_FS_KEYWORD3);
+					} else if (bEnableCode && keywords4.InList(s)) {
+						sc.ChangeState(SCE_FS_KEYWORD4);
+					}// Else, it is really an identifier...
+					sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+				}
+				break;
+			case SCE_FS_NUMBER:
+				if (!IsAWordChar(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) {
+					sc.SetState(SCE_FS_DEFAULT);
+				}
+				break;
+			case SCE_FS_NUMBER_C:
+				if (!IsAWordChar(sc.ch) && sc.ch != '.') {
+					sc.SetState(SCE_FS_DEFAULT_C);
+				}
+				break;
+			case SCE_FS_CONSTANT:
+				if (!IsAWordChar(sc.ch)) {
+					sc.SetState(SCE_FS_DEFAULT);
+				}
+				break;
+			case SCE_FS_STRING:
+			case SCE_FS_STRING_C:
+				if (sc.ch == closeStringChar) {
+					sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+				} else if (sc.atLineEnd) {
+					sc.ChangeState(bEnableCode ? SCE_FS_STRINGEOL : SCE_FS_STRINGEOL_C);
+				}
+				break;
+			case SCE_FS_STRINGEOL:
+			case SCE_FS_STRINGEOL_C:
+				if (sc.atLineStart) {
+					sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+				}
+				break;
+			case SCE_FS_COMMENTDOC:
+			case SCE_FS_COMMENTDOC_C:
+				if (sc.Match('*', '/')) {
 					sc.Forward();
+					sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+				} 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 = bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C;
+						sc.SetState(SCE_FS_COMMENTDOCKEYWORD);
+					}
+				}
+				break;
+			case SCE_FS_COMMENT:
+			case SCE_FS_COMMENTLINE:
+				if (sc.atLineStart) {
+					sc.SetState(SCE_FS_DEFAULT);
+				}
+				break;
+			case SCE_FS_COMMENTLINEDOC:
+			case SCE_FS_COMMENTLINEDOC_C:
+				if (sc.atLineStart) {
+					sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+				} 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 = bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C;
+						sc.SetState(SCE_FS_COMMENTDOCKEYWORD);
+					}
+				}
+				break;
+			case SCE_FS_COMMENTDOCKEYWORD:
+				if ((styleBeforeDCKeyword == SCE_FS_COMMENTDOC || styleBeforeDCKeyword == SCE_FS_COMMENTDOC_C) &&
+						sc.Match('*', '/')) {
+					sc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR);
+					sc.Forward();
+					sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+				} else if (!setDoxygen.Contains(sc.ch)) {
+					char s[64];
+					sc.GetCurrentLowered(s, sizeof(s));
+					if (!IsASpace(sc.ch) || !keywords5.InList(s + 1)) {
+						sc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR);
+					}
+					sc.SetState(styleBeforeDCKeyword);
+				}
+				break;
+			case SCE_FS_PREPROCESSOR:
+			case SCE_FS_PREPROCESSOR_C:
+				if (sc.atLineEnd) {
+					if (!(sc.chPrev == ';' || sc.GetRelative(-2) == ';')) {
+						sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+					}
+				} else if (stylingWithinPreprocessor) {
+					if (IsASpaceOrTab(sc.ch)) {
+						sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+					}
+				} else if (sc.Match('/', '*') || sc.Match('/', '/') || sc.Match('&', '&')) {
+					sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+				}
+				break;
+			case SCE_FS_DISABLEDCODE:
+				if (sc.ch == '#' && visibleChars == 0) {
+					sc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C);
+					do {	// Skip whitespace between # and preprocessor word
+						sc.Forward();
+					} while (IsASpaceOrTab(sc.ch) && sc.More());
+					if (sc.MatchIgnoreCase("pragma")) {
+						sc.Forward(6);
+						do {	// Skip more whitespace until keyword
+							sc.Forward();
+						} while (IsASpaceOrTab(sc.ch) && sc.More());
+						if (sc.MatchIgnoreCase("enddump") || sc.MatchIgnoreCase("__endtext")) {
+							bEnableCode = true;
+							sc.SetState(SCE_FS_DISABLEDCODE);
+							sc.Forward(sc.ch == '_' ? 8 : 6);
+							sc.ForwardSetState(SCE_FS_DEFAULT);
+						} else {
+							sc.ChangeState(SCE_FS_DISABLEDCODE);
+						}
+					} else {
+						sc.ChangeState(SCE_FS_DISABLEDCODE);
+					}
+				}
+				break;
+			case SCE_FS_DATE:
+				if (sc.ch == '}') {
+					sc.ForwardSetState(SCE_FS_DEFAULT);
+				} else if (sc.atLineEnd) {
+					sc.ChangeState(SCE_FS_STRINGEOL);
 				}
-				sc.ForwardSetState(SCE_FS_DEFAULT);
-			} else if (sc.atLineEnd) {
-				sc.ChangeState(SCE_FS_STRINGEOL);
-				sc.ForwardSetState(SCE_FS_DEFAULT);
-			}
-		} else if (sc.state == SCE_FS_COMMENT) {
-			if (sc.Match('*', '/')) {   // new code
-				sc.Forward();
-				sc.ForwardSetState(SCE_FS_DEFAULT);
-			//if (sc.atLineEnd) {       // old code
-			//	sc.SetState(SCE_FS_DEFAULT);
-			}
-		} else if (sc.state == SCE_FS_COMMENTLINE) {  //new code
-			if (sc.ch == '\r' || sc.ch == '\n') {
-				sc.SetState(SCE_FS_DEFAULT);
-				visibleChars = 0;
-			}
-		} else if (sc.state == SCE_FS_PREPROCESSOR) {
-			if (sc.atLineEnd) {
-				sc.SetState(SCE_FS_DEFAULT);
-			}
-		} else if (sc.state == SCE_FS_DATE) {
-			if (sc.ch == '#' || !IsADateCharacter(sc.chNext)) {
-				sc.ForwardSetState(SCE_FS_DEFAULT);
-			}
 		}
 
 		// Determine if a new state should be entered.
-		if (sc.state == SCE_FS_DEFAULT) {
-			if (sc.Match('/', '*')) {  // New code
-				sc.SetState(SCE_FS_COMMENT);
-				sc.Forward();	// Eat the * so it isn't used for the end of the comment
-			//if (sc.ch == '\'') {  // Old code
-			//	sc.SetState(SCE_FS_COMMENT); // old code
-			} else if (sc.Match('/', '/')) { // New code
+		if (sc.state == SCE_FS_DEFAULT || sc.state == SCE_FS_DEFAULT_C) {
+			if (bEnableCode &&
+					(sc.MatchIgnoreCase(".and.") || sc.MatchIgnoreCase(".not."))) {
+				sc.SetState(SCE_FS_WORDOPERATOR);
+				sc.Forward(4);
+			} else if (bEnableCode && sc.MatchIgnoreCase(".or.")) {
+				sc.SetState(SCE_FS_WORDOPERATOR);
+				sc.Forward(3);
+			} else if (bEnableCode &&
+					(sc.MatchIgnoreCase(".t.") || sc.MatchIgnoreCase(".f.") ||
+					(!IsAWordChar(sc.GetRelative(3)) && sc.MatchIgnoreCase("nil")))) {
+				sc.SetState(SCE_FS_CONSTANT);
+				sc.Forward(2);
+			} else if (sc.Match('/', '*')) {
+				sc.SetState(bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C);
+				sc.Forward();
+			} else if (bEnableCode && sc.Match('&', '&')) {
 				sc.SetState(SCE_FS_COMMENTLINE);
-			} else if (sc.ch == '\"') {
-				sc.SetState(SCE_FS_STRING);
+				sc.Forward();
+			} else if (sc.Match('/', '/')) {
+				sc.SetState(bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C);
+				sc.Forward();
+			} else if (bEnableCode && sc.ch == '*' && visibleChars == 0) {
+				sc.SetState(SCE_FS_COMMENT);
+			} else if (sc.ch == '\"' || sc.ch == '\'') {
+				sc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C);
+				closeStringChar = sc.ch;
+			} else if (closeStringChar == '>' && sc.ch == '<') {
+				sc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C);
 			} else if (sc.ch == '#' && visibleChars == 0) {
-				// Preprocessor commands are alone on their line
-				sc.SetState(SCE_FS_PREPROCESSOR);
-			} else if (sc.ch == '#') {
-				int n = 1;
-				int chSeek = ' ';
-				while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) {
-					chSeek = sc.GetRelative(n);
-					n++;
-				}
-				if (IsADigit(chSeek)) {
+				sc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C);
+				do {	// Skip whitespace between # and preprocessor word
+					sc.Forward();
+				} while (IsASpaceOrTab(sc.ch) && sc.More());
+				if (sc.atLineEnd) {
+					sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+				} else if (sc.MatchIgnoreCase("include")) {
+					if (stylingWithinPreprocessor) {
+						closeStringChar = '>';
+					}
+				} else if (sc.MatchIgnoreCase("pragma")) {
+					sc.Forward(6);
+					do {	// Skip more whitespace until keyword
+						sc.Forward();
+					} while (IsASpaceOrTab(sc.ch) && sc.More());
+					if (sc.MatchIgnoreCase("begindump") || sc.MatchIgnoreCase("__cstream")) {
+						bEnableCode = false;
+						if (stylingWithinPreprocessor) {
+							sc.SetState(SCE_FS_DISABLEDCODE);
+							sc.Forward(8);
+							sc.ForwardSetState(SCE_FS_DEFAULT_C);
+						} else {
+							sc.SetState(SCE_FS_DISABLEDCODE);
+						}
+					} else if (sc.MatchIgnoreCase("enddump") || sc.MatchIgnoreCase("__endtext")) {
+						bEnableCode = true;
+						sc.SetState(SCE_FS_DISABLEDCODE);
+						sc.Forward(sc.ch == '_' ? 8 : 6);
+						sc.ForwardSetState(SCE_FS_DEFAULT);
+					}
+				}
+			} else if (bEnableCode && sc.ch == '{') {
+				int p = 0;
+				int chSeek;
+				unsigned int endPos(startPos + length);
+				do {	// Skip whitespace
+					chSeek = sc.GetRelative(++p);
+				} while (IsASpaceOrTab(chSeek) && (sc.currentPos + p < endPos));
+				if (chSeek == '^') {
 					sc.SetState(SCE_FS_DATE);
 				} else {
 					sc.SetState(SCE_FS_OPERATOR);
 				}
-			} else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {
-				sc.SetState(SCE_FS_NUMBER);
-			} else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {
-				sc.SetState(SCE_FS_NUMBER);
 			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
-				sc.SetState(SCE_FS_NUMBER);
-			} else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {
-				sc.SetState(SCE_FS_IDENTIFIER);
-			} else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {
-				sc.SetState(SCE_FS_OPERATOR);
+				sc.SetState(bEnableCode ? SCE_FS_NUMBER : SCE_FS_NUMBER_C);
+			} else if (IsAWordChar(sc.ch)) {
+				sc.SetState(bEnableCode ? SCE_FS_IDENTIFIER : SCE_FS_IDENTIFIER_C);
+			} else if (isoperator(static_cast<char>(sc.ch)) || (bEnableCode && sc.ch == '@')) {
+				sc.SetState(bEnableCode ? SCE_FS_OPERATOR : SCE_FS_OPERATOR_C);
 			}
 		}
 
 		if (sc.atLineEnd) {
 			visibleChars = 0;
+			closeStringChar = 0;
 		}
 		if (!IsASpace(sc.ch)) {
 			visibleChars++;
@@ -173,36 +303,33 @@ static void ColouriseFlagShipDoc(unsigned int startPos, int length, int initStyl
 }
 
 static void FoldFlagShipDoc(unsigned int startPos, int length, int,
-						   WordList *[], Accessor &styler) {
+									WordList *[], Accessor &styler)
+{
 
 	int endPos = startPos + length;
 
 	// Backtrack to previous line in case need to fix its fold status
 	int lineCurrent = styler.GetLine(startPos);
-	if (startPos > 0) {
-		if (lineCurrent > 0) {
+	if (startPos > 0 && lineCurrent > 0) {
 			lineCurrent--;
 			startPos = styler.LineStart(lineCurrent);
-		}
 	}
 	int spaceFlags = 0;
-	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsFlagShipComment);
+	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
 	char chNext = styler[startPos];
 	for (int i = startPos; i < endPos; i++) {
 		char ch = chNext;
 		chNext = styler.SafeGetCharAt(i + 1);
 
-		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
+		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos-1)) {
 			int lev = indentCurrent;
-			int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsFlagShipComment);
+			int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
 			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
-				// Only non whitespace lines can be headers
 				if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
 					lev |= SC_FOLDLEVELHEADERFLAG;
 				} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
-					// Line after is blank so check the next - maybe should continue further?
 					int spaceFlags2 = 0;
-					int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsFlagShipComment);
+					int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2);
 					if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
 						lev |= SC_FOLDLEVELHEADERFLAG;
 					}
@@ -215,16 +342,13 @@ static void FoldFlagShipDoc(unsigned int startPos, int length, int,
 	}
 }
 
-
 static const char * const FSWordListDesc[] = {
-	"Keywords",
-	"functions",
-	"user2",
-	"user3",
+	"Keywords Commands",
+	"Std Library Functions",
+	"Procedure, return, exit",
+	"Class (oop)",
+	"Doxygen keywords",
 	0
 };
 
 LexerModule lmFlagShip(SCLEX_FLAGSHIP, ColouriseFlagShipDoc, "flagship", FoldFlagShipDoc, FSWordListDesc);
-
-
-
diff --git a/plugins/scintilla/scintilla/LexForth.cxx b/plugins/scintilla/scintilla/LexForth.cxx
index e52543f..0e9875c 100644
--- a/plugins/scintilla/scintilla/LexForth.cxx
+++ b/plugins/scintilla/scintilla/LexForth.cxx
@@ -7,18 +7,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -130,7 +133,7 @@ static void ColouriseForthDoc(unsigned int startPos, int length, int initStyle,
 				sc.SetState(SCE_FORTH_NUMBER);
 				while(sc.More() && isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))
 					sc.Forward();
-			} else if (	isascii(sc.ch) && 
+			} else if (	isascii(sc.ch) &&
 						(isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && isascii(sc.chNext) && isxdigit(sc.chNext)) )
 					){
 				sc.SetState(SCE_FORTH_NUMBER);
@@ -173,4 +176,4 @@ static const char * const forthWordLists[] = {
 
 LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth", FoldForthDoc, forthWordLists);
 
- 	  	 
+
diff --git a/plugins/scintilla/scintilla/LexFortran.cxx b/plugins/scintilla/scintilla/LexFortran.cxx
index 0b3f277..6c61c54 100644
--- a/plugins/scintilla/scintilla/LexFortran.cxx
+++ b/plugins/scintilla/scintilla/LexFortran.cxx
@@ -8,18 +8,23 @@
 /***************************************/
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 /***************************************/
-#include "Platform.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+/***************************************/
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
@@ -261,7 +266,7 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
 		|| strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0
 		|| strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0
 		|| strcmp(s, "endwhere") == 0
-		|| strcmp(s, "procedure") == 0 ) { // Take care of the module procedure statement
+		|| (strcmp(s, "procedure") == 0 && strcmp(prevWord,"module")==0) ) { // Take care of the module procedure statement
 			lev = -1;
 	} else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if
 			lev = 0;
diff --git a/plugins/scintilla/scintilla/LexGAP.cxx b/plugins/scintilla/scintilla/LexGAP.cxx
index 25bd33b..fb30660 100644
--- a/plugins/scintilla/scintilla/LexGAP.cxx
+++ b/plugins/scintilla/scintilla/LexGAP.cxx
@@ -8,25 +8,28 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
 static inline bool IsGAPOperator(char ch) {
-	if (isalnum(ch)) return false;
+	if (isascii(ch) && isalnum(ch)) return false;
 	if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
 		ch == '^' || ch == ',' || ch == '!' || ch == '.' ||
 		ch == '=' || ch == '<' || ch == '>' || ch == '(' ||
diff --git a/plugins/scintilla/scintilla/LexGen.py b/plugins/scintilla/scintilla/LexGen.py
new file mode 100755
index 0000000..22cdaae
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexGen.py
@@ -0,0 +1,304 @@
+#!/usr/bin/env python
+# LexGen.py - implemented 2002 by Neil Hodgson neilh scintilla org
+# Released to the public domain.
+
+# Regenerate the Scintilla and SciTE source files that list
+# all the lexers and all the properties files.
+# Should be run whenever a new lexer is added or removed.
+# Requires Python 2.4 or later
+# Most files are regenerated in place with templates stored in comments.
+# The VS .NET project file is generated into a different file as the
+# VS .NET environment will not retain comments when modifying the file.
+# The files are copied to a string apart from sections between a
+# ++Autogenerated comment and a --Autogenerated comment which is
+# generated by the CopyWithInsertion function. After the whole
+# string is instantiated, it is compared with the target file and
+# if different the file is rewritten.
+# Does not regenerate the Visual C++ 6 project files but does the VS .NET
+# project file.
+
+import string
+import sys
+import os
+import glob
+
+# EOL constants
+CR = "\r"
+LF = "\n"
+CRLF = "\r\n"
+if sys.platform == "win32":
+    NATIVE = CRLF
+else:
+    # Yes, LF is the native EOL even on Mac OS X. CR is just for
+    # Mac OS <=9 (a.k.a. "Mac Classic")
+    NATIVE = LF
+
+# Automatically generated sections contain start and end comments,
+# a definition line and the results.
+# The results are replaced by regenerating based on the definition line.
+# The definition line is a comment prefix followed by "**".
+# If there is a digit after the ** then this indicates which list to use
+# and the digit and next character are not part of the definition
+# Backslash is used as an escape within the definition line.
+# The part between \( and \) is repeated for each item in the list.
+# \* is replaced by each list item. \t, and \n are tab and newline.
+def CopyWithInsertion(input, commentPrefix, retainDefs, eolType, *lists):
+    copying = 1
+    listid = 0
+    output = []
+    for line in input.splitlines(0):
+        isStartGenerated = line.startswith(commentPrefix + "++Autogenerated")
+        if copying and not isStartGenerated:
+            output.append(line)
+        if isStartGenerated:
+            if retainDefs:
+                output.append(line)
+            copying = 0
+            definition = ""
+        elif not copying and line.startswith(commentPrefix + "**"):
+            if retainDefs:
+                output.append(line)
+            definition = line[len(commentPrefix + "**"):]
+            if (commentPrefix == "<!--") and (" -->" in definition):
+                definition = definition.replace(" -->", "")
+            listid = 0
+            if definition[0] in string.digits:
+                listid = int(definition[:1])
+                definition = definition[2:]
+            # Hide double slashes as a control character
+            definition = definition.replace("\\\\", "\001")
+            # Do some normal C style transforms
+            definition = definition.replace("\\n", "\n")
+            definition = definition.replace("\\t", "\t")
+            # Get the doubled backslashes back as single backslashes
+            definition = definition.replace("\001", "\\")
+            startRepeat = definition.find("\\(")
+            endRepeat = definition.find("\\)")
+            intro = definition[:startRepeat]
+            out = ""
+            if intro.endswith("\n"):
+                pos = 0
+            else:
+                pos = len(intro)
+            out += intro
+            middle = definition[startRepeat+2:endRepeat]
+            for i in lists[listid]:
+                item = middle.replace("\\*", i)
+                if pos and (pos + len(item) >= 80):
+                    out += "\\\n"
+                    pos = 0
+                out += item
+                pos += len(item)
+                if item.endswith("\n"):
+                    pos = 0
+            outro = definition[endRepeat+2:]
+            out += outro
+            out = out.replace("\n", eolType) # correct EOLs in generated content
+            output.append(out)
+        elif line.startswith(commentPrefix + "--Autogenerated"):
+            copying = 1
+            if retainDefs:
+                output.append(line)
+    output = [line.rstrip(" \t") for line in output] # trim trailing whitespace
+    return eolType.join(output) + eolType
+
+def UpdateFile(filename, updated):
+    """ If the file is different to updated then copy updated
+    into the file else leave alone so CVS and make don't treat
+    it as modified. """
+    try:
+        infile = open(filename, "rb")
+    except IOError:	# File is not there yet
+        out = open(filename, "wb")
+        out.write(updated.encode('utf-8'))
+        out.close()
+        print("New %s" % filename)
+        return
+    original = infile.read()
+    infile.close()
+    original = original.decode('utf-8')
+    if updated != original:
+        os.unlink(filename)
+        out = open(filename, "wb")
+        out.write(updated.encode('utf-8'))
+        out.close()
+        print("Changed %s " % filename)
+    #~ else:
+        #~ print "Unchanged", filename
+
+def Generate(inpath, outpath, commentPrefix, eolType, *lists):
+    """Generate 'outpath' from 'inpath'.
+
+        "eolType" indicates the type of EOLs to use in the generated
+            file. It should be one of following constants: LF, CRLF,
+            CR, or NATIVE.
+    """
+    #print "generate '%s' -> '%s' (comment prefix: %r, eols: %r)"\
+    #      % (inpath, outpath, commentPrefix, eolType)
+    try:
+        infile = open(inpath, "rb")
+    except IOError:
+        print("Can not open %s" % inpath)
+        return
+    original = infile.read()
+    infile.close()
+    original = original.decode('utf-8')
+    updated = CopyWithInsertion(original, commentPrefix,
+        inpath == outpath, eolType, *lists)
+    UpdateFile(outpath, updated)
+
+def Regenerate(filename, commentPrefix, eolType, *lists):
+    """Regenerate the given file.
+
+        "eolType" indicates the type of EOLs to use in the generated
+            file. It should be one of following constants: LF, CRLF,
+            CR, or NATIVE.
+    """
+    Generate(filename, filename, commentPrefix, eolType, *lists)
+
+def FindModules(lexFile):
+    modules = []
+    f = open(lexFile)
+    for l in f.readlines():
+        if l.startswith("LexerModule"):
+            l = l.replace("(", " ")
+            modules.append(l.split()[1])
+    return modules
+
+# Properties that start with lexer. or fold. are automatically found but there are some
+# older properties that don't follow this pattern so must be explicitly listed.
+knownIrregularProperties = [
+    "fold",
+    "styling.within.preprocessor",
+    "tab.timmy.whinge.level",
+    "asp.default.language",
+    "html.tags.case.sensitive",
+    "ps.level",
+    "ps.tokenize",
+    "sql.backslash.escapes",
+    "nsis.uservars",
+    "nsis.ignorecase"
+]
+
+def FindProperties(lexFile):
+    properties = {}
+    f = open(lexFile)
+    for l in f.readlines():
+        if ("GetProperty" in l or "DefineProperty" in l) and "\"" in l:
+            l = l.strip()
+            if not l.startswith("//"):	# Drop comments
+                propertyName = l.split("\"")[1]
+                if propertyName.lower() == propertyName:
+                    # Only allow lower case property names
+                    if propertyName in knownIrregularProperties or \
+                        propertyName.startswith("fold.") or \
+                        propertyName.startswith("lexer."):
+                        properties[propertyName] = 1
+    return properties
+
+def FindPropertyDocumentation(lexFile):
+    documents = {}
+    f = open(lexFile)
+    name = ""
+    for l in f.readlines():
+        l = l.strip()
+        if "// property " in l:
+            propertyName = l.split()[2]
+            if propertyName.lower() == propertyName:
+                # Only allow lower case property names
+                name = propertyName
+                documents[name] = ""
+        elif "DefineProperty" in l and "\"" in l:
+            propertyName = l.split("\"")[1]
+            if propertyName.lower() == propertyName:
+                # Only allow lower case property names
+                name = propertyName
+                documents[name] = ""
+        elif name:
+            if l.startswith("//"):
+                if documents[name]:
+                    documents[name] += " "
+                documents[name] += l[2:].strip()
+            elif l.startswith("\""):
+                l = l[1:].strip()
+                if l.endswith(";"):
+                    l = l[:-1].strip()
+                if l.endswith(")"):
+                    l = l[:-1].strip()
+                if l.endswith("\""):
+                    l = l[:-1]
+                # Fix escaped double quotes
+                l = l.replace("\\\"", "\"")
+                documents[name] += l
+            else:
+                name = ""
+    for name in list(documents.keys()):
+        if documents[name] == "":
+            del documents[name]
+    return documents
+
+def ciCompare(a,b):
+    return cmp(a.lower(), b.lower())
+
+def ciKey(a):
+    return a.lower()
+
+def sortListInsensitive(l):
+    try:    # Try key function
+        l.sort(key=ciKey)
+    except TypeError:    # Earlier version of Python, so use comparison function
+        l.sort(ciCompare)
+
+def RegenerateAll():
+    root="../../"
+
+    # Find all the lexer source code files
+    lexFilePaths = glob.glob(root + "scintilla/lexers/Lex*.cxx")
+    sortListInsensitive(lexFilePaths)
+    lexFiles = [os.path.basename(f)[:-4] for f in lexFilePaths]
+    print(lexFiles)
+    lexerModules = []
+    lexerProperties = {}
+    propertyDocuments = {}
+    for lexFile in lexFilePaths:
+        lexerModules.extend(FindModules(lexFile))
+        for k in FindProperties(lexFile).keys():
+            lexerProperties[k] = 1
+        documents = FindPropertyDocumentation(lexFile)
+        for k in documents.keys():
+            propertyDocuments[k] = documents[k]
+    sortListInsensitive(lexerModules)
+    del lexerProperties["fold.comment.python"]
+    lexerProperties = list(lexerProperties.keys())
+    sortListInsensitive(lexerProperties)
+
+    # Generate HTML to document each property
+    # This is done because tags can not be safely put inside comments in HTML
+    documentProperties = list(propertyDocuments.keys())
+    sortListInsensitive(documentProperties)
+    propertiesHTML = []
+    for k in documentProperties:
+        propertiesHTML.append("\t<tr>\n\t<td>%s</td>\n\t<td>%s</td>\n\t</tr>" %
+            (k, propertyDocuments[k]))
+
+    # Find all the SciTE properties files
+    otherProps = ["abbrev.properties", "Embedded.properties", "SciTEGlobal.properties", "SciTE.properties"]
+    if os.path.exists(root + "scite"):
+        propFilePaths = glob.glob(root + "scite/src/*.properties")
+        sortListInsensitive(propFilePaths)
+        propFiles = [os.path.basename(f) for f in propFilePaths if os.path.basename(f) not in otherProps]
+        sortListInsensitive(propFiles)
+        print(propFiles)
+
+    Regenerate(root + "scintilla/src/Catalogue.cxx", "//", NATIVE, lexerModules)
+    Regenerate(root + "scintilla/win32/scintilla.mak", "#", NATIVE, lexFiles)
+    Regenerate(root + "scintilla/win32/scintilla_vc6.mak", "#", NATIVE, lexFiles)
+    if os.path.exists(root + "scite"):
+        Regenerate(root + "scite/win32/makefile", "#", NATIVE, propFiles)
+        Regenerate(root + "scite/win32/scite.mak", "#", NATIVE, propFiles)
+        Regenerate(root + "scite/src/SciTEProps.cxx", "//", NATIVE, lexerProperties)
+        Regenerate(root + "scite/doc/SciTEDoc.html", "<!--", NATIVE, propertiesHTML)
+        Generate(root + "scite/boundscheck/vcproj.gen",
+         root + "scite/boundscheck/SciTE.vcproj", "#", NATIVE, lexFiles)
+
+RegenerateAll()
diff --git a/plugins/scintilla/scintilla/LexGui4Cli.cxx b/plugins/scintilla/scintilla/LexGui4Cli.cxx
index 1c92de7..13cf9ea 100644
--- a/plugins/scintilla/scintilla/LexGui4Cli.cxx
+++ b/plugins/scintilla/scintilla/LexGui4Cli.cxx
@@ -23,18 +23,21 @@ val SCE_GC_OPERATOR=9
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexHTML.cxx b/plugins/scintilla/scintilla/LexHTML.cxx
index 6038326..4c50a15 100644
--- a/plugins/scintilla/scintilla/LexHTML.cxx
+++ b/plugins/scintilla/scintilla/LexHTML.cxx
@@ -7,19 +7,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
 #include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -54,13 +56,6 @@ inline bool IsOperator(int ch) {
 	return false;
 }
 
-static inline int MakeLowerCase(int ch) {
-	if (ch < 'A' || ch > 'Z')
-		return ch;
-	else
-		return ch - 'A' + 'a';
-}
-
 static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) {
 	size_t i = 0;
 	for (; (i < end - start + 1) && (i < len-1); i++) {
@@ -76,12 +71,12 @@ static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, si
 		char ch = static_cast<char>(styler.SafeGetCharAt(start + i));
 		if ((i == 0) && !IsAWordStart(ch))
 			break;
-		if ((i > 0) && !IsAWordChar(ch)) 
+		if ((i > 0) && !IsAWordChar(ch))
 			break;
 		s[i] = ch;
 	}
 	s[i] = '\0';
-	
+
 	return s;
 }
 
@@ -323,19 +318,19 @@ static int classifyTagHTML(unsigned int start, unsigned int end,
 
 static void classifyWordHTJS(unsigned int start, unsigned int end,
                              WordList &keywords, Accessor &styler, script_mode inScriptType) {
+	char s[30 + 1];
+	unsigned int i = 0;
+	for (; i < end - start + 1 && i < 30; i++) {
+		s[i] = styler[start + i];
+	}
+	s[i] = '\0';
+
 	char chAttr = SCE_HJ_WORD;
-	bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.');
-	if (wordIsNumber)
+	bool wordIsNumber = IsADigit(s[0]) || ((s[0] == '.') && IsADigit(s[1]));
+	if (wordIsNumber) {
 		chAttr = SCE_HJ_NUMBER;
-	else {
-		char s[30 + 1];
-		unsigned int i = 0;
-		for (; i < end - start + 1 && i < 30; i++) {
-			s[i] = styler[start + i];
-		}
-		s[i] = '\0';
-		if (keywords.InList(s))
-			chAttr = SCE_HJ_KEYWORD;
+	} else if (keywords.InList(s)) {
+		chAttr = SCE_HJ_KEYWORD;
 	}
 	styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
 }
@@ -494,7 +489,7 @@ static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType
 	if (strlen(blockType) == 0) {
 		return ((ch == '%') && (chNext == '>'));
 	} else if ((0 == strcmp(blockType, "inherit")) ||
-			   (0 == strcmp(blockType, "namespace")) || 
+			   (0 == strcmp(blockType, "namespace")) ||
 			   (0 == strcmp(blockType, "include")) ||
 			   (0 == strcmp(blockType, "page"))) {
 		return ((ch == '/') && (chNext == '>'));
@@ -507,6 +502,18 @@ static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType
 	}
 }
 
+static bool isDjangoBlockEnd(const int ch, const int chNext, const char *blockType) {
+	if (strlen(blockType) == 0) {
+		return 0;
+	} else if (0 == strcmp(blockType, "%")) {
+		return ((ch == '%') && (chNext == '}'));
+	} else if (0 == strcmp(blockType, "{")) {
+		return ((ch == '}') && (chNext == '}'));
+	} else {
+		return 0;
+	}
+}
+
 static bool isPHPStringState(int state) {
 	return
 	    (state == SCE_HPHP_HSTRING) ||
@@ -575,14 +582,14 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 	styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
 	char prevWord[200];
 	prevWord[0] = '\0';
-	char nextWord[200];
-	nextWord[0] = '\0';
 	char phpStringDelimiter[200]; // PHP is not limited in length, we are
 	phpStringDelimiter[0] = '\0';
 	int StateToPrint = initStyle;
 	int state = stateForPrintState(StateToPrint);
 	char makoBlockType[200];
 	makoBlockType[0] = '\0';
+	char djangoBlockType[2];
+	djangoBlockType[0] = '\0';
 
 	// If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen
 	if (InTagState(state)) {
@@ -607,13 +614,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 	int lineCurrent = styler.GetLine(startPos);
 	int lineState;
 	if (lineCurrent > 0) {
-		lineState = styler.GetLineState(lineCurrent);
+		lineState = styler.GetLineState(lineCurrent-1);
 	} 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. 
+		// 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;
 	}
@@ -630,44 +637,49 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 	if (inScriptType == eNonHtmlScript && state == SCE_H_COMMENT) {
 		scriptLanguage = eScriptComment;
 	}
+	script_type beforeLanguage = ScriptOfState(beforePreProc);
 
-	// property fold.html 
-	//	Folding is turned on or off for HTML and XML files with this option. 
+	// 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. 
+	// 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. 
+	// 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.  
+	// 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. 
+	// 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.  
+	// property lexer.xml.allow.scripts
+	//	Set to 0 to disable scripts in XML.
 	const bool allowScripts = styler.GetPropertyInt("lexer.xml.allow.scripts", 1) != 0;
 
-	// property lexer.html.mako 
-	//	Set to 1 to enable the mako template language.  
+	// property lexer.html.mako
+	//	Set to 1 to enable the mako template language.
 	const bool isMako = styler.GetPropertyInt("lexer.html.mako", 0) != 0;
 
+	// property lexer.html.django
+	//	Set to 1 to enable the django template language.
+	const bool isDjango = styler.GetPropertyInt("lexer.html.django", 0) != 0;
+
 	const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true);
 	const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true);
 	const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", 0x80, true);
@@ -732,8 +744,18 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 				if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC) && (!isStringState(state))) {
 				//Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
 				//if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
-					if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
-						levelCurrent += ((ch == '{') || (ch == '/')) ? 1 : -1;
+					if (ch == '#') {
+						int j = i + 1;
+						while ((j < lengthDoc) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+							j++;
+						}
+						if (styler.Match(j, "region") || styler.Match(j, "if")) {
+							levelCurrent++;
+						} else if (styler.Match(j, "end")) {
+							levelCurrent--;
+						}
+					} else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
+						levelCurrent += (((ch == '{') || (ch == '/')) ? 1 : -1);
 					}
 				} else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) {
 					levelCurrent--;
@@ -785,8 +807,6 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 				visibleChars = 0;
 				levelPrev = levelCurrent;
 			}
-			lineCurrent++;
-			lineStartVisibleChars = 0;
 			styler.SetLineState(lineCurrent,
 			                    ((inScriptType & 0x03) << 0) |
 			                    ((tagOpened & 0x01) << 2) |
@@ -794,13 +814,15 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 			                    ((aspScript & 0x0F) << 4) |
 			                    ((clientScript & 0x0F) << 8) |
 			                    ((beforePreProc & 0xFF) << 12));
+			lineCurrent++;
+			lineStartVisibleChars = 0;
 		}
 
 		// Allow falling through to mako handling code if newline is going to end a block
 		if (((ch == '\r' && chNext != '\n') || (ch == '\n')) &&
 			(!isMako || (0 != strcmp(makoBlockType, "%")))) {
 		}
-		
+
 		// generic end of script processing
 		else if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) {
 			// Check if it's the end of the script tag (or any other HTML tag)
@@ -857,9 +879,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 		else if ((state != SCE_H_ASPAT) &&
 		         !isPHPStringState(state) &&
 		         (state != SCE_HPHP_COMMENT) &&
+		         (state != SCE_HPHP_COMMENTLINE) &&
 		         (ch == '<') &&
 		         (chNext == '?') &&
-				 !IsScriptCommentState(state) ) {
+				 !IsScriptCommentState(state)) {
+ 			beforeLanguage = scriptLanguage;
 			scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP);
 			if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
 			styler.ColourTo(i - 1, StateToPrint);
@@ -886,13 +910,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 		}
 
 		// handle the start Mako template Python code
-		else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') || 
+		else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') ||
 															 (lineStartVisibleChars == 1 && ch == '%') ||
 															 (ch == '$' && chNext == '{') ||
 															 (ch == '<' && chNext == '/' && chNext2 == '%'))) {
 			if (ch == '%')
 				strcpy(makoBlockType, "%");
-			else if (ch == '$') 
+			else if (ch == '$')
 				strcpy(makoBlockType, "{");
 			else if (chNext == '/')
 				GetNextWord(styler, i+3, makoBlockType, sizeof(makoBlockType));
@@ -917,7 +941,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 			styler.ColourTo(i, SCE_H_ASP);
 			if (foldHTMLPreprocessor && ch == '<')
 				levelCurrent++;
-				
+
 			if (ch != '%' && ch != '$') {
 				i += strlen(makoBlockType);
 				visibleChars += strlen(makoBlockType);
@@ -931,8 +955,62 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 			continue;
 		}
 
+		// handle the start/end of Django comment
+		else if (isDjango && state != SCE_H_COMMENT && (ch == '{' && chNext == '#')) {
+			styler.ColourTo(i - 1, StateToPrint);
+			beforePreProc = state;
+			beforeLanguage = scriptLanguage;
+			if (inScriptType == eNonHtmlScript)
+				inScriptType = eNonHtmlScriptPreProc;
+			else
+				inScriptType = eNonHtmlPreProc;
+			i += 1;
+			visibleChars += 1;
+			scriptLanguage = eScriptComment;
+			state = SCE_H_COMMENT;
+			styler.ColourTo(i, SCE_H_ASP);
+			ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+			continue;
+		} else if (isDjango && state == SCE_H_COMMENT && (ch == '#' && chNext == '}')) {
+			styler.ColourTo(i - 1, StateToPrint);
+			i += 1;
+			visibleChars += 1;
+			styler.ColourTo(i, SCE_H_ASP);
+			state = beforePreProc;
+			if (inScriptType == eNonHtmlScriptPreProc)
+				inScriptType = eNonHtmlScript;
+			else
+				inScriptType = eHtml;
+			scriptLanguage = beforeLanguage;
+			continue;
+		}
+
+		// handle the start Django template code
+		else if (isDjango && scriptLanguage != eScriptPython && (ch == '{' && (chNext == '%' ||  chNext == '{'))) {
+			if (chNext == '%')
+				strcpy(djangoBlockType, "%");
+			else
+				strcpy(djangoBlockType, "{");
+			styler.ColourTo(i - 1, StateToPrint);
+			beforePreProc = state;
+			if (inScriptType == eNonHtmlScript)
+				inScriptType = eNonHtmlScriptPreProc;
+			else
+				inScriptType = eNonHtmlPreProc;
+
+			i += 1;
+			visibleChars += 1;
+			state = SCE_HP_START;
+			beforeLanguage = scriptLanguage;
+			scriptLanguage = eScriptPython;
+			styler.ColourTo(i, SCE_H_ASP);
+
+			ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+			continue;
+		}
+
 		// handle the start of ASP pre-processor = Non-HTML
-		else if (!isMako && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
+		else if (!isMako && !isDjango && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
 			styler.ColourTo(i - 1, StateToPrint);
 			beforePreProc = state;
 			if (inScriptType == eNonHtmlScript)
@@ -977,7 +1055,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 				 (ch == '!') &&
 				 (StateToPrint != SCE_H_CDATA) &&
 				 (!IsCommentState(StateToPrint)) &&
-				 (!IsScriptCommentState(StateToPrint)) ) {
+				 (!IsScriptCommentState(StateToPrint))) {
 			beforePreProc = state;
 			styler.ColourTo(i - 2, StateToPrint);
 			if ((chNext == '-') && (chNext2 == '-')) {
@@ -998,8 +1076,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 		}
 
 		// handle the end of Mako Python code
-		else if (isMako && 
-			     ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) && 
+		else if (isMako &&
+			     ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
 				 (scriptLanguage != eScriptNone) && stateAllowsTermination(state) &&
 				 isMakoBlockEnd(ch, chNext, makoBlockType)) {
 			if (state == SCE_H_ASPAT) {
@@ -1030,8 +1108,34 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 			continue;
 		}
 
+		// handle the end of Django template code
+		else if (isDjango &&
+			     ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
+				 (scriptLanguage != eScriptNone) && stateAllowsTermination(state) &&
+				 isDjangoBlockEnd(ch, chNext, djangoBlockType)) {
+			if (state == SCE_H_ASPAT) {
+				aspScript = segIsScriptingIndicator(styler,
+				                                    styler.GetStartSegment(), i - 1, aspScript);
+			}
+			if (state == SCE_HP_WORD) {
+				classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
+			} else {
+				styler.ColourTo(i - 1, StateToPrint);
+			}
+			i += 1;
+			visibleChars += 1;
+			styler.ColourTo(i, SCE_H_ASP);
+			state = beforePreProc;
+			if (inScriptType == eNonHtmlScriptPreProc)
+				inScriptType = eNonHtmlScript;
+			else
+				inScriptType = eHtml;
+			scriptLanguage = beforeLanguage;
+			continue;
+		}
+
 		// handle the end of a pre-processor = Non-HTML
-		else if ((!isMako && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
+		else if ((!isMako && !isDjango && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
 				  (((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) &&
 				  (((ch == '%') || (ch == '?')) && (chNext == '>'))) ||
 		         ((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
@@ -1081,7 +1185,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 			if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
 				levelCurrent--;
 			}
-			scriptLanguage = eScriptNone;
+			scriptLanguage = beforeLanguage;
 			continue;
 		}
 		/////////////////////////////////////
@@ -1564,7 +1668,9 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
 				i += 2;
 			} else if (isLineEnd(ch)) {
 				styler.ColourTo(i - 1, StateToPrint);
-				state = SCE_HJ_STRINGEOL;
+				if (chPrev != '\\' && (chPrev2 != '\\' || chPrev != '\r' || ch != '\n')) {
+					state = SCE_HJ_STRINGEOL;
+				}
 			}
 			break;
 		case SCE_HJ_STRINGEOL:
diff --git a/plugins/scintilla/scintilla/LexHaskell.cxx b/plugins/scintilla/scintilla/LexHaskell.cxx
index b528f3f..37d85d0 100644
--- a/plugins/scintilla/scintilla/LexHaskell.cxx
+++ b/plugins/scintilla/scintilla/LexHaskell.cxx
@@ -7,6 +7,7 @@
  *
  *    Written by Tobias Engvall - tumm at dtek dot chalmers dot se
  *
+ *    Several bug fixes by Krasimir Angelov - kr.angelov at gmail.com
  *
  *    TODO:
  *    * Implement a folder :)
@@ -18,19 +19,22 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
 #include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -45,11 +49,13 @@ using namespace Scintilla;
 
 #endif
 
-// Max level of nested comments
-#define SCE_HA_COMMENTMAX SCE_HA_COMMENTBLOCK3
-
-
-enum kwType { kwOther, kwClass, kwData, kwInstance, kwImport, kwModule, kwType};
+#define HA_MODE_DEFAULT     0
+#define HA_MODE_IMPORT1     1
+#define HA_MODE_IMPORT2     2
+#define HA_MODE_IMPORT3     3
+#define HA_MODE_MODULE      4
+#define HA_MODE_FFI         5
+#define HA_MODE_TYPE        6
 
 static inline bool IsNewline(const int ch) {
    return (ch == '\n' || ch == '\r');
@@ -73,146 +79,234 @@ static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
                                WordList *keywordlists[], Accessor &styler) {
 
    WordList &keywords = *keywordlists[0];
-
-   int kwLast = kwOther;
+   WordList &ffi      = *keywordlists[1];
 
    StyleContext sc(startPos, length, initStyle, styler);
 
-   for (; sc.More(); sc.Forward()) {
+   int lineCurrent = styler.GetLine(startPos);
+   int state = lineCurrent ? styler.GetLineState(lineCurrent-1)
+                           : HA_MODE_DEFAULT;
+   int mode  = state & 0xF;
+   int xmode = state >> 4;
 
+   while (sc.More()) {
       // Check for state end
+
          // Operator
       if (sc.state == SCE_HA_OPERATOR) {
-         kwLast = kwOther;
-         sc.SetState(SCE_HA_DEFAULT);
+         if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
+            sc.Forward();
+         } else {
+            styler.ColourTo(sc.currentPos - 1, sc.state);
+            sc.ChangeState(SCE_HA_DEFAULT);
+         }
       }
          // String
       else if (sc.state == SCE_HA_STRING) {
          if (sc.ch == '\"') {
-            sc.ForwardSetState(SCE_HA_DEFAULT);
+			sc.Forward();
+            styler.ColourTo(sc.currentPos-1, sc.state);
+            sc.ChangeState(SCE_HA_DEFAULT);
          } else if (sc.ch == '\\') {
-            sc.Forward();
-         }
+            sc.Forward(2);
+         } else if (sc.atLineEnd) {
+			styler.ColourTo(sc.currentPos-1, sc.state);
+			sc.ChangeState(SCE_HA_DEFAULT);
+		 } else {
+			sc.Forward();
+		 }
       }
          // Char
       else if (sc.state == SCE_HA_CHARACTER) {
          if (sc.ch == '\'') {
-            sc.ForwardSetState(SCE_HA_DEFAULT);
+			sc.Forward();
+            styler.ColourTo(sc.currentPos-1, sc.state);
+            sc.ChangeState(SCE_HA_DEFAULT);
          } else if (sc.ch == '\\') {
-            sc.Forward();
-         }
+            sc.Forward(2);
+         } else if (sc.atLineEnd) {
+			styler.ColourTo(sc.currentPos-1, sc.state);
+			sc.ChangeState(SCE_HA_DEFAULT);
+		 } else {
+			sc.Forward();
+		 }
       }
          // Number
       else if (sc.state == SCE_HA_NUMBER) {
-         if (!IsADigit(sc.ch)) {
-            sc.SetState(SCE_HA_DEFAULT);
-         }
-      }
-         // Types, constructors, etc.
-      else if (sc.state == SCE_HA_CAPITAL) {
-         if (!IsAWordChar(sc.ch) || sc.ch == '.') {
-            sc.SetState(SCE_HA_DEFAULT);
+         if (IsADigit(sc.ch, xmode)) {
+            sc.Forward();
+         } else if ((xmode == 10) &&
+                    (sc.ch == 'e' || sc.ch == 'E') &&
+                    (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-')) {
+			sc.Forward();
+			if (sc.ch == '+' || sc.ch == '-')
+				sc.Forward();
+         } else {
+            styler.ColourTo(sc.currentPos - 1, sc.state);
+            sc.ChangeState(SCE_HA_DEFAULT);
          }
       }
          // Identifier
       else if (sc.state == SCE_HA_IDENTIFIER) {
-         if (!IsAWordChar(sc.ch)) {
+         if (IsAWordChar(sc.ch)) {
+            sc.Forward();
+         } else {
             char s[100];
             sc.GetCurrent(s, sizeof(s));
-            int style = SCE_HA_IDENTIFIER;
-            if ((kwLast == kwImport) || (strcmp(s,"qualified") == 0) || (strcmp(s,"as") == 0)) {
-               style = SCE_HA_IMPORT;
-            } else if (keywords.InList(s)) {
+            int style = sc.state;
+            int new_mode = 0;
+            if (keywords.InList(s)) {
                style = SCE_HA_KEYWORD;
-            } else if (kwLast == kwData) {
-               style = SCE_HA_DATA;
-            } else if (kwLast == kwClass) {
-               style = SCE_HA_CLASS;
-            } else if (kwLast == kwModule) {
-               style = SCE_HA_MODULE;
             } else if (isupper(s[0])) {
-               style = SCE_HA_CAPITAL;
-            }
-            sc.ChangeState(style);
-            sc.SetState(SCE_HA_DEFAULT);
-            if (style == SCE_HA_KEYWORD) {
-               if (0 == strcmp(s, "class"))
-                  kwLast = kwClass;
-               else if (0 == strcmp(s, "data"))
-                  kwLast = kwData;
-               else if (0 == strcmp(s, "instance"))
-                  kwLast = kwInstance;
-               else if (0 == strcmp(s, "import"))
-                  kwLast = kwImport;
-               else if (0 == strcmp(s, "module"))
-                  kwLast = kwModule;
+               if (mode >= HA_MODE_IMPORT1 && mode <= HA_MODE_IMPORT3) {
+                  style    = SCE_HA_MODULE;
+                  new_mode = HA_MODE_IMPORT2;
+               } else if (mode == HA_MODE_MODULE)
+                  style = SCE_HA_MODULE;
                else
-                  kwLast = kwOther;
-            } else if (style == SCE_HA_CLASS || style == SCE_HA_IMPORT ||
-                       style == SCE_HA_MODULE || style == SCE_HA_CAPITAL ||
-                       style == SCE_HA_DATA || style == SCE_HA_INSTANCE) {
-               kwLast = kwOther;
+                  style = SCE_HA_CAPITAL;
+            } else if (mode == HA_MODE_IMPORT1 &&
+                       strcmp(s,"qualified") == 0) {
+                style    = SCE_HA_KEYWORD;
+                new_mode = HA_MODE_IMPORT1;
+            } else if (mode == HA_MODE_IMPORT2) {
+                if (strcmp(s,"as") == 0) {
+                   style    = SCE_HA_KEYWORD;
+                   new_mode = HA_MODE_IMPORT3;
+               } else if (strcmp(s,"hiding") == 0) {
+                   style     = SCE_HA_KEYWORD;
+               }
+            } else if (mode == HA_MODE_FFI) {
+			   if (ffi.InList(s)) {
+                  style = SCE_HA_KEYWORD;
+                  new_mode = HA_MODE_FFI;
+               }
             }
+            else if (mode == HA_MODE_TYPE) {
+               if (strcmp(s,"family") == 0)
+                  style    = SCE_HA_KEYWORD;
+			}
+            styler.ColourTo(sc.currentPos - 1, style);
+            if (strcmp(s,"import") == 0 && mode != HA_MODE_FFI)
+               new_mode = HA_MODE_IMPORT1;
+            else if (strcmp(s,"module") == 0)
+               new_mode = HA_MODE_MODULE;
+            else if (strcmp(s,"foreign") == 0)
+               new_mode = HA_MODE_FFI;
+            else if (strcmp(s,"type") == 0)
+               new_mode = HA_MODE_TYPE;
+            sc.ChangeState(SCE_HA_DEFAULT);
+            mode = new_mode;
          }
       }
+
          // Comments
             // Oneliner
       else if (sc.state == SCE_HA_COMMENTLINE) {
-         if (IsNewline(sc.ch))
-            sc.SetState(SCE_HA_DEFAULT);
+         if (sc.atLineEnd) {
+            styler.ColourTo(sc.currentPos - 1, sc.state);
+            sc.ChangeState(SCE_HA_DEFAULT);
+         } else {
+            sc.Forward();
+         }
       }
             // Nested
-      else if (sc.state >= SCE_HA_COMMENTBLOCK) {
+      else if (sc.state == SCE_HA_COMMENTBLOCK) {
          if (sc.Match("{-")) {
-            if (sc.state < SCE_HA_COMMENTMAX)
-               sc.SetState(sc.state + 1);
+            sc.Forward(2);
+            xmode++;
          }
          else if (sc.Match("-}")) {
+            sc.Forward(2);
+            xmode--;
+            if (xmode == 0) {
+               styler.ColourTo(sc.currentPos - 1, sc.state);
+               sc.ChangeState(SCE_HA_DEFAULT);
+            }
+         } else {
+            if (sc.atLineEnd) {
+				// Remember the line state for future incremental lexing
+				styler.SetLineState(lineCurrent, (xmode << 4) | mode);
+				lineCurrent++;
+			}
             sc.Forward();
-            if (sc.state == SCE_HA_COMMENTBLOCK)
-               sc.ForwardSetState(SCE_HA_DEFAULT);
-            else
-               sc.ForwardSetState(sc.state - 1);
          }
       }
       // New state?
       if (sc.state == SCE_HA_DEFAULT) {
          // Digit
-         if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
-            sc.SetState(SCE_HA_NUMBER);
-            if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) { // Match anything starting with "0x" or "0X", too
-               sc.Forward(1);
-            }
+         if (IsADigit(sc.ch) ||
+             (sc.ch == '.' && IsADigit(sc.chNext)) ||
+             (sc.ch == '-' && IsADigit(sc.chNext))) {
+            styler.ColourTo(sc.currentPos - 1, sc.state);
+            sc.ChangeState(SCE_HA_NUMBER);
+            if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) {
+				// Match anything starting with "0x" or "0X", too
+				sc.Forward(2);
+				xmode = 16;
+            } else if (sc.ch == '0' && (sc.chNext == 'O' || sc.chNext == 'o')) {
+				// Match anything starting with "0x" or "0X", too
+				sc.Forward(2);
+				xmode = 8;
+            } else {
+				sc.Forward();
+				xmode = 10;
+			}
+            mode = HA_MODE_DEFAULT;
          }
          // Comment line
          else if (sc.Match("--")) {
-            sc.SetState(SCE_HA_COMMENTLINE);
+            styler.ColourTo(sc.currentPos - 1, sc.state);
+            sc.Forward(2);
+            sc.ChangeState(SCE_HA_COMMENTLINE);
          // Comment block
          }
          else if (sc.Match("{-")) {
-            sc.SetState(SCE_HA_COMMENTBLOCK);
+            styler.ColourTo(sc.currentPos - 1, sc.state);
+            sc.Forward(2);
+            sc.ChangeState(SCE_HA_COMMENTBLOCK);
+            xmode = 1;
          }
          // String
          else if (sc.Match('\"')) {
-            sc.SetState(SCE_HA_STRING);
+            styler.ColourTo(sc.currentPos - 1, sc.state);
+            sc.Forward();
+            sc.ChangeState(SCE_HA_STRING);
          }
          // Character
          else if (sc.Match('\'')) {
-            sc.SetState(SCE_HA_CHARACTER);
-         }
-         // Stringstart
-         else if (sc.Match('\"')) {
-            sc.SetState(SCE_HA_STRING);
+            styler.ColourTo(sc.currentPos - 1, sc.state);
+            sc.Forward();
+            sc.ChangeState(SCE_HA_CHARACTER);
          }
+         else if (sc.ch == '(' || sc.ch == ')' ||
+                  sc.ch == '{' || sc.ch == '}' ||
+                  sc.ch == '[' || sc.ch == ']') {
+			styler.ColourTo(sc.currentPos - 1, sc.state);
+			sc.Forward();
+			styler.ColourTo(sc.currentPos - 1, SCE_HA_OPERATOR);
+			mode = HA_MODE_DEFAULT;
+		 }
          // Operator
          else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
-            sc.SetState(SCE_HA_OPERATOR);
+            styler.ColourTo(sc.currentPos - 1, sc.state);
+            sc.Forward();
+            sc.ChangeState(SCE_HA_OPERATOR);
+            mode = HA_MODE_DEFAULT;
          }
          // Keyword
          else if (IsAWordStart(sc.ch)) {
-               sc.SetState(SCE_HA_IDENTIFIER);
+            styler.ColourTo(sc.currentPos - 1, sc.state);
+            sc.Forward();
+            sc.ChangeState(SCE_HA_IDENTIFIER);
+         } else {
+            if (sc.atLineEnd) {
+				// Remember the line state for future incremental lexing
+				styler.SetLineState(lineCurrent, (xmode << 4) | mode);
+				lineCurrent++;
+			}
+            sc.Forward();
          }
-
       }
    }
    sc.Complete();
@@ -272,4 +366,3 @@ void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
 #endif
 
 LexerModule lmHaskell(SCLEX_HASKELL, ColorizeHaskellDoc, "haskell");
-
diff --git a/plugins/scintilla/scintilla/LexInno.cxx b/plugins/scintilla/scintilla/LexInno.cxx
index 6d1102c..a0f5b32 100644
--- a/plugins/scintilla/scintilla/LexInno.cxx
+++ b/plugins/scintilla/scintilla/LexInno.cxx
@@ -7,19 +7,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "CharClassify.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -34,7 +36,6 @@ 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];
@@ -44,6 +45,10 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
 	WordList &pascalKeywords = *keywordLists[4];
 	WordList &userKeywords = *keywordLists[5];
 
+	int curLine = styler.GetLine(startPos);
+	int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
+	bool isCode = (curLineState == 1);
+
 	// Go through all provided text segment
 	// using the hand-written state machine shown below
 	styler.StartAt(startPos);
@@ -64,6 +69,12 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
 		isEOL = (ch == '\n' || ch == '\r');
 		isWS = (ch == ' ' || ch == '\t');
 
+		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+			// Remember the line state for future incremental lexing
+			curLine = styler.GetLine(i);
+			styler.SetLineState(curLine, (isCode ? 1 : 0));
+		}
+
 		switch(state) {
 			case SCE_INNO_DEFAULT:
 				if (!isCode && ch == ';' && isBOLWS) {
diff --git a/plugins/scintilla/scintilla/LexKix.cxx b/plugins/scintilla/scintilla/LexKix.cxx
index 06e7c17..32af263 100644
--- a/plugins/scintilla/scintilla/LexKix.cxx
+++ b/plugins/scintilla/scintilla/LexKix.cxx
@@ -7,18 +7,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexLisp.cxx b/plugins/scintilla/scintilla/LexLisp.cxx
old mode 100755
new mode 100644
index e1d06cb..08f765a
--- a/plugins/scintilla/scintilla/LexLisp.cxx
+++ b/plugins/scintilla/scintilla/LexLisp.cxx
@@ -8,18 +8,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
 #include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -44,7 +47,7 @@ static inline bool isLispwordstart(char ch) {
 
 
 static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, WordList &keywords_kw, Accessor &styler) {
-	PLATFORM_ASSERT(end >= start);
+	assert(end >= start);
 	char s[100];
 	unsigned int i;
 	bool digit_flag = true;
@@ -139,7 +142,7 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W
 				}
 			}
 		} else if (state == SCE_LISP_MACRO_DISPATCH) {
-			if (!isdigit(ch)) {
+			if (!(isascii(ch) && isdigit(ch))) {
 				if (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) {
 					state = SCE_LISP_DEFAULT;
 				} else {
diff --git a/plugins/scintilla/scintilla/LexLout.cxx b/plugins/scintilla/scintilla/LexLout.cxx
index 492e4ed..985b93b 100644
--- a/plugins/scintilla/scintilla/LexLout.cxx
+++ b/plugins/scintilla/scintilla/LexLout.cxx
@@ -7,18 +7,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexLua.cxx b/plugins/scintilla/scintilla/LexLua.cxx
index a1e579f..1dc9d40 100644
--- a/plugins/scintilla/scintilla/LexLua.cxx
+++ b/plugins/scintilla/scintilla/LexLua.cxx
@@ -9,19 +9,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
 #include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
 #include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -59,8 +61,9 @@ static void ColouriseLuaDoc(
 	CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
 	CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
 	// Not exactly following number definition (several dots are seen as OK, etc.)
-	// but probably enough in most cases.
-	CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefABCDEF");
+	// but probably enough in most cases. [pP] is for hex floats.
+	CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP");
+	CharacterSet setExponent(CharacterSet::setNone, "eEpP");
 	CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#");
 	CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\");
 
@@ -68,12 +71,16 @@ static void ColouriseLuaDoc(
 	// Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level,
 	// if we are inside such a string. Block comment was introduced in Lua 5.0,
 	// blocks with separators [=[ ... ]=] in Lua 5.1.
+	// Continuation of a string (\* whitespace escaping) is controlled by stringWs.
 	int nestLevel = 0;
 	int sepCount = 0;
-	if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT) {
+	int stringWs = 0;
+	if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT ||
+		initStyle == SCE_LUA_STRING || initStyle == SCE_LUA_CHARACTER) {
 		int lineState = styler.GetLineState(currentLine - 1);
-		nestLevel = lineState >> 8;
+		nestLevel = lineState >> 9;
 		sepCount = lineState & 0xFF;
+		stringWs = lineState & 0x100;
 	}
 
 	// Do not leak onto next line
@@ -93,8 +100,10 @@ static void ColouriseLuaDoc(
 			switch (sc.state) {
 			case SCE_LUA_LITERALSTRING:
 			case SCE_LUA_COMMENT:
-				// Inside a literal string or block comment, we set the line state
-				styler.SetLineState(currentLine, (nestLevel << 8) | sepCount);
+			case SCE_LUA_STRING:
+			case SCE_LUA_CHARACTER:
+				// Inside a literal string, block comment or string, we set the line state
+				styler.SetLineState(currentLine, (nestLevel << 9) | stringWs | sepCount);
 				break;
 			default:
 				// Reset the line state
@@ -123,11 +132,11 @@ static void ColouriseLuaDoc(
 		if (sc.state == SCE_LUA_OPERATOR) {
 			sc.SetState(SCE_LUA_DEFAULT);
 		} else if (sc.state == SCE_LUA_NUMBER) {
-			// We stop the number definition on non-numerical non-dot non-eE non-sign non-hexdigit char
+			// We stop the number definition on non-numerical non-dot non-eEpP non-sign non-hexdigit char
 			if (!setNumber.Contains(sc.ch)) {
 				sc.SetState(SCE_LUA_DEFAULT);
 			} else if (sc.ch == '-' || sc.ch == '+') {
-				if (sc.chPrev != 'E' && sc.chPrev != 'e')
+				if (!setExponent.Contains(sc.chPrev))
 					sc.SetState(SCE_LUA_DEFAULT);
 			}
 		} else if (sc.state == SCE_LUA_IDENTIFIER) {
@@ -158,24 +167,38 @@ static void ColouriseLuaDoc(
 				sc.ForwardSetState(SCE_LUA_DEFAULT);
 			}
 		} else if (sc.state == SCE_LUA_STRING) {
+			if (stringWs) {
+				if (!IsASpace(sc.ch))
+					stringWs = 0;
+			}
 			if (sc.ch == '\\') {
 				if (setEscapeSkip.Contains(sc.chNext)) {
 					sc.Forward();
+				} else if (sc.chNext == '*') {
+					sc.Forward();
+					stringWs = 0x100;
 				}
 			} else if (sc.ch == '\"') {
 				sc.ForwardSetState(SCE_LUA_DEFAULT);
-			} else if (sc.atLineEnd) {
+			} else if (stringWs == 0 && sc.atLineEnd) {
 				sc.ChangeState(SCE_LUA_STRINGEOL);
 				sc.ForwardSetState(SCE_LUA_DEFAULT);
 			}
 		} else if (sc.state == SCE_LUA_CHARACTER) {
+			if (stringWs) {
+				if (!IsASpace(sc.ch))
+					stringWs = 0;
+			}
 			if (sc.ch == '\\') {
 				if (setEscapeSkip.Contains(sc.chNext)) {
 					sc.Forward();
+				} else if (sc.chNext == '*') {
+					sc.Forward();
+					stringWs = 0x100;
 				}
 			} else if (sc.ch == '\'') {
 				sc.ForwardSetState(SCE_LUA_DEFAULT);
-			} else if (sc.atLineEnd) {
+			} else if (stringWs == 0 && sc.atLineEnd) {
 				sc.ChangeState(SCE_LUA_STRINGEOL);
 				sc.ForwardSetState(SCE_LUA_DEFAULT);
 			}
@@ -212,8 +235,10 @@ static void ColouriseLuaDoc(
 				sc.SetState(SCE_LUA_IDENTIFIER);
 			} else if (sc.ch == '\"') {
 				sc.SetState(SCE_LUA_STRING);
+				stringWs = 0;
 			} else if (sc.ch == '\'') {
 				sc.SetState(SCE_LUA_CHARACTER);
+				stringWs = 0;
 			} else if (sc.ch == '[') {
 				sepCount = LongDelimCheck(sc);
 				if (sepCount == 0) {
diff --git a/plugins/scintilla/scintilla/LexMMIXAL.cxx b/plugins/scintilla/scintilla/LexMMIXAL.cxx
index a00f35c..59bb9fd 100644
--- a/plugins/scintilla/scintilla/LexMMIXAL.cxx
+++ b/plugins/scintilla/scintilla/LexMMIXAL.cxx
@@ -9,18 +9,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -32,7 +35,7 @@ static inline bool IsAWordChar(const int ch) {
 }
 
 inline bool isMMIXALOperator(char ch) {
-	if (isalnum(ch))
+	if (isascii(ch) && isalnum(ch))
 		return false;
 	if (ch == '+' || ch == '-' || ch == '|' || ch == '^' ||
 		ch == '*' || ch == '/' || ch == '/' ||
diff --git a/plugins/scintilla/scintilla/LexMPT.cxx b/plugins/scintilla/scintilla/LexMPT.cxx
index b0099ff..c09ac7a 100644
--- a/plugins/scintilla/scintilla/LexMPT.cxx
+++ b/plugins/scintilla/scintilla/LexMPT.cxx
@@ -7,21 +7,25 @@
 // Copyright 2003 by Marius Gheorghe <mgheorghe cabletest com>
 // The License.txt file describes the conditions under which this software may be distributed.
 
+#include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
 
 #include <string>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
@@ -32,7 +36,7 @@ static int GetLotLineState(std::string &line) {
 		// Now finds the first non-blank character
 		unsigned i; // Declares counter here to make it persistent after the for loop
 		for (i = 0; i < line.length(); ++i) {
-			if (!isspace(line[i]))
+			if (!(isascii(line[i]) && isspace(line[i])))
 				break;
 		}
 
@@ -66,7 +70,7 @@ static int GetLotLineState(std::string &line) {
 				return SCE_LOT_ABORT;
 			}
 			else {
-				return i ? SCE_LOT_PASS : SCE_LOT_DEFAULT;			
+				return i ? SCE_LOT_PASS : SCE_LOT_DEFAULT;
 			}
 		}
 	}
@@ -135,10 +139,10 @@ static void FoldLotDoc(unsigned int startPos, int length, int, WordList *[], Acc
 		if (ch == '\r' && chNext == '\n') {
 			// TO DO:
 			// Should really get the state of the previous line from the styler
-			int stylePrev = style;	
+			int stylePrev = style;
 			style = styleNext;
 			styleNext = styler.StyleAt(i + 2);
-		
+
 			switch (style) {
 /*
 			case SCE_LOT_SET:
@@ -147,7 +151,7 @@ static void FoldLotDoc(unsigned int startPos, int length, int, WordList *[], Acc
 */
 			case SCE_LOT_FAIL:
 /*
-				if (stylePrev != SCE_LOT_FAIL) 
+				if (stylePrev != SCE_LOT_FAIL)
 					lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
 				else
 					lev = SC_FOLDLEVELBASE + 1;
@@ -156,7 +160,7 @@ static void FoldLotDoc(unsigned int startPos, int length, int, WordList *[], Acc
 				break;
 
 			default:
-				if (lineCurrent == 0 || stylePrev == SCE_LOT_FAIL) 
+				if (lineCurrent == 0 || stylePrev == SCE_LOT_FAIL)
 					lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
 				else
 					lev = SC_FOLDLEVELBASE + 1;
@@ -166,7 +170,7 @@ static void FoldLotDoc(unsigned int startPos, int length, int, WordList *[], Acc
 				break;
 			}
 
-			if (lev != styler.LevelAt(lineCurrent)) 
+			if (lev != styler.LevelAt(lineCurrent))
 				styler.SetLevel(lineCurrent, lev);
 
 			lineCurrent++;
diff --git a/plugins/scintilla/scintilla/LexMSSQL.cxx b/plugins/scintilla/scintilla/LexMSSQL.cxx
index 4a3f3be..ce60039 100644
--- a/plugins/scintilla/scintilla/LexMSSQL.cxx
+++ b/plugins/scintilla/scintilla/LexMSSQL.cxx
@@ -7,18 +7,22 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
diff --git a/plugins/scintilla/scintilla/LexMagik.cxx b/plugins/scintilla/scintilla/LexMagik.cxx
index c6f6585..45390d4 100644
--- a/plugins/scintilla/scintilla/LexMagik.cxx
+++ b/plugins/scintilla/scintilla/LexMagik.cxx
@@ -8,18 +8,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexMarkdown.cxx b/plugins/scintilla/scintilla/LexMarkdown.cxx
index f7fc48f..3937120 100644
--- a/plugins/scintilla/scintilla/LexMarkdown.cxx
+++ b/plugins/scintilla/scintilla/LexMarkdown.cxx
@@ -2,31 +2,31 @@
  *  LexMarkdown.cxx
  *
  *  A simple Markdown lexer for scintilla.
- *   
+ *
  *  Includes highlighting for some extra features from the
- *  Pandoc implementation; strikeout, using '#.' as a default 
+ *  Pandoc implementation; strikeout, using '#.' as a default
  *  ordered list item marker, and delimited code blocks.
- * 
+ *
  *  Limitations:
- * 
+ *
  *  Standard indented code blocks are not highlighted at all,
- *  as it would conflict with other indentation schemes. Use 
+ *  as it would conflict with other indentation schemes. Use
  *  delimited code blocks for blanket highlighting of an
  *  entire code block.  Embedded HTML is not highlighted either.
  *  Blanket HTML highlighting has issues, because some Markdown
  *  implementations allow Markdown markup inside of the HTML. Also,
- *  there is a following blank line issue that can't be ignored, 
- *  explained in the next paragraph. Embedded HTML and code 
- *  blocks would be better supported with language specific 
+ *  there is a following blank line issue that can't be ignored,
+ *  explained in the next paragraph. Embedded HTML and code
+ *  blocks would be better supported with language specific
  *  highlighting.
- * 
+ *
  *  The highlighting aims to accurately reflect correct syntax,
  *  but a few restrictions are relaxed. Delimited code blocks are
- *  highlighted, even if the line following the code block is not blank.  
+ *  highlighted, even if the line following the code block is not blank.
  *  Requiring a blank line after a block, breaks the highlighting
  *  in certain cases, because of the way Scintilla ends up calling
  *  the lexer.
- * 
+ *
  *  Written by Jon Strait - jstrait moonloop net
  *
  *  The License.txt file describes the conditions under which this
@@ -34,20 +34,22 @@
  *
  *****************************************************************/
 
-#include <stdlib.h>         
+#include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -74,7 +76,7 @@ static bool FollowToLineEnd(const int ch, const int state, const unsigned int en
     else return false;
 }
 
-// Set the state on text section from current to length characters, 
+// Set the state on text section from current to length characters,
 // then set the rest until the newline to default, except for any characters matching token
 static void SetStateAndZoom(const int state, const int length, const int token, StyleContext &sc) {
     sc.SetState(state);
@@ -100,9 +102,9 @@ static void SetStateAndZoom(const int state, const int length, const int token,
 static bool HasPrevLineContent(StyleContext &sc) {
     int i = 0;
     // Go back to the previous newline
-    while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i))) 
+    while ((--i + (int)sc.currentPos) >= 0 && !IsNewline(sc.GetRelative(i)))
         ;
-    while (--i + sc.currentPos) {
+    while ((--i + (int)sc.currentPos) >= 0) {
         if (IsNewline(sc.GetRelative(i)))
             break;
         if (!IsASpaceOrTab(sc.GetRelative(i)))
@@ -116,12 +118,12 @@ static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
     unsigned int i = 0;
     while (++i) {
         c = sc.GetRelative(i);
-        if (c == sc.ch) 
+        if (c == sc.ch)
             ++count;
         // hit a terminating character
         else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {
             // Are we a valid HRULE
-            if ((IsNewline(c) || sc.currentPos + i == endPos) && 
+            if ((IsNewline(c) || sc.currentPos + i == endPos) &&
                     count >= 3 && !HasPrevLineContent(sc)) {
                 sc.SetState(SCE_MARKDOWN_HRULE);
                 sc.Forward(i);
@@ -145,7 +147,7 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
     // Useful in the corner case of having to start at the beginning file position
     // in the default state.
     bool freezeCursor = false;
-    
+
     StyleContext sc(startPos, length, initStyle, styler);
 
     while (sc.More()) {
@@ -154,18 +156,18 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
             sc.Forward();
             continue;
         }
-        
+
         // A blockquotes resets the line semantics
         if (sc.state == SCE_MARKDOWN_BLOCKQUOTE)
             sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
-        
+
         // Conditional state-based actions
         if (sc.state == SCE_MARKDOWN_CODE2) {
             if (sc.Match("``") && sc.GetRelative(-2) != ' ') {
                 sc.Forward(2);
                 sc.SetState(SCE_MARKDOWN_DEFAULT);
             }
-        }    
+        }
         else if (sc.state == SCE_MARKDOWN_CODE) {
             if (sc.ch == '`' && sc.chPrev != ' ')
                 sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
@@ -201,14 +203,14 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
                 sc.Forward(2);
                 sc.SetState(SCE_MARKDOWN_DEFAULT);
             }
-        } 
-        else if (sc.state == SCE_MARKDOWN_STRONG2) {  
-            if (sc.Match("__") && sc.chPrev != ' ') {  
+        }
+        else if (sc.state == SCE_MARKDOWN_STRONG2) {
+            if (sc.Match("__") && sc.chPrev != ' ') {
                 sc.Forward(2);
                 sc.SetState(SCE_MARKDOWN_DEFAULT);
             }
         }
-        // Emphasis    
+        // Emphasis
         else if (sc.state == SCE_MARKDOWN_EM1) {
             if (sc.ch == '*' && sc.chPrev != ' ')
                 sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
@@ -281,7 +283,7 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
                 sc.SetState(SCE_MARKDOWN_PRECHAR);
             }
         }
-                
+
         // The header lasts until the newline
         else if (sc.state == SCE_MARKDOWN_HEADER1 || sc.state == SCE_MARKDOWN_HEADER2 ||
                 sc.state == SCE_MARKDOWN_HEADER3 || sc.state == SCE_MARKDOWN_HEADER4 ||
@@ -289,7 +291,7 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
             if (IsNewline(sc.ch))
                 sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
         }
-        
+
         // New state only within the initial whitespace
         if (sc.state == SCE_MARKDOWN_PRECHAR) {
             // Blockquote
@@ -300,8 +302,8 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
             else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4))
                 sc.SetState(SCE_MARKDOWN_CODEBK);
             */
-            // HRule - Total of three or more hyphens, asterisks, or underscores 
-            // on a line by themselves    
+            // HRule - Total of three or more hyphens, asterisks, or underscores
+            // on a line by themselves
             else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '_') && IsValidHrule(endPos, sc))
                 ;
             // Unordered list
@@ -314,7 +316,7 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
                 int digitCount = 0;
                 while (IsADigit(sc.GetRelative(++digitCount)))
                     ;
-                if (sc.GetRelative(digitCount) == '.' && 
+                if (sc.GetRelative(digitCount) == '.' &&
                         IsASpaceOrTab(sc.GetRelative(digitCount + 1))) {
                     sc.SetState(SCE_MARKDOWN_OLIST_ITEM);
                     sc.Forward(digitCount + 1);
@@ -332,7 +334,7 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
             else
                 ++precharCount;
         }
-        
+
         // New state anywhere in doc
         if (sc.state == SCE_MARKDOWN_DEFAULT) {
             if (sc.atLineStart && sc.ch == '#') {
diff --git a/plugins/scintilla/scintilla/LexMatlab.cxx b/plugins/scintilla/scintilla/LexMatlab.cxx
index 4e467bd..0d2064e 100644
--- a/plugins/scintilla/scintilla/LexMatlab.cxx
+++ b/plugins/scintilla/scintilla/LexMatlab.cxx
@@ -12,18 +12,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexMetapost.cxx b/plugins/scintilla/scintilla/LexMetapost.cxx
index 6afc9d8..d049521 100644
--- a/plugins/scintilla/scintilla/LexMetapost.cxx
+++ b/plugins/scintilla/scintilla/LexMetapost.cxx
@@ -14,18 +14,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
 #include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -326,11 +329,11 @@ static const char * const metapostWordListDesc[] = {
 static int classifyFoldPointMetapost(const char* s,WordList *keywordlists[]) {
 	WordList& keywordsStart=*keywordlists[3];
 	WordList& keywordsStop1=*keywordlists[4];
-	
+
 	if (keywordsStart.InList(s)) {return 1;}
 	else if (keywordsStop1.InList(s)) {return -1;}
 	return 0;
-	
+
 }
 
 static int ParseMetapostWord(unsigned int pos, Accessor &styler, char *word)
@@ -344,11 +347,11 @@ static int ParseMetapostWord(unsigned int pos, Accessor &styler, char *word)
           length++;
           ch=styler.SafeGetCharAt(pos+length);
   }
-  word[length]=0;   
+  word[length]=0;
   return length;
 }
- 
-static void FoldMetapostDoc(unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler) 
+
+static void FoldMetapostDoc(unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler)
 {
 	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 	unsigned int endPos = startPos+length;
@@ -357,9 +360,9 @@ static void FoldMetapostDoc(unsigned int startPos, int length, int, WordList *ke
 	int levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 	int levelCurrent=levelPrev;
 	char chNext=styler[startPos];
-	
+
 	char buffer[100]="";
-	
+
 	for (unsigned int i=startPos; i < endPos; i++) {
 		char ch=chNext;
 		chNext=styler.SafeGetCharAt(i+1);
@@ -371,7 +374,7 @@ static void FoldMetapostDoc(unsigned int startPos, int length, int, WordList *ke
             ParseMetapostWord(i, styler, buffer);
 			levelCurrent += classifyFoldPointMetapost(buffer,keywordlists);
 		}
-		
+
 		if (atEOL) {
 			int lev = levelPrev;
 			if (visibleChars == 0 && foldCompact)
diff --git a/plugins/scintilla/scintilla/LexModula.cxx b/plugins/scintilla/scintilla/LexModula.cxx
new file mode 100644
index 0000000..1d03611
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexModula.cxx
@@ -0,0 +1,743 @@
+//	-*- coding: utf-8 -*-
+//	Scintilla source code edit control
+/**
+ *	@file LexModula.cxx
+ *	@author Dariusz "DKnoto" KnociÅ?ski
+ *	@date 2011/02/03
+ *	@brief Lexer for Modula-2/3 documents.
+ */
+//	The License.txt file describes the conditions under which this software may
+//	be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+#ifdef DEBUG_LEX_MODULA
+#define DEBUG_STATE( p, c )\
+		fprintf( stderr, "Unknown state: currentPos = %d, char = '%c'\n", p, c );
+#else
+#define DEBUG_STATE( p, c )
+#endif
+
+static inline bool IsDigitOfBase( unsigned ch, unsigned base ) {
+	if( ch < '0' || ch > 'f' ) return false;
+	if( base <= 10 ) {
+		if( ch >= ( '0' + base ) ) return false;
+	} else {
+		if( ch > '9' ) {
+			unsigned nb = base - 10;
+			if( ( ch < 'A' ) || ( ch >= ( 'A' + nb ) ) ) {
+				if( ( ch < 'a' ) || ( ch >= ( 'a' + nb ) ) ) {
+					return false;
+				}
+			}
+		}
+	}
+	return true;
+}
+
+static inline unsigned IsOperator( StyleContext & sc, WordList & op ) {
+	int i;
+	char s[3];
+
+	s[0] = sc.ch;
+	s[1] = sc.chNext;
+	s[2] = 0;
+	for( i = 0; i < op.len; i++ ) {
+		if( ( strlen( op.words[i] ) == 2 ) &&
+			( s[0] == op.words[i][0] && s[1] == op.words[i][1] ) ) {
+			return 2;
+		}
+	}
+	s[1] = 0;
+	for( i = 0; i < op.len; i++ ) {
+		if( ( strlen( op.words[i] ) == 1 ) &&
+			( s[0] == op.words[i][0] ) ) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static inline bool IsEOL( Accessor &styler, unsigned curPos ) {
+	unsigned ch = styler.SafeGetCharAt( curPos );
+	if( ( ch == '\r' && styler.SafeGetCharAt( curPos + 1 ) == '\n' ) ||
+		( ch == '\n' ) ) {
+		return true;
+	}
+	return false;
+}
+
+static inline bool checkStatement(
+	Accessor &styler,
+	int &curPos,
+	const char *stt, bool spaceAfter = true ) {
+	int len = strlen( stt );
+	int i;
+	for( i = 0; i < len; i++ ) {
+		if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) {
+			return false;
+		}
+	}
+	if( spaceAfter ) {
+		if( ! isspace( styler.SafeGetCharAt( curPos + i ) ) ) {
+			return false;
+		}
+	}
+	curPos += ( len - 1 );
+	return true;
+}
+
+static inline bool checkEndSemicolon(
+	Accessor &styler,
+	int &curPos, int endPos )
+{
+	const char *stt = "END";
+	int len = strlen( stt );
+	int i;
+	for( i = 0; i < len; i++ ) {
+		if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) {
+			return false;
+		}
+	}
+	while( isspace( styler.SafeGetCharAt( curPos + i ) ) ) {
+		i++;
+		if( ( curPos + i ) >= endPos ) return false;
+	}
+	if( styler.SafeGetCharAt( curPos + i ) != ';' ) {
+		return false;
+	}
+	curPos += ( i - 1 );
+	return true;
+}
+
+static inline bool checkKeyIdentOper(
+
+	Accessor &styler,
+	int &curPos, int endPos,
+	const char *stt, const char etk ) {
+	int newPos = curPos;
+	if( ! checkStatement( styler, newPos, stt ) )
+		return false;
+	newPos++;
+	if( newPos >= endPos )
+		return false;
+	if( ! isspace( styler.SafeGetCharAt( newPos ) ) )
+		return false;
+	newPos++;
+	if( newPos >= endPos )
+		return false;
+	while( isspace( styler.SafeGetCharAt( newPos ) ) ) {
+		newPos++;
+		if( newPos >= endPos )
+			return false;
+	}
+	if( ! isalpha( styler.SafeGetCharAt( newPos ) ) )
+		return false;
+	newPos++;
+	if( newPos >= endPos )
+		return false;
+	char ch;
+	ch = styler.SafeGetCharAt( newPos );
+	while( isalpha( ch ) || isdigit( ch ) || ch == '_' ) {
+		newPos++;
+		if( newPos >= endPos ) return false;
+		ch = styler.SafeGetCharAt( newPos );
+	}
+	while( isspace( styler.SafeGetCharAt( newPos ) ) ) {
+		newPos++;
+		if( newPos >= endPos ) return false;
+	}
+	if( styler.SafeGetCharAt( newPos ) != etk )
+		return false;
+	curPos = newPos;
+	return true;
+}
+
+static void FoldModulaDoc( unsigned int startPos,
+						 int length,
+						 int , WordList *[],
+						 Accessor &styler)
+{
+	int curLine = styler.GetLine(startPos);
+	int curLevel = SC_FOLDLEVELBASE;
+	int endPos = startPos + length;
+	if( curLine > 0 )
+		curLevel = styler.LevelAt( curLine - 1 ) >> 16;
+	int curPos = startPos;
+	int style = styler.StyleAt( curPos );
+	int visChars = 0;
+	int nextLevel = curLevel;
+
+	while( curPos < endPos ) {
+		if( ! isspace( styler.SafeGetCharAt( curPos ) ) ) visChars++;
+
+		switch( style ) {
+		case SCE_MODULA_COMMENT:
+			if( checkStatement( styler, curPos, "(*" ) )
+				nextLevel++;
+			else
+			if( checkStatement( styler, curPos, "*)" ) )
+				nextLevel--;
+			break;
+
+		case SCE_MODULA_DOXYCOMM:
+			if( checkStatement( styler, curPos, "(**", false ) )
+				nextLevel++;
+			else
+			if( checkStatement( styler, curPos, "*)" ) )
+				nextLevel--;
+			break;
+
+		case SCE_MODULA_KEYWORD:
+			if( checkStatement( styler, curPos, "IF" ) )
+				nextLevel++;
+			else
+			if( checkStatement( styler, curPos, "BEGIN" ) )
+				nextLevel++;
+			else
+			if( checkStatement( styler, curPos, "TRY" ) )
+				nextLevel++;
+			else
+			if( checkStatement( styler, curPos, "LOOP" ) )
+				nextLevel++;
+			else
+			if( checkStatement( styler, curPos, "FOR" ) )
+				nextLevel++;
+			else
+			if( checkStatement( styler, curPos, "WHILE" ) )
+				nextLevel++;
+			else
+			if( checkStatement( styler, curPos, "REPEAT" ) )
+				nextLevel++;
+			else
+			if( checkStatement( styler, curPos, "UNTIL" ) )
+				nextLevel--;
+			else
+			if( checkStatement( styler, curPos, "WITH" ) )
+				nextLevel++;
+			else
+			if( checkStatement( styler, curPos, "CASE" ) )
+				nextLevel++;
+			else
+			if( checkStatement( styler, curPos, "TYPECASE" ) )
+				nextLevel++;
+			else
+			if( checkStatement( styler, curPos, "LOCK" ) )
+				nextLevel++;
+			else
+			if( checkKeyIdentOper( styler, curPos, endPos, "PROCEDURE", '(' ) )
+				nextLevel++;
+			else
+			if( checkKeyIdentOper( styler, curPos, endPos, "END", ';' ) ) {
+				int cln = curLine;
+				int clv_old = curLevel;
+				int pos;
+				char ch;
+				int clv_new;
+				while( cln > 0 ) {
+					clv_new = styler.LevelAt( cln - 1 ) >> 16;
+					if( clv_new < clv_old ) {
+						nextLevel--;
+						pos = styler.LineStart( cln );
+						while( ( ch = styler.SafeGetCharAt( pos ) ) != '\n' ) {
+							if( ch == 'P' ) {
+								if( styler.StyleAt(pos) == SCE_MODULA_KEYWORD )	{
+									if( checkKeyIdentOper( styler, pos, endPos,
+														"PROCEDURE", '(' ) ) {
+										break;
+									}
+								}
+							}
+							pos++;
+						}
+						clv_old = clv_new;
+					}
+					cln--;
+				}
+			}
+			else
+			if( checkKeyIdentOper( styler, curPos, endPos, "END", '.' ) )
+				nextLevel--;
+			else
+			if( checkEndSemicolon( styler, curPos, endPos ) )
+				nextLevel--;
+			else {
+				while( styler.StyleAt( curPos + 1 ) == SCE_MODULA_KEYWORD )
+					curPos++;
+			}
+			break;
+
+		default:
+			break;
+		}
+
+		if( IsEOL( styler, curPos ) || ( curPos == endPos - 1 ) ) {
+			int efectiveLevel = curLevel | nextLevel << 16;
+			if( visChars == 0 )
+				efectiveLevel |= SC_FOLDLEVELWHITEFLAG;
+			if( curLevel < nextLevel )
+				efectiveLevel |= SC_FOLDLEVELHEADERFLAG;
+			if( efectiveLevel != styler.LevelAt(curLine) ) {
+				styler.SetLevel(curLine, efectiveLevel );
+			}
+			curLine++;
+			curLevel = nextLevel;
+			if( IsEOL( styler, curPos ) && ( curPos == endPos - 1 ) ) {
+				styler.SetLevel( curLine, ( curLevel | curLevel << 16)
+								| SC_FOLDLEVELWHITEFLAG);
+			}
+			visChars = 0;
+		}
+		curPos++;
+		style = styler.StyleAt( curPos );
+	}
+}
+
+static inline bool skipWhiteSpaces( StyleContext & sc ) {
+	while( isspace( sc.ch ) ) {
+		sc.SetState( SCE_MODULA_DEFAULT );
+		if( sc.More() )
+			sc.Forward();
+		else
+			return false;
+	}
+	return true;
+}
+
+static void ColouriseModulaDoc(	unsigned int startPos,
+									int length,
+									int initStyle,
+									WordList *wl[],
+									Accessor &styler ) {
+	WordList& keyWords		= *wl[0];
+	WordList& reservedWords	= *wl[1];
+	WordList& operators 	= *wl[2];
+	WordList& pragmaWords 	= *wl[3];
+	WordList& escapeCodes	= *wl[4];
+	WordList& doxyKeys		= *wl[5];
+
+	const int BUFLEN = 128;
+
+	char	buf[BUFLEN];
+	int		i, kl;
+
+	int  charPos = 0;
+
+	StyleContext sc( startPos, length, initStyle, styler );
+
+	while( sc.More() ) 	{
+		switch( sc.state )	{
+		case SCE_MODULA_DEFAULT:
+			if( ! skipWhiteSpaces( sc ) ) break;
+
+			if( sc.ch == '(' && sc.chNext == '*' ) {
+				if( sc.GetRelative(2) == '*' ) {
+					sc.SetState( SCE_MODULA_DOXYCOMM );
+					sc.Forward();
+				} else {
+					sc.SetState( SCE_MODULA_COMMENT );
+				}
+				sc.Forward();
+			}
+			else
+			if( isalpha( sc.ch ) ) {
+				if( isupper( sc.ch ) && isupper( sc.chNext ) ) {
+					for( i = 0; i < BUFLEN - 1; i++ ) {
+						buf[i] = sc.GetRelative(i);
+						if( !isalpha( buf[i] ) && !(buf[i] == '_') )
+							break;
+					}
+					kl = i;
+					buf[kl] = 0;
+
+					if( keyWords.InList( buf ) ) {
+						sc.SetState( SCE_MODULA_KEYWORD );
+						sc.Forward( kl );
+						sc.SetState( SCE_MODULA_DEFAULT );
+						continue;
+					}
+					else
+					if( reservedWords.InList( buf ) ) {
+						sc.SetState( SCE_MODULA_RESERVED );
+						sc.Forward( kl );
+						sc.SetState( SCE_MODULA_DEFAULT );
+						continue;
+					} else {
+						/** check procedure identifier */
+					}
+				} else {
+					for( i = 0; i < BUFLEN - 1; i++ ) {
+						buf[i] = sc.GetRelative(i);
+						if( !isalpha( buf[i] ) &&
+							!isdigit( buf[i] ) &&
+							!(buf[i] == '_') )
+							break;
+					}
+					kl = i;
+					buf[kl] = 0;
+
+					sc.SetState( SCE_MODULA_DEFAULT );
+					sc.Forward( kl );
+					continue;
+				}
+			}
+			else
+			if( isdigit( sc.ch ) ) {
+				sc.SetState( SCE_MODULA_NUMBER );
+				continue;
+			}
+			else
+			if( sc.ch == '\"' ) {
+				sc.SetState( SCE_MODULA_STRING );
+			}
+			else
+			if( sc.ch == '\'' ) {
+				charPos = sc.currentPos;
+				sc.SetState( SCE_MODULA_CHAR );
+			}
+			else
+			if( sc.ch == '<' && sc.chNext == '*' ) {
+				sc.SetState( SCE_MODULA_PRAGMA );
+				sc.Forward();
+			} else {
+				unsigned len = IsOperator( sc, operators );
+				if( len > 0 ) {
+					sc.SetState( SCE_MODULA_OPERATOR );
+					sc.Forward( len );
+					sc.SetState( SCE_MODULA_DEFAULT );
+					continue;
+				} else {
+					DEBUG_STATE( sc.currentPos, sc.ch );
+				}
+			}
+			break;
+
+		case SCE_MODULA_COMMENT:
+			if( sc.ch == '*' && sc.chNext == ')' ) {
+				sc.Forward( 2 );
+				sc.SetState( SCE_MODULA_DEFAULT );
+				continue;
+			}
+			break;
+
+		case SCE_MODULA_DOXYCOMM:
+			switch( sc.ch ) {
+			case '*':
+				if( sc.chNext == ')' ) {
+					sc.Forward( 2 );
+					sc.SetState( SCE_MODULA_DEFAULT );
+					continue;
+				}
+				break;
+
+			case '@':
+				if( islower( sc.chNext ) ) {
+					for( i = 0; i < BUFLEN - 1; i++ ) {
+						buf[i] = sc.GetRelative(i+1);
+						if( isspace( buf[i] ) ) break;
+					}
+					buf[i] = 0;
+					kl = i;
+
+					if( doxyKeys.InList( buf ) ) {
+						sc.SetState( SCE_MODULA_DOXYKEY );
+						sc.Forward( kl + 1 );
+						sc.SetState( SCE_MODULA_DOXYCOMM );
+					}
+				}
+				break;
+
+			default:
+				break;
+			}
+			break;
+
+		case SCE_MODULA_NUMBER:
+			{
+				buf[0] = sc.ch;
+				for( i = 1; i < BUFLEN - 1; i++ ) {
+					buf[i] = sc.GetRelative(i);
+					if( ! isdigit( buf[i] ) )
+						break;
+				}
+				kl = i;
+				buf[kl] = 0;
+
+				switch( sc.GetRelative(kl) ) {
+				case '_':
+					{
+						int base = atoi( buf );
+						if( base < 2 || base > 16 ) {
+							sc.SetState( SCE_MODULA_BADSTR );
+						} else {
+							int imax;
+
+							kl++;
+							for( i = 0; i < BUFLEN - 1; i++ ) {
+								buf[i] = sc.GetRelative(kl+i);
+								if( ! IsDigitOfBase( buf[i], 16 ) ) {
+									break;
+								}
+							}
+							imax = i;
+							for( i = 0; i < imax; i++ ) {
+								if( ! IsDigitOfBase( buf[i], base ) ) {
+									sc.SetState( SCE_MODULA_BADSTR );
+									break;
+								}
+							}
+							kl += imax;
+						}
+						sc.SetState( SCE_MODULA_BASENUM );
+						for( i = 0; i < kl; i++ ) {
+							sc.Forward();
+						}
+						sc.SetState( SCE_MODULA_DEFAULT );
+						continue;
+					}
+					break;
+
+				case '.':
+					if( sc.GetRelative(kl+1) == '.' ) {
+						kl--;
+						for( i = 0; i < kl; i++ ) {
+							sc.Forward();
+						}
+						sc.Forward();
+						sc.SetState( SCE_MODULA_DEFAULT );
+						continue;
+					} else {
+						bool doNext = false;
+
+						kl++;
+
+						buf[0] = sc.GetRelative(kl);
+						if( isdigit( buf[0] ) ) {
+							for( i = 0;; i++ ) {
+								if( !isdigit(sc.GetRelative(kl+i)) )
+									break;
+							}
+							kl += i;
+							buf[0] = sc.GetRelative(kl);
+
+							switch( buf[0] )
+							{
+							case 'E':
+							case 'e':
+							case 'D':
+							case 'd':
+							case 'X':
+							case 'x':
+								kl++;
+								buf[0] = sc.GetRelative(kl);
+								if( buf[0] == '-' || buf[0] == '+' ) {
+									kl++;
+								}
+								buf[0] = sc.GetRelative(kl);
+								if( isdigit( buf[0] ) ) {
+									for( i = 0;; i++ ) {
+										if( !isdigit(sc.GetRelative(kl+i)) ) {
+											buf[0] = sc.GetRelative(kl+i);
+											break;
+										}
+									}
+									kl += i;
+									doNext = true;
+								} else {
+									sc.SetState( SCE_MODULA_BADSTR );
+								}
+								break;
+
+							default:
+								doNext = true;
+								break;
+							}
+						} else {
+							sc.SetState( SCE_MODULA_BADSTR );
+						}
+
+						if( doNext ) {
+							if( ! isspace( buf[0] ) &&
+								buf[0] != ')' &&
+								buf[0] != '>' &&
+								buf[0] != '<' &&
+								buf[0] != '=' &&
+								buf[0] != '#' &&
+								buf[0] != '+' &&
+								buf[0] != '-' &&
+								buf[0] != '*' &&
+								buf[0] != '/' &&
+								buf[0] != ',' &&
+								buf[0] != ';'
+								) {
+								sc.SetState( SCE_MODULA_BADSTR );
+							} else {
+								kl--;
+							}
+						}
+					}
+					sc.SetState( SCE_MODULA_FLOAT );
+					for( i = 0; i < kl; i++ ) {
+						sc.Forward();
+					}
+					sc.SetState( SCE_MODULA_DEFAULT );
+					continue;
+					break;
+
+				default:
+					for( i = 0; i < kl; i++ ) {
+						sc.Forward();
+					}
+					break;
+				}
+				sc.SetState( SCE_MODULA_DEFAULT );
+				continue;
+			}
+			break;
+
+		case SCE_MODULA_STRING:
+			if( sc.ch == '\"' ) {
+				sc.Forward();
+				sc.SetState( SCE_MODULA_DEFAULT );
+				continue;
+			} else {
+				if( sc.ch == '\\' ) {
+					i = 1;
+					if( IsDigitOfBase( sc.chNext, 8 ) ) {
+						for( i = 1; i < BUFLEN - 1; i++ ) {
+							if( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) )
+								break;
+						}
+						if( i == 3 ) {
+							sc.SetState( SCE_MODULA_STRSPEC );
+						} else {
+							sc.SetState( SCE_MODULA_BADSTR );
+						}
+					} else {
+						buf[0] = sc.chNext;
+						buf[1] = 0;
+
+						if( escapeCodes.InList( buf ) ) {
+							sc.SetState( SCE_MODULA_STRSPEC );
+						} else {
+							sc.SetState( SCE_MODULA_BADSTR );
+						}
+					}
+					sc.Forward(i+1);
+					sc.SetState( SCE_MODULA_STRING );
+					continue;
+				}
+			}
+			break;
+
+		case SCE_MODULA_CHAR:
+			if( sc.ch == '\'' ) {
+				sc.Forward();
+				sc.SetState( SCE_MODULA_DEFAULT );
+				continue;
+			}
+			else
+			if( ( sc.currentPos - charPos ) == 1 ) {
+				if( sc.ch == '\\' ) {
+					i = 1;
+					if( IsDigitOfBase( sc.chNext, 8 ) ) {
+						for( i = 1; i < BUFLEN - 1; i++ ) {
+							if( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) )
+								break;
+						}
+						if( i == 3 ) {
+							sc.SetState( SCE_MODULA_CHARSPEC );
+						} else {
+							sc.SetState( SCE_MODULA_BADSTR );
+						}
+					} else {
+						buf[0] = sc.chNext;
+						buf[1] = 0;
+
+						if( escapeCodes.InList( buf ) ) {
+							sc.SetState( SCE_MODULA_CHARSPEC );
+						} else {
+							sc.SetState( SCE_MODULA_BADSTR );
+						}
+					}
+					sc.Forward(i+1);
+					sc.SetState( SCE_MODULA_CHAR );
+					continue;
+				}
+			} else {
+				sc.SetState( SCE_MODULA_BADSTR );
+				sc.Forward();
+				sc.SetState( SCE_MODULA_CHAR );
+				continue;
+			}
+			break;
+
+		case SCE_MODULA_PRAGMA:
+			if( sc.ch == '*' && sc.chNext == '>' ) {
+				sc.Forward();
+				sc.Forward();
+				sc.SetState( SCE_MODULA_DEFAULT );
+				continue;
+			}
+			else
+			if( isupper( sc.ch ) && isupper( sc.chNext ) ) {
+				buf[0] = sc.ch;
+				buf[1] = sc.chNext;
+				for( i = 2; i < BUFLEN - 1; i++ ) {
+					buf[i] = sc.GetRelative(i);
+					if( !isupper( buf[i] ) )
+						break;
+				}
+				kl = i;
+				buf[kl] = 0;
+				if( pragmaWords.InList( buf ) ) {
+					sc.SetState( SCE_MODULA_PRGKEY );
+					sc.Forward( kl );
+					sc.SetState( SCE_MODULA_PRAGMA );
+					continue;
+				}
+			}
+			break;
+
+		default:
+			break;
+		}
+		sc.Forward();
+	}
+	sc.Complete();
+}
+
+static const char *const modulaWordListDesc[] =
+{
+	"Keywords",
+	"ReservedKeywords",
+	"Operators",
+	"PragmaKeyswords",
+	"EscapeCodes",
+	"DoxygeneKeywords",
+	0
+};
+
+LexerModule lmModula( SCLEX_MODULA, ColouriseModulaDoc, "modula", FoldModulaDoc,
+					  modulaWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexMySQL.cxx b/plugins/scintilla/scintilla/LexMySQL.cxx
index e8496ce..305fa74 100644
--- a/plugins/scintilla/scintilla/LexMySQL.cxx
+++ b/plugins/scintilla/scintilla/LexMySQL.cxx
@@ -12,18 +12,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -113,12 +116,12 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
         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;
@@ -137,7 +140,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
           if (keywordlists[4]->InList(&s[2]))
             sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE);
           delete [] s;
-          
+
           sc.SetState(SCE_MYSQL_DEFAULT);
         }
         break;
@@ -232,7 +235,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
               if (sc.Match('/', '*'))
               {
                 sc.SetState(SCE_MYSQL_COMMENT);
-                
+
                 // Skip comment introducer and check for hidden command.
                 sc.Forward(2);
                 if (sc.ch == '!')
@@ -247,7 +250,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
                   // 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);
@@ -258,7 +261,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
       }
     }
   }
-  
+
   // 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)
@@ -270,7 +273,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
     if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
       sc.ChangeState(SCE_MYSQL_DEFAULT);
   }
-	
+
   sc.Complete();
 }
 
@@ -321,9 +324,9 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
 	int styleNext = styler.StyleAt(startPos);
 	int style = initStyle;
 	
-  bool endFound = false;
-	bool whenFound = false;
-	bool elseFound = false;
+  bool endPending = false;
+	bool whenPending = false;
+	bool elseIfPending = false;
 
   char nextChar = styler.SafeGetCharAt(startPos);
   for (unsigned int i = startPos; length > 0; i++, length--)
@@ -374,18 +377,42 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
         }
         break;
       case SCE_MYSQL_HIDDENCOMMAND:
+        if (endPending)
+        {
+          // A conditional command is not a white space so it should end the current block
+          // before opening a new one.
+          endPending = false;
+          levelNext--;
+          if (levelNext < SC_FOLDLEVELBASE)
+            levelNext = SC_FOLDLEVELBASE;
+        }
         if (style != stylePrev)
           levelNext++;
         else
           if (style != styleNext)
+          {
             levelNext--;
+            if (levelNext < SC_FOLDLEVELBASE)
+              levelNext = SC_FOLDLEVELBASE;
+          }
         break;
       case SCE_MYSQL_OPERATOR:
+        if (endPending)
+        {
+          endPending = false;
+          levelNext--;
+          if (levelNext < SC_FOLDLEVELBASE)
+            levelNext = SC_FOLDLEVELBASE;
+        }
         if (currentChar == '(')
           levelNext++;
         else
           if (currentChar == ')')
+          {
             levelNext--;
+            if (levelNext < SC_FOLDLEVELBASE)
+              levelNext = SC_FOLDLEVELBASE;
+          }
         break;
       case SCE_MYSQL_MAJORKEYWORD:
       case SCE_MYSQL_KEYWORD:
@@ -394,110 +421,98 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
         // Reserved and other keywords.
         if (style != stylePrev)
         {
-          bool beginFound = MatchIgnoreCase(styler, i, "begin");
-          bool ifFound = MatchIgnoreCase(styler, i, "if");
-          bool thenFound = MatchIgnoreCase(styler, i, "then");
-          bool whileFound = MatchIgnoreCase(styler, i, "while");
-          bool loopFound = MatchIgnoreCase(styler, i, "loop");
-          bool repeatFound = MatchIgnoreCase(styler, i, "repeat");
-          
-          if (!foldOnlyBegin && endFound && (ifFound || whileFound || loopFound))
+          // END decreases the folding level, regardless which keyword follows.
+          bool endFound = MatchIgnoreCase(styler, i, "end");
+          if (endPending)
           {
-            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, i, "else"))
+            if (!endFound)
             {
-              levelNext--;
-              elseFound = true;
-            }
-            else
-              if (!foldOnlyBegin && thenFound)
-              {
-                if (whenFound)
-                  whenFound = false;
-                else
-                  levelNext++;
-              }
+              if (MatchIgnoreCase(styler, i, "begin"))
+                levelNext++;
               else
-                if (ifFound)
-                  elseFound = false;
-                else
-                  if (MatchIgnoreCase(styler, i, "when"))
-                    whenFound = true;
+              {
+                if (!foldOnlyBegin)
+                {
+                  bool whileFound = MatchIgnoreCase(styler, i, "while");
+                  bool loopFound = MatchIgnoreCase(styler, i, "loop");
+                  bool repeatFound = MatchIgnoreCase(styler, i, "repeat");
+                  bool caseFound = MatchIgnoreCase(styler, i, "case");
+
+                  if (whileFound || loopFound || repeatFound || caseFound)
+                    levelNext++;
                   else
                   {
-                    if (beginFound)
-                      levelNext++;
-                    else
-                      if (!foldOnlyBegin && (loopFound || repeatFound || whileFound))
+                    // IF alone does not increase the fold level as it is also used in non-block'ed
+                    // code like DROP PROCEDURE blah IF EXISTS.
+                    // Instead THEN opens the new level (if not part of an ELSEIF or WHEN (case) branch).
+                    if (MatchIgnoreCase(styler, i, "then"))
+                    {
+                      if (!elseIfPending && !whenPending)
+                        levelNext++;
+                      else
                       {
-                        if (endFound)
-                          endFound = false;
-                        else
-                          levelNext++;
+                        elseIfPending = false;
+                        whenPending = false;
                       }
-                      else
-                        if (MatchIgnoreCase(styler, i, "end"))
-                        {
-                          // Multiple "end" in a row are counted multiple times!
-                          if (endFound)
-                          {
-                            levelNext--;
-                            if (levelNext < SC_FOLDLEVELBASE)
-                              levelNext = SC_FOLDLEVELBASE;
-                          }
-                          endFound = true;
-                          whenFound = false;
-                        }
+                    }
+                    else
+                    {
+                      // Neither of if/then/while/loop/repeat/case, so check for
+                      // sub parts of IF and CASE.
+                      if (MatchIgnoreCase(styler, i, "elseif"))
+                        elseIfPending = true;
+                      if (MatchIgnoreCase(styler, i, "when"))
+                        whenPending = true;
+                    }
                   }
+                }
+              }
+            }
+          
+          // Keep the current end state for the next round.
+          endPending = endFound;
+        }
+        break;
+        
+      default:
+        if (!isspace(currentChar) && endPending)
+        {
+          // END followed by a non-whitespace character (not covered by other cases like identifiers)
+          // also should end a folding block. Typical case: END followed by self defined delimiter.
+          levelNext--;
+          if (levelNext < SC_FOLDLEVELBASE)
+            levelNext = SC_FOLDLEVELBASE;
         }
         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 (atEOL)
+    if (atEOL)
     {
-			if (elseFound)
-      {
-				levelNext++;
-        elseFound = false;
-      }
-
-			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);
+      // Apply the new folding level to this line.
+      // Leave pending states as they are otherwise a line break will de-sync
+      // code folding and valid syntax.
+      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);
       
-			lineCurrent++;
-			levelCurrent = levelNext;
-			visibleChars = 0;
-			endFound = false;
-			whenFound = false;
-		}
-    
+      lineCurrent++;
+      levelCurrent = levelNext;
+      visibleChars = 0;
+    }
+
 		if (!isspacechar(currentChar))
-			visibleChars++;
-	}
+      visibleChars++;
+  }
 }
 
 //--------------------------------------------------------------------------------------------------
diff --git a/plugins/scintilla/scintilla/LexNimrod.cxx b/plugins/scintilla/scintilla/LexNimrod.cxx
index 8c4d043..08b76fe 100644
--- a/plugins/scintilla/scintilla/LexNimrod.cxx
+++ b/plugins/scintilla/scintilla/LexNimrod.cxx
@@ -9,18 +9,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -113,7 +116,7 @@ static int scanNumber(Accessor &styler, int pos) {
       if (ch == '_' || (ch >= '0' && ch <= '1')) ++pos;
       else break;
     }
-  } else if (ch == '0' && 
+  } else if (ch == '0' &&
             (ch2 == 'o' || ch2 == 'O' || ch2 == 'c' || ch2 == 'C')) {
     /* octal number: */
     pos += 2;
@@ -203,7 +206,7 @@ static void ColouriseNimrodDoc(unsigned int startPos, int length, int initStyle,
       case '#': {
         bool doccomment = (styler.SafeGetCharAt(pos+1) == '#');
         while (pos < max && !isNewLine(styler.SafeGetCharAt(pos, LF))) pos++;
-        if (doccomment) 
+        if (doccomment)
           styler.ColourTo(pos, SCE_C_COMMENTLINEDOC);
         else
           styler.ColourTo(pos, SCE_P_COMMENTLINE);
@@ -280,7 +283,7 @@ static bool IsQuoteLine(int line, Accessor &styler) {
 }
 
 
-static void FoldNimrodDoc(unsigned int startPos, int length, 
+static void FoldNimrodDoc(unsigned int startPos, int length,
                           int /*initStyle - unused*/,
                           WordList *[], Accessor &styler) {
 	const int maxPos = startPos + length;
@@ -311,7 +314,7 @@ static void FoldNimrodDoc(unsigned int startPos, int length,
 	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) || 
+	int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) ||
 	                               (prev_state == SCE_P_TRIPLEDOUBLE));
 	int prevComment = 0;
 	if (lineCurrent >= 1)
@@ -320,7 +323,7 @@ static void FoldNimrodDoc(unsigned int startPos, int length,
 	// 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) || 
+	while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) ||
 	                                      prevQuote || prevComment)) {
 
 		// Gather info
@@ -338,7 +341,7 @@ static void FoldNimrodDoc(unsigned int startPos, int length,
 		const int quote_continue = (quote && prevQuote);
 		const int comment = foldComment && IsCommentLine(lineCurrent, styler);
 		const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
-		                           IsCommentLine(lineNext, styler) && 
+		                           IsCommentLine(lineNext, styler) &&
 		                           (lev > SC_FOLDLEVELBASE));
 		const int comment_continue = (comment && prevComment);
 		if ((!quote || !prevQuote) && !comment)
@@ -377,8 +380,8 @@ static void FoldNimrodDoc(unsigned int startPos, int length,
 		}
 
 		const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
-		const int levelBeforeComments = 
-		    Platform::Maximum(indentCurrentLevel,levelAfterComments);
+		const int levelBeforeComments =
+		    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
@@ -401,7 +404,7 @@ static void FoldNimrodDoc(unsigned int startPos, int length,
 
 		// Set fold header on non-quote/non-comment line
 		if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
-			if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < 
+			if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) <
 			     (indentNext & SC_FOLDLEVELNUMBERMASK))
 				lev |= SC_FOLDLEVELHEADERFLAG;
 		}
diff --git a/plugins/scintilla/scintilla/LexNsis.cxx b/plugins/scintilla/scintilla/LexNsis.cxx
index 43ddc47..cd74d54 100644
--- a/plugins/scintilla/scintilla/LexNsis.cxx
+++ b/plugins/scintilla/scintilla/LexNsis.cxx
@@ -5,21 +5,25 @@
 // Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com>
 // Last Updated: 03/13/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 <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "CharClassify.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
diff --git a/plugins/scintilla/scintilla/LexOpal.cxx b/plugins/scintilla/scintilla/LexOpal.cxx
index 221f955..320fe9b 100644
--- a/plugins/scintilla/scintilla/LexOpal.cxx
+++ b/plugins/scintilla/scintilla/LexOpal.cxx
@@ -6,18 +6,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
 #include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -92,7 +95,7 @@ inline bool HandleString( unsigned int & cur, unsigned int one_too_much, Accesso
 inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
 {
 	char ch;
-	
+
 	if( could_fail )
 	{
 		cur++;
@@ -101,7 +104,7 @@ inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, A
 			styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
 			return false; // STOP
 		}
-		
+
 		ch = styler.SafeGetCharAt( cur );
 		if( ch != '*' )
 		{
@@ -110,7 +113,7 @@ inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, A
 			return true;
 		}
 	}
-	
+
 	// Wait for comment close
 	cur++;
 	bool star_found = false;
@@ -121,7 +124,7 @@ inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, A
 			styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_BLOCK );
 			return false; // STOP
 		}
-		
+
 		ch = styler.SafeGetCharAt( cur );
 		if( star_found )
 		{
@@ -155,7 +158,7 @@ inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, A
 inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
 {
 	char ch;
-	
+
 	if( could_fail )
 	{
 		cur++;
@@ -164,7 +167,7 @@ inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Ac
 			styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
 			return false; // STOP
 		}
-		
+
 		ch = styler.SafeGetCharAt( cur );
 		if( ch != '-' )
 		{
@@ -179,7 +182,7 @@ inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Ac
 			styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
 			return false; // STOP
 		}
-		
+
 		ch = styler.SafeGetCharAt( cur );
 		if( ( ch != ' ' ) && ( ch != '\t' ) )
 		{
@@ -224,7 +227,7 @@ inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Ac
 		{
 			if( ch == '\015' )
 			{
-				fifteen_found = true;	
+				fifteen_found = true;
 			}
 			else if( ch == '\012' )
 			{
@@ -259,7 +262,7 @@ inline bool HandleSpace( unsigned int & cur, unsigned int one_too_much, Accessor
 			styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
 			return false;
 		}
-		
+
 		ch = styler.SafeGetCharAt( cur );
 		switch( ch )
 		{
@@ -269,7 +272,7 @@ inline bool HandleSpace( unsigned int & cur, unsigned int one_too_much, Accessor
 		case '\012':
 			cur++;
 			break;
-		
+
 		default:
 			styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
 			styler.StartSegment( cur );
@@ -292,7 +295,7 @@ inline bool HandleInteger( unsigned int & cur, unsigned int one_too_much, Access
 		}
 
 		ch = styler.SafeGetCharAt( cur );
-		if( !isdigit( ch ) )
+		if( !( isascii( ch ) && isdigit( ch ) ) )
 		{
 			styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
 			styler.StartSegment( cur );
@@ -311,10 +314,10 @@ inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor
 	{
 		ch = styler.SafeGetCharAt( cur );
 		if( ( ch != '_' ) && ( ch != '-' ) &&
-			!islower( ch ) && !isupper( ch ) && !isdigit( ch ) ) break;
+			!( isascii( ch ) && ( islower( ch ) || isupper( ch ) || isdigit( ch ) ) ) ) break;
 
 		cur++;
-		if( cur >= one_too_much ) 
+		if( cur >= one_too_much )
 		{
 			break;
 		}
@@ -323,7 +326,7 @@ inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor
 	const int ide_len = cur - beg + 1;
 	char * ide = new char[ ide_len ];
 	getRange( beg, cur, styler, ide, ide_len );
-	
+
 	WordList & keywords    = *keywordlists[ 0 ];
 	WordList & classwords  = *keywordlists[ 1 ];
 
@@ -338,8 +341,8 @@ inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor
 		}
 		else
 		{
-			styler.StartSegment( cur );	
-			return true;			
+			styler.StartSegment( cur );
+			return true;
 		}
 	}
 	else if( classwords.InList( ide ) ) // Sort
@@ -353,8 +356,8 @@ inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor
 		}
 		else
 		{
-			styler.StartSegment( cur );	
-			return true;			
+			styler.StartSegment( cur );
+			return true;
 		}
 	}
 	else if( !strcmp( ide, "true" ) || !strcmp( ide, "false" ) ) // Bool const
@@ -368,8 +371,8 @@ inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor
 		}
 		else
 		{
-			styler.StartSegment( cur );	
-			return true;			
+			styler.StartSegment( cur );
+			return true;
 		}
 	}
 	else // Unknown keyword
@@ -384,7 +387,7 @@ inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor
 		else
 		{
 			styler.StartSegment( cur );
-			return true;			
+			return true;
 		}
 	}
 
@@ -400,7 +403,7 @@ inline bool HandleSkip( unsigned int & cur, unsigned int one_too_much, Accessor
 	}
 	else
 	{
-		styler.StartSegment( cur );	
+		styler.StartSegment( cur );
 		return true;
 	}
 }
@@ -444,11 +447,11 @@ static void ColouriseOpalDoc( unsigned int startPos, int length, int initStyle,
 			if( !HandleString( cur, one_too_much, styler ) ) return;
 			state = SCE_OPAL_DEFAULT;
 			break;
-			
+
 		default: // SCE_OPAL_DEFAULT:
 			{
 				char ch = styler.SafeGetCharAt( cur );
-				
+
 				switch( ch )
 				{
 				// String
@@ -483,20 +486,20 @@ static void ColouriseOpalDoc( unsigned int startPos, int length, int initStyle,
 				case '\012':
 					if( !HandleSpace( cur, one_too_much, styler ) ) return;
 					break;
-				
+
 				default:
 					{
 						// Integer
-						if( isdigit( ch ) )
+						if( isascii( ch ) && isdigit( ch ) )
 						{
 							if( !HandleInteger( cur, one_too_much, styler ) ) return;
 						}
 
 						// Keyword
-						else if( islower( ch ) || isupper( ch ) )
+						else if( isascii( ch ) && ( islower( ch ) || isupper( ch ) ) )
 						{
 							if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
-							
+
 						}
 
 						// Skip
diff --git a/plugins/scintilla/scintilla/LexOthers.cxx b/plugins/scintilla/scintilla/LexOthers.cxx
index 75458f6..bc2c287 100644
--- a/plugins/scintilla/scintilla/LexOthers.cxx
+++ b/plugins/scintilla/scintilla/LexOthers.cxx
@@ -8,19 +8,22 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "CharClassify.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
@@ -37,6 +40,10 @@ static bool Is1To9(char ch) {
 	return (ch >= '1') && (ch <= '9');
 }
 
+static bool IsAlphabetic(int ch) {
+	return isascii(ch) && isalpha(ch);
+}
+
 static inline bool AtEOL(Accessor &styler, unsigned int i) {
 	return (styler[i] == '\n') ||
 	       ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
@@ -51,7 +58,7 @@ static bool IsBOperator(char ch) {
 // Tests for BATCH Separators
 static bool IsBSeparator(char ch) {
 	return (ch == '\\') || (ch == '.') || (ch == ';') ||
-		(ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')');
+		(ch == '\"') || (ch == '\'') || (ch == '/');
 }
 
 static void ColouriseBatchLine(
@@ -101,7 +108,7 @@ static void ColouriseBatchLine(
 		}
 		return;
 	// Check for Drive Change (Drive Change is internal command) - return if found
-	} else if ((isalpha(lineBuffer[offset])) &&
+	} else if ((IsAlphabetic(lineBuffer[offset])) &&
 		(lineBuffer[offset + 1] == ':') &&
 		((isspacechar(lineBuffer[offset + 2])) ||
 		(((lineBuffer[offset + 2] == '\\')) &&
@@ -502,7 +509,7 @@ static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
 		styler.ColourTo(endLine, SCE_DIFF_COMMAND);
 	} else if (0 == strncmp(lineBuffer, "Index: ", 7)) {  // For subversion's diff
 		styler.ColourTo(endLine, SCE_DIFF_COMMAND);
-	} else if (0 == strncmp(lineBuffer, "---", 3)) {
+	} else if (0 == strncmp(lineBuffer, "---", 3) && lineBuffer[3] != '-') {
 		// In a context diff, --- appears in both the header and the position markers
 		if (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/'))
 			styler.ColourTo(endLine, SCE_DIFF_POSITION);
@@ -723,10 +730,10 @@ static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *
 	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. 
+	// 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++) {
@@ -847,13 +854,17 @@ static void ColouriseMakeLine(
 		styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
 		return;
 	}
+	int varCount = 0;
 	while (i < lengthLine) {
 		if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') {
 			styler.ColourTo(startLine + i - 1, state);
 			state = SCE_MAKE_IDENTIFIER;
+			varCount++;
 		} else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
-			styler.ColourTo(startLine + i, state);
-			state = SCE_MAKE_DEFAULT;
+			if (--varCount == 0) {
+				styler.ColourTo(startLine + i, state);
+				state = SCE_MAKE_DEFAULT;
+			}
 		}
 
 		// skip identifier and target styling if this is a command line
@@ -922,8 +933,8 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
 		// Command or return status
 		return SCE_ERR_CMD;
 	} else if (lineBuffer[0] == '<') {
-		// Diff removal, but not interested. Trapped to avoid hitting CTAG cases.
-		return SCE_ERR_DEFAULT;
+		// Diff removal.
+		return SCE_ERR_DIFF_DELETION;
 	} else if (lineBuffer[0] == '!') {
 		return SCE_ERR_DIFF_CHANGED;
 	} else if (lineBuffer[0] == '+') {
@@ -961,17 +972,17 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
 	} else if (strstart(lineBuffer, "Warning ")) {
 		// Borland warning message
 		return SCE_ERR_BORLAND;
-	} else if (strstr(lineBuffer, "at line " ) &&
-	           (strstr(lineBuffer, "at line " ) < (lineBuffer + lengthLine)) &&
+	} else if (strstr(lineBuffer, "at line ") &&
+	        (strstr(lineBuffer, "at line ") < (lineBuffer + lengthLine)) &&
 	           strstr(lineBuffer, "file ") &&
 	           (strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) {
 		// Lua 4 error message
 		return SCE_ERR_LUA;
-	} else if (strstr(lineBuffer, " at " ) &&
-	           (strstr(lineBuffer, " at " ) < (lineBuffer + lengthLine)) &&
+	} else if (strstr(lineBuffer, " at ") &&
+	        (strstr(lineBuffer, " at ") < (lineBuffer + lengthLine)) &&
 	           strstr(lineBuffer, " line ") &&
 	           (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) &&
-	           (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) {
+	        (strstr(lineBuffer, " at ") < (strstr(lineBuffer, " line ")))) {
 		// perl error message
 		return SCE_ERR_PERL;
 	} else if ((memcmp(lineBuffer, "   at ", 6) == 0) &&
@@ -1065,7 +1076,7 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
 						numstep = 1; // ch was ' ', handle as if it's a delphi errorline, only add 1 to i.
 					else
 						numstep = 2; // otherwise add 2.
-					for (j = i + numstep; j < lengthLine && isalpha(lineBuffer[j]) && chPos < sizeof(word) - 1; j++)
+					for (j = i + numstep; j < lengthLine && IsAlphabetic(lineBuffer[j]) && chPos < sizeof(word) - 1; j++)
 						word[chPos++] = lineBuffer[j];
 					word[chPos] = 0;
 					if (!CompareCaseInsensitive(word, "error") || !CompareCaseInsensitive(word, "warning") ||
@@ -1131,11 +1142,11 @@ static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordLi
 	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. 
+	// 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];
@@ -1162,7 +1173,7 @@ static int isTag(int start, Accessor &styler) {
 	while (i < 5 && e) {
 		s[i] = styler[start + i];
 		i++;
-		e = styler[start + i] != '{';
+		e = (strchr("{ \t", styler[start + i]) == NULL);
 	}
 	s[i] = '\0';
 	return (strcmp(s, "begin") == 0) || (strcmp(s, "end") == 0);
@@ -1252,13 +1263,13 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
 	styler.ColourTo(lengthDoc-1, state);
 }
 
-static const char * const batchWordListDesc[] = {
+static const char *const batchWordListDesc[] = {
 	"Internal Commands",
 	"External Commands",
 	0
 };
 
-static const char * const emptyWordListDesc[] = {
+static const char *const emptyWordListDesc[] = {
 	0
 };
 
diff --git a/plugins/scintilla/scintilla/LexPB.cxx b/plugins/scintilla/scintilla/LexPB.cxx
index abc0ddc..a7b5690 100644
--- a/plugins/scintilla/scintilla/LexPB.cxx
+++ b/plugins/scintilla/scintilla/LexPB.cxx
@@ -35,18 +35,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexPLM.cxx b/plugins/scintilla/scintilla/LexPLM.cxx
index 604850f..747d158 100644
--- a/plugins/scintilla/scintilla/LexPLM.cxx
+++ b/plugins/scintilla/scintilla/LexPLM.cxx
@@ -4,18 +4,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
 #include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexPOV.cxx b/plugins/scintilla/scintilla/LexPOV.cxx
index b845b2d..353fbbe 100644
--- a/plugins/scintilla/scintilla/LexPOV.cxx
+++ b/plugins/scintilla/scintilla/LexPOV.cxx
@@ -16,18 +16,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexPS.cxx b/plugins/scintilla/scintilla/LexPS.cxx
index 2edcff1..3661c4b 100644
--- a/plugins/scintilla/scintilla/LexPS.cxx
+++ b/plugins/scintilla/scintilla/LexPS.cxx
@@ -8,18 +8,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
 #include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexPascal.cxx b/plugins/scintilla/scintilla/LexPascal.cxx
index 3dcf35a..867b00e 100644
--- a/plugins/scintilla/scintilla/LexPascal.cxx
+++ b/plugins/scintilla/scintilla/LexPascal.cxx
@@ -11,20 +11,20 @@
 
 A few words about features of the new completely rewritten LexPascal...
 
-Generally speaking LexPascal tries to support all available Delphi features (up 
+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). 
+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 
+For example, keywords "read" and "write" will only be highlighted if they are in
 property declaration:
 
-property MyProperty: boolean read FMyProperty write FMyProperty; 
+property MyProperty: boolean read FMyProperty write FMyProperty;
 
 ~ FOLDING:
 
@@ -32,34 +32,34 @@ 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 
+- 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 
+- 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 
+- 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 
+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 
+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);") 
+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", 
+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 
+- 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
@@ -76,52 +76,54 @@ type
   ...
 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 
+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 
+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 
+- 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 
+- 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 
+- Keywords related to Delphi packages (in addition to all above): package
 contains requires
 
 */
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
 #include "StyleContext.h"
 #include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -155,12 +157,12 @@ static void GetForwardRangeLowered(unsigned int start,
 }
 
 enum {
-	stateInAsm = 0x1000, 
-	stateInProperty = 0x2000, 
-	stateInExport = 0x4000, 
-	stateFoldInPreprocessor = 0x0100, 
-	stateFoldInRecord = 0x0200, 
-	stateFoldInPreprocessorLevelMask = 0x00FF, 
+	stateInAsm = 0x1000,
+	stateInProperty = 0x2000,
+	stateInExport = 0x4000,
+	stateFoldInPreprocessor = 0x0100,
+	stateFoldInRecord = 0x0200,
+	stateFoldInPreprocessorLevelMask = 0x00FF,
 	stateFoldMaskAll = 0x0FFF
 };
 
@@ -190,11 +192,11 @@ static void ClassifyPascalWord(WordList *keywordlists[], StyleContext &sc, int &
 					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 || 
+				} 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;
 				}
@@ -367,7 +369,7 @@ static void SetFoldInPreprocessorLevelFlag(int &lineFoldStateCurrent, unsigned i
 	lineFoldStateCurrent |= nestLevel & stateFoldInPreprocessorLevelMask;
 }
 
-static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent, 
+static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,
 		unsigned int startPos, Accessor &styler) {
 	CharacterSet setWord(CharacterSet::setAlpha);
 
@@ -376,17 +378,17 @@ static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFold
 
 	unsigned int nestLevel = GetFoldInPreprocessorLevelFlag(lineFoldStateCurrent);
 
-	if (strcmp(s, "if") == 0 || 
-		strcmp(s, "ifdef") == 0 || 
-		strcmp(s, "ifndef") == 0 || 
-		strcmp(s, "ifopt") == 0 || 
+	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 || 
+	} else if (strcmp(s, "endif") == 0 ||
+		strcmp(s, "ifend") == 0 ||
 		strcmp(s, "endregion") == 0) {
 		nestLevel--;
 		SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
@@ -400,12 +402,12 @@ static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFold
 	}
 }
 
-static unsigned int SkipWhiteSpace(unsigned int currentPos, unsigned int endPos, 
+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' || 
+	while ((j < endPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' ||
 		IsStreamCommentStyle(styler.StyleAt(j)) || (includeChars && setWord.Contains(ch)))) {
 		j++;
 		ch = styler.SafeGetCharAt(j);
@@ -413,8 +415,8 @@ static unsigned int SkipWhiteSpace(unsigned int currentPos, unsigned int endPos,
 	return j;
 }
 
-static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCurrent, 
-		int startPos, unsigned int endPos, 
+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));
@@ -422,9 +424,9 @@ static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCur
 	if (strcmp(s, "record") == 0) {
 		lineFoldStateCurrent |= stateFoldInRecord;
 		levelCurrent++;
-	} else if (strcmp(s, "begin") == 0 || 
-		strcmp(s, "asm") == 0 || 
-		strcmp(s, "try") == 0 || 
+	} 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) {
@@ -436,13 +438,13 @@ static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCur
 			CharacterSet setWord(CharacterSet::setAlphaNum, "_");
 
 			if (styler.SafeGetCharAt(j) == ';') {
-				// Handle forward class declarations ("type TMyClass = class;") 
+				// 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);") 
+					// 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);
@@ -454,11 +456,11 @@ static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCur
 					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 || 
+					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;
 					}
@@ -473,7 +475,7 @@ static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCur
 		bool ignoreKeyword = true;
 		int j = lastStart - 1;
 		char ch = styler.SafeGetCharAt(j);
-		while ((j >= startPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' || 
+		while ((j >= startPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' ||
 			IsStreamCommentStyle(styler.StyleAt(j)))) {
 			j--;
 			ch = styler.SafeGetCharAt(j);
@@ -539,7 +541,7 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word
 		if (foldPreprocessor) {
 			if (style == SCE_PAS_PREPROCESSOR && ch == '{' && chNext == '$') {
 				ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 2, styler);
-			} else if (style == SCE_PAS_PREPROCESSOR2 && ch == '(' && chNext == '*' 
+			} else if (style == SCE_PAS_PREPROCESSOR2 && ch == '(' && chNext == '*'
 			           && styler.SafeGetCharAt(i + 2) == '$') {
 				ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler);
 			}
diff --git a/plugins/scintilla/scintilla/LexPerl.cxx b/plugins/scintilla/scintilla/LexPerl.cxx
index 0c66036..7f0cbcf 100644
--- a/plugins/scintilla/scintilla/LexPerl.cxx
+++ b/plugins/scintilla/scintilla/LexPerl.cxx
@@ -1,6 +1,7 @@
 // Scintilla source code edit control
 /** @file LexPerl.cxx
  ** Lexer for Perl.
+ ** Converted to lexer object by "Udo Lechner" <dlchnr(at)gmx(dot)net>
  **/
 // Copyright 1998-2008 by Neil Hodgson <neilh scintilla org>
 // Lexical analysis fixes by Kein-Hong Man <mkh pl jaring my>
@@ -8,19 +9,28 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
 
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include <string>
+#include <map>
+
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "StyleContext.h"
 #include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -59,8 +69,7 @@ using namespace Scintilla;
 #define BACK_OPERATOR	1	// whitespace/comments are insignificant
 #define BACK_KEYWORD	2	// operators/keywords are needed for disambiguation
 
-static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler)
-{
+static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywords, LexAccessor &styler) {
 	// old-style keyword matcher; needed because GetCurrent() needs
 	// current segment to be committed, but we may abandon early...
 	char s[100];
@@ -71,9 +80,8 @@ static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywor
 	return keywords.InList(s);
 }
 
-static int disambiguateBareword(Accessor &styler, unsigned int bk, unsigned int fw,
-                                int backFlag, unsigned int backPos, unsigned int endPos)
-{
+static int disambiguateBareword(LexAccessor &styler, unsigned int bk, unsigned int fw,
+        int backFlag, unsigned int backPos, unsigned int endPos) {
 	// identifiers are recognized by Perl as barewords under some
 	// conditions, the following attempts to do the disambiguation
 	// by looking backward and forward; result in 2 LSB
@@ -94,25 +102,25 @@ static int disambiguateBareword(Accessor &styler, unsigned int bk, unsigned int
 		// {bareword: possible variable spec
 		brace = true;
 	} else if ((ch == '&' && styler.SafeGetCharAt(bk - 1) != '&')
-			// &bareword: subroutine call
-			   || styler.Match(bk - 1, "->")
-			// ->bareword: part of variable spec
-			   || styler.Match(bk - 2, "sub")) {
-			// sub bareword: subroutine declaration
-			// (implied BACK_KEYWORD, no keywords end in 'sub'!)
+	        // &bareword: subroutine call
+	        || styler.Match(bk - 1, "->")
+	        // ->bareword: part of variable spec
+	        || styler.Match(bk - 2, "sub")) {
+		// sub bareword: subroutine declaration
+		// (implied BACK_KEYWORD, no keywords end in 'sub'!)
 		result |= 1;
 	}
 	// next, scan forward after word past tab/spaces only;
 	// if ch isn't one of '[{(,' we can skip the test
 	if ((ch == '{' || ch == '(' || ch == '['|| ch == ',')
-		&& fw < endPos) {
+	        && fw < endPos) {
 		while (ch = static_cast<unsigned char>(styler.SafeGetCharAt(fw)),
-			   IsASpaceOrTab(ch) && fw < endPos) {
+		        IsASpaceOrTab(ch) && fw < endPos) {
 			fw++;
 		}
 		if ((ch == '}' && brace)
-			// {bareword}: variable spec
-			|| styler.Match(fw, "=>")) {
+		        // {bareword}: variable spec
+		        || styler.Match(fw, "=>")) {
 			// [{(, bareword=>: hash literal
 			result |= 2;
 		}
@@ -120,17 +128,15 @@ static int disambiguateBareword(Accessor &styler, unsigned int bk, unsigned int
 	return result;
 }
 
-static void skipWhitespaceComment(Accessor &styler, unsigned int &p)
-{
+static void skipWhitespaceComment(LexAccessor &styler, unsigned int &p) {
 	// when backtracking, we need to skip whitespace and comments
 	int style;
 	while ((p > 0) && (style = styler.StyleAt(p),
-		   style == SCE_PL_DEFAULT || style == SCE_PL_COMMENTLINE))
+	        style == SCE_PL_DEFAULT || style == SCE_PL_COMMENTLINE))
 		p--;
 }
 
-static int styleBeforeBracePair(Accessor &styler, unsigned int bk)
-{
+static int styleBeforeBracePair(LexAccessor &styler, unsigned int bk) {
 	// backtrack to find open '{' corresponding to a '}', balanced
 	// return significant style to be tested for '/' disambiguation
 	int braceCount = 1;
@@ -157,8 +163,7 @@ static int styleBeforeBracePair(Accessor &styler, unsigned int bk)
 	return SCE_PL_DEFAULT;
 }
 
-static int styleCheckIdentifier(Accessor &styler, unsigned int bk)
-{
+static int styleCheckIdentifier(LexAccessor &styler, unsigned int bk) {
 	// backtrack to classify sub-styles of identifier under test
 	// return sub-style to be tested for '/' disambiguation
 	if (styler.SafeGetCharAt(bk) == '>')	// inputsymbol, like <foo>
@@ -170,7 +175,7 @@ static int styleCheckIdentifier(Accessor &styler, unsigned int bk)
 	while (bk > 0) {
 		int bkstyle = styler.StyleAt(bk);
 		if (bkstyle == SCE_PL_DEFAULT
-			|| bkstyle == SCE_PL_COMMENTLINE) {
+		        || bkstyle == SCE_PL_COMMENTLINE) {
 			// skip whitespace, comments
 		} else if (bkstyle == SCE_PL_OPERATOR) {
 			// test for "->" and "::"
@@ -183,8 +188,7 @@ static int styleCheckIdentifier(Accessor &styler, unsigned int bk)
 	return 0;
 }
 
-static int inputsymbolScan(Accessor &styler, unsigned int pos, unsigned int endPos)
-{
+static int inputsymbolScan(LexAccessor &styler, unsigned int pos, unsigned int endPos) {
 	// looks forward for matching > on same line; a bit ugly
 	unsigned int fw = pos;
 	while (++fw < endPos) {
@@ -200,8 +204,7 @@ static int inputsymbolScan(Accessor &styler, unsigned int pos, unsigned int endP
 	return 0;
 }
 
-static int podLineScan(Accessor &styler, unsigned int &pos, unsigned int endPos)
-{
+static int podLineScan(LexAccessor &styler, unsigned int &pos, unsigned int endPos) {
 	// forward scan the current line to classify line for POD style
 	int state = -1;
 	while (pos <= endPos) {
@@ -225,8 +228,7 @@ static int podLineScan(Accessor &styler, unsigned int &pos, unsigned int endPos)
 	return state;
 }
 
-static bool styleCheckSubPrototype(Accessor &styler, unsigned int bk)
-{
+static bool styleCheckSubPrototype(LexAccessor &styler, unsigned int bk) {
 	// backtrack to identify if we're starting a subroutine prototype
 	// we also need to ignore whitespace/comments:
 	// 'sub' [whitespace|comment] <identifier> [whitespace|comment]
@@ -239,13 +241,12 @@ static bool styleCheckSubPrototype(Accessor &styler, unsigned int bk)
 	}
 	skipWhitespaceComment(styler, bk);
 	if (bk < 2 || styler.StyleAt(bk) != SCE_PL_WORD	// check "sub" keyword
-		|| !styler.Match(bk - 2, "sub"))	// assume suffix is unique!
+	        || !styler.Match(bk - 2, "sub"))	// assume suffix is unique!
 		return false;
 	return true;
 }
 
-static bool isMatch(const char *sref, char *s)
-{
+static bool isMatch(const char *sref, char *s) {
 	// match per-line delimiter - must kill trailing CR if CRLF
 	int i = strlen(s);
 	if (i != 0 && s[i - 1] == '\r')
@@ -270,10 +271,163 @@ static int opposite(int ch) {
 	return ch;
 }
 
-static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
-                             WordList *keywordlists[], Accessor &styler) {
+static bool IsCommentLine(int line, LexAccessor &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];
+		int style = styler.StyleAt(i);
+		if (ch == '#' && style == SCE_PL_COMMENTLINE)
+			return true;
+		else if (!IsASpaceOrTab(ch))
+			return false;
+	}
+	return false;
+}
+
+static bool IsPackageLine(int line, LexAccessor &styler) {
+	int pos = styler.LineStart(line);
+	int style = styler.StyleAt(pos);
+	if (style == SCE_PL_WORD && styler.Match(pos, "package")) {
+		return true;
+	}
+	return false;
+}
 
-	WordList &keywords = *keywordlists[0];
+static int PodHeadingLevel(int pos, LexAccessor &styler) {
+	int lvl = static_cast<unsigned char>(styler.SafeGetCharAt(pos + 5));
+	if (lvl >= '1' && lvl <= '4') {
+		return lvl - '0';
+	}
+	return 0;
+}
+
+// An individual named option for use in an OptionSet
+
+// Options used for LexerPerl
+struct OptionsPerl {
+	bool fold;
+	bool foldComment;
+	bool foldCompact;
+	// Custom folding of POD and packages
+	bool foldPOD;            // fold.perl.pod
+	// Enable folding Pod blocks when using the Perl lexer.
+	bool foldPackage;        // fold.perl.package
+	// Enable folding packages when using the Perl lexer.
+
+	bool foldCommentExplicit;
+
+	bool foldAtElse;
+
+	OptionsPerl() {
+		fold = false;
+		foldComment = false;
+		foldCompact = true;
+		foldPOD = true;
+		foldPackage = true;
+		foldCommentExplicit = true;
+		foldAtElse = false;
+	}
+};
+
+static const char *const perlWordListDesc[] = {
+	"Keywords",
+	0
+};
+
+struct OptionSetPerl : public OptionSet<OptionsPerl> {
+	OptionSetPerl() {
+		DefineProperty("fold", &OptionsPerl::fold);
+
+		DefineProperty("fold.comment", &OptionsPerl::foldComment);
+
+		DefineProperty("fold.compact", &OptionsPerl::foldCompact);
+
+		DefineProperty("fold.perl.pod", &OptionsPerl::foldPOD,
+		        "Set to 0 to disable folding Pod blocks when using the Perl lexer.");
+
+		DefineProperty("fold.perl.package", &OptionsPerl::foldPackage,
+		        "Set to 0 to disable folding packages when using the Perl lexer.");
+
+		DefineProperty("fold.perl.comment.explicit", &OptionsPerl::foldCommentExplicit,
+		        "Set to 0 to disable explicit folding.");
+
+		DefineProperty("fold.perl.at.else", &OptionsPerl::foldAtElse,
+		               "This option enables Perl folding on a \"} else {\" line of an if statement.");
+
+		DefineWordListSets(perlWordListDesc);
+	}
+};
+
+class LexerPerl : public ILexer {
+	WordList keywords;
+	OptionsPerl options;
+	OptionSetPerl osPerl;
+public:
+	LexerPerl() {
+	}
+	~LexerPerl() {
+	}
+	void SCI_METHOD Release() {
+		delete this;
+	}
+	int SCI_METHOD Version() const {
+		return lvOriginal;
+	}
+	const char *SCI_METHOD PropertyNames() {
+		return osPerl.PropertyNames();
+	}
+	int SCI_METHOD PropertyType(const char *name) {
+		return osPerl.PropertyType(name);
+	}
+	const char *SCI_METHOD DescribeProperty(const char *name) {
+		return osPerl.DescribeProperty(name);
+	}
+	int SCI_METHOD PropertySet(const char *key, const char *val);
+	const char *SCI_METHOD DescribeWordListSets() {
+		return osPerl.DescribeWordListSets();
+	}
+	int SCI_METHOD WordListSet(int n, const char *wl);
+	void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+	void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+
+	void *SCI_METHOD PrivateCall(int, void *) {
+		return 0;
+	}
+
+	static ILexer *LexerFactoryPerl() {
+		return new LexerPerl();
+	}
+};
+
+int SCI_METHOD LexerPerl::PropertySet(const char *key, const char *val) {
+	if (osPerl.PropertySet(&options, key, val)) {
+		return 0;
+	}
+	return -1;
+}
+
+int SCI_METHOD LexerPerl::WordListSet(int n, const char *wl) {
+	WordList *wordListN = 0;
+	switch (n) {
+	case 0:
+		wordListN = &keywords;
+		break;
+	}
+	int firstModification = -1;
+	if (wordListN) {
+		WordList wlNew;
+		wlNew.Set(wl);
+		if (*wordListN != wlNew) {
+			wordListN->Set(wl);
+			firstModification = 0;
+		}
+	}
+	return firstModification;
+}
+
+void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+	LexAccessor styler(pAccess);
 
 	// keywords that forces /PATTERN/ at all times; should track vim's behaviour
 	WordList reWords;
@@ -307,9 +461,10 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 
 	class HereDocCls {	// Class to manage HERE doc sequence
 	public:
-		int State;		// 0: '<<' encountered
-						// 1: collect the delimiter
-						// 2: here doc text (lines after the delimiter)
+		int State;
+		// 0: '<<' encountered
+		// 1: collect the delimiter
+		// 2: here doc text (lines after the delimiter)
 		int Quote;		// the char after '<<'
 		bool Quoted;		// true if Quote in ('\'','"','`')
 		int DelimiterLength;	// strlen(Delimiter)
@@ -333,7 +488,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 	HereDocCls HereDoc;		// TODO: FIFO for stacked here-docs
 
 	class QuoteCls {	// Class to manage quote pairs
-		public:
+	public:
 		int Rep;
 		int Count;
 		int Up, Down;
@@ -365,10 +520,10 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 	// Includes strings (may be multi-line), numbers (additional state), format
 	// bodies, as well as POD sections.
 	if (initStyle == SCE_PL_HERE_Q
-		|| initStyle == SCE_PL_HERE_QQ
-		|| initStyle == SCE_PL_HERE_QX
-		|| initStyle == SCE_PL_FORMAT
-	) {
+	        || initStyle == SCE_PL_HERE_QQ
+	        || initStyle == SCE_PL_HERE_QX
+	        || initStyle == SCE_PL_FORMAT
+	   ) {
 		int delim = (initStyle == SCE_PL_FORMAT) ? SCE_PL_FORMAT_IDENT:SCE_PL_HERE_DELIM;
 		while ((startPos > 1) && (styler.StyleAt(startPos) != delim)) {
 			startPos--;
@@ -377,27 +532,27 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 		initStyle = styler.StyleAt(startPos - 1);
 	}
 	if (initStyle == SCE_PL_STRING_Q
-		|| initStyle == SCE_PL_STRING_QQ
-		|| initStyle == SCE_PL_STRING_QX
-		|| initStyle == SCE_PL_STRING_QR
-		|| initStyle == SCE_PL_STRING_QW
-		|| initStyle == SCE_PL_REGEX
-		|| initStyle == SCE_PL_REGSUBST
-		|| initStyle == SCE_PL_STRING
-		|| initStyle == SCE_PL_BACKTICKS
-		|| initStyle == SCE_PL_CHARACTER
-		|| initStyle == SCE_PL_NUMBER
-		|| initStyle == SCE_PL_IDENTIFIER
-		|| initStyle == SCE_PL_ERROR
-		|| initStyle == SCE_PL_SUB_PROTOTYPE
-	) {
+	        || initStyle == SCE_PL_STRING_QQ
+	        || initStyle == SCE_PL_STRING_QX
+	        || initStyle == SCE_PL_STRING_QR
+	        || initStyle == SCE_PL_STRING_QW
+	        || initStyle == SCE_PL_REGEX
+	        || initStyle == SCE_PL_REGSUBST
+	        || initStyle == SCE_PL_STRING
+	        || initStyle == SCE_PL_BACKTICKS
+	        || initStyle == SCE_PL_CHARACTER
+	        || initStyle == SCE_PL_NUMBER
+	        || initStyle == SCE_PL_IDENTIFIER
+	        || initStyle == SCE_PL_ERROR
+	        || initStyle == SCE_PL_SUB_PROTOTYPE
+	   ) {
 		while ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) {
 			startPos--;
 		}
 		initStyle = SCE_PL_DEFAULT;
 	} else if (initStyle == SCE_PL_POD
-			   || initStyle == SCE_PL_POD_VERB
-	) {
+	        || initStyle == SCE_PL_POD_VERB
+	          ) {
 		// POD backtracking finds preceeding blank lines and goes back past them
 		int ln = styler.GetLine(startPos);
 		if (ln > 0) {
@@ -435,187 +590,187 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 
 		// Determine if the current state should terminate.
 		switch (sc.state) {
-			case SCE_PL_OPERATOR:
+		case SCE_PL_OPERATOR:
+			sc.SetState(SCE_PL_DEFAULT);
+			backFlag = BACK_OPERATOR;
+			backPos = sc.currentPos;
+			break;
+		case SCE_PL_IDENTIFIER:		// identifier, bareword, inputsymbol
+			if ((!setWord.Contains(sc.ch) && sc.ch != '\'')
+			        || sc.Match('.', '.')
+			        || sc.chPrev == '>') {	// end of inputsymbol
 				sc.SetState(SCE_PL_DEFAULT);
-				backFlag = BACK_OPERATOR;
-				backPos = sc.currentPos;
-				break;
-			case SCE_PL_IDENTIFIER:		// identifier, bareword, inputsymbol
-				if ((!setWord.Contains(sc.ch) && sc.ch != '\'')
-					|| sc.Match('.', '.')
-					|| sc.chPrev == '>') {	// end of inputsymbol
-					sc.SetState(SCE_PL_DEFAULT);
-				}
-				break;
-			case SCE_PL_WORD:		// keyword, plus special cases
-				if (!setWord.Contains(sc.ch)) {
-					char s[100];
-					sc.GetCurrent(s, sizeof(s));
-					if ((strcmp(s, "__DATA__") == 0) || (strcmp(s, "__END__") == 0)) {
-						sc.ChangeState(SCE_PL_DATASECTION);
+			}
+			break;
+		case SCE_PL_WORD:		// keyword, plus special cases
+			if (!setWord.Contains(sc.ch)) {
+				char s[100];
+				sc.GetCurrent(s, sizeof(s));
+				if ((strcmp(s, "__DATA__") == 0) || (strcmp(s, "__END__") == 0)) {
+					sc.ChangeState(SCE_PL_DATASECTION);
+				} else {
+					if ((strcmp(s, "format") == 0)) {
+						sc.SetState(SCE_PL_FORMAT_IDENT);
+						HereDoc.State = 0;
 					} else {
-						if ((strcmp(s, "format") == 0)) {
-							sc.SetState(SCE_PL_FORMAT_IDENT);
-							HereDoc.State = 0;
-						} else {
-							sc.SetState(SCE_PL_DEFAULT);
-						}
-						backFlag = BACK_KEYWORD;
-						backPos = sc.currentPos;
+						sc.SetState(SCE_PL_DEFAULT);
 					}
+					backFlag = BACK_KEYWORD;
+					backPos = sc.currentPos;
 				}
-				break;
-			case SCE_PL_SCALAR:
-			case SCE_PL_ARRAY:
-			case SCE_PL_HASH:
-			case SCE_PL_SYMBOLTABLE:
-				if (sc.Match(':', ':')) {	// skip ::
+			}
+			break;
+		case SCE_PL_SCALAR:
+		case SCE_PL_ARRAY:
+		case SCE_PL_HASH:
+		case SCE_PL_SYMBOLTABLE:
+			if (sc.Match(':', ':')) {	// skip ::
+				sc.Forward();
+			} else if (!setVar.Contains(sc.ch)) {
+				if (sc.LengthCurrent() == 1) {
+					// Special variable: $(, $_ etc.
 					sc.Forward();
-				} else if (!setVar.Contains(sc.ch)) {
-					if (sc.LengthCurrent() == 1) {
-						// Special variable: $(, $_ etc.
-						sc.Forward();
-					}
-					sc.SetState(SCE_PL_DEFAULT);
 				}
-				break;
-			case SCE_PL_NUMBER:
-				// if no early break, number style is terminated at "(go through)"
-				if (sc.ch == '.') {
-					if (sc.chNext == '.') {
-						// double dot is always an operator (go through)
-					} else if (numState <= PERLNUM_FLOAT_EXP) {
-						// non-decimal number or float exponent, consume next dot
-						sc.SetState(SCE_PL_OPERATOR);
-						break;
-					} else {	// decimal or vectors allows dots
-						dotCount++;
-						if (numState == PERLNUM_DECIMAL) {
-							if (dotCount <= 1)	// number with one dot in it
-								break;
-							if (IsADigit(sc.chNext)) {	// really a vector
-								numState = PERLNUM_VECTOR;
-								break;
-							}
-							// number then dot (go through)
-						} else if (IsADigit(sc.chNext))	// vectors
-							break;
-						// vector then dot (go through)
-					}
-				} else if (sc.ch == '_') {
-					// permissive underscoring for number and vector literals
+				sc.SetState(SCE_PL_DEFAULT);
+			}
+			break;
+		case SCE_PL_NUMBER:
+			// if no early break, number style is terminated at "(go through)"
+			if (sc.ch == '.') {
+				if (sc.chNext == '.') {
+					// double dot is always an operator (go through)
+				} else if (numState <= PERLNUM_FLOAT_EXP) {
+					// non-decimal number or float exponent, consume next dot
+					sc.SetState(SCE_PL_OPERATOR);
 					break;
-				} else if (numState == PERLNUM_DECIMAL) {
-					if (sc.ch == 'E' || sc.ch == 'e') {	// exponent, sign
-						numState = PERLNUM_FLOAT_EXP;
-						if (sc.chNext == '+' || sc.chNext == '-') {
-							sc.Forward();
+				} else {	// decimal or vectors allows dots
+					dotCount++;
+					if (numState == PERLNUM_DECIMAL) {
+						if (dotCount <= 1)	// number with one dot in it
+							break;
+						if (IsADigit(sc.chNext)) {	// really a vector
+							numState = PERLNUM_VECTOR;
+							break;
 						}
+						// number then dot (go through)
+					} else if (IsADigit(sc.chNext))	// vectors
 						break;
-					} else if (IsADigit(sc.ch))
-						break;
-					// number then word (go through)
-				} else if (numState == PERLNUM_HEX) {
-					if (IsADigit(sc.ch, 16))
-						break;
-				} else if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) {
-					if (IsADigit(sc.ch))	// vector
-						break;
-					if (setWord.Contains(sc.ch) && dotCount == 0) {	// change to word
-						sc.ChangeState(SCE_PL_IDENTIFIER);
-						break;
-					}
-					// vector then word (go through)
-				} else if (IsADigit(sc.ch)) {
-					if (numState == PERLNUM_FLOAT_EXP) {
-						break;
-					} else if (numState == PERLNUM_OCTAL) {
-						if (sc.ch <= '7') break;
-					} else if (numState == PERLNUM_BINARY) {
-						if (sc.ch <= '1') break;
+					// vector then dot (go through)
+				}
+			} else if (sc.ch == '_') {
+				// permissive underscoring for number and vector literals
+				break;
+			} else if (numState == PERLNUM_DECIMAL) {
+				if (sc.ch == 'E' || sc.ch == 'e') {	// exponent, sign
+					numState = PERLNUM_FLOAT_EXP;
+					if (sc.chNext == '+' || sc.chNext == '-') {
+						sc.Forward();
 					}
-					// mark invalid octal, binary numbers (go through)
-					numState = PERLNUM_BAD;
+					break;
+				} else if (IsADigit(sc.ch))
+					break;
+				// number then word (go through)
+			} else if (numState == PERLNUM_HEX) {
+				if (IsADigit(sc.ch, 16))
+					break;
+			} else if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) {
+				if (IsADigit(sc.ch))	// vector
+					break;
+				if (setWord.Contains(sc.ch) && dotCount == 0) {	// change to word
+					sc.ChangeState(SCE_PL_IDENTIFIER);
 					break;
 				}
-				// complete current number or vector
-				sc.ChangeState(actualNumStyle(numState));
-				sc.SetState(SCE_PL_DEFAULT);
-				break;
-			case SCE_PL_COMMENTLINE:
-				if (sc.atLineEnd) {
-					sc.SetState(SCE_PL_DEFAULT);
+				// vector then word (go through)
+			} else if (IsADigit(sc.ch)) {
+				if (numState == PERLNUM_FLOAT_EXP) {
+					break;
+				} else if (numState == PERLNUM_OCTAL) {
+					if (sc.ch <= '7') break;
+				} else if (numState == PERLNUM_BINARY) {
+					if (sc.ch <= '1') break;
 				}
+				// mark invalid octal, binary numbers (go through)
+				numState = PERLNUM_BAD;
 				break;
-			case SCE_PL_HERE_DELIM:
-				if (HereDoc.State == 0) { // '<<' encountered
-					int delim_ch = sc.chNext;
-					int ws_skip = 0;
-					HereDoc.State = 1;	// pre-init HERE doc class
-					HereDoc.Quote = sc.chNext;
-					HereDoc.Quoted = false;
-					HereDoc.DelimiterLength = 0;
-					HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
-					if (IsASpaceOrTab(delim_ch)) {
-						// skip whitespace; legal only for quoted delimiters
-						unsigned int i = sc.currentPos + 1;
-						while ((i < endPos) && IsASpaceOrTab(delim_ch)) {
-							i++;
-							delim_ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
-						}
-						ws_skip = i - sc.currentPos - 1;
+			}
+			// complete current number or vector
+			sc.ChangeState(actualNumStyle(numState));
+			sc.SetState(SCE_PL_DEFAULT);
+			break;
+		case SCE_PL_COMMENTLINE:
+			if (sc.atLineEnd) {
+				sc.SetState(SCE_PL_DEFAULT);
+			}
+			break;
+		case SCE_PL_HERE_DELIM:
+			if (HereDoc.State == 0) { // '<<' encountered
+				int delim_ch = sc.chNext;
+				int ws_skip = 0;
+				HereDoc.State = 1;	// pre-init HERE doc class
+				HereDoc.Quote = sc.chNext;
+				HereDoc.Quoted = false;
+				HereDoc.DelimiterLength = 0;
+				HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+				if (IsASpaceOrTab(delim_ch)) {
+					// skip whitespace; legal only for quoted delimiters
+					unsigned int i = sc.currentPos + 1;
+					while ((i < endPos) && IsASpaceOrTab(delim_ch)) {
+						i++;
+						delim_ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
 					}
-					if (delim_ch == '\'' || delim_ch == '"' || delim_ch == '`') {
-						// a quoted here-doc delimiter; skip any whitespace
-						sc.Forward(ws_skip + 1);
-						HereDoc.Quote = delim_ch;
-						HereDoc.Quoted = true;
-					} else if ((ws_skip == 0 && setNonHereDoc.Contains(sc.chNext))
-							   || ws_skip > 0) {
-						// left shift << or <<= operator cases
-						// restore position if operator
-						sc.ChangeState(SCE_PL_OPERATOR);
+					ws_skip = i - sc.currentPos - 1;
+				}
+				if (delim_ch == '\'' || delim_ch == '"' || delim_ch == '`') {
+					// a quoted here-doc delimiter; skip any whitespace
+					sc.Forward(ws_skip + 1);
+					HereDoc.Quote = delim_ch;
+					HereDoc.Quoted = true;
+				} else if ((ws_skip == 0 && setNonHereDoc.Contains(sc.chNext))
+				        || ws_skip > 0) {
+					// left shift << or <<= operator cases
+					// restore position if operator
+					sc.ChangeState(SCE_PL_OPERATOR);
+					sc.ForwardSetState(SCE_PL_DEFAULT);
+					backFlag = BACK_OPERATOR;
+					backPos = sc.currentPos;
+					HereDoc.State = 0;
+				} else {
+					// specially handle initial '\' for identifier
+					if (ws_skip == 0 && HereDoc.Quote == '\\')
+						sc.Forward();
+					// an unquoted here-doc delimiter, no special handling
+					// (cannot be prefixed by spaces/tabs), or
+					// symbols terminates; deprecated zero-length delimiter
+				}
+			} else if (HereDoc.State == 1) { // collect the delimiter
+				backFlag = BACK_NONE;
+				if (HereDoc.Quoted) { // a quoted here-doc delimiter
+					if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
 						sc.ForwardSetState(SCE_PL_DEFAULT);
-						backFlag = BACK_OPERATOR;
-						backPos = sc.currentPos;
-						HereDoc.State = 0;
-					} else {
-						// specially handle initial '\' for identifier
-						if (ws_skip == 0 && HereDoc.Quote == '\\')
+					} else if (!sc.atLineEnd) {
+						if (sc.Match('\\', static_cast<char>(HereDoc.Quote))) { // escaped quote
 							sc.Forward();
-						// an unquoted here-doc delimiter, no special handling
-						// (cannot be prefixed by spaces/tabs), or
-						// symbols terminates; deprecated zero-length delimiter
-					}
-				} else if (HereDoc.State == 1) { // collect the delimiter
-					backFlag = BACK_NONE;
-					if (HereDoc.Quoted) { // a quoted here-doc delimiter
-						if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
-							sc.ForwardSetState(SCE_PL_DEFAULT);
-						} else if (!sc.atLineEnd) {
-							if (sc.Match('\\', static_cast<char>(HereDoc.Quote))) { // escaped quote
-								sc.Forward();
-							}
-							if (sc.ch != '\r') {	// skip CR if CRLF
-								HereDoc.Append(sc.ch);
-							}
 						}
-					} else { // an unquoted here-doc delimiter
-						if (setHereDocDelim.Contains(sc.ch)) {
+						if (sc.ch != '\r') {	// skip CR if CRLF
 							HereDoc.Append(sc.ch);
-						} else {
-							sc.SetState(SCE_PL_DEFAULT);
 						}
 					}
-					if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {
-						sc.SetState(SCE_PL_ERROR);
-						HereDoc.State = 0;
+				} else { // an unquoted here-doc delimiter
+					if (setHereDocDelim.Contains(sc.ch)) {
+						HereDoc.Append(sc.ch);
+					} else {
+						sc.SetState(SCE_PL_DEFAULT);
 					}
 				}
-				break;
-			case SCE_PL_HERE_Q:
-			case SCE_PL_HERE_QQ:
-			case SCE_PL_HERE_QX: {
+				if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {
+					sc.SetState(SCE_PL_ERROR);
+					HereDoc.State = 0;
+				}
+			}
+			break;
+		case SCE_PL_HERE_Q:
+		case SCE_PL_HERE_QQ:
+		case SCE_PL_HERE_QX: {
 				// also implies HereDoc.State == 2
 				sc.Complete();
 				while (!sc.atLineEnd)
@@ -627,9 +782,10 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 					backFlag = BACK_NONE;
 					HereDoc.State = 0;
 				}
-				} break;
-			case SCE_PL_POD:
-			case SCE_PL_POD_VERB: {
+			}
+			break;
+		case SCE_PL_POD:
+		case SCE_PL_POD_VERB: {
 				unsigned int fw = sc.currentPos;
 				int ln = styler.GetLine(fw);
 				if (sc.atLineStart && sc.Match("=cut")) {	// end of POD
@@ -657,86 +813,87 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 						pod = SCE_PL_POD;
 				} else {
 					if (pod == SCE_PL_POD_VERB	// still part of current paragraph
-					    && (styler.GetLineState(ln - 1) == SCE_PL_POD)) {
+					        && (styler.GetLineState(ln - 1) == SCE_PL_POD)) {
 						pod = SCE_PL_POD;
 						styler.SetLineState(ln, pod);
 					} else if (pod == SCE_PL_POD
-							   && (styler.GetLineState(ln - 1) == SCE_PL_POD_VERB)) {
+					        && (styler.GetLineState(ln - 1) == SCE_PL_POD_VERB)) {
 						pod = SCE_PL_POD_VERB;
 						styler.SetLineState(ln, pod);
 					}
 					sc.SetState(pod);
 				}
 				sc.Forward(fw - sc.currentPos);	// commit style
-				} break;
-			case SCE_PL_REGEX:
-			case SCE_PL_STRING_QR:
-				if (Quote.Rep <= 0) {
-					if (!setModifiers.Contains(sc.ch))
-						sc.SetState(SCE_PL_DEFAULT);
-				} else if (!Quote.Up && !IsASpace(sc.ch)) {
-					Quote.Open(sc.ch);
-				} else if (sc.ch == '\\' && Quote.Up != '\\') {
-					sc.Forward();
-				} else if (sc.ch == Quote.Down) {
-					Quote.Count--;
-					if (Quote.Count == 0)
-						Quote.Rep--;
-				} else if (sc.ch == Quote.Up) {
-					Quote.Count++;
-				}
-				break;
-			case SCE_PL_REGSUBST:
-				if (Quote.Rep <= 0) {
-					if (!setModifiers.Contains(sc.ch))
-						sc.SetState(SCE_PL_DEFAULT);
-				} else if (!Quote.Up && !IsASpace(sc.ch)) {
+			}
+			break;
+		case SCE_PL_REGEX:
+		case SCE_PL_STRING_QR:
+			if (Quote.Rep <= 0) {
+				if (!setModifiers.Contains(sc.ch))
+					sc.SetState(SCE_PL_DEFAULT);
+			} else if (!Quote.Up && !IsASpace(sc.ch)) {
+				Quote.Open(sc.ch);
+			} else if (sc.ch == '\\' && Quote.Up != '\\') {
+				sc.Forward();
+			} else if (sc.ch == Quote.Down) {
+				Quote.Count--;
+				if (Quote.Count == 0)
+					Quote.Rep--;
+			} else if (sc.ch == Quote.Up) {
+				Quote.Count++;
+			}
+			break;
+		case SCE_PL_REGSUBST:
+			if (Quote.Rep <= 0) {
+				if (!setModifiers.Contains(sc.ch))
+					sc.SetState(SCE_PL_DEFAULT);
+			} else if (!Quote.Up && !IsASpace(sc.ch)) {
+				Quote.Open(sc.ch);
+			} else if (sc.ch == '\\' && Quote.Up != '\\') {
+				sc.Forward();
+			} else if (Quote.Count == 0 && Quote.Rep == 1) {
+				// We matched something like s(...) or tr{...}, Perl 5.10
+				// appears to allow almost any character for use as the
+				// next delimiters. Whitespace and comments are accepted in
+				// between, but we'll limit to whitespace here.
+				// For '#', if no whitespace in between, it's a delimiter.
+				if (IsASpace(sc.ch)) {
+					// Keep going
+				} else if (sc.ch == '#' && IsASpaceOrTab(sc.chPrev)) {
+					sc.SetState(SCE_PL_DEFAULT);
+				} else {
 					Quote.Open(sc.ch);
-				} else if (sc.ch == '\\' && Quote.Up != '\\') {
-					sc.Forward();
-				} else if (Quote.Count == 0 && Quote.Rep == 1) {
-					// We matched something like s(...) or tr{...}, Perl 5.10
-					// appears to allow almost any character for use as the
-					// next delimiters. Whitespace and comments are accepted in
-					// between, but we'll limit to whitespace here.
-					// For '#', if no whitespace in between, it's a delimiter.
-					if (IsASpace(sc.ch)) {
-						// Keep going
-					} else if (sc.ch == '#' && IsASpaceOrTab(sc.chPrev)) {
-						sc.SetState(SCE_PL_DEFAULT);
-					} else {
-						Quote.Open(sc.ch);
-					}
-				} else if (sc.ch == Quote.Down) {
-					Quote.Count--;
-					if (Quote.Count == 0)
-						Quote.Rep--;
-					if (Quote.Up == Quote.Down)
-						Quote.Count++;
-				} else if (sc.ch == Quote.Up) {
-					Quote.Count++;
 				}
-				break;
-			case SCE_PL_STRING_Q:
-			case SCE_PL_STRING_QQ:
-			case SCE_PL_STRING_QX:
-			case SCE_PL_STRING_QW:
-			case SCE_PL_STRING:
-			case SCE_PL_CHARACTER:
-			case SCE_PL_BACKTICKS:
-				if (!Quote.Down && !IsASpace(sc.ch)) {
-					Quote.Open(sc.ch);
-				} else if (sc.ch == '\\' && Quote.Up != '\\') {
-					sc.Forward();
-				} else if (sc.ch == Quote.Down) {
-					Quote.Count--;
-					if (Quote.Count == 0)
-						sc.ForwardSetState(SCE_PL_DEFAULT);
-				} else if (sc.ch == Quote.Up) {
+			} else if (sc.ch == Quote.Down) {
+				Quote.Count--;
+				if (Quote.Count == 0)
+					Quote.Rep--;
+				if (Quote.Up == Quote.Down)
 					Quote.Count++;
-				}
-				break;
-			case SCE_PL_SUB_PROTOTYPE: {
+			} else if (sc.ch == Quote.Up) {
+				Quote.Count++;
+			}
+			break;
+		case SCE_PL_STRING_Q:
+		case SCE_PL_STRING_QQ:
+		case SCE_PL_STRING_QX:
+		case SCE_PL_STRING_QW:
+		case SCE_PL_STRING:
+		case SCE_PL_CHARACTER:
+		case SCE_PL_BACKTICKS:
+			if (!Quote.Down && !IsASpace(sc.ch)) {
+				Quote.Open(sc.ch);
+			} else if (sc.ch == '\\' && Quote.Up != '\\') {
+				sc.Forward();
+			} else if (sc.ch == Quote.Down) {
+				Quote.Count--;
+				if (Quote.Count == 0)
+					sc.ForwardSetState(SCE_PL_DEFAULT);
+			} else if (sc.ch == Quote.Up) {
+				Quote.Count++;
+			}
+			break;
+		case SCE_PL_SUB_PROTOTYPE: {
 				int i = 0;
 				// forward scan; must all be valid proto characters
 				while (setSubPrototype.Contains(sc.GetRelative(i)))
@@ -749,8 +906,9 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 					sc.ChangeState(SCE_PL_OPERATOR);
 					sc.SetState(SCE_PL_DEFAULT);
 				}
-				} break;
-			case SCE_PL_FORMAT: {
+			}
+			break;
+		case SCE_PL_FORMAT: {
 				sc.Complete();
 				while (!sc.atLineEnd)
 					sc.Forward();
@@ -758,42 +916,43 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 				sc.GetCurrent(s, sizeof(s));
 				if (isMatch(".", s))
 					sc.SetState(SCE_PL_DEFAULT);
-				} break;
-			case SCE_PL_ERROR:
-				break;
+			}
+			break;
+		case SCE_PL_ERROR:
+			break;
 		}
 		// Needed for specific continuation styles (one follows the other)
 		switch (sc.state) {
 			// continued from SCE_PL_WORD
-			case SCE_PL_FORMAT_IDENT:
-				// occupies HereDoc state 3 to avoid clashing with HERE docs
-				if (IsASpaceOrTab(sc.ch)) {		// skip whitespace
-					sc.ChangeState(SCE_PL_DEFAULT);
-					while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
+		case SCE_PL_FORMAT_IDENT:
+			// occupies HereDoc state 3 to avoid clashing with HERE docs
+			if (IsASpaceOrTab(sc.ch)) {		// skip whitespace
+				sc.ChangeState(SCE_PL_DEFAULT);
+				while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
+					sc.Forward();
+				sc.SetState(SCE_PL_FORMAT_IDENT);
+			}
+			if (setFormatStart.Contains(sc.ch)) {	// identifier or '='
+				if (sc.ch != '=') {
+					do {
 						sc.Forward();
-					sc.SetState(SCE_PL_FORMAT_IDENT);
+					} while (setFormat.Contains(sc.ch));
 				}
-				if (setFormatStart.Contains(sc.ch)) {	// identifier or '='
-					if (sc.ch != '=') {
-						do {
-							sc.Forward();
-						} while (setFormat.Contains(sc.ch));
-					}
-					while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
-						sc.Forward();
-					if (sc.ch == '=') {
-						sc.ForwardSetState(SCE_PL_DEFAULT);
-						HereDoc.State = 3;
-					} else {
-						// invalid indentifier; inexact fallback, but hey
-						sc.ChangeState(SCE_PL_IDENTIFIER);
-						sc.SetState(SCE_PL_DEFAULT);
-					}
+				while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
+					sc.Forward();
+				if (sc.ch == '=') {
+					sc.ForwardSetState(SCE_PL_DEFAULT);
+					HereDoc.State = 3;
 				} else {
-					sc.ChangeState(SCE_PL_DEFAULT);	// invalid indentifier
+					// invalid indentifier; inexact fallback, but hey
+					sc.ChangeState(SCE_PL_IDENTIFIER);
+					sc.SetState(SCE_PL_DEFAULT);
 				}
-				backFlag = BACK_NONE;
-				break;
+			} else {
+				sc.ChangeState(SCE_PL_DEFAULT);	// invalid indentifier
+			}
+			backFlag = BACK_NONE;
+			break;
 		}
 
 		// Must check end of HereDoc states here before default state is handled
@@ -810,9 +969,15 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 					sc.ChangeState(SCE_PL_ERROR);
 				}
 				switch (HereDoc.Quote) {
-					case '\'': st_new = SCE_PL_HERE_Q ; break;
-					case '"' : st_new = SCE_PL_HERE_QQ; break;
-					case '`' : st_new = SCE_PL_HERE_QX; break;
+				case '\'':
+					st_new = SCE_PL_HERE_Q ;
+					break;
+				case '"' :
+					st_new = SCE_PL_HERE_QQ;
+					break;
+				case '`' :
+					st_new = SCE_PL_HERE_QX;
+					break;
 				}
 			} else {
 				if (HereDoc.Quote == '\\')
@@ -829,7 +994,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 		// Determine if a new state should be entered.
 		if (sc.state == SCE_PL_DEFAULT) {
 			if (IsADigit(sc.ch) ||
-				(IsADigit(sc.chNext) && (sc.ch == '.' || sc.ch == 'v'))) {
+			        (IsADigit(sc.chNext) && (sc.ch == '.' || sc.ch == 'v'))) {
 				sc.SetState(SCE_PL_NUMBER);
 				backFlag = BACK_NONE;
 				numState = PERLNUM_DECIMAL;
@@ -875,8 +1040,8 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 					sc.Forward();
 					fw++;
 				} else if (sc.ch == 'q' && setQDelim.Contains(sc.chNext)
-						   && !setWord.Contains(sc.GetRelative(2))) {
-					if      (sc.chNext == 'q') sc.ChangeState(SCE_PL_STRING_QQ);
+				        && !setWord.Contains(sc.GetRelative(2))) {
+					if (sc.chNext == 'q') sc.ChangeState(SCE_PL_STRING_QQ);
 					else if (sc.chNext == 'x') sc.ChangeState(SCE_PL_STRING_QX);
 					else if (sc.chNext == 'r') sc.ChangeState(SCE_PL_STRING_QR);
 					else sc.ChangeState(SCE_PL_STRING_QW);	// sc.chNext == 'w'
@@ -884,8 +1049,8 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 					sc.Forward();
 					fw++;
 				} else if (sc.ch == 'x' && (sc.chNext == '=' ||	// repetition
-						   !setWord.Contains(sc.chNext) ||
-						   (IsADigit(sc.chPrev) && IsADigit(sc.chNext)))) {
+				        !setWord.Contains(sc.chNext) ||
+				        (IsADigit(sc.chPrev) && IsADigit(sc.chNext)))) {
 					sc.ChangeState(SCE_PL_OPERATOR);
 				}
 				// if potentially a keyword, scan forward and grab word, then check
@@ -974,7 +1139,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 				} else {
 					int bkstyle = styler.StyleAt(bk);
 					int bkch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));
-					switch(bkstyle) {
+					switch (bkstyle) {
 					case SCE_PL_OPERATOR:
 						preferRE = true;
 						if (bkch == ')' || bkch == ']') {
@@ -984,17 +1149,17 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 							// needed to test for variables like ${}, @{} etc.
 							bkstyle = styleBeforeBracePair(styler, bk);
 							if (bkstyle == SCE_PL_SCALAR
-								|| bkstyle == SCE_PL_ARRAY
-								|| bkstyle == SCE_PL_HASH
-								|| bkstyle == SCE_PL_SYMBOLTABLE
-								|| bkstyle == SCE_PL_OPERATOR) {
+							        || bkstyle == SCE_PL_ARRAY
+							        || bkstyle == SCE_PL_HASH
+							        || bkstyle == SCE_PL_SYMBOLTABLE
+							        || bkstyle == SCE_PL_OPERATOR) {
 								preferRE = false;
 							}
 						} else if (bkch == '+' || bkch == '-') {
 							if (bkch == static_cast<unsigned char>(styler.SafeGetCharAt(bk - 1))
-								&& bkch != static_cast<unsigned char>(styler.SafeGetCharAt(bk - 2)))
-							// exceptions for operators: unary suffixes ++, --
-							preferRE = false;
+							        && bkch != static_cast<unsigned char>(styler.SafeGetCharAt(bk - 2)))
+								// exceptions for operators: unary suffixes ++, --
+								preferRE = false;
 						}
 						break;
 					case SCE_PL_IDENTIFIER:
@@ -1047,7 +1212,8 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 								preferRE = false;
 						}
 						break;
-					// other styles uses the default, preferRE=false
+
+						// other styles uses the default, preferRE=false
 					case SCE_PL_POD:
 					case SCE_PL_HERE_Q:
 					case SCE_PL_HERE_QQ:
@@ -1121,15 +1287,15 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 					}
 				}
 			} else if (sc.ch == '='		// POD
-					   && setPOD.Contains(sc.chNext)
-					   && sc.atLineStart) {
+			        && setPOD.Contains(sc.chNext)
+			        && sc.atLineStart) {
 				sc.SetState(SCE_PL_POD);
 				backFlag = BACK_NONE;
 			} else if (sc.ch == '-' && setWordStart.Contains(sc.chNext)) {	// extended '-' cases
 				unsigned int bk = sc.currentPos;
 				unsigned int fw = 2;
 				if (setSingleCharOp.Contains(sc.chNext) &&	// file test operators
-					!setWord.Contains(sc.GetRelative(2))) {
+				        !setWord.Contains(sc.GetRelative(2))) {
 					sc.SetState(SCE_PL_WORD);
 				} else {
 					// nominally a minus and bareword; find extent of bareword
@@ -1165,39 +1331,37 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
 		}
 	}
 	sc.Complete();
-}
-
-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];
-		int style = styler.StyleAt(i);
-		if (ch == '#' && style == SCE_PL_COMMENTLINE)
-			return true;
-		else if (!IsASpaceOrTab(ch))
-			return false;
+	if (sc.state == SCE_PL_HERE_Q
+	        || sc.state == SCE_PL_HERE_QQ
+	        || sc.state == SCE_PL_HERE_QX
+	        || sc.state == SCE_PL_FORMAT) {
+		styler.ChangeLexerState(sc.currentPos, styler.Length());
 	}
-	return false;
+	sc.Complete();
 }
 
-static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
-                        Accessor &styler) {
-	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
-	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
-	// Custom folding of POD and packages
+#define PERL_HEADFOLD_SHIFT		4
+#define PERL_HEADFOLD_MASK		0xF0
 
-	// property fold.perl.pod 
-	//	Enable folding Pod blocks when using the Perl lexer. 
-	bool foldPOD = styler.GetPropertyInt("fold.perl.pod", 1) != 0;
+void SCI_METHOD LexerPerl::Fold(unsigned int startPos, int length, int /* initStyle */, IDocument *pAccess) {
 
-	// property fold.perl.package 
-	//	Enable folding packages when using the Perl lexer. 
-	bool foldPackage = styler.GetPropertyInt("fold.perl.package", 1) != 0;
+	if (!options.fold)
+		return;
+
+	LexAccessor styler(pAccess);
 
 	unsigned int endPos = startPos + length;
 	int visibleChars = 0;
 	int lineCurrent = styler.GetLine(startPos);
+
+	// Backtrack to previous line in case need to fix its fold status
+	if (startPos > 0) {
+		if (lineCurrent > 0) {
+			lineCurrent--;
+			startPos = styler.LineStart(lineCurrent);
+		}
+	}
+
 	int levelPrev = SC_FOLDLEVELBASE;
 	if (lineCurrent > 0)
 		levelPrev = styler.LevelAt(lineCurrent - 1) >> 16;
@@ -1207,67 +1371,118 @@ static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
 	int styleNext = styler.StyleAt(startPos);
 	// Used at end of line to determine if the line was a package definition
 	bool isPackageLine = false;
-	bool isPodHeading = false;
+	int podHeading = 0;
 	for (unsigned int i = startPos; i < endPos; i++) {
 		char ch = chNext;
 		chNext = styler.SafeGetCharAt(i + 1);
 		int style = styleNext;
 		styleNext = styler.StyleAt(i + 1);
+		int stylePrevCh = (i) ? styler.StyleAt(i - 1):SCE_PL_DEFAULT;
 		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 		bool atLineStart = ((chPrev == '\r') || (chPrev == '\n')) || i == 0;
 		// Comment folding
-		if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
-		{
+		if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) {
 			if (!IsCommentLine(lineCurrent - 1, styler)
-				&& IsCommentLine(lineCurrent + 1, styler))
+			        && IsCommentLine(lineCurrent + 1, styler))
 				levelCurrent++;
 			else if (IsCommentLine(lineCurrent - 1, styler)
-					 && !IsCommentLine(lineCurrent+1, styler))
+			        && !IsCommentLine(lineCurrent + 1, styler))
 				levelCurrent--;
 		}
+		// {} [] block folding
 		if (style == SCE_PL_OPERATOR) {
 			if (ch == '{') {
+				if (options.foldAtElse && levelCurrent < levelPrev)
+					--levelPrev;
 				levelCurrent++;
 			} else if (ch == '}') {
 				levelCurrent--;
 			}
+			if (ch == '[') {
+				if (options.foldAtElse && levelCurrent < levelPrev)
+					--levelPrev;
+				levelCurrent++;
+			} else if (ch == ']') {
+				levelCurrent--;
+			}
 		}
-		// Custom POD folding
-		if (foldPOD && atLineStart) {
-			int stylePrevCh = (i) ? styler.StyleAt(i - 1):SCE_PL_DEFAULT;
+		// POD folding
+		if (options.foldPOD && atLineStart) {
 			if (style == SCE_PL_POD) {
 				if (stylePrevCh != SCE_PL_POD && stylePrevCh != SCE_PL_POD_VERB)
 					levelCurrent++;
 				else if (styler.Match(i, "=cut"))
-					levelCurrent--;
+					levelCurrent = (levelCurrent & ~PERL_HEADFOLD_MASK) - 1;
 				else if (styler.Match(i, "=head"))
-					isPodHeading = true;
+					podHeading = PodHeadingLevel(i, styler);
 			} else if (style == SCE_PL_DATASECTION) {
-				if (ch == '=' && isalpha(chNext) && levelCurrent == SC_FOLDLEVELBASE)
+				if (ch == '=' && isascii(chNext) && isalpha(chNext) && levelCurrent == SC_FOLDLEVELBASE)
 					levelCurrent++;
 				else if (styler.Match(i, "=cut") && levelCurrent > SC_FOLDLEVELBASE)
-					levelCurrent--;
+					levelCurrent = (levelCurrent & ~PERL_HEADFOLD_MASK) - 1;
 				else if (styler.Match(i, "=head"))
-					isPodHeading = true;
+					podHeading = PodHeadingLevel(i, styler);
 				// if package used or unclosed brace, level > SC_FOLDLEVELBASE!
 				// reset needed as level test is vs. SC_FOLDLEVELBASE
-				else if (styler.Match(i, "__END__"))
+				else if (stylePrevCh != SCE_PL_DATASECTION)
 					levelCurrent = SC_FOLDLEVELBASE;
 			}
 		}
-		// Custom package folding
-		if (foldPackage && atLineStart) {
-			if (style == SCE_PL_WORD && styler.Match(i, "package")) {
+		// package folding
+		if (options.foldPackage && atLineStart) {
+			if (IsPackageLine(lineCurrent, styler)
+			        && !IsPackageLine(lineCurrent + 1, styler))
 				isPackageLine = true;
+		}
+
+		//heredoc folding
+		switch (style) {
+		case SCE_PL_HERE_QQ :
+		case SCE_PL_HERE_Q :
+		case SCE_PL_HERE_QX :
+			switch (stylePrevCh) {
+			case SCE_PL_HERE_QQ :
+			case SCE_PL_HERE_Q :
+			case SCE_PL_HERE_QX :
+				//do nothing;
+				break;
+			default :
+				levelCurrent++;
+				break;
+			}
+			break;
+		default:
+			switch (stylePrevCh) {
+			case SCE_PL_HERE_QQ :
+			case SCE_PL_HERE_Q :
+			case SCE_PL_HERE_QX :
+				levelCurrent--;
+				break;
+			default :
+				//do nothing;
+				break;
+			}
+			break;
+		}
+
+		//explicit folding
+		if (options.foldCommentExplicit && style == SCE_PL_COMMENTLINE && ch == '#') {
+			if (chNext == '{') {
+				levelCurrent++;
+			} else if (levelCurrent > SC_FOLDLEVELBASE  && chNext == '}') {
+				levelCurrent--;
 			}
 		}
 
 		if (atEOL) {
 			int lev = levelPrev;
-			if (isPodHeading) {
-				lev = levelPrev - 1;
+			// POD headings occupy bits 7-4, leaving some breathing room for
+			// non-standard practice -- POD sections stuck in blocks, etc.
+			if (podHeading > 0) {
+				levelCurrent = (lev & ~PERL_HEADFOLD_MASK) | (podHeading << PERL_HEADFOLD_SHIFT);
+				lev = levelCurrent - 1;
 				lev |= SC_FOLDLEVELHEADERFLAG;
-				isPodHeading = false;
+				podHeading = 0;
 			}
 			// Check if line was a package declaration
 			// because packages need "special" treatment
@@ -1277,7 +1492,7 @@ static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
 				isPackageLine = false;
 			}
 			lev |= levelCurrent << 16;
-			if (visibleChars == 0 && foldCompact)
+			if (visibleChars == 0 && options.foldCompact)
 				lev |= SC_FOLDLEVELWHITEFLAG;
 			if ((levelCurrent > levelPrev) && (visibleChars > 0))
 				lev |= SC_FOLDLEVELHEADERFLAG;
@@ -1297,9 +1512,4 @@ static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
 	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 }
 
-static const char * const perlWordListDesc[] = {
-	"Keywords",
-	0
-};
-
-LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", FoldPerlDoc, perlWordListDesc, 8);
+LexerModule lmPerl(SCLEX_PERL, LexerPerl::LexerFactoryPerl, "perl", perlWordListDesc, 8);
diff --git a/plugins/scintilla/scintilla/LexPowerPro.cxx b/plugins/scintilla/scintilla/LexPowerPro.cxx
index 9320baf..89bce58 100644
--- a/plugins/scintilla/scintilla/LexPowerPro.cxx
+++ b/plugins/scintilla/scintilla/LexPowerPro.cxx
@@ -3,42 +3,45 @@
 // 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: 
+// 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 
+//	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
+//	2008-12-14 - Added bounds checking for szFirstWord 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()
+//			   - Made sure that the return value of Accessor::SafeGetCharAt is positive before
+//				 passing 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 
+//			   - 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
-//
+//	2010-06-03 - Added onlySpaces variable to allow the @function and ;comment styles to be indented
+//			   - Modified HasFunction function to be a bit more robust
+//			   - Renamed HasFunction function to IsFunction
+//			   - Cleanup
 // 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 <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
 #include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -48,65 +51,81 @@ static inline bool IsStreamCommentStyle(int style) {
 	return style == SCE_POWERPRO_COMMENTBLOCK;
 }
 
+static inline bool IsLineEndChar(unsigned char ch) {
+	return 	ch == 0x0a 		//LF
+			|| ch == 0x0c	//FF
+			|| ch == 0x0d;	//CR
+}
+
 static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
 {
-	int nsPos = styler.LineStart(szLine);
-	int nePos = styler.LineStart(szLine + 1) - 2;
-	while (nsPos < nePos)
+	int startPos = styler.LineStart(szLine);
+	int endPos = styler.LineStart(szLine + 1) - 2;
+	while (startPos < endPos)
 	{
-		int stylech = styler.StyleAt(nsPos);
+		char stylech = styler.StyleAt(startPos);
 		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;
+			char ch = styler.SafeGetCharAt(endPos);
+			char chPrev = styler.SafeGetCharAt(endPos - 1);
+			char chPrevPrev = styler.SafeGetCharAt(endPos - 2);
+			if (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) )
+				return (chPrevPrev == ';' && chPrev == ';' && ch == '+');
 			}
-		}
-		nePos--; // skip to next char
+		endPos--; // 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)
+// needed for comment lines not starting on pos 1
+static int GetStyleFirstWord(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);
+	int startPos = styler.LineStart(szLine);
+	int endPos = styler.LineStart(szLine + 1) - 1;
+	char ch = styler.SafeGetCharAt(startPos);
 
+	while (ch > 0 && isspacechar(ch) && startPos < endPos)
+	{
+		startPos++; // skip to next char
+		ch = styler.SafeGetCharAt(startPos);
 	}
-	return styler.StyleAt(nsPos);
+	return styler.StyleAt(startPos);
 }
 
 //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
-	);
+//note:
+//		sample line (without quotes): "\tfunction asdf()
+//		currentPos will be the position of 'a'
+static bool IsFunction(Accessor &styler, unsigned int currentPos) {
+
+	const char function[10] = "function "; //10 includes \0
+	unsigned int numberOfCharacters = sizeof(function) - 1;
+	unsigned int position = currentPos - numberOfCharacters;
+
+	//compare each character with the letters in the function array
+	//return false if ALL don't match
+	for (unsigned int i = 0; i < numberOfCharacters; i++) {
+		char c = styler.SafeGetCharAt(position++);
+		if (c != function[i])
+			return false;
+	}
+
+	//make sure that there are only spaces (or tabs) between the beginning
+	//of the line and the function declaration
+	position = currentPos - numberOfCharacters - 1; 		//-1 to move to char before 'function'
+	for (unsigned int j = 0; j < 16; j++) {					//check up to 16 preceeding characters
+		char c = styler.SafeGetCharAt(position--, '\0');	//if can't read char, return NUL (past beginning of document)
+		if (c <= 0)	//reached beginning of document
+			return true;
+		if (c > 0 && IsLineEndChar(c))
+			return true;
+		else if (c > 0 && !IsASpaceOrTab(c))
+			return false;
+	}
+
+	//fall-through
+	return false;
 }
 
 static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
@@ -116,22 +135,24 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
 	WordList &keywords2 = *keywordlists[1];
 	WordList &keywords3 = *keywordlists[2];
 	WordList &keywords4 = *keywordlists[3];
-	
-	//define the character sets 
+
+	//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
-	
+
+	//are there only spaces between the first letter of the line and the beginning of the line
+	bool onlySpaces = true;
+
 	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)) 
+
+		if ((sc.ch > 0) && setWord.Contains(sc.ch))
 		{
 			strcpy(s_save,s);
 			int tp = strlen(s_save);
@@ -140,8 +161,6 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
 				s_save[tp+1] = '\0';
 			}
 		}
-		// **********************************************
-		//
 
 		if (sc.atLineStart) {
 			if (sc.state == SCE_POWERPRO_DOUBLEQUOTEDSTRING) {
@@ -156,12 +175,12 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
 			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:
@@ -173,6 +192,7 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
 					} else {
 						sc.GetCurrentLowered(s, sizeof(s));
 					}
+
 					if (keywords.InList(s)) {
 						sc.ChangeState(SCE_POWERPRO_WORD);
 					} else if (keywords2.InList(s)) {
@@ -256,9 +276,9 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
 					}
 				}
 				break;
-				
+
 			case SCE_POWERPRO_FUNCTION:
-				if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ' ' || sc.ch == '(') {
+				if (isspacechar(sc.ch) || sc.ch == '(') {
 					sc.SetState(SCE_POWERPRO_DEFAULT);
 				}
 			break;
@@ -276,20 +296,20 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
 					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]
+			} else if (IsFunction(styler, sc.currentPos)) {	//highlight <name> in 'function <name>'
+				sc.SetState(SCE_POWERPRO_FUNCTION);
+			} else if (onlySpaces && sc.ch == '@') { 		//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(";;+")) { 
+			} 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
+			} else if (onlySpaces && sc.ch == ';') {		//legacy comment that can only have blank space in front of it
 				sc.SetState(SCE_POWERPRO_COMMENTLINE);
 			} else if (sc.Match(";;")) {
 				sc.SetState(SCE_POWERPRO_COMMENTLINE);
@@ -301,10 +321,19 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
 				sc.SetState(SCE_POWERPRO_OPERATOR);
 			}
 		}
+
+		//maintain a record of whether or not all the preceding characters on
+		//a line are space characters
+		if (onlySpaces && !IsASpaceOrTab(sc.ch))
+			onlySpaces = false;
+
+		//reset when starting a new line
+		if (sc.atLineEnd)
+			onlySpaces = true;
 	}
 
 	//*************************************
-	// Colourize the last word correctly 
+	// Colourize the last word correctly
 	//*************************************
 	if (sc.state == SCE_POWERPRO_IDENTIFIER)
 	{
@@ -337,7 +366,9 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
 	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)
+	//used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function)
+	bool isFoldingAll = true;
+
 	int endPos = startPos + length;
 	int lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly
 
@@ -345,7 +376,7 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
 	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) {
@@ -355,153 +386,156 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
 			startPos = styler.LineStart(lineCurrent);
 		}
 	}
-	// vars for style of previous/current/next lines 
+	// 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))) {
+	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;
-	
+	bool isFirstWordStarted = false;
+	bool isFirstWordEnded = false;
+
+	const unsigned int FIRST_WORD_MAX_LEN = 10;
+	char szFirstWord[FIRST_WORD_MAX_LEN] = "";
+	unsigned int firstWordLen = 0;
+
 	char szDo[3]="";
 	int	 szDolen = 0;
-	bool DoFoundLast = false;
-	
+	bool isDoLastWord = false;
+
 	// var for indentlevel
 	int levelCurrent = SC_FOLDLEVELBASE;
-	if (lineCurrent > 0) {
+	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)) {
+
+		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;
+
+		// start the capture of the first word
+		if (!isFirstWordStarted && (ch > 0)) {
+			if (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/') {
+				isFirstWordStarted = true;
+				if (firstWordLen < FIRST_WORD_MAX_LEN - 1) {
+					szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch));
+					szFirstWord[firstWordLen] = '\0';
+				}
 			}
-			else if (szKeywordlen < KEYWORD_MAX - 1) {
-				szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
-				szKeyword[szKeywordlen] = '\0';
+		} // continue capture of the first word on the line
+		else if (isFirstWordStarted && !isFirstWordEnded && (ch > 0)) {
+			if (!setWord.Contains(ch)) {
+				isFirstWordEnded = true;
 			}
-		}
-		
-		// 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';
-				}
+			else if (firstWordLen < (FIRST_WORD_MAX_LEN - 1)) {
+				szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch));
+				szFirstWord[firstWordLen] = '\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) {
+
+			//reset isDoLastWord if we find a character(ignoring spaces) after 'do'
+			if (isDoLastWord && (ch > 0) && setWord.Contains(ch))
+				isDoLastWord = false;
+
+			// --find out if the word "do" is the last on a "if" line--
+			// collect each letter and put it into a buffer 2 chars long
+			// if we end up with "do" in the buffer when we reach the end of
+			// the line, "do" was the last word on the line
+			if ((ch > 0) && isFirstWordEnded && strcmp(szFirstWord, "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) {
+
+					if (strcmp(szDo, "do") == 0)
+						isDoLastWord = 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)) {
-		 
+		// End of Line found so process the information
+		 if ((ch == '\r' && chNext != '\n') // \r\n
+			|| ch == '\n' 					// \n
+			|| i == endPos) {				// end of selection
+
 			// **************************
 			// 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)) ) {
-			
+			if (firstWordLen > 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) {
+				if (strcmp(szFirstWord, "if") == 0  && isDoLastWord)
 						levelNext++;
-				}
-				// create new fold for these words 
-				if (strcmp(szKeyword,"for") == 0) {
+
+				// create new fold for these words
+				if (strcmp(szFirstWord, "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 ((strcmp(szFirstWord, "function") == 0) || (firstWordLen > 0 && szFirstWord[0] == '@')) {
 					if (isFoldingAll) { //if we're folding the whole document (recursivly by lua script)
-						
+
 						if (functionCount > 0) {
 							levelCurrent--;
 						} else {
 							levelNext++;
 						}
-						functionCount++;	
-						
+						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) {
+				if (strcmp(szFirstWord, "endif") == 0 || strcmp(szFirstWord, "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 ) {
+
+				// end the fold for these words before the current line and Start new fold
+				if (strcmp(szFirstWord, "else") == 0 || strcmp(szFirstWord, "elseif") == 0 )
 						levelCurrent--;
-				}
+
 			}
 			// Preprocessor and Comment folding
 			int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
@@ -510,20 +544,19 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
 			// Folding logic for Comment blocks
 			// *********************************
 			if (foldComment && IsStreamCommentStyle(style)) {
+
 				// Start of a comment block
-				if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
+				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 
+				} // 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)
+				} // fold till the one but last line for Blockcomment lines
+				else if (IsStreamCommentStyle(stylePrev)
+						&& styleNext != SCE_POWERPRO_COMMENTBLOCK
 						&& style == SCE_POWERPRO_COMMENTBLOCK) {
 					levelNext--;
 					levelCurrent--;
@@ -534,12 +567,10 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
 			int lev = levelUse | levelNext << 16;
 			if (visibleChars == 0 && foldCompact)
 				lev |= SC_FOLDLEVELWHITEFLAG;
-			if (levelUse < levelNext) {
+			if (levelUse < levelNext)
 				lev |= SC_FOLDLEVELHEADERFLAG;
-			}
-			if (lev != styler.LevelAt(lineCurrent)) {
+			if (lev != styler.LevelAt(lineCurrent))
 				styler.SetLevel(lineCurrent, lev);
-			}
 
 			// reset values for the next line
 			lineCurrent++;
@@ -547,20 +578,18 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
 			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;
+			if (chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev != ';') {
+				firstWordLen = 0;
 				szDolen = 0;
-				FirstWordStart = false;
-				FirstWordEnd = false;
-				DoFoundLast = false;
-				//blank out keyword
-				for (unsigned int i = 0; i < KEYWORD_MAX; i++) {
-					szKeyword[i] = '\0';
-				}
+				isFirstWordStarted = false;
+				isFirstWordEnded = false;
+				isDoLastWord = false;
+
+				//blank out first word
+				for (unsigned int i = 0; i < FIRST_WORD_MAX_LEN; i++)
+					szFirstWord[i] = '\0';
 			}
 		}
 
@@ -569,11 +598,10 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
 			chPrevPrevPrev = chPrevPrev;
 			chPrevPrev = chPrev;
 			chPrev = ch;
-			visibleChars++;
 		}
 	}
 
-	//close folds on the last line - without this a 'phantom' 
+	//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) {
@@ -598,3 +626,5 @@ static void ColourisePowerProDocWrapper(unsigned int startPos, int length, int i
 }
 
 LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, "powerpro", FoldPowerProDoc, powerProWordLists);
+
+
diff --git a/plugins/scintilla/scintilla/LexPowerShell.cxx b/plugins/scintilla/scintilla/LexPowerShell.cxx
index d16ba98..7f741fc 100644
--- a/plugins/scintilla/scintilla/LexPowerShell.cxx
+++ b/plugins/scintilla/scintilla/LexPowerShell.cxx
@@ -7,18 +7,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -26,7 +29,7 @@ using namespace Scintilla;
 
 // Extended to accept accented characters
 static inline bool IsAWordChar(int ch) {
-	return ch >= 0x80 || isalnum(ch) || ch == '-';
+	return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';
 }
 
 static void ColourisePowerShellDoc(unsigned int startPos, int length, int initStyle,
@@ -35,6 +38,8 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
 	WordList &keywords = *keywordlists[0];
 	WordList &keywords2 = *keywordlists[1];
 	WordList &keywords3 = *keywordlists[2];
+	WordList &keywords4 = *keywordlists[3];
+	WordList &keywords5 = *keywordlists[4];
 
 	styler.StartAt(startPos);
 
@@ -46,6 +51,10 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
 			if (sc.atLineEnd) {
 				sc.SetState(SCE_POWERSHELL_DEFAULT);
 			}
+		} else if (sc.state == SCE_POWERSHELL_COMMENTSTREAM) {
+			if (sc.ch == '>' && sc.chPrev == '#') {
+				sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
+			}
 		} else if (sc.state == SCE_POWERSHELL_STRING) {
 			// This is a doubles quotes string
 			if (sc.ch == '\"') {
@@ -79,6 +88,10 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
 					sc.ChangeState(SCE_POWERSHELL_CMDLET);
 				} else if (keywords3.InList(s)) {
 					sc.ChangeState(SCE_POWERSHELL_ALIAS);
+				} else if (keywords4.InList(s)) {
+					sc.ChangeState(SCE_POWERSHELL_FUNCTION);
+				} else if (keywords5.InList(s)) {
+					sc.ChangeState(SCE_POWERSHELL_USER1);
 				}
 				sc.SetState(SCE_POWERSHELL_DEFAULT);
 			}
@@ -88,6 +101,8 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
 		if (sc.state == SCE_POWERSHELL_DEFAULT) {
 			if (sc.ch == '#') {
 				sc.SetState(SCE_POWERSHELL_COMMENT);
+			} else if (sc.ch == '<' && sc.chNext == '#') {
+				sc.SetState(SCE_POWERSHELL_COMMENTSTREAM);
 			} else if (sc.ch == '\"') {
 				sc.SetState(SCE_POWERSHELL_STRING);
 			} else if (sc.ch == '\'') {
@@ -109,8 +124,9 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
 // 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 FoldPowerShellDoc(unsigned int startPos, int length, int,
+static void FoldPowerShellDoc(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 foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
 	unsigned int endPos = startPos + length;
@@ -123,10 +139,12 @@ static void FoldPowerShellDoc(unsigned int startPos, int length, int,
 	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 style = styleNext;
+		int stylePrev = style;
+		style = styleNext;
 		styleNext = styler.StyleAt(i + 1);
 		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 		if (style == SCE_POWERSHELL_OPERATOR) {
@@ -140,6 +158,12 @@ static void FoldPowerShellDoc(unsigned int startPos, int length, int,
 			} else if (ch == '}') {
 				levelNext--;
 			}
+		} else if (foldComment && style == SCE_POWERSHELL_COMMENTSTREAM) {
+			if (stylePrev != SCE_POWERSHELL_COMMENTSTREAM) {
+				levelNext++;
+			} else if (styleNext != SCE_POWERSHELL_COMMENTSTREAM) {
+				levelNext--;
+			}
 		}
 		if (!IsASpace(ch))
 			visibleChars++;
@@ -168,6 +192,8 @@ static const char * const powershellWordLists[] = {
 	"Commands",
 	"Cmdlets",
 	"Aliases",
+	"Functions",
+	"User1",
 	0
 };
 
diff --git a/plugins/scintilla/scintilla/LexProgress.cxx b/plugins/scintilla/scintilla/LexProgress.cxx
index 9e1940e..2031720 100644
--- a/plugins/scintilla/scintilla/LexProgress.cxx
+++ b/plugins/scintilla/scintilla/LexProgress.cxx
@@ -13,18 +13,21 @@ Support more than 6 comments levels
 **/
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -47,7 +50,7 @@ static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, Wo
     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;
@@ -180,7 +183,7 @@ static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, Wo
 			} else if (isoperator(static_cast<char>(sc.ch))) {
 		/* 	This code allows highlight of handles. Alas, it would cause the phrase "last-event:function"
 			to be recognized as a BlockBegin */
-			
+
 				if (sc.ch == ':')
 					sc.SetState(SCE_4GL_OPERATOR & SetSentenceStart);
 				/* else */
diff --git a/plugins/scintilla/scintilla/LexPython.cxx b/plugins/scintilla/scintilla/LexPython.cxx
index 897a136..70db1ec 100644
--- a/plugins/scintilla/scintilla/LexPython.cxx
+++ b/plugins/scintilla/scintilla/LexPython.cxx
@@ -7,25 +7,28 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
 /* kwCDef, kwCTypeName only used for Cython */
-enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName };
+enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef };
 
 static const int indicatorWhitespace = 1;
 
@@ -36,7 +39,7 @@ static bool IsPyComment(Accessor &styler, int pos, int len) {
 enum literalsAllowed { litNone=0, litU=1, litB=2};
 
 static bool IsPyStringTypeChar(int ch, literalsAllowed allowed) {
-	return 
+	return
 		((allowed & litB) && (ch == 'b' || ch == 'B')) ||
 		((allowed & litU) && (ch == 'u' || ch == 'U'));
 }
@@ -136,13 +139,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
 	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 
+	//	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. 
+	//	1 is a good level to use.
 	const int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
 
 	// property lexer.python.literals.binary
@@ -243,7 +246,7 @@ 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) {
+				} else if (kwLast == kwCDef || kwLast == kwCPDef) {
 					int pos = sc.currentPos;
 					unsigned char ch = styler.SafeGetCharAt(pos, '\0');
 					while (ch != '\0') {
@@ -274,11 +277,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
 						kwLast = kwImport;
 					else if (0 == strcmp(s, "cdef"))
 						kwLast = kwCDef;
+					else if (0 == strcmp(s, "cpdef"))
+						kwLast = kwCPDef;
 					else if (0 == strcmp(s, "cimport"))
 						kwLast = kwImport;
-					else if (kwLast != kwCDef)
+					else if (kwLast != kwCDef && kwLast != kwCPDef)
 						kwLast = kwOther;
-				} else if (kwLast != kwCDef) {
+				} else if (kwLast != kwCDef && kwLast != kwCPDef) {
 					kwLast = kwOther;
 				}
 			}
@@ -334,8 +339,8 @@ 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) {
+		// One cdef or cpdef line, clear kwLast only at end of line
+		if ((kwLast == kwCDef || kwLast == kwCPDef) && sc.atLineEnd) {
 			kwLast = kwOther;
 		}
 
@@ -353,7 +358,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
 				if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) {
 					base_n_number = true;
 					sc.SetState(SCE_P_NUMBER);
-				} else if (sc.ch == '0' && 
+				} else if (sc.ch == '0' &&
 					(sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) {
 					if (base2or8Literals) {
 						base_n_number = true;
@@ -507,7 +512,7 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
 		}
 
 		const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
-		const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);
+		const int levelBeforeComments = 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
@@ -538,7 +543,7 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
 		}
 
 		// Set fold header on non-quote/non-comment line
-		if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
+		if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
 			if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
 				lev |= SC_FOLDLEVELHEADERFLAG;
 		}
@@ -558,7 +563,7 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
 	//styler.SetLevel(lineCurrent, indentCurrent);
 }
 
-static const char * const pythonWordListDesc[] = {
+static const char *const pythonWordListDesc[] = {
 	"Keywords",
 	"Highlighted identifiers",
 	0
diff --git a/plugins/scintilla/scintilla/LexR.cxx b/plugins/scintilla/scintilla/LexR.cxx
index 67e779f..d18fffb 100644
--- a/plugins/scintilla/scintilla/LexR.cxx
+++ b/plugins/scintilla/scintilla/LexR.cxx
@@ -8,18 +8,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -77,9 +80,9 @@ static void ColouriseRDoc(unsigned int startPos, int length, int initStyle, Word
 				sc.SetState(SCE_R_DEFAULT);
 			}
 		} else if (sc.state == SCE_R_IDENTIFIER) {
-			if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
+			if (!IsAWordChar(sc.ch)) {
 				char s[100];
-				sc.GetCurrentLowered(s, sizeof(s));
+				sc.GetCurrent(s, sizeof(s));
 				if (keywords.InList(s)) {
 					sc.ChangeState(SCE_R_KWORD);
 				} else if  (keywords2.InList(s)) {
diff --git a/plugins/scintilla/scintilla/LexRebol.cxx b/plugins/scintilla/scintilla/LexRebol.cxx
index 7139b8d..7d000df 100644
--- a/plugins/scintilla/scintilla/LexRebol.cxx
+++ b/plugins/scintilla/scintilla/LexRebol.cxx
@@ -13,18 +13,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
 #include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexRuby.cxx b/plugins/scintilla/scintilla/LexRuby.cxx
old mode 100755
new mode 100644
index 8d6dc90..4545bfa
--- a/plugins/scintilla/scintilla/LexRuby.cxx
+++ b/plugins/scintilla/scintilla/LexRuby.cxx
@@ -7,18 +7,22 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
@@ -78,7 +82,7 @@ static bool followsDot(unsigned int pos, Accessor &styler) {
                     return false;
                 }
                 break;
-                
+
             case SCE_RB_OPERATOR:
                 return styler[pos] == '.';
 
@@ -118,7 +122,7 @@ static int ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywor
     else if (keywords.InList(s) && !followsDot(start - 1, styler)) {
         if (keywordIsAmbiguous(s)
             && keywordIsModifier(s, start, styler)) {
-            
+
             // Demoted keywords are colored as keywords,
             // but do not affect changes in indentation.
             //
@@ -127,7 +131,7 @@ static int ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywor
             // 2. <<stmt if test>> : demoted
             // 3. <<lhs = if ...>> : normal: start a new indent level
             // 4. <<obj.if = 10>> : color as identifer, since it follows '.'
-            
+
             chAttr = SCE_RB_WORD_DEMOTED;
         } else {
             chAttr = SCE_RB_WORD;
@@ -224,7 +228,7 @@ static bool currLineContainsHereDelims(int& startPos,
             // Leave the pointers where they are -- there are no
             // here doc delims on the current line, even if
             // the EOL isn't default style
-            
+
             return false;
         } else {
             styler.Flush();
@@ -276,7 +280,7 @@ class QuoteCls {
         }
 		return *this;
     }
-            
+
 };
 
 
@@ -352,7 +356,7 @@ static int skipWhitespace(int startPos,
     }
     return endPos;
 }
-    
+
 // This routine looks for false positives like
 // undef foo, <<
 // There aren't too many.
@@ -362,7 +366,7 @@ static int skipWhitespace(int startPos,
 static bool sureThisIsHeredoc(int iPrev,
                               Accessor &styler,
                               char *prevWord) {
-                    
+
     // Not so fast, since Ruby's so dynamic.  Check the context
     // to make sure we're OK.
     int prevStyle;
@@ -453,7 +457,7 @@ static bool sureThisIsNotHeredoc(int lt2StartPos,
     styler.Flush();
     const bool definitely_not_a_here_doc = true;
     const bool looks_like_a_here_doc = false;
-    
+
     // Find the first word after some whitespace
     int firstWordPosn = skipWhitespace(lineStartPosn, lt2StartPos, styler);
     if (firstWordPosn >= lt2StartPos) {
@@ -531,7 +535,7 @@ static bool sureThisIsNotHeredoc(int lt2StartPos,
         target_quote = styler[j];
         j += 1;
     }
-    
+
     if (isSafeAlnum(styler[j])) {
         // Init target_end because some compilers think it won't
         // be initialized by the time it's used
@@ -549,7 +553,7 @@ static bool sureThisIsNotHeredoc(int lt2StartPos,
 
             // And for now make sure that it's a newline
             // don't handle arbitrary expressions yet
-            
+
             target_end = j;
 			if (target_quote) {
 				// Now we can move to the character after the string delimiter.
@@ -592,7 +596,7 @@ static bool sureThisIsNotHeredoc(int lt2StartPos,
 }
 
 //todo: if we aren't looking at a stdio character,
-// move to the start of the first line that is not in a 
+// move to the start of the first line that is not in a
 // multi-line construct
 
 static void synchronizeDocStart(unsigned int& startPos,
@@ -610,7 +614,7 @@ static void synchronizeDocStart(unsigned int& startPos,
             // Don't do anything else with these.
             return;
     }
-    
+
     int pos = startPos;
     // Quick way to characterize each line
     int lineStart;
@@ -651,7 +655,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
 	// Lexer for Ruby often has to backtrack to start of current style to determine
 	// which characters are being used as quotes, how deeply nested is the
 	// start position and what the termination string is for here documents
-    
+
 	WordList &keywords = *keywordlists[0];
 
 	class HereDocCls {
@@ -674,7 +678,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
             CanBeIndented = false;
 		}
 	};
-	HereDocCls HereDoc;	
+	HereDocCls HereDoc;
 
 	QuoteCls Quote;
 
@@ -750,7 +754,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
 			i += 1;
 			continue;
 		}
-		
+
         // skip on DOS/Windows
         //No, don't, because some things will get tagged on,
         // so we won't recognize keywords, for example
@@ -759,7 +763,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
 	    	continue;
         }
 #endif
-            
+
         if (HereDoc.State == 1 && isEOLChar(ch)) {
 			// Begin of here-doc (the line after the here-doc delimiter):
 			HereDoc.State = 2;
@@ -973,6 +977,15 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
                 } else if (preferRE && !isSafeWordcharOrHigh(chNext)) {
                     // Ruby doesn't allow high bit chars here,
                     // but the editor host might
+                    Quote.New();
+                    state = SCE_RB_STRING_QQ;
+                    Quote.Open(chNext);
+                    advance_char(i, ch, chNext, chNext2); // pass by ref
+                    have_string = true;
+                } else if (!isSafeWordcharOrHigh(chNext) && !iswhitespace(chNext) && !isEOLChar(chNext)) {
+                    // Ruby doesn't allow high bit chars here,
+                    // but the editor host might
+                    Quote.New();
                     state = SCE_RB_STRING_QQ;
                     Quote.Open(chNext);
                     advance_char(i, ch, chNext, chNext2); // pass by ref
@@ -1003,7 +1016,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
                 // So if we don't have one of these chars,
                 // we aren't ending an object exp'n, and ops
                 // like : << / are unary operators.
-                
+
                 if (ch == '{') {
                     ++brace_counts;
                     preferRE = true;
@@ -1035,7 +1048,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
 
                 // Default accessor treats '.' as word-chars,
                 // but we don't for now.
-                
+
                 if (ch == '='
                     && isSafeWordcharOrHigh(chPrev)
                     && (chNext == '('
@@ -1066,11 +1079,11 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
                         case SCE_RB_WORD:
                             preferRE = RE_CanFollowKeyword(prevWord);
 							break;
-                            
+
                         case SCE_RB_WORD_DEMOTED:
                             preferRE = true;
 							break;
-                            
+
                         case SCE_RB_IDENTIFIER:
                             if (isMatch(styler, lengthDoc, wordStartPos, "print")) {
                                 preferRE = true;
@@ -1087,7 +1100,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
                         // We might be redefining an operator-method
                         preferRE = false;
                     }
-                    // And if it's the first 
+                    // And if it's the first
                     redo_char(i, ch, chNext, chNext2, state); // pass by ref
                 }
             }
@@ -1124,6 +1137,10 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
                 }
             } else if (isSafeAlnumOrHigh(ch) || ch == '_') {
                 // Keep going
+            } else if (ch == '.' && chNext == '.') {
+                ++numDots;
+                styler.ColourTo(i - 1, state);
+                redo_char(i, ch, chNext, chNext2, state); // pass by ref
             } else if (ch == '.' && ++numDots == 1) {
                 // Keep going
             } else {
@@ -1141,7 +1158,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
             // See the comment for SCE_RB_HERE_DELIM in LexPerl.cxx
             // Slightly different: if we find an immediate '-',
             // the target can appear indented.
-            
+
 			if (HereDoc.State == 0) { // '<<' encountered
 				HereDoc.State = 1;
                 HereDoc.DelimiterLength = 0;
@@ -1157,7 +1174,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
                     preferRE = false;
                 } else {
                     HereDoc.Quote = ch;
-                
+
                     if (ch == '\'' || ch == '"' || ch == '`') {
                         HereDoc.Quoted = true;
                         HereDoc.Delimiter[0] = '\0';
@@ -1291,7 +1308,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
             } else if (ch == Quote.Up) {
                 // Only if close quoter != open quoter
                 Quote.Count++;
-                
+
             } else if (ch == '#' ) {
                 if (chNext == '{'
                     && inner_string_count < INNER_STRINGS_MAX_COUNT) {
@@ -1336,7 +1353,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
                 }
             }
         // Quotes of all kinds...
-        } else if (state == SCE_RB_STRING_Q || state == SCE_RB_STRING_QQ || 
+        } else if (state == SCE_RB_STRING_Q || state == SCE_RB_STRING_QQ ||
                    state == SCE_RB_STRING_QX || state == SCE_RB_STRING_QW ||
                    state == SCE_RB_STRING || state == SCE_RB_CHARACTER ||
                    state == SCE_RB_BACKTICKS) {
@@ -1373,7 +1390,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
                 advance_char(i, ch, chNext, chNext2);
             }
         }
-            
+
         if (state == SCE_RB_ERROR) {
             break;
         }
@@ -1389,7 +1406,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
 }
 
 // Helper functions for folding, disambiguation keywords
-// Assert that there are no high-bit chars 
+// Assert that there are no high-bit chars
 
 static void getPrevWord(int pos,
                         char *prevWord,
@@ -1430,7 +1447,7 @@ static bool keywordIsAmbiguous(const char *prevWord)
 
 // Demote keywords in the following conditions:
 // if, while, unless, until modify a statement
-// do after a while or until, as a noise word (like then after if) 
+// do after a while or until, as a noise word (like then after if)
 
 static bool keywordIsModifier(const char *word,
                               int pos,
@@ -1439,10 +1456,32 @@ static bool keywordIsModifier(const char *word,
     if (word[0] == 'd' && word[1] == 'o' && !word[2]) {
         return keywordDoStartsLoop(pos, styler);
     }
-    char ch;
+    char ch, chPrev, chPrev2;
     int style = SCE_RB_DEFAULT;
 	int lineStart = styler.GetLine(pos);
     int lineStartPosn = styler.LineStart(lineStart);
+    // We want to step backwards until we don't care about the current
+    // position. But first move lineStartPosn back behind any
+    // continuations immediately above word.
+    while (lineStartPosn > 0) {
+        ch = styler[lineStartPosn-1];
+        if (ch == '\n' || ch == '\r') {
+            chPrev  = styler.SafeGetCharAt(lineStartPosn-2);
+            chPrev2 = styler.SafeGetCharAt(lineStartPosn-3);
+            lineStart = styler.GetLine(lineStartPosn-1);
+            // If we find a continuation line, include it in our analysis.
+            if (chPrev == '\\') {
+                lineStartPosn = styler.LineStart(lineStart);
+            } else if (ch == '\n' && chPrev == '\r' && chPrev2 == '\\') {
+                lineStartPosn = styler.LineStart(lineStart);
+            } else {
+                break;
+            }
+        } else {
+          break;
+        }
+    }
+
     styler.Flush();
     while (--pos >= lineStartPosn) {
         style = actual_style(styler.StyleAt(pos));
@@ -1453,14 +1492,27 @@ static bool keywordIsModifier(const char *word,
 				// Scintilla's LineStart() and GetLine() routines aren't
 				// platform-independent, so if we have text prepared with
 				// a different system we can't rely on it.
-				return false;
+
+                // Also, lineStartPosn may have been moved to more than one
+                // line above word's line while pushing past continuations.
+                chPrev = styler.SafeGetCharAt(pos - 1);
+                chPrev2 = styler.SafeGetCharAt(pos - 2);
+                if (chPrev == '\\') {
+                    pos-=1;  // gloss over the "\\"
+                    //continue
+                } else if (ch == '\n' && chPrev == '\r' && chPrev2 == '\\') {
+                    pos-=2;  // gloss over the "\\\r"
+                    //continue
+                } else {
+				    return false;
+                }
 			}
 		} else {
             break;
 		}
     }
     if (pos < lineStartPosn) {
-        return false; //XXX not quite right if the prev line is a continuation
+        return false;
     }
     // First things where the action is unambiguous
     switch (style) {
@@ -1490,7 +1542,7 @@ static bool keywordIsModifier(const char *word,
     // Assume that if the keyword follows an operator,
     // usually it's a block assignment, like
     // a << if x then y else z
-    
+
     ch = styler[pos];
     switch (ch) {
         case ')':
@@ -1561,25 +1613,25 @@ static bool keywordDoStartsLoop(int pos,
 
 /*
  *  Folding Ruby
- * 
+ *
  *  The language is quite complex to analyze without a full parse.
  *  For example, this line shouldn't affect fold level:
- * 
+ *
  *   print "hello" if feeling_friendly?
- * 
+ *
  *  Neither should this:
- * 
+ *
  *   print "hello" \
  *      if feeling_friendly?
- * 
- * 
+ *
+ *
  *  But this should:
- * 
+ *
  *   if feeling_friendly?  #++
  *     print "hello" \
  *     print "goodbye"
  *   end                   #--
- * 
+ *
  *  So we cheat, by actually looking at the existing indentation
  *  levels for each line, and just echoing it back.  Like Python.
  *  Then if we get better at it, we'll take braces into consideration,
@@ -1587,29 +1639,29 @@ static bool keywordDoStartsLoop(int pos,
 
  *  How the keywords should work:
  *  No effect:
- *  __FILE__ __LINE__ BEGIN END alias and 
+ *  __FILE__ __LINE__ BEGIN END alias and
  *  defined? false in nil not or self super then
  *  true undef
 
  *  Always increment:
  *  begin  class def do for module when {
- * 
+ *
  *  Always decrement:
  *  end }
- * 
+ *
  *  Increment if these start a statement
  *  if unless until while -- do nothing if they're modifiers
 
  *  These end a block if there's no modifier, but don't bother
  *  break next redo retry return yield
- * 
+ *
  *  These temporarily de-indent, but re-indent
  *  case else elsif ensure rescue
- * 
+ *
  *  This means that the folder reflects indentation rather
  *  than setting it.  The language-service updates indentation
  *  when users type return and finishes entering de-denters.
- * 
+ *
  *  Later offer to fold POD, here-docs, strings, and blocks of comments
  */
 
@@ -1617,7 +1669,7 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
                       WordList *[], Accessor &styler) {
 	const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
-    
+
     synchronizeDocStart(startPos, length, initStyle, styler, // ref args
                         false);
 	unsigned int endPos = startPos + length;
@@ -1676,7 +1728,13 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
                           ) {
 				levelCurrent++;
             }
-        }
+		} else if (style == SCE_RB_HERE_DELIM) {
+			if (styler.SafeGetCharAt(i-2) == '<' && styler.SafeGetCharAt(i-1) == '<') {
+				levelCurrent++;
+			} else if (styleNext == SCE_RB_DEFAULT) {
+				levelCurrent--;
+			}
+		}
 		if (atEOL) {
 			int lev = levelPrev;
 			if (visibleChars == 0 && foldCompact)
@@ -1712,4 +1770,4 @@ static const char * const rubyWordListDesc[] = {
 	0
 };
 
-LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc);
+LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc, 6);
diff --git a/plugins/scintilla/scintilla/LexSML.cxx b/plugins/scintilla/scintilla/LexSML.cxx
index a617530..6ab902d 100644
--- a/plugins/scintilla/scintilla/LexSML.cxx
+++ b/plugins/scintilla/scintilla/LexSML.cxx
@@ -6,21 +6,23 @@
 // 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 <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 inline int  issml(int c) {return isalnum(c) || c == '_';}
 inline int issmlf(int c) {return isalpha(c) || c == '_';}
@@ -67,7 +69,7 @@ void ColouriseSMLDoc(
 			else if (sc.Match('#','\"')){
 					state2 = SCE_SML_CHAR,chLit = 0;
 					sc.Forward();
-					
+
 				}
 			else if (isdigit(sc.ch)) {
 				state2 = SCE_SML_NUMBER, chBase = 10;
@@ -203,13 +205,11 @@ void ColouriseSMLDoc(
 }
 
 void FoldSMLDoc(
-	unsigned int startPos, int length,
-	int initStyle,
-	WordList *keywordlists[],
-	Accessor &styler)
+	unsigned int, int,
+	int,
+	WordList *[],
+	Accessor &)
 {
-	//supress "not used" warnings
-	startPos || length || initStyle || keywordlists[0] || styler.Length();
 }
 
 static const char * const SMLWordListDesc[] = {
@@ -220,4 +220,4 @@ static const char * const SMLWordListDesc[] = {
 };
 
 LexerModule lmSML(SCLEX_SML, ColouriseSMLDoc, "SML", FoldSMLDoc, SMLWordListDesc);
- 	  	 
+
diff --git a/plugins/scintilla/scintilla/LexSQL.cxx b/plugins/scintilla/scintilla/LexSQL.cxx
index 7a4335b..64a896e 100644
--- a/plugins/scintilla/scintilla/LexSQL.cxx
+++ b/plugins/scintilla/scintilla/LexSQL.cxx
@@ -2,30 +2,46 @@
 /** @file LexSQL.cxx
  ** Lexer for SQL, including PL/SQL and SQL*Plus.
  **/
-// Copyright 1998-2005 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 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 <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
 
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include <string>
+#include <vector>
+#include <map>
+#include <algorithm>
+
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
 
-static inline bool IsAWordChar(int ch) {
-	return (ch < 0x80) && (isalnum(ch) || ch == '_');
+static inline bool IsAWordChar(int ch, bool sqlAllowDottedWord) {
+	if (!sqlAllowDottedWord)
+		return (ch < 0x80) && (isalnum(ch) || ch == '_');
+	else
+		return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
 }
 
 static inline bool IsAWordStart(int ch) {
@@ -43,31 +59,303 @@ static inline bool IsANumberChar(int ch) {
 	// Not exactly following number definition (several dots are seen as OK, etc.)
 	// but probably enough in most cases.
 	return (ch < 0x80) &&
-	        (isdigit(ch) || toupper(ch) == 'E' ||
-             ch == '.' || ch == '-' || ch == '+');
+	       (isdigit(ch) || toupper(ch) == 'E' ||
+	        ch == '.' || ch == '-' || ch == '+');
 }
 
-static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
-                            Accessor &styler) {
 
-	WordList &keywords1 = *keywordlists[0];
-	WordList &keywords2 = *keywordlists[1];
-	WordList &kw_pldoc = *keywordlists[2];
-	WordList &kw_sqlplus = *keywordlists[3];
-	WordList &kw_user1 = *keywordlists[4];
-	WordList &kw_user2 = *keywordlists[5];
-	WordList &kw_user3 = *keywordlists[6];
-	WordList &kw_user4 = *keywordlists[7];
+class SQLStates {
+public :
+	void Set(int lineNumber, unsigned short int sqlStatesLine) {
+		if (!sqlStatement.size() == 0 || !sqlStatesLine == 0) {
+			sqlStatement.resize(lineNumber + 1, 0);
+			sqlStatement[lineNumber] = sqlStatesLine;
+		}
+	}
 
-	StyleContext sc(startPos, length, initStyle, styler);
+	unsigned short int IgnoreWhen (unsigned short int sqlStatesLine, bool enable) {
+		if (enable)
+			sqlStatesLine |= MASK_IGNORE_WHEN;
+		else
+			sqlStatesLine &= ~MASK_IGNORE_WHEN;
+
+		return sqlStatesLine;
+	}
+
+	unsigned short int IntoCondition (unsigned short int sqlStatesLine, bool enable) {
+		if (enable)
+			sqlStatesLine |= MASK_INTO_CONDITION;
+		else
+			sqlStatesLine &= ~MASK_INTO_CONDITION;
+
+		return sqlStatesLine;
+	}
+
+	unsigned short int IntoExceptionBlock (unsigned short int sqlStatesLine, bool enable) {
+		if (enable)
+			sqlStatesLine |= MASK_INTO_EXCEPTION;
+		else
+			sqlStatesLine &= ~MASK_INTO_EXCEPTION;
+
+		return sqlStatesLine;
+	}
+
+	unsigned short int IntoDeclareBlock (unsigned short int sqlStatesLine, bool enable) {
+		if (enable)
+			sqlStatesLine |= MASK_INTO_DECLARE;
+		else
+			sqlStatesLine &= ~MASK_INTO_DECLARE;
+
+		return sqlStatesLine;
+	}
+
+	unsigned short int BeginCaseBlock (unsigned short int sqlStatesLine) {
+		if ((sqlStatesLine & MASK_NESTED_CASES) < MASK_NESTED_CASES) {
+			sqlStatesLine++;
+		}
+		return sqlStatesLine;
+	}
+
+	unsigned short int EndCaseBlock (unsigned short int sqlStatesLine) {
+		if ((sqlStatesLine & MASK_NESTED_CASES) > 0) {
+			sqlStatesLine--;
+		}
+		return sqlStatesLine;
+	}
+
+	bool IsIgnoreWhen (unsigned short int sqlStatesLine) {
+		return (sqlStatesLine & MASK_IGNORE_WHEN) != 0;
+	}
+
+	bool IsIntoCondition (unsigned short int sqlStatesLine) {
+		return (sqlStatesLine & MASK_INTO_CONDITION) != 0;
+	}
+
+	bool IsIntoCaseBlock (unsigned short int sqlStatesLine) {
+		return (sqlStatesLine & MASK_NESTED_CASES) != 0;
+	}
+
+	bool IsIntoExceptionBlock (unsigned short int sqlStatesLine) {
+		return (sqlStatesLine & MASK_INTO_EXCEPTION) != 0;
+	}
+
+	bool IsIntoDeclareBlock (unsigned short int sqlStatesLine) {
+		return (sqlStatesLine & MASK_INTO_DECLARE) != 0;
+	}
+
+	unsigned short int ForLine(int lineNumber) {
+		if ((lineNumber > 0) && (sqlStatement.size() > static_cast<size_t>(lineNumber))) {
+			return sqlStatement[lineNumber];
+		} else {
+			return 0;
+		}
+	}
+
+	SQLStates() {}
+
+private :
+	std::vector <unsigned short int> sqlStatement;
+	enum {
+		MASK_INTO_DECLARE = 0x1000,
+		MASK_INTO_EXCEPTION = 0x2000,
+		MASK_INTO_CONDITION = 0x4000,
+		MASK_IGNORE_WHEN = 0x8000,
+		MASK_NESTED_CASES = 0x0FFF
+	};
+};
+
+// Options used for LexerSQL
+struct OptionsSQL {
+	bool fold;
+	bool foldAtElse;
+	bool foldComment;
+	bool foldCompact;
+	bool foldOnlyBegin;
+	bool sqlBackticksIdentifier;
+	bool sqlNumbersignComment;
+	bool sqlBackslashEscapes;
+	bool sqlAllowDottedWord;
+	OptionsSQL() {
+		fold = false;
+		foldAtElse = false;
+		foldComment = false;
+		foldCompact = false;
+		foldOnlyBegin = false;
+		sqlBackticksIdentifier = false;
+		sqlNumbersignComment = false;
+		sqlBackslashEscapes = false;
+		sqlAllowDottedWord = false;
+	}
+};
+
+static const char * const sqlWordListDesc[] = {
+	"Keywords",
+	"Database Objects",
+	"PLDoc",
+	"SQL*Plus",
+	"User Keywords 1",
+	"User Keywords 2",
+	"User Keywords 3",
+	"User Keywords 4",
+	0
+};
+
+struct OptionSetSQL : public OptionSet<OptionsSQL> {
+	OptionSetSQL() {
+		DefineProperty("fold", &OptionsSQL::fold);
+
+		DefineProperty("fold.sql.at.else", &OptionsSQL::foldAtElse,
+		               "This option enables SQL folding on a \"ELSE\" and \"ELSIF\" line of an IF statement.");
+
+		DefineProperty("fold.comment", &OptionsSQL::foldComment);
+
+		DefineProperty("fold.compact", &OptionsSQL::foldCompact);
+
+		DefineProperty("fold.sql.only.begin", &OptionsSQL::foldOnlyBegin);
+
+		DefineProperty("lexer.sql.backticks.identifier", &OptionsSQL::sqlBackticksIdentifier);
+
+		DefineProperty("lexer.sql.numbersign.comment", &OptionsSQL::sqlNumbersignComment,
+		               "If \"lexer.sql.numbersign.comment\" property is set to 0 a line beginning with '#' will not be a comment.");
+
+		DefineProperty("sql.backslash.escapes", &OptionsSQL::sqlBackslashEscapes,
+		               "Enables backslash as an escape character in SQL.");
+
+		DefineProperty("lexer.sql.allow.dotted.word", &OptionsSQL::sqlAllowDottedWord,
+		               "Set to 1 to colourise recognized words with dots "
+		               "(recommended for Oracle PL/SQL objects).");
+
+		DefineWordListSets(sqlWordListDesc);
+	}
+};
+
+class LexerSQL : public ILexer {
+public :
+	LexerSQL() {}
+
+	int SCI_METHOD Version () const {
+		return lvOriginal;
+	}
+
+	void SCI_METHOD Release() {
+		delete this;
+	}
+
+	const char * SCI_METHOD PropertyNames() {
+		return osSQL.PropertyNames();
+	}
 
-	// property sql.backslash.escapes 
-	//	Enables backslash as an escape character in SQL. 
-	bool sqlBackslashEscapes = styler.GetPropertyInt("sql.backslash.escapes", 0) != 0;
+	int SCI_METHOD PropertyType(const char *name) {
+		return osSQL.PropertyType(name);
+	}
+
+	const char * SCI_METHOD DescribeProperty(const char *name) {
+		return osSQL.DescribeProperty(name);
+	}
+
+	int SCI_METHOD PropertySet(const char *key, const char *val) {
+		if (osSQL.PropertySet(&options, key, val)) {
+			return 0;
+		}
+		return -1;
+	}
+
+	const char * SCI_METHOD DescribeWordListSets() {
+		return osSQL.DescribeWordListSets();
+	}
+
+	int SCI_METHOD WordListSet(int n, const char *wl);
+	void SCI_METHOD Lex (unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+	void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+
+	void * SCI_METHOD PrivateCall(int, void *) {
+		return 0;
+	}
+
+	static ILexer *LexerFactorySQL() {
+		return new LexerSQL();
+	}
+private:
+	bool IsStreamCommentStyle(int style) {
+		return style == SCE_SQL_COMMENT ||
+		       style == SCE_SQL_COMMENTDOC ||
+		       style == SCE_SQL_COMMENTDOCKEYWORD ||
+		       style == SCE_SQL_COMMENTDOCKEYWORDERROR;
+	}
 
-	bool sqlBackticksIdentifier = styler.GetPropertyInt("lexer.sql.backticks.identifier", 0) != 0;
+	bool IsCommentStyle (int style) {
+		switch (style) {
+		case SCE_SQL_COMMENT :
+		case SCE_SQL_COMMENTDOC :
+		case SCE_SQL_COMMENTLINE :
+		case SCE_SQL_COMMENTLINEDOC :
+		case SCE_SQL_COMMENTDOCKEYWORD :
+		case SCE_SQL_COMMENTDOCKEYWORDERROR :
+			return true;
+		default :
+			return false;
+		}
+	}
+
+	OptionsSQL options;
+	OptionSetSQL osSQL;
+	SQLStates sqlStates;
+
+	WordList keywords1;
+	WordList keywords2;
+	WordList kw_pldoc;
+	WordList kw_sqlplus;
+	WordList kw_user1;
+	WordList kw_user2;
+	WordList kw_user3;
+	WordList kw_user4;
+};
+
+int SCI_METHOD LexerSQL::WordListSet(int n, const char *wl) {
+	WordList *wordListN = 0;
+	switch (n) {
+	case 0:
+		wordListN = &keywords1;
+		break;
+	case 1:
+		wordListN = &keywords2;
+		break;
+	case 2:
+		wordListN = &kw_pldoc;
+		break;
+	case 3:
+		wordListN = &kw_sqlplus;
+		break;
+	case 4:
+		wordListN = &kw_user1;
+		break;
+	case 5:
+		wordListN = &kw_user2;
+		break;
+	case 6:
+		wordListN = &kw_user3;
+		break;
+	case 7:
+		wordListN = &kw_user4;
+	}
+	int firstModification = -1;
+	if (wordListN) {
+		WordList wlNew;
+		wlNew.Set(wl);
+		if (*wordListN != wlNew) {
+			wordListN->Set(wl);
+			firstModification = 0;
+		}
+	}
+	return firstModification;
+}
+
+void SCI_METHOD LexerSQL::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+	LexAccessor styler(pAccess);
+	StyleContext sc(startPos, length, initStyle, styler);
 	int styleBeforeDCKeyword = SCE_SQL_DEFAULT;
-	for (; sc.More(); sc.Forward()) {
+	int offset = 0;
+	for (; sc.More(); sc.Forward(), offset++) {
 		// Determine if the current state should terminate.
 		switch (sc.state) {
 		case SCE_SQL_OPERATOR:
@@ -80,7 +368,7 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
 			}
 			break;
 		case SCE_SQL_IDENTIFIER:
-			if (!IsAWordChar(sc.ch)) {
+			if (!IsAWordChar(sc.ch, options.sqlAllowDottedWord)) {
 				int nextState = SCE_SQL_DEFAULT;
 				char s[1000];
 				sc.GetCurrentLowered(s, sizeof(s));
@@ -157,7 +445,7 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
 			}
 			break;
 		case SCE_SQL_CHARACTER:
-			if (sqlBackslashEscapes && sc.ch == '\\') {
+			if (options.sqlBackslashEscapes && sc.ch == '\\') {
 				sc.Forward();
 			} else if (sc.ch == '\'') {
 				if (sc.chNext == '\"') {
@@ -187,7 +475,7 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
 				sc.SetState(SCE_SQL_NUMBER);
 			} else if (IsAWordStart(sc.ch)) {
 				sc.SetState(SCE_SQL_IDENTIFIER);
-			} else if (sc.ch == 0x60 && sqlBackticksIdentifier) {
+			} else if (sc.ch == 0x60 && options.sqlBackticksIdentifier) {
 				sc.SetState(SCE_SQL_QUOTEDIDENTIFIER);
 			} else if (sc.Match('/', '*')) {
 				if (sc.Match("/**") || sc.Match("/*!")) {	// Support of Doxygen doc. style
@@ -200,9 +488,9 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
 				// MySQL requires a space or control char after --
 				// http://dev.mysql.com/doc/mysql/en/ansi-diff-comments.html
 				// Perhaps we should enforce that with proper property:
-//~ 			} else if (sc.Match("-- ")) {
+				//~ 			} else if (sc.Match("-- ")) {
 				sc.SetState(SCE_SQL_COMMENTLINE);
-			} else if (sc.ch == '#') {
+			} else if (sc.ch == '#' && options.sqlNumbersignComment) {
 				sc.SetState(SCE_SQL_COMMENTLINEDOC);
 			} else if (sc.ch == '\'') {
 				sc.SetState(SCE_SQL_CHARACTER);
@@ -216,25 +504,10 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
 	sc.Complete();
 }
 
-static bool IsStreamCommentStyle(int style) {
-	return style == SCE_SQL_COMMENT ||
-	       style == SCE_SQL_COMMENTDOC ||
-	       style == SCE_SQL_COMMENTDOCKEYWORD ||
-	       style == SCE_SQL_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.
-static void FoldSQLDoc(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;
-
-	// property fold.sql.exists 
-	//	Enables "EXISTS" to end a fold as is started by "IF" in "DROP TABLE IF EXISTS". 
-	bool foldSqlExists = styler.GetPropertyInt("fold.sql.exists", 1) != 0;
-
+void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+	if (!options.fold)
+		return;
+	LexAccessor styler(pAccess);
 	unsigned int endPos = startPos + length;
 	int visibleChars = 0;
 	int lineCurrent = styler.GetLine(startPos);
@@ -247,6 +520,14 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
 	int styleNext = styler.StyleAt(startPos);
 	int style = initStyle;
 	bool endFound = false;
+	bool isUnfoldingIgnored = false;
+	// this statementFound flag avoids to fold when the statement is on only one line by ignoring ELSE or ELSIF
+	// eg. "IF condition1 THEN ... ELSIF condition2 THEN ... ELSE ... END IF;"
+	bool statementFound = false;
+	unsigned short int sqlStatesCurrentLine = 0;
+	if (!options.foldOnlyBegin) {
+		sqlStatesCurrentLine = sqlStates.ForLine(lineCurrent);
+	}
 	for (unsigned int i = startPos; i < endPos; i++) {
 		char ch = chNext;
 		chNext = styler.SafeGetCharAt(i + 1);
@@ -254,7 +535,16 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
 		style = styleNext;
 		styleNext = styler.StyleAt(i + 1);
 		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-		if (foldComment && IsStreamCommentStyle(style)) {
+		if (atEOL || (!IsCommentStyle(style) && ch == ';')) {
+			if (endFound) {
+				//Maybe this is the end of "EXCEPTION" BLOCK (eg. "BEGIN ... EXCEPTION ... END;")
+				sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, false);
+			}
+			// set endFound and isUnfoldingIgnored to false if EOL is reached or ';' is found
+			endFound = false;
+			isUnfoldingIgnored = false;
+		}
+		if (options.foldComment && IsStreamCommentStyle(style)) {
 			if (!IsStreamCommentStyle(stylePrev)) {
 				levelNext++;
 			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
@@ -262,7 +552,7 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
 				levelNext--;
 			}
 		}
-		if (foldComment && (style == SCE_SQL_COMMENTLINE)) {
+		if (options.foldComment && (style == SCE_SQL_COMMENTLINE)) {
 			// MySQL needs -- comments to be followed by space or control char
 			if ((ch == '-') && (chNext == '-')) {
 				char chNext2 = styler.SafeGetCharAt(i + 2);
@@ -276,14 +566,18 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
 		}
 		if (style == SCE_SQL_OPERATOR) {
 			if (ch == '(') {
+				if (levelCurrent > levelNext)
+					levelCurrent--;
 				levelNext++;
 			} else if (ch == ')') {
 				levelNext--;
+			} else if ((!options.foldOnlyBegin) && ch == ';') {
+				sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, false);
 			}
 		}
 		// If new keyword (cannot trigger on elseif or nullif, does less tests)
 		if (style == SCE_SQL_WORD && stylePrev != SCE_SQL_WORD) {
-			const int MAX_KW_LEN = 6;	// Maximum length of folding keywords
+			const int MAX_KW_LEN = 9;	// Maximum length of folding keywords
 			char s[MAX_KW_LEN + 2];
 			unsigned int j = 0;
 			for (; j < MAX_KW_LEN + 1; j++) {
@@ -298,33 +592,133 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
 			} else {
 				s[j] = '\0';
 			}
-			if ((!foldOnlyBegin) && (strcmp(s, "if") == 0 || strcmp(s, "loop") == 0)) {
+
+			if (strcmp(s, "if") == 0) {
 				if (endFound) {
-					// ignore
 					endFound = false;
+					if (options.foldOnlyBegin && !isUnfoldingIgnored) {
+						// this end isn't for begin block, but for if block ("end if;")
+						// so ignore previous "end" by increment levelNext.
+						levelNext++;
+					}
 				} else {
-					levelNext++;
+					if (!options.foldOnlyBegin)
+						sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
+					if (levelCurrent > levelNext) {
+						// doesn't include this line into the folding block
+						// because doesn't hide IF (eg "END; IF")
+						levelCurrent = levelNext;
+					}
+				}
+			} else if (!options.foldOnlyBegin &&
+			           strcmp(s, "then") == 0 &&
+			           sqlStates.IsIntoCondition(sqlStatesCurrentLine)) {
+				sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, false);
+				if (!options.foldOnlyBegin) {
+					if (levelCurrent > levelNext) {
+						levelCurrent = levelNext;
+					}
+					if (!statementFound)
+						levelNext++;
+
+					statementFound = true;
+				} else if (levelCurrent > levelNext) {
+					// doesn't include this line into the folding block
+					// because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE")
+					levelCurrent = levelNext;
+				}
+			} else if (strcmp(s, "loop") == 0 ||
+			           strcmp(s, "case") == 0) {
+				if (endFound) {
+					endFound = false;
+					if (options.foldOnlyBegin && !isUnfoldingIgnored) {
+						// this end isn't for begin block, but for loop block ("end loop;") or case block ("end case;")
+						// so ignore previous "end" by increment levelNext.
+						levelNext++;
+					}
+					if ((!options.foldOnlyBegin) && strcmp(s, "case") == 0) {
+						sqlStatesCurrentLine = sqlStates.EndCaseBlock(sqlStatesCurrentLine);
+						levelNext--; //again for the "end case;" and block when
+					}
+				} else if (!options.foldOnlyBegin) {
+					if (strcmp(s, "case") == 0) {
+						sqlStatesCurrentLine = sqlStates.BeginCaseBlock(sqlStatesCurrentLine);
+
+						//for case block increment 2 times
+						if (!statementFound)
+							levelNext++;
+					}
+
+					if (levelCurrent > levelNext) {
+						levelCurrent = levelNext;
+					}
+					if (!statementFound)
+						levelNext++;
+
+					statementFound = true;
+				} else if (levelCurrent > levelNext) {
+					// doesn't include this line into the folding block
+					// because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE")
+					levelCurrent = levelNext;
 				}
+			} else if ((!options.foldOnlyBegin) && (
+			               // folding for ELSE and ELSIF block only if foldAtElse is set
+			               // and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)
+			               options.foldAtElse && !statementFound) && strcmp(s, "elsif") == 0) {
+				sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
+				levelCurrent--;
+				levelNext--;
+			} else if ((!options.foldOnlyBegin) && (
+			               // folding for ELSE and ELSIF block only if foldAtElse is set
+			               // and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)
+			               options.foldAtElse && !statementFound) && strcmp(s, "else") == 0) {
+				// prevent also ELSE is on the same line (eg. "ELSE ... END IF;")
+				statementFound = true;
+				// we are in same case "} ELSE {" in C language
+				levelCurrent--;
+
 			} else if (strcmp(s, "begin") == 0) {
 				levelNext++;
+				sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, false);
 			} else if ((strcmp(s, "end") == 0) ||
-//						// DROP TABLE IF EXISTS or CREATE TABLE IF NOT EXISTS
-						(foldSqlExists && (strcmp(s, "exists") == 0)) ||
-//						//  SQL Anywhere permits IF ... ELSE ... ENDIF
-//						//      will only be active if "endif" appears in the 
-//						//		keyword list.
-						(strcmp(s, "endif") == 0)) {
+			           // SQL Anywhere permits IF ... ELSE ... ENDIF
+			           // will only be active if "endif" appears in the
+			           // keyword list.
+			           (strcmp(s, "endif") == 0)) {
 				endFound = true;
 				levelNext--;
 				if (levelNext < SC_FOLDLEVELBASE) {
 					levelNext = SC_FOLDLEVELBASE;
+					isUnfoldingIgnored = true;
+				}
+			} else if ((!options.foldOnlyBegin) &&
+			           strcmp(s, "when") == 0 &&
+			           !sqlStates.IsIgnoreWhen(sqlStatesCurrentLine) &&
+			           !sqlStates.IsIntoExceptionBlock(sqlStatesCurrentLine) &&
+			           sqlStates.IsIntoCaseBlock(sqlStatesCurrentLine)) {
+				sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
+
+				// Don't foldind when CASE and WHEN are on the same line (with flag statementFound) (eg. "CASE selector WHEN expression1 THEN sequence_of_statements1;\n")
+				if (!statementFound) {
+					levelCurrent--;
+					levelNext--;
 				}
+			} else if ((!options.foldOnlyBegin) && strcmp(s, "exit") == 0) {
+				sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, true);
+			} else if ((!options.foldOnlyBegin) && !sqlStates.IsIntoDeclareBlock(sqlStatesCurrentLine) && strcmp(s, "exception") == 0) {
+				sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, true);
+			} else if ((!options.foldOnlyBegin) &&
+			           (strcmp(s, "declare") == 0 ||
+			            strcmp(s, "function") == 0 ||
+			            strcmp(s, "procedure") == 0 ||
+			            strcmp(s, "package") == 0)) {
+				sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, true);
 			}
 		}
 		if (atEOL) {
 			int levelUse = levelCurrent;
 			int lev = levelUse | levelNext << 16;
-			if (visibleChars == 0 && foldCompact)
+			if (visibleChars == 0 && options.foldCompact)
 				lev |= SC_FOLDLEVELWHITEFLAG;
 			if (levelUse < levelNext)
 				lev |= SC_FOLDLEVELHEADERFLAG;
@@ -334,7 +728,9 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
 			lineCurrent++;
 			levelCurrent = levelNext;
 			visibleChars = 0;
-			endFound = false;
+			statementFound = false;
+			if (!options.foldOnlyBegin)
+				sqlStates.Set(lineCurrent, sqlStatesCurrentLine);
 		}
 		if (!isspacechar(ch)) {
 			visibleChars++;
@@ -342,16 +738,4 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
 	}
 }
 
-static const char * const sqlWordListDesc[] = {
-	"Keywords",
-	"Database Objects",
-	"PLDoc",
-	"SQL*Plus",
-	"User Keywords 1",
-	"User Keywords 2",
-	"User Keywords 3",
-	"User Keywords 4",
-	0
-};
-
-LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", FoldSQLDoc, sqlWordListDesc);
+LexerModule lmSQL(SCLEX_SQL, LexerSQL::LexerFactorySQL, "sql", sqlWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexScriptol.cxx b/plugins/scintilla/scintilla/LexScriptol.cxx
index 76c38e6..17184fc 100644
--- a/plugins/scintilla/scintilla/LexScriptol.cxx
+++ b/plugins/scintilla/scintilla/LexScriptol.cxx
@@ -5,18 +5,22 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
 #endif
@@ -48,10 +52,9 @@ static void ClassifyWordSol(unsigned int start, unsigned int end, WordList &keyw
 
 static bool IsSolComment(Accessor &styler, int pos, int len)
 {
-   char c;
    if(len > 0)
    {
-     c = styler[pos];
+     char c = styler[pos];
      if(c == '`') return true;
      if(len > 1)
      {
@@ -328,7 +331,7 @@ static void ColouriseSolDoc(unsigned int startPos, int length, int initStyle,
                     state = SCE_SCRIPTOL_DEFAULT;
                  }
              }
-            
+
            }
           chPrev2 = chPrev;
           chPrev = ch;
diff --git a/plugins/scintilla/scintilla/LexSmalltalk.cxx b/plugins/scintilla/scintilla/LexSmalltalk.cxx
index 265de38..7c7c067 100644
--- a/plugins/scintilla/scintilla/LexSmalltalk.cxx
+++ b/plugins/scintilla/scintilla/LexSmalltalk.cxx
@@ -8,16 +8,21 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
 #include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -39,7 +44,7 @@ classificationBlock
     value: #BinSel value: '~ %&*-+=|\/,<>?!';
     value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
 
-((String new: 500) streamContents: [ :stream |            
+((String new: 500) streamContents: [ :stream |
     stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'.
     lexTable keysAndValuesDo: [ :index :value |
         ((index - 1) rem: 16) == 0 ifTrue: [
@@ -50,7 +55,7 @@ classificationBlock
         index ~= 256 ifTrue: [
             stream nextPut: $,]].
     stream crLf; nextPutAll: '};'; crLf.
-    
+
     charClasses keysAndValuesDo: [ :index :name |
         stream
             crLf;
@@ -95,7 +100,7 @@ static inline bool isDigitOfRadix(int ch, int radix)
 }
 
 static inline void skipComment(StyleContext& sc)
-{    
+{
     while (sc.More() && sc.ch != '\"')
         sc.Forward();
 }
@@ -118,7 +123,7 @@ static void handleHash(StyleContext& sc)
         sc.SetState(SCE_ST_SPECIAL);
         return;
     }
-    
+
     sc.SetState(SCE_ST_SYMBOL);
     sc.Forward();
     if (sc.ch == '\'') {
@@ -162,7 +167,7 @@ static void handleNumeric(StyleContext& sc)
     char num[256];
     int nl;
     int radix;
-    
+
     sc.SetState(SCE_ST_NUMBER);
     num[0] = static_cast<char>(sc.ch);
     nl = 1;
@@ -217,7 +222,7 @@ static void handleLetter(StyleContext& sc, WordList* specialSelectorList)
     int il;
     int state;
     bool doubleColonPresent;
-    
+
     sc.SetState(SCE_ST_DEFAULT);
 
     ident[0] = static_cast<char>(sc.ch);
@@ -237,7 +242,7 @@ static void handleLetter(StyleContext& sc, WordList* specialSelectorList)
     else
         doubleColonPresent = false;
     ident[il] = 0;
-    
+
     if (specialSelectorList->InList(ident))
             state = SCE_ST_SPEC_SEL;
     else if (doubleColonPresent)
@@ -256,7 +261,7 @@ static void handleLetter(StyleContext& sc, WordList* specialSelectorList)
         else
             state = SCE_ST_DEFAULT;
     }
-    
+
     sc.ChangeState(state);
 }
 
@@ -277,7 +282,7 @@ static void colorizeSmalltalkDoc(unsigned int startPos, int length, int initStyl
 
     for (; sc.More(); sc.Forward()) {
         int ch;
-        
+
         ch = sc.ch;
         if (ch == '\"') {
             sc.SetState(SCE_ST_COMMENT);
diff --git a/plugins/scintilla/scintilla/LexSorcus.cxx b/plugins/scintilla/scintilla/LexSorcus.cxx
index 1d8ba27..ba5588b 100644
--- a/plugins/scintilla/scintilla/LexSorcus.cxx
+++ b/plugins/scintilla/scintilla/LexSorcus.cxx
@@ -9,18 +9,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -29,7 +32,7 @@ using namespace Scintilla;
 
 //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)           
+static inline bool IsSWordStart(const int ch, const int prev_ch)
 {
     if (isalpha(ch) || (ch == '_') || ((isdigit(ch)) && (prev_ch == 'M')))
         return true;
@@ -39,7 +42,7 @@ static inline bool IsSWordStart(const int ch, const int prev_ch)
 
 
 //only digits that are not preceded by 'M' count as a number
-static inline bool IsSorcusNumber(const int ch, const int prev_ch)         
+static inline bool IsSorcusNumber(const int ch, const int prev_ch)
 {
     if ((isdigit(ch)) && (prev_ch != 'M'))
         return true;
@@ -49,46 +52,46 @@ static inline bool IsSorcusNumber(const int ch, const int prev_ch)
 
 
 //only = is a valid operator
-static inline bool IsSorcusOperator(const int ch)           
+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)                                        
+                               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)              
+    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);         
-        }       
-        
+            sc.SetState(SCE_SORCUS_STRING);
+        }
+
         // Determine if the current state should terminate.
         if (sc.state == SCE_SORCUS_OPERATOR)
         {
-            if (!IsSorcusOperator(sc.ch)) 
+            if (!IsSorcusOperator(sc.ch))
             {
                 sc.SetState(SCE_SORCUS_DEFAULT);
             }
-        }       
+        }
         else if(sc.state == SCE_SORCUS_NUMBER)
         {
             if(!IsSorcusNumber(sc.ch, sc.chPrev))
@@ -101,25 +104,25 @@ static void ColouriseSorcusDoc(unsigned int startPos, int length, int initStyle,
             if (!IsSWordStart(sc.ch, sc.chPrev))
             {
                 char s[100];
-                
+
                 sc.GetCurrent(s, sizeof(s));
-                
+
                 if (Command.InList(s))
-                { 
-                    sc.ChangeState(SCE_SORCUS_COMMAND); 
+                {
+                    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)
@@ -133,24 +136,24 @@ static void ColouriseSorcusDoc(unsigned int startPos, int length, int initStyle,
             {
                 sc.ForwardSetState(SCE_SORCUS_DEFAULT);
             }
-            else if (sc.atLineEnd) 
+            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);
@@ -164,42 +167,42 @@ static void ColouriseSorcusDoc(unsigned int startPos, int length, int initStyle,
                 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/LexSpecman.cxx b/plugins/scintilla/scintilla/LexSpecman.cxx
index 093efae..1b96482 100644
--- a/plugins/scintilla/scintilla/LexSpecman.cxx
+++ b/plugins/scintilla/scintilla/LexSpecman.cxx
@@ -11,15 +11,18 @@
 #include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexSpice.cxx b/plugins/scintilla/scintilla/LexSpice.cxx
index 6aa2e8f..cb1e658 100644
--- a/plugins/scintilla/scintilla/LexSpice.cxx
+++ b/plugins/scintilla/scintilla/LexSpice.cxx
@@ -6,19 +6,23 @@
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <stdlib.h>
-#include <ctype.h>
 #include <string.h>
 #include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
 
 #include <string>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "PropSet.h"
-#include "KeyWords.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexTACL.cxx b/plugins/scintilla/scintilla/LexTACL.cxx
index b0c1244..fb7d695 100644
--- a/plugins/scintilla/scintilla/LexTACL.cxx
+++ b/plugins/scintilla/scintilla/LexTACL.cxx
@@ -10,18 +10,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
 #include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexTADS3.cxx b/plugins/scintilla/scintilla/LexTADS3.cxx
index ee16a0a..a180544 100644
--- a/plugins/scintilla/scintilla/LexTADS3.cxx
+++ b/plugins/scintilla/scintilla/LexTADS3.cxx
@@ -33,18 +33,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -70,7 +73,7 @@ static inline bool IsEOL(const int ch, const int chNext) {
  *   - it doesn't want to admit that there's a newline until reaching the END
  *   of the sequence.  We meet both needs by saying that there's a newline
  *   when we see the CR in a CR-LF, but skipping the CR before returning so
- *   that the caller's caller will see that we've stopped at the LF.  
+ *   that the caller's caller will see that we've stopped at the LF.
  */
 static inline bool IsEOLSkip(StyleContext &sc)
 {
@@ -82,17 +85,13 @@ static inline bool IsEOLSkip(StyleContext &sc)
         return true;
     }
 
-    /* 
+    /*
      *   in other cases, we have at most a 1-character newline, so do the
-     *   normal IsEOL test 
+     *   normal IsEOL test
      */
     return IsEOL(sc.ch, sc.chNext);
 }
 
-static inline bool IsASpaceOrTab(const int ch) {
-        return ch == ' ' || ch == '\t';
-}
-
 static inline bool IsATADS3Operator(const int ch) {
         return ch == '=' || ch == '{' || ch == '}' || ch == '(' || ch == ')'
                 || ch == '[' || ch == ']' || ch == ',' || ch == ':' || ch == ';'
@@ -156,7 +155,7 @@ static void ColouriseTADSHTMLString(StyleContext &sc, int &lineState) {
                 sc.Forward();
         }
         if (chQuote == '"')
-                lineState &= ~T3_HTML_SQUOTE; 
+                lineState &= ~T3_HTML_SQUOTE;
         else
                 lineState |= T3_HTML_SQUOTE;
 
diff --git a/plugins/scintilla/scintilla/LexTAL.cxx b/plugins/scintilla/scintilla/LexTAL.cxx
index a76a296..15dc741 100644
--- a/plugins/scintilla/scintilla/LexTAL.cxx
+++ b/plugins/scintilla/scintilla/LexTAL.cxx
@@ -10,18 +10,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
 #include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -94,7 +97,7 @@ static int classifyWordTAL(unsigned int start, unsigned int end, /*WordList &key
 			else if (strcmp(s, "end") == 0) {
 				ret = -1;
 			}
-		} 
+		}
 		else if (s[0] == '$' || builtins.InList(s)) {
 			chAttr = SCE_C_WORD2;
 		}
diff --git a/plugins/scintilla/scintilla/LexTCL.cxx b/plugins/scintilla/scintilla/LexTCL.cxx
index 3c175de..de309f2 100644
--- a/plugins/scintilla/scintilla/LexTCL.cxx
+++ b/plugins/scintilla/scintilla/LexTCL.cxx
@@ -7,18 +7,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
 #include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -47,7 +50,7 @@ static void ColouriseTCLDoc(unsigned int startPos, int length, int , WordList *k
 	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 	bool commentLevel = false;
     bool subBrace = false; // substitution begin with a brace ${.....}
-	enum tLineState {LS_DEFAULT, LS_OPEN_COMMENT, LS_OPEN_DOUBLE_QUOTE, LS_COMMENT_BOX, LS_MASK_STATE = 0xf, 
+	enum tLineState {LS_DEFAULT, LS_OPEN_COMMENT, LS_OPEN_DOUBLE_QUOTE, LS_COMMENT_BOX, LS_MASK_STATE = 0xf,
         LS_COMMAND_EXPECTED = 16, LS_BRACE_ONLY = 32 } lineState = LS_DEFAULT;
 	bool prevSlash = false;
 	int currentLevel = 0;
@@ -86,7 +89,7 @@ static void ColouriseTCLDoc(unsigned int startPos, int length, int , WordList *k
     StyleContext sc(startPos, length, SCE_TCL_DEFAULT, styler);
 	for (; ; sc.Forward()) {
 next:
-        if (sc.ch=='\r' && sc.chNext == '\n') // only ignore \r on PC process on the mac 
+        if (sc.ch=='\r' && sc.chNext == '\n') // only ignore \r on PC process on the mac
             continue;
         bool atEnd = !sc.More();  // make sure we coloured the last word
         if (lineState != LS_DEFAULT) {
@@ -170,7 +173,7 @@ next:
                         sc.ChangeState(SCE_TCL_WORD7);
                     } else if (keywords9.InList(s)) {
                         sc.ChangeState(SCE_TCL_WORD8);
-                    } 
+                    }
                 }
                 expected = false;
                 sc.SetState(quote ? SCE_TCL_IN_QUOTE : SCE_TCL_DEFAULT);
@@ -212,7 +215,7 @@ next:
                 } else if (sc.state == SCE_TCL_COMMENT_BOX)
                     lineState = LS_COMMENT_BOX;
 			}
-            styler.SetLineState(currentLine, 
+            styler.SetLineState(currentLine,
                 (subBrace ? LS_BRACE_ONLY : 0) |
                 (expected ? LS_COMMAND_EXPECTED : 0)  | lineState);
             if (lineState == LS_COMMENT_BOX)
@@ -285,7 +288,7 @@ next:
 
 		if (sc.ch == '\\') {
 			prevSlash = true;
-			continue;		
+			continue;
 		}
 
 		// Determine if a new state should be entered.
@@ -322,7 +325,7 @@ next:
                     subParen = 0;
                     if (sc.chNext != '{') {
                         sc.SetState(SCE_TCL_SUBSTITUTION);
-                    } 
+                    }
                     else {
                         sc.SetState(SCE_TCL_OPERATOR);  // $
                         sc.Forward();  // {
diff --git a/plugins/scintilla/scintilla/LexTeX.cxx b/plugins/scintilla/scintilla/LexTeX.cxx
index 62ade1d..7b79670 100644
--- a/plugins/scintilla/scintilla/LexTeX.cxx
+++ b/plugins/scintilla/scintilla/LexTeX.cxx
@@ -18,18 +18,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.h"
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
 #include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -285,8 +288,8 @@ static void ColouriseTeXDoc(
 
 static inline bool isNumber(int ch) {
 	return
-      (ch == '0') || (ch == '1') || (ch == '2') || 
-      (ch == '3') || (ch == '4') || (ch == '5') || 
+      (ch == '0') || (ch == '1') || (ch == '2') ||
+      (ch == '3') || (ch == '4') || (ch == '5') ||
       (ch == '6') || (ch == '7') || (ch == '8') || (ch == '9');
 }
 
@@ -298,7 +301,7 @@ static int ParseTeXCommand(unsigned int pos, Accessor &styler, char *command)
 {
   int length=0;
   char ch=styler.SafeGetCharAt(pos+1);
-  
+
   if(ch==',' || ch==':' || ch==';' || ch=='%'){
       command[0]=ch;
       command[1]=0;
@@ -311,14 +314,14 @@ static int ParseTeXCommand(unsigned int pos, Accessor &styler, char *command)
           length++;
           ch=styler.SafeGetCharAt(pos+length+1);
      }
-     
-  command[length]='\0';   
+
+  command[length]='\0';
   if(!length) return 0;
   return length+1;
 }
 
 static int classifyFoldPointTeXPaired(const char* s) {
-	int lev=0; 
+	int lev=0;
 	if (!(isdigit(s[0]) || (s[0] == '.'))){
 		if (strcmp(s, "begin")==0||strcmp(s,"FoldStart")==0||
 			strcmp(s,"abstract")==0||strcmp(s,"unprotect")==0||
@@ -330,14 +333,14 @@ static int classifyFoldPointTeXPaired(const char* s) {
 			strcmp(s,"maketitle")==0||strcmp(s,"protect")==0||
 			strncmp(s,"stop",4)==0||strncmp(s,"Stop",4)==0||
 			strcmp(s,"fi")==0
-			) 
+			)
 		lev=-1;
 	}
 	return lev;
 }
 
 static int classifyFoldPointTeXUnpaired(const char* s) {
-	int lev=0; 
+	int lev=0;
 	if (!(isdigit(s[0]) || (s[0] == '.'))){
 		if (strcmp(s,"part")==0||
 			strcmp(s,"chapter")==0||
@@ -362,7 +365,7 @@ static int classifyFoldPointTeXUnpaired(const char* s) {
 static bool IsTeXCommentLine(int line, Accessor &styler) {
 	int pos = styler.LineStart(line);
 	int eol_pos = styler.LineStart(line + 1) - 1;
-	
+
 	int startpos = pos;
 
 	while (startpos<eol_pos){
@@ -370,14 +373,14 @@ static bool IsTeXCommentLine(int line, Accessor &styler) {
 		if (ch!='%' && ch!=' ') return false;
 		else if (ch=='%') return true;
 		startpos++;
-	}		
+	}
 
 	return false;
 }
 
 // FoldTeXDoc: borrowed from VisualTeX with modifications
 
-static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) 
+static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
 {
 	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 	unsigned int endPos = startPos+length;
@@ -387,7 +390,7 @@ static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Acc
 	int levelCurrent=levelPrev;
 	char chNext=styler[startPos];
 	char buffer[100]="";
-	
+
 	for (unsigned int i=startPos; i < endPos; i++) {
 		char ch=chNext;
 		chNext=styler.SafeGetCharAt(i+1);
@@ -412,12 +415,12 @@ static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Acc
 	chNext4=styler.SafeGetCharAt(i+4);
 	chNext5=styler.SafeGetCharAt(i+5);
 
-	bool atEOfold = (ch == '%') && 
-			(chNext == '%') && (chNext2=='}') && 
+	bool atEOfold = (ch == '%') &&
+			(chNext == '%') && (chNext2=='}') &&
 				(chNext3=='}')&& (chNext4=='-')&& (chNext5=='-');
 
-	bool atBOfold = (ch == '%') && 
-			(chNext == '%') && (chNext2=='-') && 
+	bool atBOfold = (ch == '%') &&
+			(chNext == '%') && (chNext2=='-') &&
 				(chNext3=='-')&& (chNext4=='{')&& (chNext5=='{');
 
 	if(atBOfold){
@@ -427,11 +430,11 @@ static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Acc
 	if(atEOfold){
 		levelCurrent-=1;
 	}
-	
+
 	if(ch=='\\' && chNext=='['){
 		levelCurrent+=1;
 	}
-	
+
 	if(ch=='\\' && chNext==']'){
 		levelCurrent-=1;
 	}
@@ -452,8 +455,8 @@ static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Acc
                 levelCurrent--;
         }
 
-//---------------------------------------------------------------------------------------------	
-		
+//---------------------------------------------------------------------------------------------
+
 		if (atEOL) {
 			int lev = levelPrev;
 			if (visibleChars == 0 && foldCompact)
diff --git a/plugins/scintilla/scintilla/LexTxt2tags.cxx b/plugins/scintilla/scintilla/LexTxt2tags.cxx
new file mode 100644
index 0000000..8f8e181
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexTxt2tags.cxx
@@ -0,0 +1,480 @@
+/******************************************************************
+ *  LexTxt2tags.cxx
+ *
+ *  A simple Txt2tags lexer for scintilla.
+ *
+ *
+ *  Adapted by Eric Forgeot
+ *  Based on the LexMarkdown.cxx by Jon Strait - jstrait moonloop net
+ *
+ *  What could be improved:
+ *   - Verbatim lines could be like for raw lines : when there is no space between the ``` and the following text, the first letter should be colored so the user would understand there must be a space for a valid tag.
+ *   - marks such as bold, italic, strikeout, underline should begin to be highlighted only when they are closed and valid.
+ *   - verbatim and raw area should be highlighted too.
+ *
+ *  The License.txt file describes the conditions under which this
+ *  software may be distributed.
+ *
+ *****************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+
+
+static inline bool IsNewline(const int ch) {
+    return (ch == '\n' || ch == '\r');
+}
+
+// True if can follow ch down to the end with possibly trailing whitespace
+static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) {
+    unsigned int i = 0;
+    while (sc.GetRelative(++i) == ch)
+        ;
+    // Skip over whitespace
+    while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos)
+        ++i;
+    if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) {
+        sc.Forward(i);
+        sc.ChangeState(state);
+        sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+        return true;
+    }
+    else return false;
+}
+
+// Does the previous line have more than spaces and tabs?
+static bool HasPrevLineContent(StyleContext &sc) {
+    int i = 0;
+    // Go back to the previous newline
+    while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i)))
+        ;
+    while (--i + sc.currentPos) {
+        if (IsNewline(sc.GetRelative(i)))
+            break;
+        if (!IsASpaceOrTab(sc.GetRelative(i)))
+            return true;
+    }
+    return false;
+}
+
+// Separator line
+static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
+    int c, count = 1;
+    unsigned int i = 0;
+    while (++i) {
+        c = sc.GetRelative(i);
+        if (c == sc.ch)
+            ++count;
+        // hit a terminating character
+        else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {
+            // Are we a valid HRULE
+            if ((IsNewline(c) || sc.currentPos + i == endPos) &&
+                    count >= 20 && !HasPrevLineContent(sc)) {
+                sc.SetState(SCE_TXT2TAGS_HRULE);
+                sc.Forward(i);
+                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+                return true;
+            }
+            else {
+                sc.SetState(SCE_TXT2TAGS_DEFAULT);
+		return false;
+            }
+        }
+    }
+    return false;
+}
+
+static void ColorizeTxt2tagsDoc(unsigned int startPos, int length, int initStyle,
+                               WordList **, Accessor &styler) {
+    unsigned int endPos = startPos + length;
+    int precharCount = 0;
+    // Don't advance on a new loop iteration and retry at the same position.
+    // Useful in the corner case of having to start at the beginning file position
+    // in the default state.
+    bool freezeCursor = false;
+
+    StyleContext sc(startPos, length, initStyle, styler);
+
+    while (sc.More()) {
+        // Skip past escaped characters
+        if (sc.ch == '\\') {
+            sc.Forward();
+            continue;
+        }
+
+        // A blockquotes resets the line semantics
+        if (sc.state == SCE_TXT2TAGS_BLOCKQUOTE){
+            sc.Forward(2);
+            sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+        }
+        // An option colors the whole line
+        if (sc.state == SCE_TXT2TAGS_OPTION){
+            FollowToLineEnd('%', SCE_TXT2TAGS_OPTION, endPos, sc);
+        }
+        if (sc.state == SCE_TXT2TAGS_POSTPROC){
+            FollowToLineEnd('%', SCE_TXT2TAGS_POSTPROC, endPos, sc);
+        }
+        if (sc.state == SCE_TXT2TAGS_PREPROC){
+            FollowToLineEnd('%', SCE_TXT2TAGS_PREPROC, endPos, sc);
+        }
+        // A comment colors the whole line
+        if (sc.state == SCE_TXT2TAGS_COMMENT){
+            FollowToLineEnd('%', SCE_TXT2TAGS_COMMENT, endPos, sc);
+        }
+        // Conditional state-based actions
+        if (sc.state == SCE_TXT2TAGS_CODE2) {
+        if (IsNewline(sc.ch))
+                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+            if (sc.Match("``") && sc.GetRelative(-2) != ' ') {
+                sc.Forward(2);
+                sc.SetState(SCE_TXT2TAGS_DEFAULT);
+            }
+        }
+        // Table
+        else if (sc.state == SCE_TXT2TAGS_CODE) {
+        if (IsNewline(sc.ch))
+                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+            if (sc.ch == '|' && sc.chPrev != ' ')
+                sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+        }
+        // Strong
+        else if (sc.state == SCE_TXT2TAGS_STRONG1) {
+        if (IsNewline(sc.ch))
+                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+            if (sc.Match("**") && sc.chPrev != ' ') {
+                sc.Forward(2);
+                sc.SetState(SCE_TXT2TAGS_DEFAULT);
+            }
+        }
+        // Emphasis
+        else if (sc.state == SCE_TXT2TAGS_EM1) {
+        if (IsNewline(sc.ch))
+                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+            if (sc.Match("//") && sc.chPrev != ' ') {
+                sc.Forward(2);
+                sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+           }
+        }
+        // Underline
+        else if (sc.state == SCE_TXT2TAGS_EM2) {
+        if (IsNewline(sc.ch))
+                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+            if (sc.Match("__") && sc.chPrev != ' ') {
+                sc.Forward(2);
+                sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+           }
+        }
+        // codeblock
+        else if (sc.state == SCE_TXT2TAGS_CODEBK) {
+                if (IsNewline(sc.ch))
+                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+            if (sc.atLineStart && sc.Match("```")) {
+                int i = 1;
+                while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos)
+                    i++;
+                sc.Forward(i);
+                sc.SetState(SCE_TXT2TAGS_DEFAULT);
+            }
+        }
+        // strikeout
+        else if (sc.state == SCE_TXT2TAGS_STRIKEOUT) {
+        if (IsNewline(sc.ch))
+                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+            if (sc.Match("--") && sc.chPrev != ' ') {
+                sc.Forward(2);
+                sc.SetState(SCE_TXT2TAGS_DEFAULT);
+            }
+        }
+        // Headers
+        else if (sc.state == SCE_TXT2TAGS_LINE_BEGIN) {
+            if (sc.Match("======"))
+                {
+                sc.SetState(SCE_TXT2TAGS_HEADER6);
+                sc.Forward();
+                }
+            else if (sc.Match("====="))
+                {
+                sc.SetState(SCE_TXT2TAGS_HEADER5);
+                sc.Forward();
+                }
+            else if (sc.Match("===="))
+                {
+                sc.SetState(SCE_TXT2TAGS_HEADER4);
+                sc.Forward();
+                }
+            else if (sc.Match("==="))
+                {
+                sc.SetState(SCE_TXT2TAGS_HEADER3);
+                sc.Forward();
+                }
+                //SetStateAndZoom(SCE_TXT2TAGS_HEADER3, 3, '=', sc);
+            else if (sc.Match("==")) {
+                sc.SetState(SCE_TXT2TAGS_HEADER2);
+                sc.Forward();
+                }
+                //SetStateAndZoom(SCE_TXT2TAGS_HEADER2, 2, '=', sc);
+            else if (sc.Match("=")) {
+                // Catch the special case of an unordered list
+                if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {
+                    precharCount = 0;
+                    sc.SetState(SCE_TXT2TAGS_PRECHAR);
+                }
+                else
+                    {
+                    sc.SetState(SCE_TXT2TAGS_HEADER1);
+                    sc.Forward();
+                    }
+                    //SetStateAndZoom(SCE_TXT2TAGS_HEADER1, 1, '=', sc);
+            }
+
+            // Numbered title
+            else if (sc.Match("++++++"))
+                {
+                sc.SetState(SCE_TXT2TAGS_HEADER6);
+                sc.Forward();
+                }
+            else if (sc.Match("+++++"))
+                {
+                sc.SetState(SCE_TXT2TAGS_HEADER5);
+                sc.Forward();
+                }
+            else if (sc.Match("++++"))
+                {
+                sc.SetState(SCE_TXT2TAGS_HEADER4);
+                sc.Forward();
+                }
+            else if (sc.Match("+++"))
+                {
+                sc.SetState(SCE_TXT2TAGS_HEADER3);
+                sc.Forward();
+                }
+                //SetStateAndZoom(SCE_TXT2TAGS_HEADER3, 3, '+', sc);
+            else if (sc.Match("++")) {
+                sc.SetState(SCE_TXT2TAGS_HEADER2);
+                sc.Forward();
+                }
+                //SetStateAndZoom(SCE_TXT2TAGS_HEADER2, 2, '+', sc);
+            else if (sc.Match("+")) {
+                // Catch the special case of an unordered list
+                if (sc.chNext == ' ' && IsASpaceOrTab(sc.GetRelative(1))) {
+                 //    if (IsNewline(sc.ch)) {
+                     	//precharCount = 0;
+                //		sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+                		//sc.SetState(SCE_TXT2TAGS_PRECHAR);
+				//	}
+                //    else {
+                //    precharCount = 0;
+                    sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);
+                    sc.Forward(2);
+                    sc.SetState(SCE_TXT2TAGS_DEFAULT);
+               //     sc.SetState(SCE_TXT2TAGS_PRECHAR);
+				//	}
+                }
+                else
+                    {
+                    sc.SetState(SCE_TXT2TAGS_HEADER1);
+                    sc.Forward();
+                    }
+            }
+
+
+            // Codeblock
+            else if (sc.Match("```")) {
+                if (!HasPrevLineContent(sc))
+              //  if (!FollowToLineEnd(sc))
+                    sc.SetState(SCE_TXT2TAGS_CODEBK);
+                else
+                    sc.SetState(SCE_TXT2TAGS_DEFAULT);
+            }
+
+            // Preproc
+            else if (sc.Match("%!preproc")) {
+                sc.SetState(SCE_TXT2TAGS_PREPROC);
+            }
+            // Postproc
+            else if (sc.Match("%!postproc")) {
+                sc.SetState(SCE_TXT2TAGS_POSTPROC);
+            }
+            // Option
+            else if (sc.Match("%!")) {
+                sc.SetState(SCE_TXT2TAGS_OPTION);
+            }
+
+             // Comment
+            else if (sc.ch == '%') {
+                sc.SetState(SCE_TXT2TAGS_COMMENT);
+            }
+            // list
+            else if (sc.ch == '-') {
+                    precharCount = 0;
+                    sc.SetState(SCE_TXT2TAGS_PRECHAR);
+            }
+            // def list
+            else if (sc.ch == ':') {
+                    precharCount = 0;
+                   sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);
+                   sc.Forward(1);
+                   sc.SetState(SCE_TXT2TAGS_PRECHAR);
+            }
+            else if (IsNewline(sc.ch))
+                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+            else {
+                precharCount = 0;
+                sc.SetState(SCE_TXT2TAGS_PRECHAR);
+            }
+        }
+
+        // The header lasts until the newline
+        else if (sc.state == SCE_TXT2TAGS_HEADER1 || sc.state == SCE_TXT2TAGS_HEADER2 ||
+                sc.state == SCE_TXT2TAGS_HEADER3 || sc.state == SCE_TXT2TAGS_HEADER4 ||
+                sc.state == SCE_TXT2TAGS_HEADER5 || sc.state == SCE_TXT2TAGS_HEADER6) {
+            if (IsNewline(sc.ch))
+                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+        }
+
+        // New state only within the initial whitespace
+        if (sc.state == SCE_TXT2TAGS_PRECHAR) {
+            // Blockquote
+            if (sc.Match("\"\"\"") && precharCount < 5){
+
+                sc.SetState(SCE_TXT2TAGS_BLOCKQUOTE);
+                sc.Forward(1);
+                }
+            /*
+            // Begin of code block
+            else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4))
+                sc.SetState(SCE_TXT2TAGS_CODEBK);
+            */
+            // HRule - Total of 20 or more hyphens, asterisks, or underscores
+            // on a line by themselves
+            else if ((sc.ch == '-' ) && IsValidHrule(endPos, sc))
+                ;
+            // Unordered list
+            else if ((sc.ch == '-') && IsASpaceOrTab(sc.chNext)) {
+                sc.SetState(SCE_TXT2TAGS_ULIST_ITEM);
+                sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+            }
+            // Ordered list
+            else if (IsADigit(sc.ch)) {
+                int digitCount = 0;
+                while (IsADigit(sc.GetRelative(++digitCount)))
+                    ;
+                if (sc.GetRelative(digitCount) == '.' &&
+                        IsASpaceOrTab(sc.GetRelative(digitCount + 1))) {
+                    sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);
+                    sc.Forward(digitCount + 1);
+                    sc.SetState(SCE_TXT2TAGS_DEFAULT);
+                }
+            }
+            // Alternate Ordered list
+            else if (sc.ch == '+' && sc.chNext == ' ' && IsASpaceOrTab(sc.GetRelative(2))) {
+            //    sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);
+            //    sc.Forward(2);
+             //   sc.SetState(SCE_TXT2TAGS_DEFAULT);
+            }
+            else if (sc.ch != ' ' || precharCount > 2)
+                sc.SetState(SCE_TXT2TAGS_DEFAULT);
+            else
+                ++precharCount;
+        }
+
+        // New state anywhere in doc
+        if (sc.state == SCE_TXT2TAGS_DEFAULT) {
+         //   if (sc.atLineStart && sc.ch == '#') {
+         //       sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+         //       freezeCursor = true;
+         //   }
+            // Links and Images
+            if (sc.Match("![") || sc.ch == '[') {
+                int i = 0, j = 0, k = 0;
+                int len = endPos - sc.currentPos;
+                while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
+                    ;
+                if (sc.GetRelative(i) == ']') {
+                    j = i;
+                    if (sc.GetRelative(++i) == '(') {
+                        while (i < len && (sc.GetRelative(++i) != '(' || sc.GetRelative(i - 1) == '\\'))
+                            ;
+                        if (sc.GetRelative(i) == '(')
+                            k = i;
+                    }
+
+                    else if (sc.GetRelative(i) == '[' || sc.GetRelative(++i) == '[') {
+                        while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
+                            ;
+                        if (sc.GetRelative(i) == ']')
+                            k = i;
+                    }
+                }
+                // At least a link text
+                if (j) {
+                    sc.SetState(SCE_TXT2TAGS_LINK);
+                    sc.Forward(j);
+                    // Also has a URL or reference portion
+                    if (k)
+                        sc.Forward(k - j);
+                    sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+                }
+            }
+            // Code - also a special case for alternate inside spacing
+            if (sc.Match("``") && sc.GetRelative(3) != ' ') {
+                sc.SetState(SCE_TXT2TAGS_CODE2);
+                sc.Forward();
+            }
+            else if (sc.ch == '|' && sc.GetRelative(3) != ' ') {
+                sc.SetState(SCE_TXT2TAGS_CODE);
+            }
+            // Strong
+            else if (sc.Match("**") && sc.GetRelative(2) != ' ') {
+                sc.SetState(SCE_TXT2TAGS_STRONG1);
+                sc.Forward();
+           }
+            // Emphasis
+            else if (sc.Match("//") && sc.GetRelative(2) != ' ') {
+                sc.SetState(SCE_TXT2TAGS_EM1);
+                sc.Forward();
+            }
+            else if (sc.Match("__") && sc.GetRelative(2) != ' ') {
+                sc.SetState(SCE_TXT2TAGS_EM2);
+                sc.Forward();
+            }
+            // Strikeout
+            else if (sc.Match("--") && sc.GetRelative(2) != ' ') {
+                sc.SetState(SCE_TXT2TAGS_STRIKEOUT);
+                sc.Forward();
+            }
+
+            // Beginning of line
+            else if (IsNewline(sc.ch))
+                sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+        }
+        // Advance if not holding back the cursor for this iteration.
+        if (!freezeCursor)
+            sc.Forward();
+        freezeCursor = false;
+    }
+    sc.Complete();
+}
+
+LexerModule lmTxt2tags(SCLEX_TXT2TAGS, ColorizeTxt2tagsDoc, "txt2tags");
+
+
diff --git a/plugins/scintilla/scintilla/LexVB.cxx b/plugins/scintilla/scintilla/LexVB.cxx
index c57a9ac..54050c7 100644
--- a/plugins/scintilla/scintilla/LexVB.cxx
+++ b/plugins/scintilla/scintilla/LexVB.cxx
@@ -7,18 +7,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexVHDL.cxx b/plugins/scintilla/scintilla/LexVHDL.cxx
index c082cdb..58bcd1a 100644
--- a/plugins/scintilla/scintilla/LexVHDL.cxx
+++ b/plugins/scintilla/scintilla/LexVHDL.cxx
@@ -1,9 +1,9 @@
 // Scintilla source code edit control
 /** @file LexVHDL.cxx
  ** Lexer for VHDL
- ** Written by Phil Reid, 
+ ** Written by Phil Reid,
  ** Based on:
- **  - The Verilog Lexer by Avi Yegudin 
+ **  - The Verilog Lexer by Avi Yegudin
  **  - The Fortran Lexer by Chuan-jian Shen
  **  - The C++ lexer by Neil Hodgson
  **/
@@ -15,15 +15,18 @@
 #include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -101,7 +104,7 @@ static void ColouriseVHDLDoc(
         }
         sc.SetState(SCE_VHDL_DEFAULT);
       }
-    } else if (sc.state == SCE_VHDL_COMMENT || sc.state == SCE_V_COMMENTLINEBANG) {
+    } else if (sc.state == SCE_VHDL_COMMENT || sc.state == SCE_VHDL_COMMENTLINEBANG) {
       if (sc.atLineEnd) {
         sc.SetState(SCE_VHDL_DEFAULT);
       }
@@ -113,7 +116,7 @@ static void ColouriseVHDLDoc(
       } else if (sc.ch == '\"') {
         sc.ForwardSetState(SCE_VHDL_DEFAULT);
       } else if (sc.atLineEnd) {
-        sc.ChangeState(SCE_V_STRINGEOL);
+        sc.ChangeState(SCE_VHDL_STRINGEOL);
         sc.ForwardSetState(SCE_VHDL_DEFAULT);
       }
     }
@@ -126,7 +129,7 @@ static void ColouriseVHDLDoc(
         sc.SetState(SCE_VHDL_IDENTIFIER);
       } else if (sc.Match('-', '-')) {
         sc.SetState(SCE_VHDL_COMMENT);
-        sc.Forward(); 
+        sc.Forward();
       } else if (sc.Match('-', '-')) {
         if (sc.Match("--!"))  // Nice to have a different comment style
           sc.SetState(SCE_VHDL_COMMENTLINEBANG);
@@ -161,7 +164,7 @@ static bool IsCommentLine(int line, Accessor &styler) {
 static void FoldNoBoxVHDLDoc(
   unsigned int startPos,
   int length,
-  int initStyle,
+  int,
   Accessor &styler)
 {
   // Decided it would be smarter to have the lexer have all keywords included. Therefore I
@@ -249,7 +252,6 @@ static void FoldNoBoxVHDLDoc(
   char  chPrev          = '\0';
   char  chNextNonBlank;
   int   styleNext       = styler.StyleAt(startPos);
-  int   style           = initStyle;
   //Platform::DebugPrintf("Line[%04d] Prev[%20s] ************************* Level[%x]\n", lineCurrent+1, prevWord, levelCurrent);
 
   /***************************************/
@@ -265,16 +267,16 @@ static void FoldNoBoxVHDLDoc(
       j ++ ;
       chNextNonBlank = styler.SafeGetCharAt(j);
     }
-    style           = styleNext;
+    int style           = styleNext;
     styleNext       = styler.StyleAt(i + 1);
     bool atEOL      = (ch == '\r' && chNext != '\n') || (ch == '\n');
 
-		if (foldComment && atEOL && IsCommentLine(lineCurrent, styler)) 
+		if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
     {
       if(!IsCommentLine(lineCurrent-1, styler) && IsCommentLine(lineCurrent+1, styler))
       {
         levelNext++;
-      } 
+      }
       else if(IsCommentLine(lineCurrent-1, styler) && !IsCommentLine(lineCurrent+1, styler))
       {
         levelNext--;
@@ -380,7 +382,7 @@ static void FoldNoBoxVHDLDoc(
             ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "function") == 0)) ||
             ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "procedure") == 0)))
           {
-            levelMinCurrentBegin = levelNext - 1;  
+            levelMinCurrentBegin = levelNext - 1;
           }
           //Platform::DebugPrintf("Line[%04d] Prev[%20s] Cur[%20s] Level[%x]\n", lineCurrent+1, prevWord, s, levelCurrent);
           strcpy(prevWord, s);
@@ -444,34 +446,34 @@ LexerModule lmVHDL(SCLEX_VHDL, ColouriseVHDLDoc, "vhdl", FoldVHDLDoc, VHDLWordLi
 
 
 // Keyword:
-//    access after alias all architecture array assert attribute begin block body buffer bus case component 
-//    configuration constant disconnect downto else elsif end entity exit file for function generate generic 
-//    group guarded if impure in inertial inout is label library linkage literal loop map new next null of 
-//    on open others out package port postponed procedure process pure range record register reject report 
-//    return select severity shared signal subtype then to transport type unaffected units until use variable 
+//    access after alias all architecture array assert attribute begin block body buffer bus case component
+//    configuration constant disconnect downto else elsif end entity exit file for function generate generic
+//    group guarded if impure in inertial inout is label library linkage literal loop map new next null of
+//    on open others out package port postponed procedure process pure range record register reject report
+//    return select severity shared signal subtype then to transport type unaffected units until use variable
 //    wait when while with
 //
 // Operators:
 //    abs and mod nand nor not or rem rol ror sla sll sra srl xnor xor
 //
 // Attributes:
-//    left right low high ascending image value pos val succ pred leftof rightof base range reverse_range 
-//    length delayed stable quiet transaction event active last_event last_active last_value driving 
+//    left right low high ascending image value pos val succ pred leftof rightof base range reverse_range
+//    length delayed stable quiet transaction event active last_event last_active last_value driving
 //    driving_value simple_name path_name instance_name
 //
 // Std Functions:
-//    now readline read writeline write endfile resolved to_bit to_bitvector to_stdulogic to_stdlogicvector 
-//    to_stdulogicvector to_x01 to_x01z to_UX01 rising_edge falling_edge is_x shift_left shift_right rotate_left 
+//    now readline read writeline write endfile resolved to_bit to_bitvector to_stdulogic to_stdlogicvector
+//    to_stdulogicvector to_x01 to_x01z to_UX01 rising_edge falling_edge is_x shift_left shift_right rotate_left
 //    rotate_right resize to_integer to_unsigned to_signed std_match to_01
 //
 // Std Packages:
-//    std ieee work standard textio std_logic_1164 std_logic_arith std_logic_misc std_logic_signed 
-//    std_logic_textio std_logic_unsigned numeric_bit numeric_std math_complex math_real vital_primitives 
+//    std ieee work standard textio std_logic_1164 std_logic_arith std_logic_misc std_logic_signed
+//    std_logic_textio std_logic_unsigned numeric_bit numeric_std math_complex math_real vital_primitives
 //    vital_timing
 //
 // Std Types:
-//    boolean bit character severity_level integer real time delay_length natural positive string bit_vector 
-//    file_open_kind file_open_status line text side width std_ulogic std_ulogic_vector std_logic 
+//    boolean bit character severity_level integer real time delay_length natural positive string bit_vector
+//    file_open_kind file_open_status line text side width std_ulogic std_ulogic_vector std_logic
 //    std_logic_vector X01 X01Z UX01 UX01Z unsigned signed
 //
 
diff --git a/plugins/scintilla/scintilla/LexVerilog.cxx b/plugins/scintilla/scintilla/LexVerilog.cxx
index 3fd0fc3..8de04ff 100644
--- a/plugins/scintilla/scintilla/LexVerilog.cxx
+++ b/plugins/scintilla/scintilla/LexVerilog.cxx
@@ -8,18 +8,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -150,6 +153,22 @@ static bool IsStreamCommentStyle(int style) {
 	return style == SCE_V_COMMENT;
 }
 
+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_V_COMMENTLINE || style == SCE_V_COMMENTLINEBANG)) {
+			return true;
+		} else if (!IsASpaceOrTab(ch)) {
+			return false;
+		}
+	}
+	return false;
+}
 // 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 {".
@@ -195,6 +214,15 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle
 				levelNext--;
 			}
 		}
+		if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
+		{
+			if (!IsCommentLine(lineCurrent - 1, styler)
+			    && IsCommentLine(lineCurrent + 1, styler))
+				levelNext++;
+			else if (IsCommentLine(lineCurrent - 1, styler)
+			         && !IsCommentLine(lineCurrent+1, styler))
+				levelNext--;
+		}
 		if (foldComment && (style == SCE_V_COMMENTLINE)) {
 			if ((ch == '/') && (chNext == '/')) {
 				char chNext2 = styler.SafeGetCharAt(i + 2);
diff --git a/plugins/scintilla/scintilla/LexYAML.cxx b/plugins/scintilla/scintilla/LexYAML.cxx
index 99f34da..727e8af 100644
--- a/plugins/scintilla/scintilla/LexYAML.cxx
+++ b/plugins/scintilla/scintilla/LexYAML.cxx
@@ -7,18 +7,21 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
 
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
 
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -270,7 +273,7 @@ static void FoldYAMLDoc(unsigned int startPos, int length, int /*initStyle - unu
 		}
 
 		const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
-		const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);
+		const int levelBeforeComments = 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
diff --git a/plugins/scintilla/scintilla/LexerBase.cxx b/plugins/scintilla/scintilla/LexerBase.cxx
new file mode 100644
index 0000000..ea5734d
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerBase.cxx
@@ -0,0 +1,92 @@
+// Scintilla source code edit control
+/** @file LexerSimple.cxx
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 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 <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+LexerBase::LexerBase() {
+	for (int wl = 0; wl < numWordLists; wl++)
+		keyWordLists[wl] = new WordList;
+	keyWordLists[numWordLists] = 0;
+}
+
+LexerBase::~LexerBase() {
+	for (int wl = 0; wl < numWordLists; wl++) {
+		delete keyWordLists[wl];
+		keyWordLists[wl] = 0;
+	}
+	keyWordLists[numWordLists] = 0;
+}
+
+void SCI_METHOD LexerBase::Release() {
+	delete this;
+}
+
+int SCI_METHOD LexerBase::Version() const {
+	return lvOriginal;
+}
+
+const char * SCI_METHOD LexerBase::PropertyNames() {
+	return "";
+}
+
+int SCI_METHOD LexerBase::PropertyType(const char *) {
+	return SC_TYPE_BOOLEAN;
+}
+
+const char * SCI_METHOD LexerBase::DescribeProperty(const char *) {
+	return "";
+}
+
+int SCI_METHOD LexerBase::PropertySet(const char *key, const char *val) {
+	const char *valOld = props.Get(key);
+	if (strcmp(val, valOld) != 0) {
+		props.Set(key, val);
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+const char * SCI_METHOD LexerBase::DescribeWordListSets() {
+	return "";
+}
+
+int SCI_METHOD LexerBase::WordListSet(int n, const char *wl) {
+	if (n < numWordLists) {
+		WordList wlNew;
+		wlNew.Set(wl);
+		if (*keyWordLists[n] != wlNew) {
+			keyWordLists[n]->Set(wl);
+			return 0;
+		}
+	}
+	return -1;
+}
+
+void * SCI_METHOD LexerBase::PrivateCall(int, void *) {
+	return 0;
+}
diff --git a/plugins/scintilla/scintilla/LexerBase.h b/plugins/scintilla/scintilla/LexerBase.h
new file mode 100644
index 0000000..2998d24
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerBase.h
@@ -0,0 +1,41 @@
+// Scintilla source code edit control
+/** @file LexerBase.h
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXERBASE_H
+#define LEXERBASE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// A simple lexer with no state
+class LexerBase : public ILexer {
+protected:
+	PropSetSimple props;
+	enum {numWordLists=KEYWORDSET_MAX+1};
+	WordList *keyWordLists[numWordLists+1];
+public:
+	LexerBase();
+	virtual ~LexerBase();
+	void SCI_METHOD Release();
+	int SCI_METHOD Version() const;
+	const char * SCI_METHOD PropertyNames();
+	int SCI_METHOD PropertyType(const char *name);
+	const char * SCI_METHOD DescribeProperty(const char *name);
+	int SCI_METHOD PropertySet(const char *key, const char *val);
+	const char * SCI_METHOD DescribeWordListSets();
+	int SCI_METHOD WordListSet(int n, const char *wl);
+	void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+	void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+	void * SCI_METHOD PrivateCall(int operation, void *pointer);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/LexerModule.cxx b/plugins/scintilla/scintilla/LexerModule.cxx
new file mode 100644
index 0000000..defc863
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerModule.cxx
@@ -0,0 +1,121 @@
+// Scintilla source code edit control
+/** @file LexerModule.cxx
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2010 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 <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <string>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+#include "LexerSimple.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+LexerModule::LexerModule(int language_,
+	LexerFunction fnLexer_,
+	const char *languageName_,
+	LexerFunction fnFolder_,
+        const char *const wordListDescriptions_[],
+	int styleBits_) :
+	language(language_),
+	fnLexer(fnLexer_),
+	fnFolder(fnFolder_),
+	fnFactory(0),
+	wordListDescriptions(wordListDescriptions_),
+	styleBits(styleBits_),
+	languageName(languageName_) {
+}
+
+LexerModule::LexerModule(int language_,
+	LexerFactoryFunction fnFactory_,
+	const char *languageName_,
+	const char * const wordListDescriptions_[],
+	int styleBits_) :
+	language(language_),
+	fnLexer(0),
+	fnFolder(0),
+	fnFactory(fnFactory_),
+	wordListDescriptions(wordListDescriptions_),
+	styleBits(styleBits_),
+	languageName(languageName_) {
+}
+
+int LexerModule::GetNumWordLists() const {
+	if (wordListDescriptions == NULL) {
+		return -1;
+	} else {
+		int numWordLists = 0;
+
+		while (wordListDescriptions[numWordLists]) {
+			++numWordLists;
+		}
+
+		return numWordLists;
+	}
+}
+
+const char *LexerModule::GetWordListDescription(int index) const {
+	static const char *emptyStr = "";
+
+	assert(index < GetNumWordLists());
+	if (index >= GetNumWordLists()) {
+		return emptyStr;
+	} else {
+		return wordListDescriptions[index];
+ 	}
+}
+
+int LexerModule::GetStyleBitsNeeded() const {
+	return styleBits;
+}
+
+ILexer *LexerModule::Create() const {
+	if (fnFactory)
+		return fnFactory();
+	else
+		return new LexerSimple(this);
+}
+
+void LexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
+	  WordList *keywordlists[], Accessor &styler) const {
+	if (fnLexer)
+		fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler);
+}
+
+void LexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
+	  WordList *keywordlists[], Accessor &styler) const {
+	if (fnFolder) {
+		int lineCurrent = styler.GetLine(startPos);
+		// Move back one line in case deletion wrecked current line fold state
+		if (lineCurrent > 0) {
+			lineCurrent--;
+			int newStartPos = styler.LineStart(lineCurrent);
+			lengthDoc += startPos - newStartPos;
+			startPos = newStartPos;
+			initStyle = 0;
+			if (startPos > 0) {
+				initStyle = styler.StyleAt(startPos - 1);
+			}
+		}
+		fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler);
+	}
+}
diff --git a/plugins/scintilla/scintilla/LexerModule.h b/plugins/scintilla/scintilla/LexerModule.h
new file mode 100644
index 0000000..e502541
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerModule.h
@@ -0,0 +1,82 @@
+// Scintilla source code edit control
+/** @file LexerModule.h
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2001 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXERMODULE_H
+#define LEXERMODULE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class Accessor;
+class WordList;
+
+typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
+                  WordList *keywordlists[], Accessor &styler);
+typedef ILexer *(*LexerFactoryFunction)();
+
+/**
+ * A LexerModule is responsible for lexing and folding a particular language.
+ * The class maintains a list of LexerModules which can be searched to find a
+ * module appropriate to a particular language.
+ */
+class LexerModule {
+protected:
+	int language;
+	LexerFunction fnLexer;
+	LexerFunction fnFolder;
+	LexerFactoryFunction fnFactory;
+	const char * const * wordListDescriptions;
+	int styleBits;
+
+public:
+	const char *languageName;
+	LexerModule(int language_,
+		LexerFunction fnLexer_,
+		const char *languageName_=0,
+		LexerFunction fnFolder_=0,
+		const char * const wordListDescriptions_[] = NULL,
+		int styleBits_=5);
+	LexerModule(int language_,
+		LexerFactoryFunction fnFactory_,
+		const char *languageName_,
+		const char * const wordListDescriptions_[] = NULL,
+		int styleBits_=8);
+	virtual ~LexerModule() {
+	}
+	int GetLanguage() const { return language; }
+
+	// -1 is returned if no WordList information is available
+	int GetNumWordLists() const;
+	const char *GetWordListDescription(int index) const;
+
+	int GetStyleBitsNeeded() const;
+
+	ILexer *Create() const;
+
+	virtual void Lex(unsigned int startPos, int length, int initStyle,
+                  WordList *keywordlists[], Accessor &styler) const;
+	virtual void Fold(unsigned int startPos, int length, int initStyle,
+                  WordList *keywordlists[], Accessor &styler) const;
+
+	friend class Catalogue;
+};
+
+inline int Maximum(int a, int b) {
+	return (a > b) ? a : b;
+}
+
+// Shut up annoying Visual C++ warnings:
+#ifdef _MSC_VER
+#pragma warning(disable: 4244 4309 4514 4710)
+#endif
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/LexerNoExceptions.cxx b/plugins/scintilla/scintilla/LexerNoExceptions.cxx
new file mode 100644
index 0000000..9ebae2a
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerNoExceptions.cxx
@@ -0,0 +1,68 @@
+// Scintilla source code edit control
+/** @file LexerNoExceptions.cxx
+ ** A simple lexer with no state which does not throw exceptions so can be used in an external lexer.
+ **/
+// Copyright 1998-2010 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 <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+#include "LexerNoExceptions.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+int SCI_METHOD LexerNoExceptions::PropertySet(const char *key, const char *val) {
+	try {
+		return LexerBase::PropertySet(key, val);
+	} catch (...) {
+		// Should not throw into caller as may be compiled with different compiler or options
+	}
+	return -1;
+}
+
+int SCI_METHOD LexerNoExceptions::WordListSet(int n, const char *wl) {
+	try {
+		return LexerBase::WordListSet(n, wl);
+	} catch (...) {
+		// Should not throw into caller as may be compiled with different compiler or options
+	}
+	return -1;
+}
+
+void SCI_METHOD LexerNoExceptions::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+	try {
+		Accessor astyler(pAccess, &props);
+		Lexer(startPos, length, initStyle, pAccess, astyler);
+		astyler.Flush();
+	} catch (...) {
+		// Should not throw into caller as may be compiled with different compiler or options
+		pAccess->SetErrorStatus(SC_STATUS_FAILURE);
+	}
+}
+void SCI_METHOD LexerNoExceptions::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+	try {
+		Accessor astyler(pAccess, &props);
+		Folder(startPos, length, initStyle, pAccess, astyler);
+		astyler.Flush();
+	} catch (...) {
+		// Should not throw into caller as may be compiled with different compiler or options
+		pAccess->SetErrorStatus(SC_STATUS_FAILURE);
+	}
+}
diff --git a/plugins/scintilla/scintilla/LexerNoExceptions.h b/plugins/scintilla/scintilla/LexerNoExceptions.h
new file mode 100644
index 0000000..caac61a
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerNoExceptions.h
@@ -0,0 +1,32 @@
+// Scintilla source code edit control
+/** @file LexerNoExceptions.h
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LexerNoExceptions_H
+#define LexerNoExceptions_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// A simple lexer with no state
+class LexerNoExceptions : public LexerBase {
+public:
+	// TODO Also need to prevent exceptions in constructor and destructor
+	int SCI_METHOD PropertySet(const char *key, const char *val);
+	int SCI_METHOD WordListSet(int n, const char *wl);
+	void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+	void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *);
+
+	virtual void Lexer(unsigned int startPos, int length, int initStyle, IDocument *pAccess, Accessor &styler) = 0;
+	virtual void Folder(unsigned int startPos, int length, int initStyle, IDocument *pAccess, Accessor &styler) = 0;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/LexerSimple.cxx b/plugins/scintilla/scintilla/LexerSimple.cxx
new file mode 100644
index 0000000..4d0e178
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerSimple.cxx
@@ -0,0 +1,57 @@
+// Scintilla source code edit control
+/** @file LexerSimple.cxx
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 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 <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <string>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+#include "LexerSimple.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+LexerSimple::LexerSimple(const LexerModule *module_) : module(module_) {
+	for (int wl = 0; wl < module->GetNumWordLists(); wl++) {
+		if (!wordLists.empty())
+			wordLists += "\n";
+		wordLists += module->GetWordListDescription(wl);
+	}
+}
+
+const char * SCI_METHOD LexerSimple::DescribeWordListSets() {
+	return wordLists.c_str();
+}
+
+void SCI_METHOD LexerSimple::Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) {
+	Accessor astyler(pAccess, &props);
+	module->Lex(startPos, lengthDoc, initStyle, keyWordLists, astyler);
+	astyler.Flush();
+}
+
+void SCI_METHOD LexerSimple::Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) {
+	if (props.GetInt("fold")) {
+		Accessor astyler(pAccess, &props);
+		module->Fold(startPos, lengthDoc, initStyle, keyWordLists, astyler);
+		astyler.Flush();
+	}
+}
diff --git a/plugins/scintilla/scintilla/LexerSimple.h b/plugins/scintilla/scintilla/LexerSimple.h
new file mode 100644
index 0000000..8963193
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerSimple.h
@@ -0,0 +1,30 @@
+// Scintilla source code edit control
+/** @file LexerSimple.h
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXERSIMPLE_H
+#define LEXERSIMPLE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// A simple lexer with no state
+class LexerSimple : public LexerBase {
+	const LexerModule *module;
+	std::string wordLists;
+public:
+	LexerSimple(const LexerModule *module_);
+	const char * SCI_METHOD DescribeWordListSets();
+	void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+	void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/LineMarker.cxx b/plugins/scintilla/scintilla/LineMarker.cxx
index 0bfd479..73410e2 100644
--- a/plugins/scintilla/scintilla/LineMarker.cxx
+++ b/plugins/scintilla/scintilla/LineMarker.cxx
@@ -2,7 +2,7 @@
 /** @file LineMarker.cxx
  ** Defines the look of a line marker in the margin .
  **/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #include <string.h>
@@ -20,6 +20,7 @@ using namespace Scintilla;
 void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
 	pal.WantFind(fore, want);
 	pal.WantFind(back, want);
+	pal.WantFind(backSelected, want);
 	if (pxpm) {
 		pxpm->RefreshColourPalette(pal, want);
 	}
@@ -31,7 +32,7 @@ void LineMarker::SetXPM(const char *textForm) {
 	markType = SC_MARK_PIXMAP;
 }
 
-void LineMarker::SetXPM(const char * const *linesForm) {
+void LineMarker::SetXPM(const char *const *linesForm) {
 	delete pxpm;
 	pxpm = new XPM(linesForm);
 	markType = SC_MARK_PIXMAP;
@@ -67,7 +68,32 @@ static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, C
 	surface->FillRectangle(rcH, fore);
 }
 
-void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) {
+void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold) {
+	ColourPair head = back;
+	ColourPair body = back;
+	ColourPair tail = back;
+
+	switch (tFold) {
+	case LineMarker::head :
+		head = backSelected;
+		tail = backSelected;
+		if (markType == SC_MARK_VLINE)
+			body = backSelected;
+		break;
+	case LineMarker::body :
+		head = backSelected;
+		body = backSelected;
+		break;
+	case LineMarker::tail :
+		body = backSelected;
+		tail = backSelected;
+		break;
+	default :
+		// LineMarker::undefined
+		break;
+	}
+
+
 	if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
 		pxpm->Draw(surface, rcWhole);
 		return;
@@ -154,111 +180,143 @@ 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) {
-		surface->PenColour(back.allocated);
-		surface->MoveTo(centreX, rcWhole.top);
+		surface->PenColour(body.allocated);
+		surface->MoveTo(centreX, rcWhole.top + blobSize - (rcWhole.bottom - rcWhole.top)/2);
 		surface->LineTo(centreX, rcWhole.bottom);
 
 	} else if (markType == SC_MARK_LCORNER) {
-		surface->PenColour(back.allocated);
+		surface->PenColour(tail.allocated);
 		surface->MoveTo(centreX, rcWhole.top);
 		surface->LineTo(centreX, rc.top + dimOn2);
 		surface->LineTo(rc.right - 2, rc.top + dimOn2);
 
 	} else if (markType == SC_MARK_TCORNER) {
-		surface->PenColour(back.allocated);
-		surface->MoveTo(centreX, rcWhole.top);
-		surface->LineTo(centreX, rcWhole.bottom);
+		surface->PenColour(tail.allocated);
 		surface->MoveTo(centreX, rc.top + dimOn2);
 		surface->LineTo(rc.right - 2, rc.top + dimOn2);
 
+		surface->PenColour(body.allocated);
+		surface->MoveTo(centreX, rcWhole.top);
+		surface->LineTo(centreX, rc.top + dimOn2 + 1);
+
+		surface->PenColour(head.allocated);
+		surface->LineTo(centreX, rcWhole.bottom);
+
 	} else if (markType == SC_MARK_LCORNERCURVE) {
-		surface->PenColour(back.allocated);
+		surface->PenColour(tail.allocated);
 		surface->MoveTo(centreX, rcWhole.top);
 		surface->LineTo(centreX, rc.top + dimOn2-3);
 		surface->LineTo(centreX+3, rc.top + dimOn2);
 		surface->LineTo(rc.right - 1, rc.top + dimOn2);
 
 	} else if (markType == SC_MARK_TCORNERCURVE) {
-		surface->PenColour(back.allocated);
-		surface->MoveTo(centreX, rcWhole.top);
-		surface->LineTo(centreX, rcWhole.bottom);
-
+		surface->PenColour(tail.allocated);
 		surface->MoveTo(centreX, rc.top + dimOn2-3);
 		surface->LineTo(centreX+3, rc.top + dimOn2);
 		surface->LineTo(rc.right - 1, rc.top + dimOn2);
 
+		surface->PenColour(body.allocated);
+		surface->MoveTo(centreX, rcWhole.top);
+		surface->LineTo(centreX, rc.top + dimOn2-2);
+
+		surface->PenColour(head.allocated);
+		surface->LineTo(centreX, rcWhole.bottom);
+
 	} else if (markType == SC_MARK_BOXPLUS) {
-		surface->PenColour(back.allocated);
-		DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
-		DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
+		DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+		DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
 
 	} else if (markType == SC_MARK_BOXPLUSCONNECTED) {
-		surface->PenColour(back.allocated);
-		DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
-		DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-
+		surface->PenColour(body.allocated);
 		surface->MoveTo(centreX, centreY + blobSize);
 		surface->LineTo(centreX, rcWhole.bottom);
 
+		surface->PenColour(body.allocated);
 		surface->MoveTo(centreX, rcWhole.top);
 		surface->LineTo(centreX, centreY - blobSize);
 
+		DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+		DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
+
+		if (tFold == LineMarker::body) {
+			surface->PenColour(tail.allocated);
+			surface->MoveTo(centreX + 1, centreY + blobSize);
+			surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
+
+			surface->MoveTo(centreX + blobSize, centreY + blobSize);
+			surface->LineTo(centreX + blobSize, centreY - blobSize);
+
+			surface->MoveTo(centreX + 1, centreY - blobSize);
+			surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
+		}
 	} else if (markType == SC_MARK_BOXMINUS) {
-		surface->PenColour(back.allocated);
-		DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
-		DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
+		DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+		DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
 
+		surface->PenColour(head.allocated);
 		surface->MoveTo(centreX, centreY + blobSize);
 		surface->LineTo(centreX, rcWhole.bottom);
 
 	} else if (markType == SC_MARK_BOXMINUSCONNECTED) {
-		surface->PenColour(back.allocated);
-		DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
-		DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
+		DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+		DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
 
+		surface->PenColour(head.allocated);
 		surface->MoveTo(centreX, centreY + blobSize);
 		surface->LineTo(centreX, rcWhole.bottom);
 
+		surface->PenColour(body.allocated);
 		surface->MoveTo(centreX, rcWhole.top);
 		surface->LineTo(centreX, centreY - blobSize);
 
+		if (tFold == LineMarker::body) {
+			surface->PenColour(tail.allocated);
+			surface->MoveTo(centreX + 1, centreY + blobSize);
+			surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
+
+			surface->MoveTo(centreX + blobSize, centreY + blobSize);
+			surface->LineTo(centreX + blobSize, centreY - blobSize);
+
+			surface->MoveTo(centreX + 1, centreY - blobSize);
+			surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
+		}
 	} else if (markType == SC_MARK_CIRCLEPLUS) {
-		DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
-		surface->PenColour(back.allocated);
-		DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
+		DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+		DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
 
 	} else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
-		DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
-		surface->PenColour(back.allocated);
-		DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-
+		surface->PenColour(body.allocated);
 		surface->MoveTo(centreX, centreY + blobSize);
 		surface->LineTo(centreX, rcWhole.bottom);
 
 		surface->MoveTo(centreX, rcWhole.top);
 		surface->LineTo(centreX, centreY - blobSize);
 
+		DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+		DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
+
 	} else if (markType == SC_MARK_CIRCLEMINUS) {
-		DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
-		surface->PenColour(back.allocated);
-		DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
+		DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+		DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
 
+		surface->PenColour(head.allocated);
 		surface->MoveTo(centreX, centreY + blobSize);
 		surface->LineTo(centreX, rcWhole.bottom);
 
 	} else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
-		DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
-		surface->PenColour(back.allocated);
-		DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
+		DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+		DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
 
+		surface->PenColour(head.allocated);
 		surface->MoveTo(centreX, centreY + blobSize);
 		surface->LineTo(centreX, rcWhole.bottom);
 
+		surface->PenColour(body.allocated);
 		surface->MoveTo(centreX, rcWhole.top);
 		surface->LineTo(centreX, centreY - blobSize);
 
diff --git a/plugins/scintilla/scintilla/LineMarker.h b/plugins/scintilla/scintilla/LineMarker.h
index 3cb4139..39c38fa 100644
--- a/plugins/scintilla/scintilla/LineMarker.h
+++ b/plugins/scintilla/scintilla/LineMarker.h
@@ -2,7 +2,7 @@
 /** @file LineMarker.h
  ** Defines the look of a line marker in the margin .
  **/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 #ifndef LINEMARKER_H
@@ -12,19 +12,24 @@
 namespace Scintilla {
 #endif
 
+
 /**
  */
 class LineMarker {
 public:
+	enum typeOfFold { undefined, head, body, tail };
+
 	int markType;
 	ColourPair fore;
 	ColourPair back;
+	ColourPair backSelected;
 	int alpha;
 	XPM *pxpm;
 	LineMarker() {
 		markType = SC_MARK_CIRCLE;
 		fore = ColourDesired(0,0,0);
 		back = ColourDesired(0xff,0xff,0xff);
+		backSelected = ColourDesired(0xff,0x00,0x00);
 		alpha = SC_ALPHA_NOALPHA;
 		pxpm = NULL;
 	}
@@ -33,6 +38,7 @@ public:
 		markType = SC_MARK_CIRCLE;
 		fore = ColourDesired(0,0,0);
 		back = ColourDesired(0xff,0xff,0xff);
+		backSelected = ColourDesired(0xff,0x00,0x00);
 		alpha = SC_ALPHA_NOALPHA;
 		pxpm = NULL;
 	}
@@ -44,6 +50,7 @@ public:
 		markType = SC_MARK_CIRCLE;
 		fore = ColourDesired(0,0,0);
 		back = ColourDesired(0xff,0xff,0xff);
+		backSelected = ColourDesired(0xff,0x00,0x00);
 		alpha = SC_ALPHA_NOALPHA;
 		delete pxpm;
 		pxpm = NULL;
@@ -51,8 +58,8 @@ public:
 	}
 	void RefreshColourPalette(Palette &pal, bool want);
 	void SetXPM(const char *textForm);
-	void SetXPM(const char * const *linesForm);
-	void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter);
+	void SetXPM(const char *const *linesForm);
+	void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter, typeOfFold tFold);
 };
 
 #ifdef SCI_NAMESPACE
diff --git a/plugins/scintilla/scintilla/Makefile.am b/plugins/scintilla/scintilla/Makefile.am
index 42c4eee..dec5b51 100644
--- a/plugins/scintilla/scintilla/Makefile.am
+++ b/plugins/scintilla/scintilla/Makefile.am
@@ -15,24 +15,25 @@ AM_CXXFLAGS = -DGTK -DSCI_LEXER -DUSE_XIM
 include $(srcdir)/lexers.make
 
 libanjuta_scintilla_la_SOURCES =\
+	Accessor.cxx \
 	AutoComplete.cxx \
 	CallTip.cxx \
+	Catalogue.cxx \
 	CellBuffer.cxx \
 	CharClassify.cxx \
+	CharacterSet.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 \
+	PropSetSimple.cxx \
 	RESearch.cxx \
 	RunStyles.cxx \
 	ScintillaBase.cxx \
@@ -42,23 +43,26 @@ libanjuta_scintilla_la_SOURCES =\
 	Style.cxx \
 	UniConversion.cxx \
 	ViewStyle.cxx \
-	WindowAccessor.cxx \
+	WordList.cxx \
 	XPM.cxx\
+	Accessor.h \
 	AutoComplete.h \
 	CallTip.h \
+	Catalogue.h \
 	CellBuffer.h \
 	CharacterSet.h \
 	CharClassify.h \
 	ContractionState.h \
 	Converter.h \
 	Decoration.h \
-	DocumentAccessor.h \
 	Document.h \
 	Editor.h \
 	ExternalLexer.h \
 	Indicator.h \
 	KeyMap.h \
+	LexAccessor.h \
 	LineMarker.h \
+	OptionSet.h \
 	Partitioning.h \
 	PerLine.h \
 	PositionCache.h \
@@ -67,12 +71,14 @@ libanjuta_scintilla_la_SOURCES =\
 	RunStyles.h \
 	ScintillaBase.h \
 	Selection.h \
+	SparseState.h \
 	SplitVector.h \
 	StyleContext.h\
 	Style.h \
 	SVector.h \
 	UniConversion.h \
 	ViewStyle.h\
+	WordList.h \
 	XPM.h\
 	scintilla-marshal.h\
 	scintilla-marshal.c\
@@ -88,6 +94,25 @@ test_scintilla_CXXFLAGS = -DGTK
 test_scintilla_SOURCES = test-scintilla.cxx
 test_scintilla_LDADD = libanjuta-scintilla.la
 
+$(srcdir)/lexers.make:
+	cd $(srcdir); \
+	echo "## Lexers make file" > $(notdir $@); \
+	echo 'LEXER_OBJS = \' >> $(notdir $@); \
+	echo -n '	StyleContext.o' >> $(notdir $@); \
+	for lex in Lex*.cxx; do \
+		lex=`echo $$lex | sed -e "s,.*/,," -e "s/cxx$$/o/"`; \
+		echo '\' >> $(notdir $@); \
+		echo -n "	$$lex" >> $(notdir $@); \
+	done; \
+	echo "" >> $(notdir $@); \
+	echo "" >> $(notdir $@); \
+	echo -n 'LEXER_SRCS = ' >> $(notdir $@); \
+	for lex in Lex*.cxx; do \
+		echo '\' >> $(notdir $@); \
+		echo -n "	$$lex" >> $(notdir $@); \
+	done; \
+	echo "" >> $(notdir $@)
+
 update-scintilla:
 	cd $(srcdir); \
 	cp scintilla/gtk/*.cxx .; \
@@ -97,22 +122,6 @@ update-scintilla:
 	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,.*/,," -e "s/cxx$$/o/"`; \
-		echo '\' >> 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; \
-	echo "" >> lexers.make
 	echo "Patching files ..."
 	cd $(srcdir); \
 	for patchfile in patches/*.diff; do \
diff --git a/plugins/scintilla/scintilla/OptionSet.h b/plugins/scintilla/scintilla/OptionSet.h
new file mode 100644
index 0000000..873ac8b
--- /dev/null
+++ b/plugins/scintilla/scintilla/OptionSet.h
@@ -0,0 +1,142 @@
+// Scintilla source code edit control
+/** @file OptionSet.h
+ ** Manage descriptive information about an options struct for a lexer.
+ ** Hold the names, positions, and descriptions of boolean, integer and string options and
+ ** allow setting options and retrieving metadata about the options.
+ **/
+// Copyright 2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef OPTIONSET_H
+#define OPTIONSET_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+template <typename T>
+class OptionSet {
+	typedef T Target;
+	typedef bool T::*plcob;
+	typedef int T::*plcoi;
+	typedef std::string T::*plcos;
+	struct Option {
+		int opType;
+		union {
+			plcob pb;
+			plcoi pi;
+			plcos ps;
+		};
+		std::string description;
+		Option() :
+			opType(SC_TYPE_BOOLEAN), pb(0), description("") {
+		}
+		Option(plcob pb_, std::string description_="") :
+			opType(SC_TYPE_BOOLEAN), pb(pb_), description(description_) {
+		}
+		Option(plcoi pi_, std::string description_) :
+			opType(SC_TYPE_INTEGER), pi(pi_), description(description_) {
+		}
+		Option(plcos ps_, std::string description_) :
+			opType(SC_TYPE_STRING), ps(ps_), description(description_) {
+		}
+		bool Set(T *base, const char *val) {
+			switch (opType) {
+			case SC_TYPE_BOOLEAN: {
+					bool option = atoi(val) != 0;
+					if ((*base).*pb != option) {
+						(*base).*pb = option;
+						return true;
+					}
+					break;
+				}
+			case SC_TYPE_INTEGER: {
+					int option = atoi(val);
+					if ((*base).*pi != option) {
+						(*base).*pi = option;
+						return true;
+					}
+					break;
+				}
+			case SC_TYPE_STRING: {
+					if ((*base).*ps != val) {
+						(*base).*ps = val;
+						return true;
+					}
+					break;
+				}
+			}
+			return false;
+		}
+	};
+	typedef std::map<std::string, Option> OptionMap;
+	OptionMap nameToDef;
+	std::string names;
+	std::string wordLists;
+
+	void AppendName(const char *name) {
+		if (!names.empty())
+			names += "\n";
+		names += name;
+	}
+public:
+	virtual ~OptionSet() {
+	}
+	void DefineProperty(const char *name, plcob pb, std::string description="") {
+		nameToDef[name] = Option(pb, description);
+		AppendName(name);
+	}
+	void DefineProperty(const char *name, plcoi pi, std::string description="") {
+		nameToDef[name] = Option(pi, description);
+		AppendName(name);
+	}
+	void DefineProperty(const char *name, plcos ps, std::string description="") {
+		nameToDef[name] = Option(ps, description);
+		AppendName(name);
+	}
+	const char *PropertyNames() {
+		return names.c_str();
+	}
+	int PropertyType(const char *name) {
+		typename OptionMap::iterator it = nameToDef.find(name);
+		if (it != nameToDef.end()) {
+			return it->second.opType;
+		}
+		return SC_TYPE_BOOLEAN;
+	}
+	const char *DescribeProperty(const char *name) {
+		typename OptionMap::iterator it = nameToDef.find(name);
+		if (it != nameToDef.end()) {
+			return it->second.description.c_str();
+		}
+		return "";
+	}
+
+	bool PropertySet(T *base, const char *name, const char *val) {
+		typename OptionMap::iterator it = nameToDef.find(name);
+		if (it != nameToDef.end()) {
+			return it->second.Set(base, val);
+		}
+		return false;
+	}
+
+	void DefineWordListSets(const char * const wordListDescriptions[]) {
+		if (wordListDescriptions) {
+			for (size_t wl = 0; wordListDescriptions[wl]; wl++) {
+				if (!wordLists.empty())
+					wordLists += "\n";
+				wordLists += wordListDescriptions[wl];
+			}
+		}
+	}
+
+	const char *DescribeWordListSets() {
+		return wordLists.c_str();
+	}
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/Partitioning.h b/plugins/scintilla/scintilla/Partitioning.h
index 225e350..07f3c5d 100644
--- a/plugins/scintilla/scintilla/Partitioning.h
+++ b/plugins/scintilla/scintilla/Partitioning.h
@@ -8,7 +8,7 @@
 #ifndef PARTITIONING_H
 #define PARTITIONING_H
 
-/// A split vector of integers with a method for adding a value to all elements 
+/// A split vector of integers with a method for adding a value to all elements
 /// in a range.
 /// Used by the Partitioning class.
 
@@ -42,6 +42,10 @@ public:
 
 /// Divide an interval into multiple partitions.
 /// Useful for breaking a document down into sections such as lines.
+/// A 0 length interval has a single 0 length partition, numbered 0
+/// If interval not 0 length then each partition non-zero length
+/// When needed, positions after the interval are considered part of the last partition
+/// but the end of the last partition can be found with PositionFromPartition(last+1).
 
 class Partitioning {
 private:
@@ -153,6 +157,7 @@ public:
 		return pos;
 	}
 
+	/// Return value in range [0 .. Partitions() - 1] even for arguments outside interval
 	int PartitionFromPosition(int pos) const {
 		if (body->Length() <= 1)
 			return 0;
diff --git a/plugins/scintilla/scintilla/PerLine.cxx b/plugins/scintilla/scintilla/PerLine.cxx
index 3e02d65..8fc6e25 100644
--- a/plugins/scintilla/scintilla/PerLine.cxx
+++ b/plugins/scintilla/scintilla/PerLine.cxx
@@ -202,15 +202,19 @@ int LineMarkers::AddMark(int line, int markerNum, int lines) {
 	return handleCurrent;
 }
 
-void LineMarkers::DeleteMark(int line, int markerNum, bool all) {
+bool LineMarkers::DeleteMark(int line, int markerNum, bool all) {
+	bool someChanges = false;
 	if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) {
 		if (markerNum == -1) {
+			someChanges = true;
 			delete markers[line];
 			markers[line] = NULL;
 		} else {
 			bool performedDeletion = markers[line]->RemoveNumber(markerNum);
+			someChanges = someChanges || performedDeletion;
 			while (all && performedDeletion) {
 				performedDeletion = markers[line]->RemoveNumber(markerNum);
+				someChanges = someChanges || performedDeletion;
 			}
 			if (markers[line]->Length() == 0) {
 				delete markers[line];
@@ -218,6 +222,7 @@ void LineMarkers::DeleteMark(int line, int markerNum, bool all) {
 			}
 		}
 	}
+	return someChanges;
 }
 
 void LineMarkers::DeleteMarkFromHandle(int markerHandle) {
@@ -240,10 +245,7 @@ void LineLevels::Init() {
 
 void LineLevels::InsertLine(int line) {
 	if (levels.Length()) {
-		int level = SC_FOLDLEVELBASE;
-		if ((line > 0) && (line < levels.Length())) {	
-			level = levels[line-1] & ~SC_FOLDLEVELWHITEFLAG;
-		}
+		int level = (line < levels.Length()) ? levels[line] : SC_FOLDLEVELBASE;
 		levels.InsertValue(line, 1, level);
 	}
 }
@@ -301,7 +303,8 @@ void LineState::Init() {
 void LineState::InsertLine(int line) {
 	if (lineStates.Length()) {
 		lineStates.EnsureLength(line);
-		lineStates.Insert(line, 0);
+		int val = (line < lineStates.Length()) ? lineStates[line] : 0;
+		lineStates.Insert(line, val);
 	}
 }
 
@@ -319,6 +322,8 @@ int LineState::SetLineState(int line, int state) {
 }
 
 int LineState::GetLineState(int line) {
+	if (line < 0)
+		return 0;
 	lineStates.EnsureLength(line + 1);
 	return lineStates[line];
 }
@@ -421,7 +426,7 @@ void LineAnnotation::SetText(int line, const char *text) {
 			delete []annotations[line];
 		}
 		annotations[line] = AllocateAnnotation(strlen(text), style);
-		AnnotationHeader *pah = reinterpret_cast<AnnotationHeader*>(annotations[line]);
+		AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
 		pah->style = static_cast<short>(style);
 		pah->length = strlen(text);
 		pah->lines = static_cast<short>(NumberLines(text));
diff --git a/plugins/scintilla/scintilla/PerLine.h b/plugins/scintilla/scintilla/PerLine.h
index ab34c46..df47286 100644
--- a/plugins/scintilla/scintilla/PerLine.h
+++ b/plugins/scintilla/scintilla/PerLine.h
@@ -11,7 +11,7 @@
 #ifdef SCI_NAMESPACE
 namespace Scintilla {
 #endif
-	
+
 /**
  * This holds the marker identifier and the marker type to display.
  * MarkerHandleNumbers are members of lists.
@@ -56,7 +56,7 @@ public:
 	int MarkValue(int line);
 	int AddMark(int line, int marker, int lines);
 	void MergeMarkers(int pos);
-	void DeleteMark(int line, int markerNum, bool all);
+	bool DeleteMark(int line, int markerNum, bool all);
 	void DeleteMarkFromHandle(int markerHandle);
 	int LineFromHandle(int markerHandle);
 };
diff --git a/plugins/scintilla/scintilla/PlatGTK.cxx b/plugins/scintilla/scintilla/PlatGTK.cxx
index 35f8d93..ee74c65 100644
--- a/plugins/scintilla/scintilla/PlatGTK.cxx
+++ b/plugins/scintilla/scintilla/PlatGTK.cxx
@@ -7,6 +7,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
+#include <math.h>
 
 #include <glib.h>
 #include <gmodule.h>
@@ -31,9 +32,28 @@
    with gdk_string_extents. */
 #define FAST_WAY
 
-#if GTK_MAJOR_VERSION >= 2
-#define USE_PANGO 1
 #include "Converter.h"
+
+#if GTK_CHECK_VERSION(2,20,0)
+#define IS_WIDGET_FOCUSSED(w) (gtk_widget_has_focus(GTK_WIDGET(w)))
+#else
+#define IS_WIDGET_FOCUSSED(w) (GTK_WIDGET_HAS_FOCUS(w))
+#endif
+
+#if GTK_CHECK_VERSION(2,22,0)
+#define USE_CAIRO 1
+#endif
+
+static GdkWindow *WindowFromWidget(GtkWidget *w) {
+#if GTK_CHECK_VERSION(3,0,0)
+	return gtk_widget_get_window(w);
+#else
+	return w->window;
+#endif
+}
+
+#ifdef USE_CAIRO
+#define DISABLE_GDK_FONT 1
 #endif
 
 #ifdef _MSC_VER
@@ -104,40 +124,44 @@ class FontHandle {
 	encodingType et;
 public:
 	int ascent;
+#ifndef DISABLE_GDK_FONT
 	GdkFont *pfont;
-#ifdef USE_PANGO
+#endif
 	PangoFontDescription *pfd;
 	int characterSet;
-#endif
-	FontHandle(GdkFont *pfont_) {
+#ifdef DISABLE_GDK_FONT
+	FontHandle() : et(singleByte), ascent(0), pfd(0), characterSet(-1) {
+		ResetWidths(et);
+	}
+#else
+	FontHandle(GdkFont *pfont_=0) {
 		et = singleByte;
 		ascent = 0;
 		pfont = pfont_;
-#ifdef USE_PANGO
 		pfd = 0;
 		characterSet = -1;
-#endif
 		ResetWidths(et);
 	}
-#ifdef USE_PANGO
+#endif
 	FontHandle(PangoFontDescription *pfd_, int characterSet_) {
 		et = singleByte;
 		ascent = 0;
+#ifndef DISABLE_GDK_FONT
 		pfont = 0;
+#endif
 		pfd = pfd_;
 		characterSet = characterSet_;
 		ResetWidths(et);
 	}
-#endif
 	~FontHandle() {
+#ifndef DISABLE_GDK_FONT
 		if (pfont)
 			gdk_font_unref(pfont);
 		pfont = 0;
-#ifdef USE_PANGO
+#endif
 		if (pfd)
 			pango_font_description_free(pfd);
 		pfd = 0;
-#endif
 	}
 	void ResetWidths(encodingType et_) {
 		et = et_;
@@ -177,9 +201,11 @@ static GtkWidget *PWidget(WindowID wid) {
 	return reinterpret_cast<GtkWidget *>(wid);
 }
 
+#if !GTK_CHECK_VERSION(3,0,0)
 static GtkWidget *PWidget(Window &w) {
 	return PWidget(w.GetID());
 }
+#endif
 
 Point Point::FromLong(long lpoint) {
 	return Point(
@@ -248,6 +274,8 @@ void Palette::WantFind(ColourPair &cp, bool want) {
 }
 
 void Palette::Allocate(Window &w) {
+#if !GTK_CHECK_VERSION(3,0,0)
+	// Disable palette on GTK+ 3.
 	if (allocatedPalette) {
 		gdk_colormap_free_colors(gtk_widget_get_colormap(PWidget(w)),
 		                         reinterpret_cast<GdkColor *>(allocatedPalette),
@@ -276,8 +304,11 @@ void Palette::Allocate(Window &w) {
 		}
 	}
 	delete []successPalette;
+#endif
 }
 
+#ifndef DISABLE_GDK_FONT
+
 static const char *CharacterSetName(int characterSet) {
 	switch (characterSet) {
 	case SC_CHARSET_ANSI:
@@ -358,7 +389,7 @@ static void GenerateFontSpecStrings(const char *fontName, int characterSet,
 		d2 = strchr(d1 + 1, '-');
 		if (d2)
 			d3 = strchr(d2 + 1, '-');
-		if (d3) {
+		if (d3 && d2) {
 			// foundary-fontface-isoxxx-x
 			*d2 = '\0';
 			foundary[0] = '-';
@@ -385,6 +416,8 @@ static void GenerateFontSpecStrings(const char *fontName, int characterSet,
 	}
 }
 
+#endif
+
 static void SetLogFont(LOGFONT &lf, const char *faceName, int characterSet, int size, bool bold, bool italic) {
 	memset(&lf, 0, sizeof(lf));
 	lf.size = size;
@@ -492,6 +525,7 @@ void FontCached::ReleaseId(FontID fid_) {
 	FontMutexUnlock();
 }
 
+#ifndef DISABLE_GDK_FONT
 static GdkFont *LoadFontOrSet(const char *fontspec, int characterSet) {
 	if (IsDBCSCharacterSet(characterSet)) {
 		return gdk_fontset_load(fontspec);
@@ -499,9 +533,22 @@ static GdkFont *LoadFontOrSet(const char *fontspec, int characterSet) {
 		return gdk_font_load(fontspec);
 	}
 }
+#endif
 
 FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
                                  int size, bool bold, bool italic) {
+	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);
+		}
+	}
+
+#ifndef DISABLE_GDK_FONT
 	char fontset[1024];
 	char fontspec[300];
 	char foundary[50];
@@ -513,19 +560,6 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
 	faceName[0] = '\0';
 	charset[0] = '\0';
 
-#ifdef USE_PANGO
-	//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;
 	// If name of the font begins with a '-', assume, that it is
 	// a full fontspec.
@@ -611,7 +645,6 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
 		newid = gdk_fontset_load(fontset);
 		if (newid)
 			return new FontHandle(newid);
-
 		// if fontset load failed, fall through, we'll use
 		// the last font entry and continue to try and
 		// get something that matches
@@ -660,6 +693,18 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
 			characterSet);
 	}
 	return new FontHandle(newid);
+#else
+	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);
+	}
+
+	return new FontHandle();
+#endif
 }
 
 Font::Font() : fid(0) {}
@@ -680,26 +725,29 @@ void Font::Release() {
 
 // Required on OS X
 #ifdef SCI_NAMESPACE
-class Scintilla::SurfaceImpl : public Surface
-#else
-class SurfaceImpl : public Surface
+namespace Scintilla {
 #endif
-{
+
+// On GTK+ 2.x, SurfaceID is a GdkDrawable* and on GTK+ 3.x, it is a cairo_t*
+class SurfaceImpl : public Surface {
 	encodingType et;
+#ifdef USE_CAIRO
+	cairo_t *context;
+	cairo_surface_t *psurf;
+#else
 	GdkDrawable *drawable;
 	GdkGC *gc;
 	GdkPixmap *ppixmap;
+#endif
 	int x;
 	int y;
 	bool inited;
 	bool createdGC;
-#ifdef USE_PANGO
 	PangoContext *pcontext;
 	PangoLayout *layout;
 	Converter conv;
 	int characterSet;
 	void SetConverter(int characterSet_);
-#endif
 public:
 	SurfaceImpl();
 	virtual ~SurfaceImpl();
@@ -746,6 +794,9 @@ public:
 	void SetUnicodeMode(bool unicodeMode_);
 	void SetDBCSMode(int codePage);
 };
+#ifdef SCI_NAMESPACE
+}
+#endif
 
 const char *CharacterSetID(int characterSet) {
 	switch (characterSet) {
@@ -760,11 +811,11 @@ const char *CharacterSetID(int characterSet) {
 	case SC_CHARSET_EASTEUROPE:
 		return "ISO-8859-2";
 	case SC_CHARSET_GB2312:
-		return "GB2312";
+		return "CP936";
 	case SC_CHARSET_GREEK:
 		return "ISO-8859-7";
 	case SC_CHARSET_HANGUL:
-		return "";
+		return "CP949";
 	case SC_CHARSET_MAC:
 		return "MACINTOSH";
 	case SC_CHARSET_OEM:
@@ -780,7 +831,7 @@ const char *CharacterSetID(int characterSet) {
 	case SC_CHARSET_TURKISH:
 		return "ISO-8859-9";
 	case SC_CHARSET_JOHAB:
-		return "JOHAB";
+		return "CP1361";
 	case SC_CHARSET_HEBREW:
 		return "ISO-8859-8";
 	case SC_CHARSET_ARABIC:
@@ -796,22 +847,24 @@ const char *CharacterSetID(int characterSet) {
 	}
 }
 
-#ifdef USE_PANGO
-
 void SurfaceImpl::SetConverter(int characterSet_) {
 	if (characterSet != characterSet_) {
 		characterSet = characterSet_;
 		conv.Open("UTF-8", CharacterSetID(characterSet), false);
 	}
 }
-#endif
 
-SurfaceImpl::SurfaceImpl() : et(singleByte), drawable(0), gc(0), ppixmap(0),
-x(0), y(0), inited(false), createdGC(false)
-#ifdef USE_PANGO
-, pcontext(0), layout(0), characterSet(-1)
+SurfaceImpl::SurfaceImpl() : et(singleByte),
+#ifdef USE_CAIRO
+context(0),
+psurf(0),
+#else
+drawable(0),
+gc(0),
+ppixmap(0),
 #endif
-{
+x(0), y(0), inited(false), createdGC(false)
+, pcontext(0), layout(0), characterSet(-1) {
 }
 
 SurfaceImpl::~SurfaceImpl() {
@@ -820,16 +873,28 @@ SurfaceImpl::~SurfaceImpl() {
 
 void SurfaceImpl::Release() {
 	et = singleByte;
+#ifndef USE_CAIRO
 	drawable = 0;
+#endif
 	if (createdGC) {
 		createdGC = false;
-		gdk_gc_unref(gc);
+#ifdef USE_CAIRO
+		cairo_destroy(context);
+#else
+		g_object_unref(gc);
+#endif
 	}
+#ifdef USE_CAIRO
+	context = 0;
+	if (psurf)
+		cairo_surface_destroy(psurf);
+	psurf = 0;
+#else
 	gc = 0;
 	if (ppixmap)
-		gdk_pixmap_unref(ppixmap);
+		g_object_unref(ppixmap);
 	ppixmap = 0;
-#ifdef USE_PANGO
+#endif
 	if (layout)
 		g_object_unref(layout);
 	layout = 0;
@@ -838,7 +903,6 @@ void SurfaceImpl::Release() {
 	pcontext = 0;
 	conv.Close();
 	characterSet = -1;
-#endif
 	x = 0;
 	y = 0;
 	inited = false;
@@ -849,70 +913,127 @@ bool SurfaceImpl::Initialised() {
 	return inited;
 }
 
-// The WindowID argument is only used for Pango builds
-#ifdef USE_PANGO
-#define WID_NAME wid
-#else
-#define WID_NAME
-#endif
-
-void SurfaceImpl::Init(WindowID WID_NAME) {
+void SurfaceImpl::Init(WindowID wid) {
 	Release();
-#ifdef USE_PANGO
 	PLATFORM_ASSERT(wid);
+#ifdef USE_CAIRO
+#if GTK_CHECK_VERSION(3,0,0)
+	GdkWindow *drawable_ = gtk_widget_get_window(PWidget(wid));
+#else
+	GdkDrawable *drawable_ = GDK_DRAWABLE(PWidget(wid)->window);
+#endif
+	if (drawable_) {
+		context = gdk_cairo_create(drawable_);
+		PLATFORM_ASSERT(context);
+	} else {
+		// Shouldn't happen with valid window but may when calls made before
+		// window completely allocated and mapped.
+		psurf = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 1, 1);
+		context = cairo_create(psurf);
+	}
+	createdGC = true;
+#endif
 	pcontext = gtk_widget_create_pango_context(PWidget(wid));
 	PLATFORM_ASSERT(pcontext);
 	layout = pango_layout_new(pcontext);
 	PLATFORM_ASSERT(layout);
-#endif
 	inited = true;
 }
 
-void SurfaceImpl::Init(SurfaceID sid, WindowID WID_NAME) {
+void SurfaceImpl::Init(SurfaceID sid, WindowID wid) {
 	PLATFORM_ASSERT(sid);
-	GdkDrawable *drawable_ = reinterpret_cast<GdkDrawable *>(sid);
 	Release();
-#ifdef USE_PANGO
 	PLATFORM_ASSERT(wid);
+#ifdef USE_CAIRO
+#if GTK_CHECK_VERSION(3,0,0)
+	context = cairo_reference(reinterpret_cast<cairo_t *>(sid));
+#else
+	context = gdk_cairo_create(reinterpret_cast<GdkDrawable *>(sid));
+#endif
+#else
+	drawable = reinterpret_cast<GdkDrawable *>(sid);
+	gc = gdk_gc_new(drawable);
+#endif
 	pcontext = gtk_widget_create_pango_context(PWidget(wid));
 	layout = pango_layout_new(pcontext);
-#endif
-	drawable = drawable_;
-	gc = gdk_gc_new(drawable_);
+#ifdef USE_CAIRO
+	cairo_set_line_width(context, 1);
+#else
 	// Ask for lines that do not paint the last pixel so is like Win32
 	gdk_gc_set_line_attributes(gc, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
+#endif
 	createdGC = true;
 	inited = true;
 }
 
-void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID WID_NAME) {
+void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID wid) {
 	PLATFORM_ASSERT(surface_);
 	Release();
 	SurfaceImpl *surfImpl = static_cast<SurfaceImpl *>(surface_);
-	PLATFORM_ASSERT(surfImpl->drawable);
-#ifdef USE_PANGO
 	PLATFORM_ASSERT(wid);
+#ifdef USE_CAIRO
+	context = cairo_reference(surfImpl->context);
+#else
+	PLATFORM_ASSERT(surfImpl->drawable);
+	gc = gdk_gc_new(surfImpl->drawable);
+#endif
 	pcontext = gtk_widget_create_pango_context(PWidget(wid));
 	PLATFORM_ASSERT(pcontext);
 	layout = pango_layout_new(pcontext);
 	PLATFORM_ASSERT(layout);
-#endif
+#ifdef USE_CAIRO
+	if (height > 0 && width > 0)
+		psurf = gdk_window_create_similar_surface(
+			gtk_widget_get_window(PWidget(wid)),
+			CAIRO_CONTENT_COLOR_ALPHA, width, height);
+#else
 	if (height > 0 && width > 0)
 		ppixmap = gdk_pixmap_new(surfImpl->drawable, width, height, -1);
 	drawable = ppixmap;
-	gc = gdk_gc_new(surfImpl->drawable);
+#endif
+#ifdef USE_CAIRO
+	cairo_destroy(context);
+	context = cairo_create(psurf);
+	cairo_rectangle(context, 0, 0, width, height);
+	cairo_set_source_rgb(context, 1.0, 0, 0);
+	cairo_fill(context);
+	// This produces sharp drawing more similar to GDK:
+	//cairo_set_antialias(context, CAIRO_ANTIALIAS_NONE);
+#endif
+#ifdef USE_CAIRO
+	cairo_set_line_width(context, 1);
+#else
 	// Ask for lines that do not paint the last pixel so is like Win32
 	gdk_gc_set_line_attributes(gc, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
+#endif
 	createdGC = true;
 	inited = true;
 }
 
 void SurfaceImpl::PenColour(ColourAllocated fore) {
+#ifdef USE_CAIRO
+	if (context) {
+		ColourDesired cdFore(fore.AsLong());
+#if GTK_CHECK_VERSION(3,0,0)
+		// Colours appear inverted - possibly because palette no longer used
+		cairo_set_source_rgb(context,
+			cdFore.GetRed() / 255.0,
+			cdFore.GetGreen() / 255.0,
+			cdFore.GetBlue() / 255.0);
+#else
+		cairo_set_source_rgb(context,
+			cdFore.GetBlue() / 255.0,
+			cdFore.GetGreen() / 255.0,
+			cdFore.GetRed() / 255.0);
+#endif
+	}
+#else
 	if (gc) {
 		GdkColor co;
 		co.pixel = fore.AsLong();
 		gdk_gc_set_foreground(gc, &co);
 	}
+#endif
 }
 
 int SurfaceImpl::LogPixelsY() {
@@ -929,18 +1050,71 @@ void SurfaceImpl::MoveTo(int x_, int y_) {
 	y = y_;
 }
 
+#ifdef USE_CAIRO
+static int Delta(int difference) {
+	if (difference < 0)
+		return -1;
+	else if (difference > 0)
+		return 1;
+	else
+		return 0;
+}
+#endif
+
 void SurfaceImpl::LineTo(int x_, int y_) {
+#ifdef USE_CAIRO
+	// cairo_line_to draws the end position, unlike Win32 or GDK with GDK_CAP_NOT_LAST.
+	// For simple cases, move back one pixel from end.
+	if (context) {
+		int xDiff = x_ - x;
+		int xDelta = Delta(xDiff);
+		int yDiff = y_ - y;
+		int yDelta = Delta(yDiff);
+		if ((xDiff == 0) || (yDiff == 0)) {
+			// Horizontal or vertical lines can be more precisely drawn as a filled rectangle
+			int xEnd = x_ - xDelta;
+			int left = Platform::Minimum(x, xEnd);
+			int width = abs(x - xEnd) + 1;
+			int yEnd = y_ - yDelta;
+			int top = Platform::Minimum(y, yEnd);
+			int height = abs(y - yEnd) + 1;
+			cairo_rectangle(context, left, top, width, height);
+			cairo_fill(context);
+		} else if ((abs(xDiff) == abs(yDiff))) {
+			// 45 degree slope
+			cairo_move_to(context, x + 0.5, y + 0.5);
+			cairo_line_to(context, x_ + 0.5 - xDelta, y_ + 0.5 - yDelta);
+		} else {
+			// Line has a different slope so difficult to avoid last pixel
+			cairo_move_to(context, x + 0.5, y + 0.5);
+			cairo_line_to(context, x_ + 0.5, y_ + 0.5);
+		}
+		cairo_stroke(context);
+	}
+#else
 	if (drawable && gc) {
 		gdk_draw_line(drawable, gc,
 		              x, y,
 		              x_, y_);
 	}
+#endif
 	x = x_;
 	y = y_;
 }
 
 void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore,
                           ColourAllocated back) {
+#ifdef USE_CAIRO
+	PenColour(back);
+	cairo_move_to(context, pts[0].x + 0.5, pts[0].y + 0.5);
+	for (int i = 1;i < npts;i++) {
+		cairo_line_to(context, pts[i].x + 0.5, pts[i].y + 0.5);
+	}
+	cairo_close_path(context);
+	cairo_fill_preserve(context);
+	PenColour(fore);
+	cairo_stroke(context);
+#else
 	GdkPoint gpts[20];
 	if (npts < static_cast<int>((sizeof(gpts) / sizeof(gpts[0])))) {
 		for (int i = 0;i < npts;i++) {
@@ -952,35 +1126,62 @@ void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore,
 		PenColour(fore);
 		gdk_draw_polygon(drawable, gc, 0, gpts, npts);
 	}
+#endif
 }
 
 void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
+#ifdef USE_CAIRO
+	if (context) {
+#else
 	if (gc && drawable) {
+#endif
+#ifdef USE_CAIRO
+		cairo_rectangle(context, rc.left + 0.5, rc.top + 0.5,
+	                     rc.right - rc.left - 1, rc.bottom - rc.top - 1);
+		PenColour(back);
+		cairo_fill_preserve(context);
+		PenColour(fore);
+		cairo_stroke(context);
+#else
 		PenColour(back);
 		gdk_draw_rectangle(drawable, gc, 1,
 		                   rc.left + 1, rc.top + 1,
 		                   rc.right - rc.left - 2, rc.bottom - rc.top - 2);
-
 		PenColour(fore);
 		// The subtraction of 1 off the width and height here shouldn't be needed but
 		// otherwise a different rectangle is drawn than would be done if the fill parameter == 1
 		gdk_draw_rectangle(drawable, gc, 0,
 		                   rc.left, rc.top,
 		                   rc.right - rc.left - 1, rc.bottom - rc.top - 1);
+#endif
 	}
 }
 
 void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {
 	PenColour(back);
+#ifdef USE_CAIRO
+	if (context && (rc.left < maxCoordinate)) {	// Protect against out of range
+		cairo_rectangle(context, rc.left, rc.top,
+	                     rc.right - rc.left, rc.bottom - rc.top);
+		cairo_fill(context);
+	}
+#else
 	if (drawable && (rc.left < maxCoordinate)) {	// Protect against out of range
 		gdk_draw_rectangle(drawable, gc, 1,
 		                   rc.left, rc.top,
 		                   rc.right - rc.left, rc.bottom - rc.top);
 	}
+#endif
 }
 
 void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
-	if (static_cast<SurfaceImpl &>(surfacePattern).drawable) {
+	SurfaceImpl &surfi = static_cast<SurfaceImpl &>(surfacePattern);
+#ifdef USE_CAIRO
+	bool canDraw = surfi.psurf;
+#else
+	bool canDraw = surfi.drawable;
+#endif
+	if (canDraw) {
 		// Tile pattern over rectangle
 		// Currently assumes 8x8 pattern
 		int widthPat = 8;
@@ -989,12 +1190,18 @@ void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
 			int widthx = (xTile + widthPat > rc.right) ? rc.right - xTile : widthPat;
 			for (int yTile = rc.top; yTile < rc.bottom; yTile += heightPat) {
 				int heighty = (yTile + heightPat > rc.bottom) ? rc.bottom - yTile : heightPat;
-				gdk_draw_pixmap(drawable,
+#ifdef USE_CAIRO
+				cairo_set_source_surface(context, surfi.psurf, xTile, yTile);
+				cairo_rectangle(context, xTile, yTile, widthx, heighty);
+				cairo_fill(context);
+#else
+				gdk_draw_drawable(drawable,
 				                gc,
 				                static_cast<SurfaceImpl &>(surfacePattern).drawable,
 				                0, 0,
 				                xTile, yTile,
 				                widthx, heighty);
+#endif
 			}
 		}
 	} else {
@@ -1023,7 +1230,20 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAl
 	}
 }
 
-#if GTK_MAJOR_VERSION >= 2
+#ifdef USE_CAIRO
+
+static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, int radius) {
+	double degrees = M_PI / 180.0;
+
+	cairo_new_sub_path(context);
+	cairo_arc(context, left + width - radius, top + radius, radius, -90 * degrees, 0 * degrees);
+	cairo_arc(context, left + width - radius, top + height - radius, radius, 0 * degrees, 90 * degrees);
+	cairo_arc(context, left + radius, top + height - radius, radius, 90 * degrees, 180 * degrees);
+	cairo_arc(context, left + radius, top + radius, radius, 180 * degrees, 270 * degrees);
+	cairo_close_path(context);
+}
+
+#else
 
 // Plot a point into a guint32 buffer symetrically to all 4 qudrants
 static void AllFour(guint32 *pixels, int stride, int width, int height, int x, int y, guint32 val) {
@@ -1033,32 +1253,6 @@ static void AllFour(guint32 *pixels, int stride, int width, int height, int x, i
 	pixels[(height-1-y)*stride+width-1-x] = val;
 }
 
-static unsigned int GetRValue(unsigned int co) {
-	return (co >> 16) & 0xff;
-}
-
-static unsigned int GetGValue(unsigned int co) {
-	return (co >> 8) & 0xff;
-}
-
-static unsigned int GetBValue(unsigned int co) {
-	return co & 0xff;
-}
-
-#endif
-
-#if GTK_MAJOR_VERSION < 2
-void SurfaceImpl::AlphaRectangle(PRectangle rc, int , ColourAllocated , int , ColourAllocated outline, int , int ) {
-	if (gc && drawable) {
-		// Can't use GdkPixbuf on GTK+ 1.x, so draw an outline rather than use alpha.
-		PenColour(outline);
-		gdk_draw_rectangle(drawable, gc, 0,
-		                   rc.left, rc.top,
-		                   rc.right - rc.left - 1, rc.bottom - rc.top - 1);
-	}
-}
-#else
-
 static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
 	union {
 		guint8 pixVal[4];
@@ -1071,8 +1265,41 @@ static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
 	return converter.val;
 }
 
+#endif
+
+static unsigned int GetRValue(unsigned int co) {
+	return (co >> 16) & 0xff;
+}
+
+static unsigned int GetGValue(unsigned int co) {
+	return (co >> 8) & 0xff;
+}
+
+static unsigned int GetBValue(unsigned int co) {
+	return co & 0xff;
+}
+
 void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
 		ColourAllocated outline, int alphaOutline, int flags) {
+#ifdef USE_CAIRO
+	if (context && rc.Width() > 0) {
+		cairo_set_source_rgba(context,
+			GetRValue(fill.AsLong()) / 255.0,
+			GetGValue(fill.AsLong()) / 255.0,
+			GetBValue(fill.AsLong()) / 255.0,
+			alphaFill / 255.0);
+		PathRoundRectangle(context, rc.left + 1.0, rc.top+1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0, cornerSize);
+		cairo_fill(context);
+
+		cairo_set_source_rgba(context,
+			GetRValue(outline.AsLong()) / 255.0,
+			GetGValue(outline.AsLong()) / 255.0,
+			GetBValue(outline.AsLong()) / 255.0,
+			alphaOutline / 255.0);
+		PathRoundRectangle(context, rc.left +0.5, rc.top+0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1, cornerSize);
+		cairo_stroke(context);
+	}
+#else
 	if (gc && drawable && rc.Width() > 0) {
 		int width = rc.Width();
 		int height = rc.Height();
@@ -1082,9 +1309,9 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated
 		GdkPixbuf *pixalpha = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
 
 		guint32 valEmpty = u32FromRGBA(0,0,0,0);
-		guint32 valFill = u32FromRGBA(GetRValue(fill.AsLong()), 
+		guint32 valFill = u32FromRGBA(GetRValue(fill.AsLong()),
 			GetGValue(fill.AsLong()), GetBValue(fill.AsLong()), alphaFill);
-		guint32 valOutline = u32FromRGBA(GetRValue(outline.AsLong()), 
+		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;
@@ -1112,12 +1339,18 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated
 
 		g_object_unref(pixalpha);
 	}
-}
-
 #endif
+}
 
 void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
 	PenColour(back);
+#ifdef USE_CAIRO
+	cairo_arc(context, (rc.left + rc.right) / 2 + 0.5, (rc.top + rc.bottom) / 2 + 0.5,
+		Platform::Minimum(rc.Width(), rc.Height()) / 2, 0, 2*M_PI);
+	cairo_fill_preserve(context);
+	PenColour(fore);
+	cairo_stroke(context);
+#else
 	gdk_draw_arc(drawable, gc, 1,
 	             rc.left + 1, rc.top + 1,
 	             rc.right - rc.left - 2, rc.bottom - rc.top - 2,
@@ -1129,19 +1362,34 @@ void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated b
 	             rc.left, rc.top,
 	             rc.right - rc.left - 1, rc.bottom - rc.top - 1,
 	             0, 32767);
+#endif
 }
 
 void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
-	if (static_cast<SurfaceImpl &>(surfaceSource).drawable) {
-		gdk_draw_pixmap(drawable,
+	SurfaceImpl &surfi = static_cast<SurfaceImpl &>(surfaceSource);
+#ifdef USE_CAIRO
+	bool canDraw = surfi.psurf;
+#else
+	bool canDraw = surfi.drawable;
+#endif
+	if (canDraw) {
+#ifdef USE_CAIRO
+		cairo_set_source_surface(context, surfi.psurf,
+			rc.left - from.x, rc.top - from.y);
+		cairo_rectangle(context, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
+		cairo_fill(context);
+#else
+		gdk_draw_drawable(drawable,
 		                gc,
 		                static_cast<SurfaceImpl &>(surfaceSource).drawable,
 		                from.x, from.y,
 		                rc.left, rc.top,
 		                rc.right - rc.left, rc.bottom - rc.top);
+#endif
 	}
 }
 
+#ifndef DISABLE_GDK_FONT
 static size_t UTF8Len(char ch) {
 	unsigned char uch = static_cast<unsigned char>(ch);
 	if (uch < 0x80)
@@ -1151,6 +1399,7 @@ static size_t UTF8Len(char ch) {
 	else
 		return 3;
 }
+#endif
 
 char *UTF8FromLatin1(const char *s, int &len) {
 	char *utfForm = new char[len*2+1];
@@ -1169,7 +1418,6 @@ char *UTF8FromLatin1(const char *s, int &len) {
 	return utfForm;
 }
 
-#ifdef USE_PANGO
 static char *UTF8FromIconv(const Converter &conv, const char *s, int &len) {
 	if (conv) {
 		char *utfForm = new char[len*3+1];
@@ -1205,6 +1453,7 @@ static size_t MultiByteLenFromIconv(const Converter &conv, const char *s, size_t
 	return 1;
 }
 
+#ifndef DISABLE_GDK_FONT
 static char *UTF8FromGdkWChar(GdkWChar *wctext, int wclen) {
 	char *utfForm = new char[wclen*3+1];	// Maximum of 3 UTF-8 bytes per character
 	size_t lenU = 0;
@@ -1224,8 +1473,10 @@ static char *UTF8FromGdkWChar(GdkWChar *wctext, int wclen) {
 	utfForm[lenU] = '\0';
 	return utfForm;
 }
+#endif
 
 static char *UTF8FromDBCS(const char *s, int &len) {
+#ifndef DISABLE_GDK_FONT
 	GdkWChar *wctext = new GdkWChar[len + 1];
 	GdkWChar *wcp = wctext;
 	int wclen = gdk_mbstowcs(wcp, s, len);
@@ -1240,6 +1491,9 @@ static char *UTF8FromDBCS(const char *s, int &len) {
 	delete []wctext;
 	len = strlen(utfForm);
 	return utfForm;
+#else
+	return 0;
+#endif
 }
 
 static size_t UTF8CharLength(const char *s) {
@@ -1254,8 +1508,6 @@ static size_t UTF8CharLength(const char *s) {
 	}
 }
 
-#endif
-
 // On GTK+, wchar_t is 4 bytes
 
 const int maxLengthTextRun = 10000;
@@ -1263,9 +1515,12 @@ const int maxLengthTextRun = 10000;
 void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char *s, int len,
                                  ColourAllocated fore) {
 	PenColour(fore);
+#ifdef USE_CAIRO
+	if (context) {
+#else
 	if (gc && drawable) {
+#endif
 		int xText = rc.left;
-#ifdef USE_PANGO
 		if (PFont(font_)->pfd) {
 			char *utfForm = 0;
 			bool useGFree = false;
@@ -1288,12 +1543,20 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
 				pango_layout_set_text(layout, utfForm, len);
 			}
 			pango_layout_set_font_description(layout, PFont(font_)->pfd);
+#ifdef USE_CAIRO
+			pango_cairo_update_layout(context, layout);
+#endif
 #ifdef PANGO_VERSION
 			PangoLayoutLine *pll = pango_layout_get_line_readonly(layout,0);
 #else
 			PangoLayoutLine *pll = pango_layout_get_line(layout,0);
 #endif
+#ifdef USE_CAIRO
+			cairo_move_to(context, xText, ybase);
+			pango_cairo_show_layout_line(context, pll);
+#else
 			gdk_draw_layout_line(drawable, gc, xText, ybase, pll);
+#endif
 			if (useGFree) {
 				g_free(utfForm);
 			} else {
@@ -1301,7 +1564,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
 			}
 			return;
 		}
-#endif
+#ifndef DISABLE_GDK_FONT
 		// Draw text as a series of segments to avoid limitations in X servers
 		const int segmentLength = 1000;
 		bool draw8bit = true;
@@ -1349,6 +1612,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
 				s += lenDraw;
 			}
 		}
+#endif
 	}
 }
 
@@ -1376,8 +1640,6 @@ void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, int ybase, con
 	}
 }
 
-#ifdef USE_PANGO
-
 class ClusterIterator {
 	PangoLayoutIter *iter;
 	PangoRectangle pos;
@@ -1388,8 +1650,8 @@ public:
 	int position;
 	int distance;
 	int curIndex;
-	ClusterIterator(PangoLayout *layout, int len) : lenPositions(len), finished(false), 
-		positionStart(0), position(0), distance(0) {
+	ClusterIterator(PangoLayout *layout, int len) : lenPositions(len), finished(false),
+		positionStart(0), position(0), distance(0), curIndex(0) {
 		iter = pango_layout_get_iter(layout);
 		pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
 	}
@@ -1397,7 +1659,7 @@ public:
 		pango_layout_iter_free(iter);
 	}
 
-	void Next() { 
+	void Next() {
 		positionStart = position;
 		if (pango_layout_iter_next_cluster(iter)) {
 			pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
@@ -1412,12 +1674,8 @@ public:
 	}
 };
 
-#endif
-
 void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) {
 	if (font_.GetID()) {
-		int totalWidth = 0;
-#ifdef USE_PANGO
 		const int lenPositions = len;
 		if (PFont(font_)->pfd) {
 			if (len == 1) {
@@ -1516,7 +1774,8 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
 			}
 			return;
 		}
-#endif
+#ifndef DISABLE_GDK_FONT
+		int totalWidth = 0;
 		GdkFont *gf = PFont(font_)->pfont;
 		bool measure8bit = true;
 		if (et != singleByte) {
@@ -1567,6 +1826,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
 				positions[i] = totalWidth;
 			}
 		}
+#endif
 	} else {
 		// No font so return an ascending range of values
 		for (int i = 0; i < len; i++) {
@@ -1577,7 +1837,6 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
 
 int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
 	if (font_.GetID()) {
-#ifdef USE_PANGO
 		if (PFont(font_)->pfd) {
 			char *utfForm = 0;
 			pango_layout_set_font_description(layout, PFont(font_)->pfd);
@@ -1612,7 +1871,7 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
 			}
 			return PANGO_PIXELS(pos.width);
 		}
-#endif
+#ifndef DISABLE_GDK_FONT
 		if (et == UTF8) {
 			GdkWChar wctext[maxLengthTextRun];
 			size_t wclen = UTF16FromUTF8(s, len, static_cast<wchar_t *>(static_cast<void *>(wctext)),
@@ -1622,6 +1881,9 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
 		} else {
 			return gdk_text_width(PFont(font_)->pfont, s, len);
 		}
+#else
+		return 1;
+#endif
 	} else {
 		return 1;
 	}
@@ -1629,12 +1891,14 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
 
 int SurfaceImpl::WidthChar(Font &font_, char ch) {
 	if (font_.GetID()) {
-#ifdef USE_PANGO
 		if (PFont(font_)->pfd) {
 			return WidthText(font_, &ch, 1);
 		}
-#endif
+#ifndef DISABLE_GDK_FONT
 		return gdk_char_width(PFont(font_)->pfont, ch);
+#else
+		return 1;
+#endif
 	} else {
 		return 1;
 	}
@@ -1663,7 +1927,6 @@ int SurfaceImpl::Ascent(Font &font_) {
 #ifdef FAST_WAY
 	FontMutexLock();
 	int ascent = PFont(font_)->ascent;
-#ifdef USE_PANGO
 	if ((ascent == 0) && (PFont(font_)->pfd)) {
 		PangoFontMetrics *metrics = pango_context_get_metrics(pcontext,
 			PFont(font_)->pfd, pango_context_get_language(pcontext));
@@ -1672,10 +1935,11 @@ int SurfaceImpl::Ascent(Font &font_) {
 		pango_font_metrics_unref(metrics);
 		ascent = PFont(font_)->ascent;
 	}
-#endif
+#ifndef DISABLE_GDK_FONT
 	if ((ascent == 0) && (PFont(font_)->pfont)) {
 		ascent = PFont(font_)->pfont->ascent;
 	}
+#endif
 	if (ascent == 0) {
 		ascent = 1;
 	}
@@ -1700,7 +1964,6 @@ int SurfaceImpl::Descent(Font &font_) {
 		return 1;
 #ifdef FAST_WAY
 
-#ifdef USE_PANGO
 	if (PFont(font_)->pfd) {
 		PangoFontMetrics *metrics = pango_context_get_metrics(pcontext,
 			PFont(font_)->pfd, pango_context_get_language(pcontext));
@@ -1708,9 +1971,12 @@ int SurfaceImpl::Descent(Font &font_) {
 		pango_font_metrics_unref(metrics);
 		return descent;
 	}
-#endif
+#ifndef DISABLE_GDK_FONT
 	return PFont(font_)->pfont->descent;
 #else
+	return 0;
+#endif
+#else
 
 	gint lbearing;
 	gint rbearing;
@@ -1746,9 +2012,14 @@ int SurfaceImpl::SetPalette(Palette *, bool) {
 }
 
 void SurfaceImpl::SetClip(PRectangle rc) {
+#ifdef USE_CAIRO
+	cairo_rectangle(context, rc.left, rc.top, rc.right, rc.bottom);
+	cairo_clip(context);
+#else
 	GdkRectangle area = {rc.left, rc.top,
 	                     rc.right - rc.left, rc.bottom - rc.top};
 	gdk_gc_set_clip_rectangle(gc, &area);
+#endif
 }
 
 void SurfaceImpl::FlushCachedState() {}
@@ -1776,42 +2047,42 @@ void Window::Destroy() {
 }
 
 bool Window::HasFocus() {
-	return GTK_WIDGET_HAS_FOCUS(wid);
+	return IS_WIDGET_FOCUSSED(wid);
 }
 
 PRectangle Window::GetPosition() {
 	// Before any size allocated pretend its 1000 wide so not scrolled
 	PRectangle rc(0, 0, 1000, 1000);
 	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;
+		GtkAllocation allocation;
+#if GTK_CHECK_VERSION(3,0,0)
+		gtk_widget_get_allocation(PWidget(wid), &allocation);
+#else
+		allocation = PWidget(wid)->allocation;
+#endif
+		rc.left = allocation.x;
+		rc.top = allocation.y;
+		if (allocation.width > 20) {
+			rc.right = rc.left + allocation.width;
+			rc.bottom = rc.top + allocation.height;
 		}
 	}
 	return rc;
 }
 
 void Window::SetPosition(PRectangle rc) {
-#if 1
 	GtkAllocation alloc;
 	alloc.x = rc.left;
 	alloc.y = rc.top;
 	alloc.width = rc.Width();
 	alloc.height = rc.Height();
 	gtk_widget_size_allocate(PWidget(wid), &alloc);
-#else
-
-	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.wid)->window, &ox, &oy);
+	gdk_window_get_origin(WindowFromWidget(PWidget(relativeTo.wid)), &ox, &oy);
 	ox += rc.left;
 	if (ox < 0)
 		ox = 0;
@@ -1831,21 +2102,8 @@ void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
 	if (oy + sizey > screenHeight)
 		oy = screenHeight - sizey;
 
-#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;
-	alloc.x = rc.left + ox;
-	alloc.y = rc.top + oy;
-	alloc.width = rc.right - rc.left;
-	alloc.height = rc.bottom - rc.top;
-	gtk_widget_size_allocate(wid, &alloc);
-#endif
 	gtk_widget_set_size_request(PWidget(wid), sizex, sizey);
 }
 
@@ -1910,9 +2168,9 @@ void Window::SetCursor(Cursor curs) {
 		break;
 	}
 
-	if (PWidget(wid)->window)
-		gdk_window_set_cursor(PWidget(wid)->window, gdkCurs);
-	gdk_cursor_destroy(gdkCurs);
+	if (WindowFromWidget(PWidget(wid)))
+		gdk_window_set_cursor(WindowFromWidget(PWidget(wid)), gdkCurs);
+	gdk_cursor_unref(gdkCurs);
 }
 
 void Window::SetTitle(const char *s) {
@@ -1923,12 +2181,11 @@ void Window::SetTitle(const char *s) {
    gdk window coordinates */
 PRectangle Window::GetMonitorRect(Point pt) {
 	gint x_offset, y_offset;
-	pt = pt;
 
-	gdk_window_get_origin(PWidget(wid)->window, &x_offset, &y_offset);
+	gdk_window_get_origin(WindowFromWidget(PWidget(wid)), &x_offset, &y_offset);
 
-// gtk 2.2+
-#if GTK_MAJOR_VERSION > 2 || (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 2)
+#if GTK_CHECK_VERSION(2,2,0)
+	// GTK+ 2.2+
 	{
 		GdkScreen* screen;
 		gint monitor_num;
@@ -1942,6 +2199,7 @@ PRectangle Window::GetMonitorRect(Point pt) {
 		return PRectangle(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
 	}
 #else
+	pt = pt;
 	return PRectangle(-x_offset, -y_offset, (-x_offset) + gdk_screen_width(),
 	                  (-y_offset) + gdk_screen_height());
 #endif
@@ -1949,25 +2207,13 @@ PRectangle Window::GetMonitorRect(Point pt) {
 
 struct ListImage {
 	const char *xpm_data;
-#if GTK_MAJOR_VERSION < 2
-	GdkPixmap *pixmap;
-	GdkBitmap *bitmap;
-#else
 	GdkPixbuf *pixbuf;
-#endif
 };
 
 static void list_image_free(gpointer, gpointer value, gpointer) {
 	ListImage *list_image = (ListImage *) value;
-#if GTK_MAJOR_VERSION < 2
-	if (list_image->pixmap)
-		gdk_pixmap_unref(list_image->pixmap);
-	if (list_image->bitmap)
-		gdk_bitmap_unref(list_image->bitmap);
-#else
 	if (list_image->pixbuf)
-		g_object_unref (list_image->pixbuf);
-#endif
+		g_object_unref(list_image->pixbuf);
 	g_free(list_image);
 }
 
@@ -1977,24 +2223,17 @@ ListBox::ListBox() {
 ListBox::~ListBox() {
 }
 
-#if GTK_MAJOR_VERSION >= 2
 enum {
 	PIXBUF_COLUMN,
 	TEXT_COLUMN,
 	N_COLUMNS
 };
-#endif
 
 class ListBoxX : public ListBox {
 	WindowID list;
 	WindowID scroller;
-#if GTK_MAJOR_VERSION < 2
-	int current;
-#endif
 	void *pixhash;
-#if GTK_MAJOR_VERSION >= 2
-        GtkCellRenderer* pixbuf_renderer;
-#endif
+	GtkCellRenderer* pixbuf_renderer;
 	XPMSet xset;
 	int desiredVisibleRows;
 	unsigned int maxItemCharacters;
@@ -2003,15 +2242,9 @@ public:
 	CallBackAction doubleClickAction;
 	void *doubleClickActionData;
 
-	ListBoxX() : list(0), pixhash(NULL),
+	ListBoxX() : list(0), scroller(0), pixhash(NULL), pixbuf_renderer(0),
 		desiredVisibleRows(5), maxItemCharacters(0),
 		aveCharWidth(1), doubleClickAction(NULL), doubleClickActionData(NULL) {
-#if GTK_MAJOR_VERSION < 2
-			current = 0;
-#endif
-#if GTK_MAJOR_VERSION >= 2
-			pixbuf_renderer = 0;
-#endif
 	}
 	virtual ~ListBoxX() {
 		if (pixhash) {
@@ -2047,19 +2280,6 @@ ListBox *ListBox::Allocate() {
 	return lb;
 }
 
-#if GTK_MAJOR_VERSION < 2
-static void UnselectionAC(GtkWidget *, gint, gint,
-                        GdkEventButton *, gpointer p) {
-	int *pi = reinterpret_cast<int *>(p);
-	*pi = -1;
-}
-static void SelectionAC(GtkWidget *, gint row, gint,
-                        GdkEventButton *, gpointer p) {
-	int *pi = reinterpret_cast<int *>(p);
-	*pi = row;
-}
-#endif
-
 static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) {
 	try {
 		ListBoxX* lb = reinterpret_cast<ListBoxX*>(p);
@@ -2074,30 +2294,51 @@ static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) {
 	return FALSE;
 }
 
-#if GTK_MAJOR_VERSION >= 2
 /* Change the active color to the selected color so the listbox uses the color
 scheme that it would use if it had the focus. */
 static void StyleSet(GtkWidget *w, GtkStyle*, void*) {
-	GtkStyle* style;
 
 	g_return_if_fail(w != NULL);
 
 	/* Copy the selected color to active.  Note that the modify calls will cause
 	recursive calls to this function after the value is updated and w->style to
 	be set to a new object */
-	style = gtk_widget_get_style(w);
+
+#if GTK_CHECK_VERSION(3,0,0)
+	GtkStyleContext *styleContext = gtk_widget_get_style_context(w);
+	if (styleContext == NULL)
+		return;
+
+	GdkRGBA colourForeSelected;
+	gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourForeSelected);
+	GdkRGBA colourForeActive;
+	gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourForeActive);
+	if (!gdk_rgba_equal(&colourForeSelected, &colourForeActive))
+		gtk_widget_override_color(w, GTK_STATE_FLAG_ACTIVE, &colourForeSelected);
+
+	styleContext = gtk_widget_get_style_context(w);
+	if (styleContext == NULL)
+		return;
+
+	GdkRGBA colourBaseSelected;
+	gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourBaseSelected);
+	GdkRGBA colourBaseActive;
+	gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourBaseActive);
+	if (!gdk_rgba_equal(&colourBaseSelected, &colourBaseActive))
+		gtk_widget_override_background_color(w, GTK_STATE_FLAG_ACTIVE, &colourBaseSelected);
+#else
+	GtkStyle *style = gtk_widget_get_style(w);
 	if (style == NULL)
 		return;
 	if (!gdk_color_equal(&style->base[GTK_STATE_SELECTED], &style->base[GTK_STATE_ACTIVE]))
 		gtk_widget_modify_base(w, GTK_STATE_ACTIVE, &style->base[GTK_STATE_SELECTED]);
-
 	style = gtk_widget_get_style(w);
 	if (style == NULL)
 		return;
 	if (!gdk_color_equal(&style->text[GTK_STATE_SELECTED], &style->text[GTK_STATE_ACTIVE]))
 		gtk_widget_modify_text(w, GTK_STATE_ACTIVE, &style->text[GTK_STATE_SELECTED]);
-}
 #endif
+}
 
 void ListBoxX::Create(Window &, int, Point, int, bool) {
 	wid = gtk_window_new(GTK_WINDOW_POPUP);
@@ -2115,21 +2356,6 @@ void ListBoxX::Create(Window &, int, Point, int, bool) {
 	gtk_container_add(GTK_CONTAINER(frame), PWidget(scroller));
 	gtk_widget_show(PWidget(scroller));
 
-#if GTK_MAJOR_VERSION < 2
-	list = gtk_clist_new(1);
-	GtkWidget *wid = PWidget(list);	// No code inside the GTK_OBJECT macro
-	gtk_widget_show(wid);
-	gtk_container_add(GTK_CONTAINER(PWidget(scroller)), wid);
-	gtk_clist_set_column_auto_resize(GTK_CLIST(wid), 0, TRUE);
-	gtk_clist_set_selection_mode(GTK_CLIST(wid), GTK_SELECTION_BROWSE);
-	gtk_signal_connect(GTK_OBJECT(wid), "unselect_row",
-	                   GTK_SIGNAL_FUNC(UnselectionAC), &current);
-	gtk_signal_connect(GTK_OBJECT(wid), "select_row",
-	                   GTK_SIGNAL_FUNC(SelectionAC), &current);
-	gtk_signal_connect(GTK_OBJECT(wid), "button_press_event",
-	                   GTK_SIGNAL_FUNC(ButtonPress), this);
-	gtk_clist_set_shadow_type(GTK_CLIST(wid), GTK_SHADOW_NONE);
-#else
 	/* Tree and its model */
 	GtkListStore *store =
 		gtk_list_store_new(N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING);
@@ -2153,7 +2379,7 @@ void ListBoxX::Create(Window &, int, Point, int, bool) {
 	gtk_tree_view_column_pack_start(column, pixbuf_renderer, FALSE);
 	gtk_tree_view_column_add_attribute(column, pixbuf_renderer,
 										"pixbuf", PIXBUF_COLUMN);
-	
+
 	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);
@@ -2169,28 +2395,19 @@ void ListBoxX::Create(Window &, int, Point, int, bool) {
 	gtk_widget_show(wid);
 	g_signal_connect(G_OBJECT(wid), "button_press_event",
 	                   G_CALLBACK(ButtonPress), this);
-#endif
 	gtk_widget_realize(PWidget(wid));
 }
 
 void ListBoxX::SetFont(Font &scint_font) {
-#if GTK_MAJOR_VERSION < 2
-	GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(PWidget(list)));
-	if (!gdk_font_equal(style->font, PFont(scint_font)->pfont)) {
-		style = gtk_style_copy(style);
-		gdk_font_unref(style->font);
-		style->font = PFont(scint_font)->pfont;
-		gdk_font_ref(style->font);
-		gtk_widget_set_style(GTK_WIDGET(PWidget(list)), style);
-		gtk_style_unref(style);
-	}
-#else
 	// Only do for Pango font as there have been crashes for GDK fonts
 	if (Created() && PFont(scint_font)->pfd) {
 		// Current font is Pango font
+#if GTK_CHECK_VERSION(3,0,0)
+		gtk_widget_override_font(PWidget(list), PFont(scint_font)->pfd);
+#else
 		gtk_widget_modify_font(PWidget(list), PFont(scint_font)->pfd);
-	}
 #endif
+	}
 }
 
 void ListBoxX::SetAverageCharWidth(int width) {
@@ -2218,13 +2435,6 @@ PRectangle ListBoxX::GetDesiredRect() {
 
 		// First calculate height of the clist for our desired visible
 		// row count otherwise it tries to expand to the total # of rows
-#if GTK_MAJOR_VERSION < 2
-		int ythickness = PWidget(list)->style->klass->ythickness;
-		height = (rows * GTK_CLIST(list)->row_height
-		          + rows + 1
-		          + 2 * (ythickness
-		                 + GTK_CONTAINER(PWidget(list))->border_width));
-#else
 		// Get cell height
 		int row_width=0;
 		int row_height=0;
@@ -2232,6 +2442,14 @@ PRectangle ListBoxX::GetDesiredRect() {
 			gtk_tree_view_get_column(GTK_TREE_VIEW(list), 0);
 		gtk_tree_view_column_cell_get_size(column, NULL,
 			NULL, NULL, &row_width, &row_height);
+#if GTK_CHECK_VERSION(3,0,0)
+		GtkStyleContext *styleContextList = gtk_widget_get_style_context(PWidget(list));
+		GtkBorder padding;
+		gtk_style_context_get_padding(styleContextList, GTK_STATE_FLAG_NORMAL, &padding);
+		height = (rows * row_height
+		          + padding.top + padding.bottom
+		          + 2 * (gtk_container_get_border_width(GTK_CONTAINER(PWidget(list))) + 1));
+#else
 		int ythickness = PWidget(list)->style->ythickness;
 		height = (rows * row_height
 		          + 2 * (ythickness
@@ -2240,7 +2458,11 @@ PRectangle ListBoxX::GetDesiredRect() {
 		gtk_widget_set_size_request(GTK_WIDGET(PWidget(list)), -1, height);
 
 		// Get the size of the scroller because we set usize on the window
+#if GTK_CHECK_VERSION(3,0,0)
+		gtk_widget_get_preferred_size(GTK_WIDGET(scroller), NULL, &req);
+#else
 		gtk_widget_size_request(GTK_WIDGET(scroller), &req);
+#endif
 		rc.right = req.width;
 		rc.bottom = req.height;
 
@@ -2256,30 +2478,19 @@ 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();
 }
 
 void ListBoxX::Clear() {
-#if GTK_MAJOR_VERSION < 2
-	gtk_clist_clear(GTK_CLIST(list));
-#else
 	GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list));
 	gtk_list_store_clear(GTK_LIST_STORE(model));
-#endif
 	maxItemCharacters = 0;
 }
 
-#if GTK_MAJOR_VERSION < 2
-static void init_pixmap(ListImage *list_image, GtkWidget *window) {
-#else
 static void init_pixmap(ListImage *list_image) {
-#endif
 	const char *textForm = list_image->xpm_data;
 	const char * const * xpm_lineform = reinterpret_cast<const char * const *>(textForm);
 	const char **xpm_lineformfromtext = 0;
@@ -2294,28 +2505,10 @@ static void init_pixmap(ListImage *list_image) {
 	}
 
 	// Drop any existing pixmap/bitmap as data may have changed
-#if GTK_MAJOR_VERSION < 2
-	if (list_image->pixmap)
-		gdk_pixmap_unref(list_image->pixmap);
-	list_image->pixmap = NULL;
-	if (list_image->bitmap)
-		gdk_bitmap_unref(list_image->bitmap);
-	list_image->bitmap = NULL;
-
-	list_image->pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL
-	             , gtk_widget_get_colormap(window), &(list_image->bitmap), NULL
-	             , (gchar **) xpm_lineform);
-	if (NULL == list_image->pixmap) {
-		if (list_image->bitmap)
-			gdk_bitmap_unref(list_image->bitmap);
-		list_image->bitmap = NULL;
-	}
-#else
 	if (list_image->pixbuf)
 		g_object_unref(list_image->pixbuf);
 	list_image->pixbuf =
 		gdk_pixbuf_new_from_xpm_data((const gchar**)xpm_lineform);
-#endif
 	delete []xpm_lineformfromtext;
 }
 
@@ -2327,16 +2520,6 @@ void ListBoxX::Append(char *s, int type) {
 		list_image = (ListImage *) g_hash_table_lookup((GHashTable *) pixhash
 		             , (gconstpointer) GINT_TO_POINTER(type));
 	}
-#if GTK_MAJOR_VERSION < 2
-	char * szs[] = { s, NULL };
-	int rownum = gtk_clist_append(GTK_CLIST(list), szs);
-	if (list_image) {
-		if (NULL == list_image->pixmap)
-			init_pixmap(list_image, (GtkWidget *) list);
-		gtk_clist_set_pixtext(GTK_CLIST(list), rownum, 0, s, SPACING
-		                      , list_image->pixmap, list_image->bitmap);
-	}
-#else
 	GtkTreeIter iter;
 	GtkListStore *store =
 		GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list)));
@@ -2351,7 +2534,7 @@ void ListBoxX::Append(char *s, int type) {
 
 			gint pixbuf_width = gdk_pixbuf_get_width(list_image->pixbuf);
 			gint renderer_height, renderer_width;
-			gtk_cell_renderer_get_fixed_size(pixbuf_renderer, 
+			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,
@@ -2364,7 +2547,6 @@ void ListBoxX::Append(char *s, int type) {
 			gtk_list_store_set(GTK_LIST_STORE(store), &iter,
 								TEXT_COLUMN, s, -1);
 	}
-#endif
 	size_t len = strlen(s);
 	if (maxItemCharacters < len)
 		maxItemCharacters = len;
@@ -2372,24 +2554,12 @@ void ListBoxX::Append(char *s, int type) {
 
 int ListBoxX::Length() {
 	if (wid)
-#if GTK_MAJOR_VERSION < 2
-		return GTK_CLIST(list)->rows;
-#else
 		return gtk_tree_model_iter_n_children(gtk_tree_view_get_model
 											   (GTK_TREE_VIEW(list)), NULL);
-#endif
 	return 0;
 }
 
 void ListBoxX::Select(int n) {
-#if GTK_MAJOR_VERSION < 2
-	if (n == -1) {
-		gtk_clist_unselect_row(GTK_CLIST(list), current, 0);
-	} else {
-		gtk_clist_select_row(GTK_CLIST(list), n, 0);
-		gtk_clist_moveto(GTK_CLIST(list), n, 0, 0.5, 0.5);
-	}
-#else
 	GtkTreeIter iter;
 	GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list));
 	GtkTreeSelection *selection =
@@ -2406,11 +2576,17 @@ void ListBoxX::Select(int n) {
 
 		// Move the scrollbar to show the selection.
 		int total = Length();
+#if GTK_CHECK_VERSION(3,0,0)
+		GtkAdjustment *adj =
+			gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list));
+		gfloat value = ((gfloat)n / total) * (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj))
+							+ gtk_adjustment_get_lower(adj) - gtk_adjustment_get_page_size(adj) / 2;
+#else
 		GtkAdjustment *adj =
 			gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(list));
 		gfloat value = ((gfloat)n / total) * (adj->upper - adj->lower)
 							+ adj->lower - adj->page_size / 2;
-
+#endif
 		// Get cell height
 		int row_width;
 		int row_height;
@@ -2429,21 +2605,22 @@ void ListBoxX::Select(int n) {
 		}
 		// Clamp it.
 		value = (value < 0)? 0 : value;
+#if GTK_CHECK_VERSION(3,0,0)
+		value = (value > (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)))?
+					(gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)) : value;
+#else
 		value = (value > (adj->upper - adj->page_size))?
 					(adj->upper - adj->page_size) : value;
+#endif
 
 		// Set it.
 		gtk_adjustment_set_value(adj, value);
 	} else {
 		gtk_tree_selection_unselect_all(selection);
 	}
-#endif
 }
 
 int ListBoxX::GetSelection() {
-#if GTK_MAJOR_VERSION < 2
-	return current;
-#else
 	GtkTreeIter iter;
 	GtkTreeModel *model;
 	GtkTreeSelection *selection;
@@ -2456,20 +2633,9 @@ int ListBoxX::GetSelection() {
 			return indices[0];
 	}
 	return -1;
-#endif
 }
 
 int ListBoxX::Find(const char *prefix) {
-#if GTK_MAJOR_VERSION < 2
-	int count = Length();
-	for (int i = 0; i < count; i++) {
-		char *s = 0;
-		gtk_clist_get_text(GTK_CLIST(list), i, 0, &s);
-		if (s && (0 == strncmp(prefix, s, strlen(prefix)))) {
-			return i;
-		}
-	}
-#else
 	GtkTreeIter iter;
 	GtkTreeModel *model =
 		gtk_tree_view_get_model(GTK_TREE_VIEW(list));
@@ -2479,43 +2645,31 @@ int ListBoxX::Find(const char *prefix) {
 		gchar *s;
 		gtk_tree_model_get(model, &iter, TEXT_COLUMN, &s, -1);
 		if (s && (0 == strncmp(prefix, s, strlen(prefix)))) {
+			g_free(s);
 			return i;
 		}
+		g_free(s);
 		valid = gtk_tree_model_iter_next(model, &iter) != FALSE;
 		i++;
 	}
-#endif
 	return -1;
 }
 
 void ListBoxX::GetValue(int n, char *value, int len) {
 	char *text = NULL;
-#if GTK_MAJOR_VERSION < 2
-	GtkCellType type = gtk_clist_get_cell_type(GTK_CLIST(list), n, 0);
-	switch (type) {
-	case GTK_CELL_TEXT:
-		gtk_clist_get_text(GTK_CLIST(list), n, 0, &text);
-		break;
-	case GTK_CELL_PIXTEXT:
-		gtk_clist_get_pixtext(GTK_CLIST(list), n, 0, &text, NULL, NULL, NULL);
-		break;
-	default:
-		break;
-	}
-#else
 	GtkTreeIter iter;
 	GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list));
 	bool valid = gtk_tree_model_iter_nth_child(model, &iter, NULL, n) != FALSE;
 	if (valid) {
 		gtk_tree_model_get(model, &iter, TEXT_COLUMN, &text, -1);
 	}
-#endif
 	if (text && len > 0) {
 		strncpy(value, text, len);
 		value[len - 1] = '\0';
 	} else {
 		value[0] = '\0';
 	}
+	g_free(text);
 }
 
 // g_return_if_fail causes unnecessary compiler warning in release compile.
@@ -2538,18 +2692,9 @@ void ListBoxX::RegisterImage(int type, const char *xpm_data) {
 		(gconstpointer) GINT_TO_POINTER(type));
 	if (list_image) {
 		// Drop icon already registered
-#if GTK_MAJOR_VERSION < 2
-		if (list_image->pixmap)
-			gdk_pixmap_unref(list_image->pixmap);
-		list_image->pixmap = 0;
-		if (list_image->bitmap)
-			gdk_bitmap_unref(list_image->bitmap);
-		list_image->bitmap = 0;
-#else
 		if (list_image->pixbuf)
 			g_object_unref(list_image->pixbuf);
 		list_image->pixbuf = NULL;
-#endif
 		list_image->xpm_data = xpm_data;
 	} else {
 		list_image = g_new0(ListImage, 1);
@@ -2597,39 +2742,47 @@ Menu::Menu() : mid(0) {}
 
 void Menu::CreatePopUp() {
 	Destroy();
-	mid = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
+	mid = gtk_menu_new();
+#if GLIB_CHECK_VERSION(2,10,0)
+	 g_object_ref_sink(G_OBJECT(mid));
+#else
+	g_object_ref(G_OBJECT(mid));
+	gtk_object_sink(GTK_OBJECT(G_OBJECT(mid)));
+#endif
 }
 
 void Menu::Destroy() {
 	if (mid)
-#if GTK_MAJOR_VERSION < 2
-		gtk_object_unref(GTK_OBJECT(mid));
-#else
 		g_object_unref(G_OBJECT(mid));
-#endif
 	mid = 0;
 }
 
+static void  MenuPositionFunc(GtkMenu *, gint *x, gint *y, gboolean *, gpointer userData) {
+	sptr_t intFromPointer = reinterpret_cast<sptr_t>(userData);
+	*x = intFromPointer & 0xffff;
+	*y = intFromPointer >> 16;
+}
+
 void Menu::Show(Point pt, Window &) {
 	int screenHeight = gdk_screen_height();
 	int screenWidth = gdk_screen_width();
-	GtkItemFactory *factory = reinterpret_cast<GtkItemFactory *>(mid);
-	GtkWidget *widget = gtk_item_factory_get_widget(factory, "<main>");
-	gtk_widget_show_all(widget);
+	GtkMenu *widget = reinterpret_cast<GtkMenu *>(mid);
+	gtk_widget_show_all(GTK_WIDGET(widget));
 	GtkRequisition requisition;
-	gtk_widget_size_request(widget, &requisition);
+#if GTK_CHECK_VERSION(3,0,0)
+	gtk_widget_get_preferred_size(GTK_WIDGET(widget), NULL, &requisition);
+#else
+	gtk_widget_size_request(GTK_WIDGET(widget), &requisition);
+#endif
 	if ((pt.x + requisition.width) > screenWidth) {
 		pt.x = screenWidth - requisition.width;
 	}
 	if ((pt.y + requisition.height) > screenHeight) {
 		pt.y = screenHeight - requisition.height;
 	}
-#if GTK_MAJOR_VERSION >= 2
-	gtk_item_factory_popup(factory, pt.x - 4, pt.y - 4, 3,
+	gtk_menu_popup(widget, NULL, NULL, MenuPositionFunc,
+		reinterpret_cast<void *>((pt.y << 16) | pt.x), 0,
 		gtk_get_current_event_time());
-#else
-	gtk_item_factory_popup(factory, pt.x - 4, pt.y - 4, 3, 0);
-#endif
 }
 
 ElapsedTime::ElapsedTime() {
@@ -2701,11 +2854,7 @@ const char *Platform::DefaultFont() {
 #ifdef G_OS_WIN32
 	return "Lucida Console";
 #else
-#ifdef USE_PANGO
 	return "!Sans";
-#else
-	return "lucidatypewriter";
-#endif
 #endif
 }
 
diff --git a/plugins/scintilla/scintilla/PositionCache.cxx b/plugins/scintilla/scintilla/PositionCache.cxx
index 7bb0106..e59c126 100644
--- a/plugins/scintilla/scintilla/PositionCache.cxx
+++ b/plugins/scintilla/scintilla/PositionCache.cxx
@@ -10,6 +10,7 @@
 #include <stdio.h>
 #include <ctype.h>
 
+#include <string>
 #include <vector>
 
 #include "Platform.h"
@@ -29,6 +30,7 @@
 #include "ViewStyle.h"
 #include "CharClassify.h"
 #include "Decoration.h"
+#include "ILexer.h"
 #include "Document.h"
 #include "Selection.h"
 #include "PositionCache.h"
@@ -66,6 +68,8 @@ LineLayout::LineLayout(int maxLineLength_) :
 	widthLine(wrapWidthInfinite),
 	lines(1),
 	wrapIndent(0) {
+	bracePreviousStyles[0] = 0;
+	bracePreviousStyles[1] = 0;
 	Resize(maxLineLength_);
 }
 
@@ -147,15 +151,15 @@ void LineLayout::SetLineStart(int line, int start) {
 }
 
 void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
-                                    char bracesMatchStyle, int xHighlight) {
-	if (rangeLine.ContainsCharacter(braces[0])) {
+                                    char bracesMatchStyle, int xHighlight, bool ignoreStyle) {
+	if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
 		int braceOffset = braces[0] - rangeLine.start;
 		if (braceOffset < numCharsInLine) {
 			bracePreviousStyles[0] = styles[braceOffset];
 			styles[braceOffset] = bracesMatchStyle;
 		}
 	}
-	if (rangeLine.ContainsCharacter(braces[1])) {
+	if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
 		int braceOffset = braces[1] - rangeLine.start;
 		if (braceOffset < numCharsInLine) {
 			bracePreviousStyles[1] = styles[braceOffset];
@@ -168,14 +172,14 @@ void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
 	}
 }
 
-void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[]) {
-	if (rangeLine.ContainsCharacter(braces[0])) {
+void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle) {
+	if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
 		int braceOffset = braces[0] - rangeLine.start;
 		if (braceOffset < numCharsInLine) {
 			styles[braceOffset] = bracePreviousStyles[0];
 		}
 	}
-	if (rangeLine.ContainsCharacter(braces[1])) {
+	if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
 		int braceOffset = braces[1] - rangeLine.start;
 		if (braceOffset < numCharsInLine) {
 			styles[braceOffset] = bracePreviousStyles[1];
@@ -361,7 +365,8 @@ void BreakFinder::Insert(int val) {
 		for (unsigned int j = 0; j<saeLen; j++) {
 			if (val == selAndEdge[j]) {
 				return;
-			} if (val < selAndEdge[j]) {
+			}
+			if (val < selAndEdge[j]) {
 				for (unsigned int k = saeLen; k>j; k--) {
 					selAndEdge[k] = selAndEdge[k-1];
 				}
@@ -386,18 +391,19 @@ static int NextBadU(const char *s, int p, int len, int &trailBytes) {
 	return -1;
 }
 
-BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection) :
+BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
+	int xStart, bool breakForSelection, Document *pdoc_) :
 	ll(ll_),
 	lineStart(lineStart_),
 	lineEnd(lineEnd_),
 	posLineStart(posLineStart_),
-	utf8(utf8_),
 	nextBreak(lineStart_),
 	saeSize(0),
 	saeLen(0),
 	saeCurrentPos(0),
 	saeNext(0),
-	subBreak(-1) {
+	subBreak(-1),
+	pdoc(pdoc_) {
 	saeSize = 8;
 	selAndEdge = new int[saeSize];
 	for (unsigned int j=0; j < saeSize; j++) {
@@ -430,7 +436,7 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL
 	Insert(ll->edgeColumn - 1);
 	Insert(lineEnd - 1);
 
-	if (utf8) {
+	if (pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage)) {
 		int trailBytes=0;
 		for (int pos = -1;;) {
 			pos = NextBadU(ll->chars, pos, lineEnd, trailBytes);
@@ -447,14 +453,10 @@ BreakFinder::~BreakFinder() {
 	delete []selAndEdge;
 }
 
-int BreakFinder::First() {
+int BreakFinder::First() const {
 	return nextBreak;
 }
 
-static bool IsTrailByte(int ch) {
-	return (ch >= 0x80) && (ch < (0x80 + 0x40));
-}
-
 int BreakFinder::Next() {
 	if (subBreak == -1) {
 		int prev = nextBreak;
@@ -485,34 +487,7 @@ int BreakFinder::Next() {
 		subBreak = -1;
 		return nextBreak;
 	} 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 (static_cast<unsigned char>(ll->chars[j]) < 'A') {
-				lastOKBreak = j;
-			}
-			if (utf8 && !IsTrailByte(static_cast<unsigned char>(ll->chars[j]))) {
-				lastUTF8Break = j;
-			}
-			if (((j - subBreak) >= lengthEachSubdivision) &&
-				((lastGoodBreak >= 0) || (lastOKBreak >= 0) || (lastUTF8Break >= 0))) {
-				break;
-			}
-		}
-		if (lastGoodBreak >= 0) {
-			subBreak = lastGoodBreak;
-		} else if (lastOKBreak >= 0) {
-			subBreak = lastOKBreak;
-		} else if (lastUTF8Break >= 0) {
-			subBreak = lastUTF8Break;
-		} else {
-			subBreak = nextBreak;
-		}
+		subBreak += pdoc->SafeSegment(ll->chars + subBreak, nextBreak-subBreak, lengthEachSubdivision);
 		if (subBreak >= nextBreak) {
 			subBreak = -1;
 			return nextBreak;
@@ -534,7 +509,7 @@ void PositionCacheEntry::Set(unsigned int styleNumber_, const char *s_,
 	clock = clock_;
 	if (s_ && positions_) {
 		positions = new short[len + (len + 1) / 2];
-		for (unsigned int i=0;i<len;i++) {
+		for (unsigned int i=0; i<len; i++) {
 			positions[i] = static_cast<short>(positions_[i]);
 		}
 		memcpy(reinterpret_cast<char *>(positions + len), s_, len);
@@ -557,7 +532,7 @@ bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, const char *s_,
 	unsigned int len_, int *positions_) const {
 	if ((styleNumber == styleNumber_) && (len == len_) &&
 		(memcmp(reinterpret_cast<char *>(positions + len), s_, len)== 0)) {
-		for (unsigned int i=0;i<len;i++) {
+		for (unsigned int i=0; i<len; i++) {
 			positions_[i] = positions[i];
 		}
 		return true;
@@ -579,7 +554,7 @@ int PositionCacheEntry::Hash(unsigned int styleNumber, const char *s, unsigned i
 	return ret;
 }
 
-bool PositionCacheEntry::NewerThan(const PositionCacheEntry &other) {
+bool PositionCacheEntry::NewerThan(const PositionCacheEntry &other) const {
 	return clock > other.clock;
 }
 
@@ -603,7 +578,7 @@ PositionCache::~PositionCache() {
 
 void PositionCache::Clear() {
 	if (!allClear) {
-		for (size_t i=0;i<size;i++) {
+		for (size_t i=0; i<size; i++) {
 			pces[i].Clear();
 		}
 	}
@@ -619,7 +594,8 @@ void PositionCache::SetSize(size_t size_) {
 }
 
 void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
-	const char *s, unsigned int len, int *positions) {
+	const char *s, unsigned int len, int *positions, Document *pdoc) {
+
 	allClear = false;
 	int probe = -1;
 	if ((size > 0) && (len < 30)) {
@@ -641,13 +617,28 @@ void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned
 			probe = probe2;
 		}
 	}
-	surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions);
+	if (len > BreakFinder::lengthStartSubdivision) {
+		// Break up into segments
+		unsigned int startSegment = 0;
+		int xStartSegment = 0;
+		while (startSegment < len) {
+			unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision);
+			surface->MeasureWidths(vstyle.styles[styleNumber].font, s + startSegment, lenSegment, positions + startSegment);
+			for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) {
+				positions[startSegment + inSeg] += xStartSegment;
+			}
+			xStartSegment = positions[startSegment + lenSegment - 1];
+			startSegment += lenSegment;
+		}
+	} else {
+		surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions);
+	}
 	if (probe >= 0) {
 		clock++;
 		if (clock > 60000) {
 			// Since there are only 16 bits for the clock, wrap it round and
 			// reset all cache entries so none get stuck with a high clock.
-			for (size_t i=0;i<size;i++) {
+			for (size_t i=0; i<size; i++) {
 				pces[i].ResetClock();
 			}
 			clock = 2;
diff --git a/plugins/scintilla/scintilla/PositionCache.h b/plugins/scintilla/scintilla/PositionCache.h
index e99ae58..6abec6e 100644
--- a/plugins/scintilla/scintilla/PositionCache.h
+++ b/plugins/scintilla/scintilla/PositionCache.h
@@ -63,8 +63,8 @@ public:
 	bool InLine(int offset, int line) const;
 	void SetLineStart(int line, int start);
 	void SetBracesHighlight(Range rangeLine, Position braces[],
-		char bracesMatchStyle, int xHighlight);
-	void RestoreBracesHighlight(Range rangeLine, Position braces[]);
+		char bracesMatchStyle, int xHighlight, bool ignoreStyle);
+	void RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle);
 	int FindBefore(int x, int lower, int upper) const;
 	int EndLineStyle() const;
 };
@@ -93,7 +93,7 @@ public:
 	};
 	void Invalidate(LineLayout::validLevel validity_);
 	void SetLevel(int level_);
-	int GetLevel() { return level; }
+	int GetLevel() const { return level; }
 	LineLayout *Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_,
 		int linesOnScreen, int linesInDoc);
 	void Dispose(LineLayout *ll);
@@ -111,22 +111,16 @@ public:
 	void Clear();
 	bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, int *positions_) const;
 	static int Hash(unsigned int styleNumber, const char *s, unsigned int len);
-	bool NewerThan(const PositionCacheEntry &other);
+	bool NewerThan(const PositionCacheEntry &other) const;
 	void ResetClock();
 };
 
 // Class to break a line of text into shorter runs at sensible places.
 class BreakFinder {
-	// If a whole run is longer than lengthStartSubdivision then subdivide
-	// into smaller runs at spaces or punctuation.
-	enum { lengthStartSubdivision = 300 };
-	// Try to make each subdivided run lengthEachSubdivision or shorter.
-	enum { lengthEachSubdivision = 100 };
 	LineLayout *ll;
 	int lineStart;
 	int lineEnd;
 	int posLineStart;
-	bool utf8;
 	int nextBreak;
 	int *selAndEdge;
 	unsigned int saeSize;
@@ -134,11 +128,18 @@ class BreakFinder {
 	unsigned int saeCurrentPos;
 	int saeNext;
 	int subBreak;
+	Document *pdoc;
 	void Insert(int val);
 public:
-	BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection);
+	// If a whole run is longer than lengthStartSubdivision then subdivide
+	// into smaller runs at spaces or punctuation.
+	enum { lengthStartSubdivision = 300 };
+	// Try to make each subdivided run lengthEachSubdivision or shorter.
+	enum { lengthEachSubdivision = 100 };
+	BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
+		int xStart, bool breakForSelection, Document *pdoc_);
 	~BreakFinder();
-	int First();
+	int First() const;
 	int Next();
 };
 
@@ -152,9 +153,9 @@ public:
 	~PositionCache();
 	void Clear();
 	void SetSize(size_t size_);
-	int GetSize() { return size; }
+	size_t GetSize() const { return size; }
 	void MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
-		const char *s, unsigned int len, int *positions);
+		const char *s, unsigned int len, int *positions, Document *pdoc);
 };
 
 inline bool IsSpaceOrTab(int ch) {
diff --git a/plugins/scintilla/scintilla/PropSet.cxx b/plugins/scintilla/scintilla/PropSetSimple.cxx
similarity index 88%
rename from plugins/scintilla/scintilla/PropSet.cxx
rename to plugins/scintilla/scintilla/PropSetSimple.cxx
index 9936c39..6942f6e 100644
--- a/plugins/scintilla/scintilla/PropSet.cxx
+++ b/plugins/scintilla/scintilla/PropSetSimple.cxx
@@ -1,8 +1,8 @@
 // SciTE - Scintilla based Text Editor
-/** @file PropSet.cxx
+/** @file PropSetSimple.cxx
  ** A Java style properties file module.
  **/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 // Maintain a dictionary of properties
@@ -19,9 +19,6 @@
 #include <string>
 #include <map>
 
-#include "Platform.h"
-
-#include "PropSet.h"
 #include "PropSetSimple.h"
 
 #ifdef SCI_NAMESPACE
@@ -96,7 +93,7 @@ const char *PropSetSimple::Get(const char *key) const {
 // 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_) {}
+	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)))
@@ -151,18 +148,14 @@ char *PropSetSimple::Expanded(const char *key) const {
 	return ret;
 }
 
-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";
+int PropSetSimple::GetExpanded(const char *key, char *result) const {
+	char *val = Expanded(key);
+	const int n = strlen(val);
+	if (result) {
+		strcpy(result, val);
 	}
-	char *ret = new char [sval.size() + 1];
-	strcpy(ret, sval.c_str());
-	return ret;
+	delete []val;
+	return n;	// Not including NUL
 }
 
 int PropSetSimple::GetInt(const char *key, int defaultValue) const {
diff --git a/plugins/scintilla/scintilla/PropSetSimple.h b/plugins/scintilla/scintilla/PropSetSimple.h
index 1674cfb..b798737 100644
--- a/plugins/scintilla/scintilla/PropSetSimple.h
+++ b/plugins/scintilla/scintilla/PropSetSimple.h
@@ -12,7 +12,7 @@
 namespace Scintilla {
 #endif
 
-class PropSetSimple : public PropertyGet {
+class PropSetSimple {
 	void *impl;
 	void Set(const char *keyVal);
 public:
@@ -22,7 +22,7 @@ public:
 	void SetMultiple(const char *);
 	const char *Get(const char *key) const;
 	char *Expanded(const char *key) const;
-	char *ToString() const;
+	int GetExpanded(const char *key, char *result) const;
 	int GetInt(const char *key, int defaultValue=0) const;
 };
 
diff --git a/plugins/scintilla/scintilla/RESearch.cxx b/plugins/scintilla/scintilla/RESearch.cxx
index 0c40045..f26375f 100644
--- a/plugins/scintilla/scintilla/RESearch.cxx
+++ b/plugins/scintilla/scintilla/RESearch.cxx
@@ -17,6 +17,7 @@
  * Put all global/static variables into an object so this code can be
  * used from multiple threads, etc.
  * Some extensions by Philippe Lhoste PhiLho(a)GMX.net
+ * '?' extensions by Michael Mullin masmullin gmail com
  *
  * These routines are the PUBLIC DOMAIN equivalents of regex
  * routines as found in 4.nBSD UN*X, with minor extensions.
@@ -53,7 +54,7 @@
  * Regular Expressions:
  *
  *      [1]     char    matches itself, unless it is a special
- *                      character (metachar): . \ [ ] * + ^ $
+ *                      character (metachar): . \ [ ] * + ? ^ $
  *                      and ( ) if posix option.
  *
  *      [2]     .       matches any character.
@@ -65,12 +66,12 @@
  *                      regex searches are made line per line
  *                      (stripped of end-of-line chars).
  *                      - if not in posix mode, when followed by a
- *                      left or right round bracket (see [7]);
- *                      - when followed by a digit 1 to 9 (see [8]);
+ *                      left or right round bracket (see [8]);
+ *                      - when followed by a digit 1 to 9 (see [9]);
  *                      - when followed by a left or right angle bracket
- *                      (see [9]);
- *                      - when followed by d, D, s, S, w or W (see [10]);
- *                      - when followed by x and two hexa digits (see [11].
+ *                      (see [10]);
+ *                      - when followed by d, D, s, S, w or W (see [11]);
+ *                      - when followed by x and two hexa digits (see [12].
  *                      Backslash is used as an escape character for all
  *                      other meta-characters, and itself.
  *
@@ -101,23 +102,28 @@
  *                              [a-zA-Z] any alpha
  *
  *      [5]     *       any regular expression form [1] to [4]
- *                      (except [7], [8] and [9] forms of [3]),
+ *                      (except [8], [9] and [10] forms of [3]),
  *                      followed by closure char (*)
  *                      matches zero or more matches of that form.
  *
  *      [6]     +       same as [5], except it matches one or more.
- *                      Both [5] and [6] are greedy (they match as much as possible).
  *
- *      [7]             a regular expression in the form [1] to [12], enclosed
+ *      [5-6]           Both [5] and [6] are greedy (they match as much as possible).
+ *                      Unless they are followed by the 'lazy' quantifier (?)
+ *                      In which case both [5] and [6] try to match as little as possible
+ *
+ *      [7]     ?       same as [5] except it matches zero or one.
+ *
+ *      [8]             a regular expression in the form [1] to [13], enclosed
  *                      as \(form\) (or (form) with posix flag) matches what
  *                      form matches. The enclosure creates a set of tags,
- *                      used for [8] and for pattern substitution.
+ *                      used for [9] and for pattern substitution.
  *                      The tagged forms are numbered starting from 1.
  *
- *      [8]             a \ followed by a digit 1 to 9 matches whatever a
- *                      previously tagged regular expression ([7]) matched.
+ *      [9]             a \ followed by a digit 1 to 9 matches whatever a
+ *                      previously tagged regular expression ([8]) matched.
  *
- *      [9]     \<      a regular expression starting with a \< construct
+ *      [10]    \<      a regular expression starting with a \< construct
  *              \>      and/or ending with a \> construct, restricts the
  *                      pattern matching to the beginning of a word, and/or
  *                      the end of a word. A word is defined to be a character
@@ -126,7 +132,7 @@
  *                      by user setting. The word must also be preceded and/or
  *                      followed by any character outside those mentioned.
  *
- *      [10]    \l      a backslash followed by d, D, s, S, w or W,
+ *      [11]    \l      a backslash followed by d, D, s, S, w or W,
  *                      becomes a character class (both inside and
  *                      outside sets []).
  *                        d: decimal digits
@@ -136,16 +142,16 @@
  *                        w: alphanumeric & underscore (changed by user setting)
  *                        W: any char except alphanumeric & underscore (see above)
  *
- *      [11]    \xHH    a backslash followed by x and two hexa digits,
+ *      [12]    \xHH    a backslash followed by x and two hexa digits,
  *                      becomes the character whose Ascii code is equal
  *                      to these digits. If not followed by two digits,
  *                      it is 'x' char itself.
  *
- *      [12]            a composite regular expression xy where x and y
- *                      are in the form [1] to [11] matches the longest
+ *      [13]            a composite regular expression xy where x and y
+ *                      are in the form [1] to [12] matches the longest
  *                      match of x followed by a match for y.
  *
- *      [13]    ^       a regular expression starting with a ^ character
+ *      [14]    ^       a regular expression starting with a ^ character
  *              $       and/or ending with a $ character, restricts the
  *                      pattern matching to the beginning of the line,
  *                      or the end of line. [anchors] Elsewhere in the
@@ -226,6 +232,8 @@ using namespace Scintilla;
 #define EOW     9
 #define REF     10
 #define CLO     11
+#define CLQ     12 /* 0 to 1 closure */
+#define LCLO    13 /* lazy closure */
 
 #define END     0
 
@@ -248,6 +256,7 @@ const char bitarr[] = { 1, 2, 4, 8, 16, 32, 64, '\200' };
  */
 
 RESearch::RESearch(CharClassify *charClassTable) {
+	failure = 0;
 	charClass = charClassTable;
 	Init();
 }
@@ -355,8 +364,8 @@ static int GetHexaChar(unsigned char hd1, unsigned char hd2) {
  * or -1 for a char class. In this case, bittab is changed.
  */
 int RESearch::GetBackslashExpression(
-		const char *pattern,
-		int &incr) {
+    const char *pattern,
+    int &incr) {
 	// Since error reporting is primitive and messages are not used anyway,
 	// I choose to interpret unexpected syntax in a logical way instead
 	// of reporting errors. Otherwise, we can stick on, eg., PCRE behavior.
@@ -521,7 +530,7 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
 						if (*(p+1) != ']') {
 							c1 = prevChar + 1;
 							i++;
-							c2 = *++p;
+							c2 = static_cast<unsigned char>(*++p);
 							if (c2 == '\\') {
 								if (!*(p+1))	// End of RE
 									return badpat("Missing ]");
@@ -576,7 +585,7 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
 						prevChar = -1;
 					}
 				} else {
-					prevChar = *p;
+					prevChar = static_cast<unsigned char>(*p);
 					ChSetWithCase(*p, caseSensitive);
 				}
 				i++;
@@ -592,10 +601,11 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
 
 		case '*':               /* match 0 or more... */
 		case '+':               /* match 1 or more... */
+		case '?':
 			if (p == pattern)
 				return badpat("Empty closure");
 			lp = sp;		/* previous opcode */
-			if (*lp == CLO)		/* equivalence... */
+			if (*lp == CLO || *lp == LCLO)		/* equivalence... */
 				break;
 			switch (*lp) {
 
@@ -617,9 +627,13 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
 			*mp++ = END;
 			*mp++ = END;
 			sp = mp;
+
 			while (--mp > lp)
 				*mp = mp[-1];
-			*mp = CLO;
+			if (*p == '?')          *mp = CLQ;
+			else if (*(p+1) == '?') *mp = LCLO;
+			else                    *mp = CLO;
+
 			mp = sp;
 			break;
 
@@ -844,6 +858,7 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
 	int bp;		/* beginning of subpat... */
 	int ep;		/* ending of subpat...    */
 	int are;	/* to save the line ptr.  */
+	int llp;	/* lazy lp for LCLO       */
 
 	while ((op = *ap++) != END)
 		switch (op) {
@@ -878,7 +893,7 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
 		case EOT:
 			eopat[*ap++] = lp;
 			break;
- 		case BOW:
+		case BOW:
 			if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp)))
 				return NOTFOUND;
 			break;
@@ -894,18 +909,27 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
 				if (ci.CharAt(bp++) != ci.CharAt(lp++))
 					return NOTFOUND;
 			break;
+		case LCLO:
+		case CLQ:
 		case CLO:
 			are = lp;
 			switch (*ap) {
 
 			case ANY:
-				while (lp < endp)
+				if (op == CLO || op == LCLO)
+					while (lp < endp)
+						lp++;
+				else if (lp < endp)
 					lp++;
+
 				n = ANYSKIP;
 				break;
 			case CHR:
 				c = *(ap+1);
-				while ((lp < endp) && (c == ci.CharAt(lp)))
+				if (op == CLO || op == LCLO)
+					while ((lp < endp) && (c == ci.CharAt(lp)))
+						lp++;
+				else if ((lp < endp) && (c == ci.CharAt(lp)))
 					lp++;
 				n = CHRSKIP;
 				break;
@@ -919,15 +943,23 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
 				//re_fail("closure: bad nfa.", *ap);
 				return NOTFOUND;
 			}
-
 			ap += n;
 
-			while (lp >= are) {
-				if ((e = PMatch(ci, lp, endp, ap)) != NOTFOUND)
-					return e;
-				--lp;
+			llp = lp;
+			e = NOTFOUND;
+			while (llp >= are) {
+				int q;
+				if ((q = PMatch(ci, llp, endp, ap)) != NOTFOUND) {
+					e = q;
+					lp = llp;
+					if (op != LCLO) return e;
+				}
+				if (*ap == END) return e;
+				--llp;
 			}
-			return NOTFOUND;
+			if (*ap == EOT)
+				PMatch(ci, lp, endp, ap);
+			return e;
 		default:
 			//re_fail("RESearch::Execute: bad nfa.", static_cast<char>(op));
 			return NOTFOUND;
diff --git a/plugins/scintilla/scintilla/RunStyles.cxx b/plugins/scintilla/scintilla/RunStyles.cxx
index ae32c73..460d5d2 100644
--- a/plugins/scintilla/scintilla/RunStyles.cxx
+++ b/plugins/scintilla/scintilla/RunStyles.cxx
@@ -147,8 +147,10 @@ bool RunStyles::FillRange(int &position, int value, int &fillLength) {
 		runEnd = RunFromPosition(end);
 		RemoveRunIfSameAsPrevious(runEnd);
 		RemoveRunIfSameAsPrevious(runStart);
+		return true;
+	} else {
+		return false;
 	}
-	return true;
 }
 
 void RunStyles::SetValueAt(int position, int value) {
diff --git a/plugins/scintilla/scintilla/SVector.h b/plugins/scintilla/scintilla/SVector.h
index 7b92919..12a7d5d 100644
--- a/plugins/scintilla/scintilla/SVector.h
+++ b/plugins/scintilla/scintilla/SVector.h
@@ -19,19 +19,19 @@ namespace Scintilla {
  */
 class SVector {
 	enum { allocSize = 4000 };
-	
+
 	int *v;				///< The vector
 	unsigned int size;	///< Number of elements allocated
 	unsigned int len;	///< Number of elements used in vector
-	
+
 	/** Internally allocate more elements than the user wants
 	 * to avoid thrashing the memory allocator. */
 	void SizeTo(int newSize) {
 		if (newSize < allocSize)
 			newSize += allocSize;
-		else 
+		else
 			newSize = (newSize * 3) / 2;
-		int* newv = new int[newSize];
+		int *newv = new int[newSize];
 		size = newSize;
         unsigned int i=0;
 		for (; i<len; i++) {
@@ -43,7 +43,7 @@ class SVector {
 		delete []v;
 		v = newv;
 	}
-	
+
 public:
 	SVector() {
 		v = 0;
@@ -60,7 +60,7 @@ public:
 		size = 0;
 		if (other.Length() > 0) {
 			SizeTo(other.Length());
-			for (int i=0;i<other.Length();i++)
+			for (int i=0; i<other.Length(); i++)
 				v[i] = other.v[i];
 			len = other.Length();
 		}
@@ -74,7 +74,7 @@ public:
 			size = 0;
 			if (other.Length() > 0) {
 				SizeTo(other.Length());
-				for (int i=0;i<other.Length();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 8b1a048..3de4a45 100644
--- a/plugins/scintilla/scintilla/ScintillaBase.cxx
+++ b/plugins/scintilla/scintilla/ScintillaBase.cxx
@@ -9,19 +9,21 @@
 #include <string.h>
 #include <stdio.h>
 #include <ctype.h>
+#include <assert.h>
 
+#include <string>
 #include <vector>
 
 #include "Platform.h"
 
+#include "ILexer.h"
 #include "Scintilla.h"
-#include "PropSet.h"
+
 #include "PropSetSimple.h"
 #ifdef SCI_LEXER
 #include "SciLexer.h"
-#include "Accessor.h"
-#include "DocumentAccessor.h"
-#include "KeyWords.h"
+#include "LexerModule.h"
+#include "Catalogue.h"
 #endif
 #include "SplitVector.h"
 #include "Partitioning.h"
@@ -52,21 +54,9 @@ ScintillaBase::ScintillaBase() {
 	displayPopupMenu = true;
 	listType = 0;
 	maxListWidth = 0;
-#ifdef SCI_LEXER
-	lexLanguage = SCLEX_CONTAINER;
-	performingStyle = false;
-	lexCurrent = 0;
-	for (int wl = 0;wl < numWordLists;wl++)
-		keyWordLists[wl] = new WordList;
-	keyWordLists[numWordLists] = 0;
-#endif
 }
 
 ScintillaBase::~ScintillaBase() {
-#ifdef SCI_LEXER
-	for (int wl = 0;wl < numWordLists;wl++)
-		delete keyWordLists[wl];
-#endif
 }
 
 void ScintillaBase::Finalise() {
@@ -145,16 +135,16 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
 			AutoCompleteMove(1);
 			return 0;
 		case SCI_LINEUP:
-			AutoCompleteMove( -1);
+			AutoCompleteMove(-1);
 			return 0;
 		case SCI_PAGEDOWN:
 			AutoCompleteMove(5);
 			return 0;
 		case SCI_PAGEUP:
-			AutoCompleteMove( -5);
+			AutoCompleteMove(-5);
 			return 0;
 		case SCI_VCHOME:
-			AutoCompleteMove( -5000);
+			AutoCompleteMove(-5000);
 			return 0;
 		case SCI_LINEEND:
 			AutoCompleteMove(5000);
@@ -202,8 +192,8 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
 	return Editor::KeyCommand(iMessage);
 }
 
-void ScintillaBase::AutoCompleteDoubleClick(void* p) {
-	ScintillaBase* sci = reinterpret_cast<ScintillaBase*>(p);
+void ScintillaBase::AutoCompleteDoubleClick(void *p) {
+	ScintillaBase *sci = reinterpret_cast<ScintillaBase *>(p);
 	sci->AutoCompleteCompleted();
 }
 
@@ -359,6 +349,7 @@ void ScintillaBase::AutoCompleteCompleted() {
 	scn.wParam = listType;
 	scn.listType = listType;
 	Position firstPos = ac.posStart - ac.startLen;
+	scn.position = firstPos;
 	scn.lParam = firstPos;
 	scn.text = selected;
 	NotifyParent(scn);
@@ -384,6 +375,7 @@ void ScintillaBase::AutoCompleteCompleted() {
 		pdoc->InsertCString(firstPos, selected);
 		SetEmptySelection(firstPos + static_cast<int>(strlen(selected)));
 	}
+	SetLastXChosen();
 }
 
 int ScintillaBase::AutoCompleteGetCurrent() {
@@ -476,76 +468,194 @@ void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool
 }
 
 #ifdef SCI_LEXER
-void ScintillaBase::SetLexer(uptr_t wParam) {
-	lexLanguage = wParam;
-	lexCurrent = LexerModule::Find(lexLanguage);
-	if (!lexCurrent)
-		lexCurrent = LexerModule::Find(SCLEX_NULL);
-	int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
-	vs.EnsureStyle((1 << bits) - 1);
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class LexState : public LexInterface {
+	const LexerModule *lexCurrent;
+	void SetLexerModule(const LexerModule *lex);
+	PropSetSimple props;
+public:
+	int lexLanguage;
+
+	LexState(Document *pdoc_);
+	virtual ~LexState();
+	void SetLexer(uptr_t wParam);
+	void SetLexerLanguage(const char *languageName);
+	const char *DescribeWordListSets();
+	void SetWordList(int n, const char *wl);
+	int GetStyleBitsNeeded() const;
+	const char *GetName() const;
+	void *PrivateCall(int operation, void *pointer);
+	const char *PropertyNames();
+	int PropertyType(const char *name);
+	const char *DescribeProperty(const char *name);
+	void PropSet(const char *key, const char *val);
+	const char *PropGet(const char *key) const;
+	int PropGetInt(const char *key, int defaultValue=0) const;
+	int PropGetExpanded(const char *key, char *result) const;
+};
+
+#ifdef SCI_NAMESPACE
 }
+#endif
 
-void ScintillaBase::SetLexerLanguage(const char *languageName) {
+LexState::LexState(Document *pdoc_) : LexInterface(pdoc_) {
+	lexCurrent = 0;
+	performingStyle = false;
 	lexLanguage = SCLEX_CONTAINER;
-	lexCurrent = LexerModule::Find(languageName);
-	if (!lexCurrent)
-		lexCurrent = LexerModule::Find(SCLEX_NULL);
-	if (lexCurrent)
-		lexLanguage = lexCurrent->GetLanguage();
-	int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
-	vs.EnsureStyle((1 << bits) - 1);
 }
 
-void ScintillaBase::Colourise(int start, int end) {
-	if (!performingStyle) {
-		// Protect against reentrance, which may occur, for example, when
-		// fold points are discovered while performing styling and the folding
-		// code looks for child lines which may trigger styling.
-		performingStyle = true;
+LexState::~LexState() {
+	if (instance) {
+		instance->Release();
+		instance = 0;
+	}
+}
 
-		int lengthDoc = pdoc->Length();
-		if (end == -1)
-			end = lengthDoc;
-		int len = end - start;
+LexState *ScintillaBase::DocumentLexState() {
+	if (!pdoc->pli) {
+		pdoc->pli = new LexState(pdoc);
+	}
+	return static_cast<LexState *>(pdoc->pli);
+}
+
+void LexState::SetLexerModule(const LexerModule *lex) {
+	if (lex != lexCurrent) {
+		if (instance) {
+			instance->Release();
+			instance = 0;
+		}
+		lexCurrent = lex;
+		if (lexCurrent)
+			instance = lexCurrent->Create();
+		pdoc->LexerChanged();
+	}
+}
 
-		PLATFORM_ASSERT(len >= 0);
-		PLATFORM_ASSERT(start + len <= lengthDoc);
+void LexState::SetLexer(uptr_t wParam) {
+	lexLanguage = wParam;
+	if (lexLanguage == SCLEX_CONTAINER) {
+		SetLexerModule(0);
+	} else {
+		const LexerModule *lex = Catalogue::Find(lexLanguage);
+		if (!lex)
+			lex = Catalogue::Find(SCLEX_NULL);
+		SetLexerModule(lex);
+	}
+}
 
-		//WindowAccessor styler(wMain.GetID(), props);
-		DocumentAccessor styler(pdoc, props, wMain.GetID());
+void LexState::SetLexerLanguage(const char *languageName) {
+	const LexerModule *lex = Catalogue::Find(languageName);
+	if (!lex)
+		lex = Catalogue::Find(SCLEX_NULL);
+	if (lex)
+		lexLanguage = lex->GetLanguage();
+	SetLexerModule(lex);
+}
 
-		int styleStart = 0;
-		if (start > 0)
-			styleStart = styler.StyleAt(start - 1) & pdoc->stylingBitsMask;
-		styler.SetCodePage(pdoc->dbcsCodePage);
+const char *LexState::DescribeWordListSets() {
+	if (instance) {
+		return instance->DescribeWordListSets();
+	} else {
+		return 0;
+	}
+}
 
-		if (lexCurrent && (len > 0)) {	// Should always succeed as null lexer should always be available
-			lexCurrent->Lex(start, len, styleStart, keyWordLists, styler);
-			styler.Flush();
-			if (styler.GetPropertyInt("fold")) {
-				lexCurrent->Fold(start, len, styleStart, keyWordLists, styler);
-				styler.Flush();
-			}
+void LexState::SetWordList(int n, const char *wl) {
+	if (instance) {
+		int firstModification = instance->WordListSet(n, wl);
+		if (firstModification >= 0) {
+			pdoc->ModifiedAt(firstModification);
 		}
+	}
+}
+
+int LexState::GetStyleBitsNeeded() const {
+	return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
+}
 
-		performingStyle = false;
+const char *LexState::GetName() const {
+	return lexCurrent ? lexCurrent->languageName : "";
+}
+
+void *LexState::PrivateCall(int operation, void *pointer) {
+	if (pdoc && instance) {
+		return instance->PrivateCall(operation, pointer);
+	} else {
+		return 0;
+	}
+}
+
+const char *LexState::PropertyNames() {
+	if (instance) {
+		return instance->PropertyNames();
+	} else {
+		return 0;
+	}
+}
+
+int LexState::PropertyType(const char *name) {
+	if (instance) {
+		return instance->PropertyType(name);
+	} else {
+		return SC_TYPE_BOOLEAN;
+	}
+}
+
+const char *LexState::DescribeProperty(const char *name) {
+	if (instance) {
+		return instance->DescribeProperty(name);
+	} else {
+		return 0;
 	}
 }
+
+void LexState::PropSet(const char *key, const char *val) {
+	props.Set(key, val);
+	if (instance) {
+		int firstModification = instance->PropertySet(key, val);
+		if (firstModification >= 0) {
+			pdoc->ModifiedAt(firstModification);
+		}
+	}
+}
+
+const char *LexState::PropGet(const char *key) const {
+	return props.Get(key);
+}
+
+int LexState::PropGetInt(const char *key, int defaultValue) const {
+	return props.GetInt(key, defaultValue);
+}
+
+int LexState::PropGetExpanded(const char *key, char *result) const {
+	return props.GetExpanded(key, result);
+}
+
 #endif
 
 void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) {
 #ifdef SCI_LEXER
-	if (lexLanguage != SCLEX_CONTAINER) {
-		int endStyled = WndProc(SCI_GETENDSTYLED, 0, 0);
-		int lineEndStyled = WndProc(SCI_LINEFROMPOSITION, endStyled, 0);
-		endStyled = WndProc(SCI_POSITIONFROMLINE, lineEndStyled, 0);
-		Colourise(endStyled, endStyleNeeded);
+	if (DocumentLexState()->lexLanguage != SCLEX_CONTAINER) {
+		int lineEndStyled = pdoc->LineFromPosition(pdoc->GetEndStyled());
+		int endStyled = pdoc->LineStart(lineEndStyled);
+		DocumentLexState()->Colourise(endStyled, endStyleNeeded);
 		return;
 	}
 #endif
 	Editor::NotifyStyleToNeeded(endStyleNeeded);
 }
 
+void ScintillaBase::NotifyLexerChanged(Document *, void *) {
+#ifdef SCI_LEXER
+	int bits = DocumentLexState()->GetStyleBitsNeeded();
+	vs.EnsureStyle((1 << bits) - 1);
+#endif
+}
+
 sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	switch (iMessage) {
 	case SCI_AUTOCSHOW:
@@ -708,61 +818,66 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
 
 #ifdef SCI_LEXER
 	case SCI_SETLEXER:
-		SetLexer(wParam);
-		lexLanguage = wParam;
+		DocumentLexState()->SetLexer(wParam);
 		break;
 
 	case SCI_GETLEXER:
-		return lexLanguage;
+		return DocumentLexState()->lexLanguage;
 
 	case SCI_COLOURISE:
-		if (lexLanguage == SCLEX_CONTAINER) {
+		if (DocumentLexState()->lexLanguage == SCLEX_CONTAINER) {
 			pdoc->ModifiedAt(wParam);
 			NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : lParam);
 		} else {
-			Colourise(wParam, lParam);
+			DocumentLexState()->Colourise(wParam, lParam);
 		}
 		Redraw();
 		break;
 
 	case SCI_SETPROPERTY:
-		props.Set(reinterpret_cast<const char *>(wParam),
+		DocumentLexState()->PropSet(reinterpret_cast<const char *>(wParam),
 		          reinterpret_cast<const char *>(lParam));
 		break;
 
 	case SCI_GETPROPERTY:
-			return StringResult(lParam, props.Get(reinterpret_cast<const char *>(wParam)));
-
-	case SCI_GETPROPERTYEXPANDED: {
-			char *val = props.Expanded(reinterpret_cast<const char *>(wParam));
-			const int n = strlen(val);
-			if (lParam != 0) {
-				char *ptr = reinterpret_cast<char *>(lParam);
-				strcpy(ptr, val);
-			}
-			delete []val;
-			return n;	// Not including NUL
-		}
+		return StringResult(lParam, DocumentLexState()->PropGet(reinterpret_cast<const char *>(wParam)));
+
+	case SCI_GETPROPERTYEXPANDED:
+		return DocumentLexState()->PropGetExpanded(reinterpret_cast<const char *>(wParam),
+			reinterpret_cast<char *>(lParam));
 
 	case SCI_GETPROPERTYINT:
-		return props.GetInt(reinterpret_cast<const char *>(wParam), lParam);
+		return DocumentLexState()->PropGetInt(reinterpret_cast<const char *>(wParam), lParam);
 
 	case SCI_SETKEYWORDS:
-		if (wParam < numWordLists) {
-			keyWordLists[wParam]->Clear();
-			keyWordLists[wParam]->Set(reinterpret_cast<const char *>(lParam));
-		}
+		DocumentLexState()->SetWordList(wParam, reinterpret_cast<const char *>(lParam));
 		break;
 
 	case SCI_SETLEXERLANGUAGE:
-		SetLexerLanguage(reinterpret_cast<const char *>(lParam));
+		DocumentLexState()->SetLexerLanguage(reinterpret_cast<const char *>(lParam));
 		break;
 
 	case SCI_GETLEXERLANGUAGE:
-		return StringResult(lParam, lexCurrent ? lexCurrent->languageName : "");
+		return StringResult(lParam, DocumentLexState()->GetName());
+
+	case SCI_PRIVATELEXERCALL:
+		return reinterpret_cast<sptr_t>(
+			DocumentLexState()->PrivateCall(wParam, reinterpret_cast<void *>(lParam)));
 
 	case SCI_GETSTYLEBITSNEEDED:
-		return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
+		return DocumentLexState()->GetStyleBitsNeeded();
+
+	case SCI_PROPERTYNAMES:
+		return StringResult(lParam, DocumentLexState()->PropertyNames());
+
+	case SCI_PROPERTYTYPE:
+		return DocumentLexState()->PropertyType(reinterpret_cast<const char *>(wParam));
+
+	case SCI_DESCRIBEPROPERTY:
+		return StringResult(lParam, DocumentLexState()->DescribeProperty(reinterpret_cast<const char *>(wParam)));
+
+	case SCI_DESCRIBEKEYWORDSETS:
+		return StringResult(lParam, DocumentLexState()->DescribeWordListSets());
 
 #endif
 
diff --git a/plugins/scintilla/scintilla/ScintillaBase.h b/plugins/scintilla/scintilla/ScintillaBase.h
index f1fdc5d..2035108 100644
--- a/plugins/scintilla/scintilla/ScintillaBase.h
+++ b/plugins/scintilla/scintilla/ScintillaBase.h
@@ -12,6 +12,10 @@
 namespace Scintilla {
 #endif
 
+#ifdef SCI_LEXER
+class LexState;
+#endif
+
 /**
  */
 class ScintillaBase : public Editor {
@@ -44,12 +48,7 @@ protected:
 	int maxListWidth;		/// Maximum width of list, in average character widths
 
 #ifdef SCI_LEXER
-	bool performingStyle;	///< Prevent reentrance
-	int lexLanguage;
-	const LexerModule *lexCurrent;
-	PropSetSimple props;
-	enum {numWordLists=KEYWORDSET_MAX+1};
-	WordList *keyWordLists[numWordLists+1];
+	LexState *DocumentLexState();
 	void SetLexer(uptr_t wParam);
 	void SetLexerLanguage(const char *languageName);
 	void Colourise(int start, int end);
@@ -76,7 +75,7 @@ protected:
 	void AutoCompleteCharacterDeleted();
 	void AutoCompleteCompleted();
 	void AutoCompleteMoveToCurrentWord();
-	static void AutoCompleteDoubleClick(void* p);
+	static void AutoCompleteDoubleClick(void *p);
 
 	void CallTipClick();
 	void CallTipShow(Point pt, const char *defn);
@@ -87,7 +86,9 @@ protected:
 
 	virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
 
-	virtual void NotifyStyleToNeeded(int endStyleNeeded);
+	void NotifyStyleToNeeded(int endStyleNeeded);
+	void NotifyLexerChanged(Document *doc, void *userData);
+
 public:
 	// Public so scintilla_send_message can use it
 	virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
diff --git a/plugins/scintilla/scintilla/ScintillaGTK.cxx b/plugins/scintilla/scintilla/ScintillaGTK.cxx
index c1243a4..5682fde 100644
--- a/plugins/scintilla/scintilla/ScintillaGTK.cxx
+++ b/plugins/scintilla/scintilla/ScintillaGTK.cxx
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <assert.h>
 #include <ctype.h>
 #include <time.h>
 
@@ -22,14 +23,11 @@
 #include "windows.h"
 #endif
 
+#include "ILexer.h"
 #include "Scintilla.h"
 #include "ScintillaWidget.h"
 #ifdef SCI_LEXER
 #include "SciLexer.h"
-#include "PropSet.h"
-#include "PropSetSimple.h"
-#include "Accessor.h"
-#include "KeyWords.h"
 #endif
 #include "SVector.h"
 #include "SplitVector.h"
@@ -54,28 +52,48 @@
 #include "ScintillaBase.h"
 #include "UniConversion.h"
 
-#include "gtk/gtksignal.h"
-#include "gtk/gtkmarshal.h"
-#if GLIB_MAJOR_VERSION >= 2
 #include "scintilla-marshal.h"
-#endif
 
 #ifdef SCI_LEXER
 #include <glib.h>
 #include <gmodule.h>
+#include "LexerModule.h"
 #include "ExternalLexer.h"
 #endif
 
-#define INTERNATIONAL_INPUT
+#include "Converter.h"
 
-#if !PLAT_GTK_WIN32 || GTK_MAJOR_VERSION >= 2
-#define USE_CONVERTER
+#if GTK_CHECK_VERSION(2,20,0)
+#define IS_WIDGET_REALIZED(w) (gtk_widget_get_realized(GTK_WIDGET(w)))
+#define IS_WIDGET_MAPPED(w) (gtk_widget_get_mapped(GTK_WIDGET(w)))
+#define IS_WIDGET_VISIBLE(w) (gtk_widget_get_visible(GTK_WIDGET(w)))
+#else
+#define IS_WIDGET_REALIZED(w) (GTK_WIDGET_REALIZED(w))
+#define IS_WIDGET_MAPPED(w) (GTK_WIDGET_MAPPED(w))
+#define IS_WIDGET_VISIBLE(w) (GTK_WIDGET_VISIBLE(w))
 #endif
 
-#ifdef USE_CONVERTER
-#include "Converter.h"
+#if GTK_CHECK_VERSION(2,22,0)
+#define USE_CAIRO 1
 #endif
 
+static GdkWindow *WindowFromWidget(GtkWidget *w) {
+#if GTK_CHECK_VERSION(3,0,0)
+	return gtk_widget_get_window(w);
+#else
+	return w->window;
+#endif
+}
+
+static GdkWindow *PWindow(const Window &w) {
+	GtkWidget *widget = reinterpret_cast<GtkWidget *>(w.GetID());
+#if GTK_CHECK_VERSION(3,0,0)
+	return gtk_widget_get_window(widget);
+#else
+	return widget->window;
+#endif
+}
+
 #ifdef _MSC_VER
 // Constant conditional expressions are because of GTK+ headers
 #pragma warning(disable: 4127)
@@ -87,11 +105,7 @@
 #define USE_GTK_CLIPBOARD
 #endif
 
-#if GLIB_MAJOR_VERSION < 2
-#define OBJECT_CLASS GtkObjectClass
-#else
 #define OBJECT_CLASS GObjectClass
-#endif
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -104,8 +118,8 @@ class ScintillaGTK : public ScintillaBase {
 	Window wText;
 	Window scrollbarv;
 	Window scrollbarh;
-	GtkObject *adjustmentv;
-	GtkObject *adjustmenth;
+	GtkAdjustment *adjustmentv;
+	GtkAdjustment *adjustmenth;
 	int scrollBarWidth;
 	int scrollBarHeight;
 
@@ -135,17 +149,9 @@ class ScintillaGTK : public ScintillaBase {
 	CLIPFORMAT cfColumnSelect;
 #endif
 
-#ifdef INTERNATIONAL_INPUT
-#if GTK_MAJOR_VERSION < 2
-	// Input context used for supporting internationalized key entry
-	GdkIC *ic;
-	GdkICAttr *ic_attr;
-#else
 	Window wPreedit;
 	Window wPreeditDraw;
 	GtkIMContext *im_context;
-#endif
-#endif
 
 	// Wheel mouse support
 	unsigned int linesPerScroll;
@@ -153,7 +159,11 @@ class ScintillaGTK : public ScintillaBase {
 	gint lastWheelMouseDirection;
 	gint wheelMouseIntensity;
 
+#if GTK_CHECK_VERSION(3,0,0)
+	cairo_rectangle_list_t *rgnUpdate;
+#else
 	GdkRegion *rgnUpdate;
+#endif
 
 	// Private so ScintillaGTK objects can not be copied
 	ScintillaGTK(const ScintillaGTK &);
@@ -195,6 +205,8 @@ private:
 	void NotifyKey(int key, int modifiers);
 	void NotifyURIDropped(const char *list);
 	const char *CharacterSetID() const;
+	virtual CaseFolder *CaseFolderForEncoding();
+	virtual std::string CaseMapString(const std::string &s, int caseMapping);
 	virtual int KeyDefault(int key, int modifiers);
 	virtual void CopyToClipboard(const SelectionText &selectedText);
 	virtual void Copy();
@@ -225,15 +237,25 @@ private:
 	static void Map(GtkWidget *widget);
 	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 GetPreferredWidth(GtkWidget *widget, gint *minimalWidth, gint *naturalWidth);
+	static void GetPreferredHeight(GtkWidget *widget, gint *minimalHeight, gint *naturalHeight);
 	static void SizeAllocate(GtkWidget *widget, GtkAllocation *allocation);
-	gint Expose(GtkWidget *widget, GdkEventExpose *ose);
-	static gint ExposeMain(GtkWidget *widget, GdkEventExpose *ose);
+#if GTK_CHECK_VERSION(3,0,0)
+	gboolean DrawTextThis(cairo_t *cr);
+	static gboolean DrawText(GtkWidget *widget, cairo_t *cr, ScintillaGTK *sciThis);
+	gboolean DrawThis(cairo_t *cr);
+	static gboolean DrawMain(GtkWidget *widget, cairo_t *cr);
+#else
+	gboolean ExposeTextThis(GtkWidget *widget, GdkEventExpose *ose);
+	static gboolean ExposeText(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis);
+	gboolean Expose(GtkWidget *widget, GdkEventExpose *ose);
+	static gboolean ExposeMain(GtkWidget *widget, GdkEventExpose *ose);
+#endif
 	static void Draw(GtkWidget *widget, GdkRectangle *area);
 	void ForAll(GtkCallback callback, gpointer callback_data);
 	static void MainForAll(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data);
@@ -243,36 +265,25 @@ private:
 	gint PressThis(GdkEventButton *event);
 	static gint Press(GtkWidget *widget, GdkEventButton *event);
 	static gint MouseRelease(GtkWidget *widget, GdkEventButton *event);
-#if PLAT_GTK_WIN32 || (GTK_MAJOR_VERSION >= 2)
 	static gint ScrollEvent(GtkWidget *widget, GdkEventScroll *event);
-#endif
 	static gint Motion(GtkWidget *widget, GdkEventMotion *event);
 	gboolean KeyThis(GdkEventKey *event);
 	static gboolean KeyPress(GtkWidget *widget, GdkEventKey *event);
 	static gboolean KeyRelease(GtkWidget *widget, GdkEventKey *event);
-#if GTK_MAJOR_VERSION >= 2
 	gboolean ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose);
 	static gboolean ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis);
 	void CommitThis(char *str);
 	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*);
-#if GLIB_MAJOR_VERSION < 2
-	static void Destroy(GtkObject *object);
-#else
+	static void StyleSetText(GtkWidget *widget, GtkStyle *previous, void*);
+	static void RealizeText(GtkWidget *widget, void*);
 	static void Destroy(GObject *object);
-#endif
 	static void SelectionReceived(GtkWidget *widget, GtkSelectionData *selection_data,
 	                              guint time);
 	static void SelectionGet(GtkWidget *widget, GtkSelectionData *selection_data,
 	                         guint info, guint time);
 	static gint SelectionClear(GtkWidget *widget, GdkEventSelection *selection_event);
-#if GTK_MAJOR_VERSION < 2
-	static gint SelectionNotify(GtkWidget *widget, GdkEventSelection *selection_event);
-#endif
 	static void DragBegin(GtkWidget *widget, GdkDragContext *context);
 	gboolean DragMotionThis(GdkDragContext *context, gint x, gint y, guint dragtime);
 	static gboolean DragMotion(GtkWidget *widget, GdkDragContext *context,
@@ -286,15 +297,18 @@ private:
 	                             gint x, gint y, GtkSelectionData *selection_data, guint info, guint time);
 	static void DragDataGet(GtkWidget *widget, GdkDragContext *context,
 	                        GtkSelectionData *selection_data, guint info, guint time);
-	static gint TimeOut(ScintillaGTK *sciThis);
-	static gint IdleCallback(ScintillaGTK *sciThis);
-	static void PopUpCB(ScintillaGTK *sciThis, guint action, GtkWidget *widget);
-
-	gint ExposeTextThis(GtkWidget *widget, GdkEventExpose *ose);
-	static gint ExposeText(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis);
-
-	static gint ExposeCT(GtkWidget *widget, GdkEventExpose *ose, CallTip *ct);
-	static gint PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGTK *sciThis);
+	static gboolean TimeOut(ScintillaGTK *sciThis);
+	static gboolean IdleCallback(ScintillaGTK *sciThis);
+	static gboolean StyleIdle(ScintillaGTK *sciThis);
+	virtual void QueueStyling(int upTo);
+	static void PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis);
+
+#if GTK_CHECK_VERSION(3,0,0)
+	static gboolean DrawCT(GtkWidget *widget, cairo_t *cr, CallTip *ctip);
+#else
+	static gboolean ExposeCT(GtkWidget *widget, GdkEventExpose *ose, CallTip *ct);
+#endif
+	static gboolean PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGTK *sciThis);
 
 	static sptr_t DirectFunction(ScintillaGTK *sciThis,
 	                             unsigned int iMessage, uptr_t wParam, sptr_t lParam);
@@ -307,9 +321,6 @@ enum {
 };
 
 static gint scintilla_signals[LAST_SIGNAL] = { 0 };
-#if GLIB_MAJOR_VERSION < 2
-static GtkWidgetClass *parent_class = NULL;
-#endif
 
 enum {
     TARGET_STRING,
@@ -352,14 +363,7 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
 		scrollBarWidth(30), scrollBarHeight(30),
 		capturedMouse(false), dragWasDropped(false),
 		lastKey(0), rectangularSelectionModifier(SCMOD_CTRL), parentClass(0),
-#ifdef INTERNATIONAL_INPUT
-#if GTK_MAJOR_VERSION < 2
-		ic(NULL),
-		ic_attr(NULL),
-#else
 		im_context(NULL),
-#endif
-#endif
 		lastWheelMouseDirection(0),
 		wheelMouseIntensity(0),
 		rgnUpdate(0) {
@@ -394,94 +398,62 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
 }
 
 ScintillaGTK::~ScintillaGTK() {
+	g_idle_remove_by_data(this);
 }
 
 void ScintillaGTK::RealizeThis(GtkWidget *widget) {
 	//Platform::DebugPrintf("ScintillaGTK::realize this\n");
+#if GTK_CHECK_VERSION(2,20,0)
+	gtk_widget_set_realized(widget, TRUE);
+#else
 	GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+#endif
 	GdkWindowAttr attrs;
 	attrs.window_type = GDK_WINDOW_CHILD;
-	attrs.x = widget->allocation.x;
-	attrs.y = widget->allocation.y;
-	attrs.width = widget->allocation.width;
-	attrs.height = widget->allocation.height;
+	GtkAllocation allocation;
+#if GTK_CHECK_VERSION(3,0,0)
+	gtk_widget_get_allocation(widget, &allocation);
+#else
+	allocation = widget->allocation;
+#endif
+	attrs.x = allocation.x;
+	attrs.y = allocation.y;
+	attrs.width = allocation.width;
+	attrs.height = allocation.height;
 	attrs.wclass = GDK_INPUT_OUTPUT;
 	attrs.visual = gtk_widget_get_visual(widget);
+#if !GTK_CHECK_VERSION(3,0,0)
 	attrs.colormap = gtk_widget_get_colormap(widget);
+#endif
 	attrs.event_mask = gtk_widget_get_events(widget) | GDK_EXPOSURE_MASK;
 	GdkCursor *cursor = gdk_cursor_new(GDK_XTERM);
 	attrs.cursor = cursor;
+#if GTK_CHECK_VERSION(3,0,0)
+	gtk_widget_set_window(widget, gdk_window_new(gtk_widget_get_parent_window(widget), &attrs,
+		GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_CURSOR));
+	gdk_window_set_user_data(gtk_widget_get_window(widget), widget);
+	gdk_window_set_background(gtk_widget_get_window(widget),
+		&(gtk_widget_get_style(widget)->bg[GTK_STATE_NORMAL]));
+	gdk_window_show(gtk_widget_get_window(widget));
+	gdk_cursor_unref(cursor);
+	// Deprecated: should chain up to parent class' "realize" implementation
+	gtk_widget_style_attach(widget);
+#else
 	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_window_set_user_data(widget->window, widget);
 	gdk_window_set_background(widget->window, &widget->style->bg[GTK_STATE_NORMAL]);
 	gdk_window_show(widget->window);
-	gdk_cursor_destroy(cursor);
+	gdk_cursor_unref(cursor);
 	widget->style = gtk_style_attach(widget->style, widget->window);
-#ifdef INTERNATIONAL_INPUT
-#if GTK_MAJOR_VERSION < 2
-	if (gdk_im_ready() && (ic_attr = gdk_ic_attr_new()) != NULL) {
-		gint width, height;
-		GdkColormap *colormap;
-		GdkEventMask mask;
-		GdkICAttr *attr = ic_attr;
-		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);
-
-		if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
-			supported_style = (GdkIMStyle) ((int) supported_style & ~GDK_IM_PREEDIT_POSITION);
-
-		attr->style = style = gdk_im_decide_style(supported_style);
-		attr->client_window = widget->window;
-
-		if ((colormap = gtk_widget_get_colormap (widget)) != gtk_widget_get_default_colormap ()) {
-			attrmask = (GdkICAttributesType) ((int) attrmask | GDK_IC_PREEDIT_COLORMAP);
-			attr->preedit_colormap = colormap;
-		}
-
-		switch (style & GDK_IM_PREEDIT_MASK) {
-		case GDK_IM_PREEDIT_POSITION:
-			if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)	{
-				g_warning("over-the-spot style requires fontset");
-				break;
-			}
-
-			attrmask = (GdkICAttributesType) ((int) attrmask | GDK_IC_PREEDIT_POSITION_REQ);
-			gdk_window_get_size(widget->window, &width, &height);
-			attr->spot_location.x = 0;
-			attr->spot_location.y = height;
-			attr->preedit_area.x = 0;
-			attr->preedit_area.y = 0;
-			attr->preedit_area.width = width;
-			attr->preedit_area.height = height;
-			attr->preedit_fontset = widget->style->font;
-
-			break;
-		}
-		ic = gdk_ic_new(attr, attrmask);
-
-		if (ic == NULL) {
-			g_warning("Can't create input context.");
-		} else {
-			mask = gdk_window_get_events(widget->window);
-			mask = (GdkEventMask) ((int) mask | gdk_ic_get_events(ic));
-			gdk_window_set_events(widget->window, mask);
-
-			if (GTK_WIDGET_HAS_FOCUS(widget))
-				gdk_im_begin(ic, widget->window);
-		}
-	}
-#else
+#endif
 	wPreedit = gtk_window_new(GTK_WINDOW_POPUP);
 	wPreeditDraw = gtk_drawing_area_new();
 	GtkWidget *predrw = PWidget(wPreeditDraw);	// No code inside the G_OBJECT macro
+#if !GTK_CHECK_VERSION(3,0,0)
 	g_signal_connect(G_OBJECT(predrw), "expose_event",
 		G_CALLBACK(ExposePreedit), this);
+#endif
 	gtk_container_add(GTK_CONTAINER(PWidget(wPreedit)), predrw);
 	gtk_widget_realize(PWidget(wPreedit));
 	gtk_widget_realize(predrw);
@@ -492,24 +464,34 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) {
 		G_CALLBACK(Commit), this);
 	g_signal_connect(G_OBJECT(im_context), "preedit_changed",
 		G_CALLBACK(PreeditChanged), this);
-	gtk_im_context_set_client_window(im_context, widget->window);
-#endif
-#endif
+	gtk_im_context_set_client_window(im_context, WindowFromWidget(widget));
 	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);
-	gtk_signal_connect_after(GTK_OBJECT(widtxt), "realize",
-		GtkSignalFunc(ScintillaGTK::RealizeText), NULL);
-#else
 	g_signal_connect_after(G_OBJECT(widtxt), "style_set",
 		G_CALLBACK(ScintillaGTK::StyleSetText), NULL);
 	g_signal_connect_after(G_OBJECT(widtxt), "realize",
 		G_CALLBACK(ScintillaGTK::RealizeText), NULL);
-#endif
 	gtk_widget_realize(widtxt);
 	gtk_widget_realize(PWidget(scrollbarv));
 	gtk_widget_realize(PWidget(scrollbarh));
+
+	cursor = gdk_cursor_new(GDK_XTERM);
+	gdk_window_set_cursor(PWindow(wText), cursor);
+	gdk_cursor_unref(cursor);
+
+	cursor = gdk_cursor_new(GDK_LEFT_PTR);
+	gdk_window_set_cursor(PWindow(scrollbarv), cursor);
+	gdk_cursor_unref(cursor);
+
+	cursor = gdk_cursor_new(GDK_LEFT_PTR);
+	gdk_window_set_cursor(PWindow(scrollbarh), cursor);
+	gdk_cursor_unref(cursor);
+
+	gtk_selection_add_targets(widget, GDK_SELECTION_PRIMARY,
+	                          clipboardCopyTargets, nClipboardCopyTargets);
+#ifndef USE_GTK_CLIPBOARD
+	gtk_selection_add_targets(widget, atomClipboard,
+	                          clipboardPasteTargets, nClipboardPasteTargets);
+#endif
 }
 
 void ScintillaGTK::Realize(GtkWidget *widget) {
@@ -519,30 +501,26 @@ void ScintillaGTK::Realize(GtkWidget *widget) {
 
 void ScintillaGTK::UnRealizeThis(GtkWidget *widget) {
 	try {
-		if (GTK_WIDGET_MAPPED(widget)) {
+		gtk_selection_clear_targets(widget, GDK_SELECTION_PRIMARY);
+#ifndef USE_GTK_CLIPBOARD
+		gtk_selection_clear_targets(widget, atomClipboard);
+#endif
+
+		if (IS_WIDGET_MAPPED(widget)) {
 			gtk_widget_unmap(widget);
 		}
+#if GTK_CHECK_VERSION(2,20,0)
+		gtk_widget_set_realized(widget, FALSE);
+#else
 		GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);
+#endif
 		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;
-		}
-#else
 		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);
 
@@ -559,8 +537,8 @@ void ScintillaGTK::UnRealize(GtkWidget *widget) {
 
 static void MapWidget(GtkWidget *widget) {
 	if (widget &&
-	        GTK_WIDGET_VISIBLE(widget) &&
-	        !GTK_WIDGET_MAPPED(widget)) {
+	        IS_WIDGET_VISIBLE(widget) &&
+	        !IS_WIDGET_MAPPED(widget)) {
 		gtk_widget_map(widget);
 	}
 }
@@ -568,7 +546,11 @@ static void MapWidget(GtkWidget *widget) {
 void ScintillaGTK::MapThis() {
 	try {
 		//Platform::DebugPrintf("ScintillaGTK::map this\n");
+#if GTK_CHECK_VERSION(2,20,0)
+		gtk_widget_set_mapped(PWidget(wMain), TRUE);
+#else
 		GTK_WIDGET_SET_FLAGS(PWidget(wMain), GTK_MAPPED);
+#endif
 		MapWidget(PWidget(wText));
 		MapWidget(PWidget(scrollbarh));
 		MapWidget(PWidget(scrollbarv));
@@ -576,7 +558,7 @@ void ScintillaGTK::MapThis() {
 		scrollbarv.SetCursor(Window::cursorArrow);
 		scrollbarh.SetCursor(Window::cursorArrow);
 		ChangeSize();
-		gdk_window_show(PWidget(wMain)->window);
+		gdk_window_show(PWindow(wMain));
 	} catch (...) {
 		errorStatus = SC_STATUS_FAILURE;
 	}
@@ -590,9 +572,13 @@ void ScintillaGTK::Map(GtkWidget *widget) {
 void ScintillaGTK::UnMapThis() {
 	try {
 		//Platform::DebugPrintf("ScintillaGTK::unmap this\n");
+#if GTK_CHECK_VERSION(2,20,0)
+		gtk_widget_set_mapped(PWidget(wMain), FALSE);
+#else
 		GTK_WIDGET_UNSET_FLAGS(PWidget(wMain), GTK_MAPPED);
+#endif
 		DropGraphics();
-		gdk_window_hide(PWidget(wMain)->window);
+		gdk_window_hide(PWindow(wMain));
 		gtk_widget_unmap(PWidget(wText));
 		gtk_widget_unmap(PWidget(scrollbarh));
 		gtk_widget_unmap(PWidget(scrollbarv));
@@ -624,43 +610,9 @@ void ScintillaGTK::MainForAll(GtkContainer *container, gboolean include_internal
 	}
 }
 
-#ifdef INTERNATIONAL_INPUT
-#if GTK_MAJOR_VERSION < 2
-gint ScintillaGTK::CursorMoved(GtkWidget *widget, int xoffset, int yoffset, ScintillaGTK *sciThis) {
-	if (GTK_WIDGET_HAS_FOCUS(widget) && gdk_im_ready() && sciThis->ic &&
-	        (gdk_ic_get_style(sciThis->ic) & GDK_IM_PREEDIT_POSITION)) {
-		sciThis->ic_attr->spot_location.x = xoffset;
-		sciThis->ic_attr->spot_location.y = yoffset;
-		gdk_ic_set_attr(sciThis->ic, sciThis->ic_attr, GDK_IC_SPOT_LOCATION);
-	}
-	return FALSE;
-}
-#else
-gint ScintillaGTK::CursorMoved(GtkWidget *, int xoffset, int yoffset, ScintillaGTK *sciThis) {
-	GdkRectangle area;
-	area.x = xoffset;
-	area.y = yoffset;
-	area.width = 1;
-	area.height = 1;
-	gtk_im_context_set_cursor_location(sciThis->im_context, &area);
-	return FALSE;
-}
-#endif
-#else
-gint ScintillaGTK::CursorMoved(GtkWidget *, int, int, ScintillaGTK *) {
-	return FALSE;
-}
-#endif
-
 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 (ic)
-			gdk_im_begin(ic, widget->window);
-#else
 		if (im_context != NULL) {
 			gchar *str = NULL;
 			gint cursor_pos;
@@ -676,8 +628,6 @@ gint ScintillaGTK::FocusInThis(GtkWidget *widget) {
 			g_free(str);
 			gtk_im_context_focus_in(im_context);
 		}
-#endif
-#endif
 
 	} catch (...) {
 		errorStatus = SC_STATUS_FAILURE;
@@ -692,19 +642,12 @@ gint ScintillaGTK::FocusIn(GtkWidget *widget, GdkEventFocus * /*event*/) {
 
 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();
-#else
 		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;
@@ -719,39 +662,47 @@ gint ScintillaGTK::FocusOut(GtkWidget *widget, GdkEventFocus * /*event*/) {
 
 void ScintillaGTK::SizeRequest(GtkWidget *widget, GtkRequisition *requisition) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	requisition->width = 600;
-	requisition->height = gdk_screen_height();
+	requisition->width = 1;
+	requisition->height = 1;
 	GtkRequisition child_requisition;
+#if GTK_CHECK_VERSION(3,0,0)
+	gtk_widget_get_preferred_size(PWidget(sciThis->scrollbarh), NULL, &child_requisition);
+	gtk_widget_get_preferred_size(PWidget(sciThis->scrollbarv), NULL, &child_requisition);
+#else
 	gtk_widget_size_request(PWidget(sciThis->scrollbarh), &child_requisition);
 	gtk_widget_size_request(PWidget(sciThis->scrollbarv), &child_requisition);
+#endif
+}
+
+void ScintillaGTK::GetPreferredWidth(GtkWidget *widget, gint *minimalWidth, gint *naturalWidth) {
+	GtkRequisition requisition;
+	SizeRequest(widget, &requisition);
+	*minimalWidth = *naturalWidth = requisition.width;
+}
+
+void ScintillaGTK::GetPreferredHeight(GtkWidget *widget, gint *minimalHeight, gint *naturalHeight) {
+	GtkRequisition requisition;
+	SizeRequest(widget, &requisition);
+	*minimalHeight = *naturalHeight = requisition.height;
 }
 
 void ScintillaGTK::SizeAllocate(GtkWidget *widget, GtkAllocation *allocation) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
 	try {
+#if GTK_CHECK_VERSION(2,20,0)
+		gtk_widget_set_allocation(widget, allocation);
+#else
 		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);
+#endif
+		if (IS_WIDGET_REALIZED(widget))
+			gdk_window_move_resize(WindowFromWidget(widget),
+			        allocation->x,
+			        allocation->y,
+			        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;
-
-			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);
-		}
-#endif
-#endif
 	} catch (...) {
 		sciThis->errorStatus = SC_STATUS_FAILURE;
 	}
@@ -760,10 +711,15 @@ void ScintillaGTK::SizeAllocate(GtkWidget *widget, GtkAllocation *allocation) {
 void ScintillaGTK::Initialise() {
 	//Platform::DebugPrintf("ScintillaGTK::Initialise\n");
 	parentClass = reinterpret_cast<GtkWidgetClass *>(
-	                  gtk_type_class(gtk_container_get_type()));
+	                  g_type_class_ref(gtk_container_get_type()));
 
+#if GTK_CHECK_VERSION(2,20,0)
+	gtk_widget_set_can_focus(PWidget(wMain), TRUE);
+	gtk_widget_set_sensitive(PWidget(wMain), TRUE);
+#else
 	GTK_WIDGET_SET_FLAGS(PWidget(wMain), GTK_CAN_FOCUS);
 	GTK_WIDGET_SET_FLAGS(GTK_WIDGET(PWidget(wMain)), GTK_SENSITIVE);
+#endif
 	gtk_widget_set_events(PWidget(wMain),
 	                      GDK_EXPOSURE_MASK
 	                      | GDK_STRUCTURE_MASK
@@ -780,61 +736,47 @@ void ScintillaGTK::Initialise() {
 	gtk_widget_set_parent(PWidget(wText), PWidget(wMain));
 	GtkWidget *widtxt = PWidget(wText);	// No code inside the G_OBJECT macro
 	gtk_widget_show(widtxt);
-#if GLIB_MAJOR_VERSION < 2
-	gtk_signal_connect(GTK_OBJECT(widtxt), "expose_event",
-			   GtkSignalFunc(ScintillaGTK::ExposeText), this);
+#if GTK_CHECK_VERSION(3,0,0)
+	g_signal_connect(G_OBJECT(widtxt), "draw",
+			   G_CALLBACK(ScintillaGTK::DrawText), this);
 #else
 	g_signal_connect(G_OBJECT(widtxt), "expose_event",
 			   G_CALLBACK(ScintillaGTK::ExposeText), this);
 #endif
 	gtk_widget_set_events(widtxt, GDK_EXPOSURE_MASK);
-#if GTK_MAJOR_VERSION >= 2
 	// Avoid background drawing flash
 	gtk_widget_set_double_buffered(widtxt, FALSE);
-#endif
-	gtk_drawing_area_size(GTK_DRAWING_AREA(widtxt),
-	                      100,100);
-	adjustmentv = gtk_adjustment_new(0.0, 0.0, 201.0, 1.0, 20.0, 20.0);
+	gtk_widget_set_size_request(widtxt, 100, 100);
+	adjustmentv = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 201.0, 1.0, 20.0, 20.0));
 	scrollbarv = gtk_vscrollbar_new(GTK_ADJUSTMENT(adjustmentv));
-	GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarv), GTK_CAN_FOCUS);
-#if GLIB_MAJOR_VERSION < 2
-	gtk_signal_connect(adjustmentv, "value_changed",
-			   GtkSignalFunc(ScrollSignal), this);
+#if GTK_CHECK_VERSION(2,20,0)
+	gtk_widget_set_can_focus(PWidget(scrollbarv), FALSE);
 #else
+	GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarv), GTK_CAN_FOCUS);
+#endif
 	g_signal_connect(G_OBJECT(adjustmentv), "value_changed",
 			   G_CALLBACK(ScrollSignal), this);
-#endif
 	gtk_widget_set_parent(PWidget(scrollbarv), PWidget(wMain));
 	gtk_widget_show(PWidget(scrollbarv));
 
-	adjustmenth = gtk_adjustment_new(0.0, 0.0, 101.0, 1.0, 20.0, 20.0);
+	adjustmenth = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 101.0, 1.0, 20.0, 20.0));
 	scrollbarh = gtk_hscrollbar_new(GTK_ADJUSTMENT(adjustmenth));
-	GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarh), GTK_CAN_FOCUS);
-#if GLIB_MAJOR_VERSION < 2
-	gtk_signal_connect(adjustmenth, "value_changed",
-			   GtkSignalFunc(ScrollHSignal), this);
+#if GTK_CHECK_VERSION(2,20,0)
+	gtk_widget_set_can_focus(PWidget(scrollbarh), FALSE);
 #else
+	GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarh), GTK_CAN_FOCUS);
+#endif
 	g_signal_connect(G_OBJECT(adjustmenth), "value_changed",
 			   G_CALLBACK(ScrollHSignal), this);
-#endif
 	gtk_widget_set_parent(PWidget(scrollbarh), PWidget(wMain));
 	gtk_widget_show(PWidget(scrollbarh));
 
 	gtk_widget_grab_focus(PWidget(wMain));
 
-	gtk_selection_add_targets(GTK_WIDGET(PWidget(wMain)), GDK_SELECTION_PRIMARY,
-	                          clipboardCopyTargets, nClipboardCopyTargets);
-
-#ifndef USE_GTK_CLIPBOARD
-	gtk_selection_add_targets(GTK_WIDGET(PWidget(wMain)), atomClipboard,
-	                          clipboardPasteTargets, nClipboardPasteTargets);
-#endif
-
 	gtk_drag_dest_set(GTK_WIDGET(PWidget(wMain)),
 	                  GTK_DEST_DEFAULT_ALL, clipboardPasteTargets, nClipboardPasteTargets,
 	                  static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE));
 
-#if GLIB_MAJOR_VERSION >= 2
 	// Set caret period based on GTK settings
 	gboolean blinkOn = false;
 	if (g_object_class_find_property(G_OBJECT_GET_CLASS(
@@ -852,7 +794,6 @@ void ScintillaGTK::Initialise() {
 	} else {
 		caret.period = 0;
 	}
-#endif
 
 	SetTicking(true);
 }
@@ -870,12 +811,8 @@ void ScintillaGTK::DisplayCursor(Window::Cursor c) {
 }
 
 bool ScintillaGTK::DragThreshold(Point ptStart, Point ptNow) {
-#if GTK_MAJOR_VERSION < 2
-	return Editor::DragThreshold(ptStart, ptNow);
-#else
 	return gtk_drag_check_threshold(GTK_WIDGET(PWidget(wMain)),
 		ptStart.x, ptStart.y, ptNow.x, ptNow.y);
-#endif
 }
 
 void ScintillaGTK::StartDrag() {
@@ -889,9 +826,9 @@ void ScintillaGTK::StartDrag() {
 	               reinterpret_cast<GdkEvent *>(&evbtn));
 }
 
-#ifdef USE_CONVERTER
 static char *ConvertText(int *lenResult, char *s, size_t len, const char *charSetDest,
-	const char *charSetSource, bool transliterations) {
+	const char *charSetSource, bool transliterations, bool silent=false) {
+	// s is not const because of different versions of iconv disagreeing about const
 	*lenResult = 0;
 	char *destForm = 0;
 	Converter conv(charSetDest, charSetSource, transliterations);
@@ -903,7 +840,9 @@ static char *ConvertText(int *lenResult, char *s, size_t len, const char *charSe
 		size_t outLeft = len*3+1;
 		size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft);
 		if (conversions == ((size_t)(-1))) {
-fprintf(stderr, "iconv %s->%s failed for %s\n", charSetSource, charSetDest, static_cast<char *>(s));
+			if (!silent)
+				fprintf(stderr, "iconv %s->%s failed for %s\n",
+					charSetSource, charSetDest, static_cast<char *>(s));
 			delete []destForm;
 			destForm = 0;
 		} else {
@@ -921,7 +860,6 @@ fprintf(stderr, "Can not iconv %s %s\n", charSetDest, charSetSource);
 	}
 	return destForm;
 }
-#endif
 
 // Returns the target converted to UTF8.
 // Return the length in bytes.
@@ -933,7 +871,6 @@ int ScintillaGTK::TargetAsUTF8(char *text) {
 		}
 	} else {
 		// Need to convert
-#ifdef USE_CONVERTER
 		const char *charSetBuffer = CharacterSetID();
 		if (*charSetBuffer) {
 //~ fprintf(stderr, "AsUTF8 %s %d  %0d-%0d\n", charSetBuffer, targetLength, targetStart, targetEnd);
@@ -954,10 +891,6 @@ int ScintillaGTK::TargetAsUTF8(char *text) {
 				pdoc->GetCharRange(text, targetStart, targetLength);
 			}
 		}
-#else
-		// Fail
-		return 0;
-#endif
 	}
 //~ fprintf(stderr, "Length = %d bytes\n", targetLength);
 	return targetLength;
@@ -974,14 +907,11 @@ int ScintillaGTK::EncodedFromUTF8(char *utf8, char *encoded) {
 		return inputLength;
 	} else {
 		// Need to convert
-#ifdef USE_CONVERTER
 		const char *charSetBuffer = CharacterSetID();
 		if (*charSetBuffer) {
-//~ fprintf(stderr, "Encode %s %d\n", charSetBuffer, inputLength);
 			int outLength = 0;
 			char *tmpEncoded = ConvertText(&outLength, utf8, inputLength, charSetBuffer, "UTF-8", true);
 			if (tmpEncoded) {
-//~ fprintf(stderr, "    \"%s\"\n", tmpEncoded);
 				if (encoded) {
 					memcpy(encoded, tmpEncoded, outLength);
 				}
@@ -994,19 +924,19 @@ int ScintillaGTK::EncodedFromUTF8(char *utf8, char *encoded) {
 			}
 			return inputLength;
 		}
-#endif
 	}
 	// Fail
 	return 0;
 }
 
 bool ScintillaGTK::ValidCodePage(int codePage) const {
-	return codePage == 0 
-	|| codePage == SC_CP_UTF8 
+	return codePage == 0
+	|| codePage == SC_CP_UTF8
 	|| codePage == 932
 	|| codePage == 936
+	|| codePage == 949
 	|| codePage == 950
-	|| codePage == SC_CP_DBCS;
+	|| codePage == 1361;
 }
 
 sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
@@ -1025,7 +955,7 @@ sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
 
 #ifdef SCI_LEXER
 		case SCI_LOADLEXERLIBRARY:
-			LexerManager::GetInstance()->Load(reinterpret_cast<const char*>(wParam));
+                        LexerManager::GetInstance()->Load(reinterpret_cast<const char*>(lParam));
 			break;
 #endif
 		case SCI_TARGETASUTF8:
@@ -1038,10 +968,10 @@ sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
 		case SCI_SETRECTANGULARSELECTIONMODIFIER:
 			rectangularSelectionModifier = wParam;
 			break;
-		
+
 		case SCI_GETRECTANGULARSELECTIONMODIFIER:
 			return rectangularSelectionModifier;
-		
+
 		default:
 			return ScintillaBase::WndProc(iMessage, wParam, lParam);
 		}
@@ -1061,9 +991,10 @@ void ScintillaGTK::SetTicking(bool on) {
 	if (timer.ticking != on) {
 		timer.ticking = on;
 		if (timer.ticking) {
-			timer.tickerID = reinterpret_cast<TickerID>(g_timeout_add(timer.tickSize, (GSourceFunc)TimeOut, this));
+			timer.tickerID = reinterpret_cast<TickerID>(g_timeout_add(timer.tickSize,
+				reinterpret_cast<GSourceFunc>(TimeOut), this));
 		} else {
-			gtk_timeout_remove(GPOINTER_TO_UINT(timer.tickerID));
+			g_source_remove(GPOINTER_TO_UINT(timer.tickerID));
 		}
 	}
 	timer.ticksToWait = caret.period;
@@ -1072,16 +1003,17 @@ void ScintillaGTK::SetTicking(bool on) {
 bool ScintillaGTK::SetIdle(bool on) {
 	if (on) {
 		// Start idler, if it's not running.
-		if (idler.state == false) {
+		if (!idler.state) {
 			idler.state = true;
-			idler.idlerID = reinterpret_cast<IdlerID>
-				(gtk_idle_add((GtkFunction)IdleCallback, this));
+			idler.idlerID = reinterpret_cast<IdlerID>(
+				g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
+					reinterpret_cast<GSourceFunc>(IdleCallback), this, NULL));
 		}
 	} else {
 		// Stop idler, if it's running
-		if (idler.state == true) {
+		if (idler.state) {
 			idler.state = false;
-			gtk_idle_remove(GPOINTER_TO_UINT(idler.idlerID));
+			g_source_remove(GPOINTER_TO_UINT(idler.idlerID));
 		}
 	}
 	return true;
@@ -1102,17 +1034,46 @@ bool ScintillaGTK::HaveMouseCapture() {
 	return capturedMouse;
 }
 
+#if GTK_CHECK_VERSION(3,0,0)
+
+// Is crcTest completely in crcContainer?
+static bool CRectContains(const cairo_rectangle_t &crcContainer, const cairo_rectangle_t &crcTest) {
+	return
+		(crcTest.x >= crcContainer.x) && ((crcTest.x + crcTest.width) <= (crcContainer.x + crcContainer.width)) &&
+		(crcTest.y >= crcContainer.y) && ((crcTest.y + crcTest.height) <= (crcContainer.y + crcContainer.height));
+}
+
+// Is crcTest completely in crcListContainer?
+// May incorrectly return false if complex shape
+static bool CRectListContains(const cairo_rectangle_list_t *crcListContainer, const cairo_rectangle_t &crcTest) {
+	for (int r=0; r<crcListContainer->num_rectangles; r++) {
+		if (CRectContains(crcListContainer->rectangles[r], crcTest))
+			return true;
+	}
+	return false;
+}
+
+#endif
+
 bool ScintillaGTK::PaintContains(PRectangle rc) {
+	// This allows optimization when a rectangle is completely in the update region.
+	// It is OK to return false when too difficult to determine as that just performs extra drawing
 	bool contains = true;
 	if (paintState == painting) {
 		if (!rcPaint.Contains(rc)) {
 			contains = false;
 		} else if (rgnUpdate) {
+#if GTK_CHECK_VERSION(3,0,0)
+			cairo_rectangle_t grc = {rc.left, rc.top,
+				rc.right - rc.left, rc.bottom - rc.top};
+			contains = CRectListContains(rgnUpdate, grc);
+#else
 			GdkRectangle grc = {rc.left, rc.top,
 				rc.right - rc.left, rc.bottom - rc.top};
 			if (gdk_region_rect_in(rgnUpdate, &grc) != GDK_OVERLAP_RECTANGLE_IN) {
 				contains = false;
 			}
+#endif
 		}
 	}
 	return contains;
@@ -1120,25 +1081,7 @@ bool ScintillaGTK::PaintContains(PRectangle rc) {
 
 // Redraw all of text area. This paint will not be abandoned.
 void ScintillaGTK::FullPaint() {
-#if GTK_MAJOR_VERSION < 2
-	paintState = painting;
-	rcPaint = GetClientRectangle();
-	//Platform::DebugPrintf("ScintillaGTK::FullPaint %0d,%0d %0d,%0d\n",
-	//	rcPaint.left, rcPaint.top, rcPaint.right, rcPaint.bottom);
-	paintingAllText = true;
-	if ((PWidget(wText))->window) {
-		Surface *sw = Surface::Allocate();
-		if (sw) {
-			sw->Init(PWidget(wText)->window, PWidget(wText));
-			Paint(sw, rcPaint);
-			sw->Release();
-			delete sw;
-		}
-	}
-	paintState = notPainting;
-#else
 	wText.InvalidateAll();
-#endif
 }
 
 PRectangle ScintillaGTK::GetClientRectangle() {
@@ -1161,13 +1104,21 @@ void ScintillaGTK::SyncPaint(PRectangle rc) {
 	rcPaint = rc;
 	PRectangle rcClient = GetClientRectangle();
 	paintingAllText = rcPaint.Contains(rcClient);
-	if ((PWidget(wText))->window) {
+	if (PWindow(wText)) {
 		Surface *sw = Surface::Allocate();
 		if (sw) {
-			sw->Init(PWidget(wText)->window, PWidget(wText));
+#if GTK_CHECK_VERSION(3,0,0)
+			cairo_t *cr = gdk_cairo_create(PWindow(wText));
+			sw->Init(cr, PWidget(wText));
+#else
+			sw->Init(PWindow(wText), PWidget(wText));
+#endif
 			Paint(sw, rc);
 			sw->Release();
 			delete sw;
+#if GTK_CHECK_VERSION(3,0,0)
+			cairo_destroy(cr);
+#endif
 		}
 	}
 	if (paintState == paintAbandoned) {
@@ -1183,50 +1134,8 @@ void ScintillaGTK::ScrollText(int linesToMove) {
 	//	rc.left, rc.top, rc.right, rc.bottom);
 	GtkWidget *wi = PWidget(wText);
 
-#if GTK_MAJOR_VERSION < 2
-	PRectangle rc = GetClientRectangle();
-	GdkGC *gc = gdk_gc_new(wi->window);
-
-	// Set up gc so we get GraphicsExposures from gdk_draw_pixmap
-	//  which calls XCopyArea
-	gdk_gc_set_exposures(gc, TRUE);
-
-	// Redraw exposed bit : scrolling upwards
-	if (diff > 0) {
-		gdk_draw_pixmap(wi->window,
-		                gc, wi->window,
-		                0, diff,
-		                0, 0,
-		                rc.Width()-1, rc.Height() - diff);
-		SyncPaint(PRectangle(0, rc.Height() - diff,
-		                     rc.Width(), rc.Height()+1));
-
-	// Redraw exposed bit : scrolling downwards
-	} else {
-		gdk_draw_pixmap(wi->window,
-		                gc, wi->window,
-		                0, 0,
-		                0, -diff,
-		                rc.Width()-1, rc.Height() + diff);
-		SyncPaint(PRectangle(0, 0, rc.Width(), -diff));
-	}
-
-	// Look for any graphics expose
-	GdkEvent* event;
-	while ((event = gdk_event_get_graphics_expose(wi->window)) != NULL) {
-		gtk_widget_event(wi, event);
-		if (event->expose.count == 0) {
-			gdk_event_free(event);
-			break;
-		}
-		gdk_event_free(event);
-	}
-
-	gdk_gc_unref(gc);
-#else
-	gdk_window_scroll(wi->window, 0, -diff);
-	gdk_window_process_updates(wi->window, FALSE);
-#endif
+	gdk_window_scroll(WindowFromWidget(wi), 0, -diff);
+	gdk_window_process_updates(WindowFromWidget(wi), FALSE);
 }
 
 void ScintillaGTK::SetVerticalScrollPos() {
@@ -1243,6 +1152,17 @@ bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) {
 	bool modified = false;
 	int pageScroll = LinesToScroll();
 
+#if GTK_CHECK_VERSION(3,0,0)
+	if (gtk_adjustment_get_upper(adjustmentv) != (nMax + 1) ||
+	        gtk_adjustment_get_page_size(adjustmentv) != nPage ||
+	        gtk_adjustment_get_page_increment(adjustmentv) != pageScroll) {
+		gtk_adjustment_set_upper(adjustmentv, nMax + 1);
+	        gtk_adjustment_set_page_size(adjustmentv, nPage);
+	        gtk_adjustment_set_page_increment(adjustmentv, pageScroll);
+		gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmentv));
+		modified = true;
+	}
+#else
 	if (GTK_ADJUSTMENT(adjustmentv)->upper != (nMax + 1) ||
 	        GTK_ADJUSTMENT(adjustmentv)->page_size != nPage ||
 	        GTK_ADJUSTMENT(adjustmentv)->page_increment != pageScroll) {
@@ -1252,6 +1172,7 @@ bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) {
 		gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmentv));
 		modified = true;
 	}
+#endif
 
 	PRectangle rcText = GetTextRectangle();
 	int horizEndPreferred = scrollWidth;
@@ -1260,6 +1181,19 @@ bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) {
 	unsigned int pageWidth = rcText.Width();
 	unsigned int pageIncrement = pageWidth / 3;
 	unsigned int charWidth = vs.styles[STYLE_DEFAULT].aveCharWidth;
+#if GTK_CHECK_VERSION(3,0,0)
+	if (gtk_adjustment_get_upper(adjustmenth) != horizEndPreferred ||
+	        gtk_adjustment_get_page_size(adjustmenth) != pageWidth ||
+	        gtk_adjustment_get_page_increment(adjustmenth) != pageIncrement ||
+	        gtk_adjustment_get_step_increment(adjustmenth) != charWidth) {
+		gtk_adjustment_set_upper(adjustmenth, horizEndPreferred);
+	        gtk_adjustment_set_page_size(adjustmenth, pageWidth);
+	        gtk_adjustment_set_page_increment(adjustmenth, pageIncrement);
+	        gtk_adjustment_set_step_increment(adjustmenth, charWidth);
+		gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmenth));
+		modified = true;
+	}
+#else
 	if (GTK_ADJUSTMENT(adjustmenth)->upper != horizEndPreferred ||
 	        GTK_ADJUSTMENT(adjustmenth)->page_size != pageWidth ||
 	        GTK_ADJUSTMENT(adjustmenth)->page_increment != pageIncrement ||
@@ -1271,6 +1205,7 @@ bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) {
 		gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmenth));
 		modified = true;
 	}
+#endif
 	return modified;
 }
 
@@ -1280,37 +1215,21 @@ void ScintillaGTK::ReconfigureScrollBars() {
 }
 
 void ScintillaGTK::NotifyChange() {
-#if GLIB_MAJOR_VERSION < 2
-	gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL],
-	                Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), PWidget(wMain));
-#else
 	g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0,
 	                Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), PWidget(wMain));
-#endif
 }
 
 void ScintillaGTK::NotifyFocus(bool focus) {
-#if GLIB_MAJOR_VERSION < 2
-	gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL],
-	                Platform::LongFromTwoShorts
-					(GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain));
-#else
 	g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0,
 	                Platform::LongFromTwoShorts
 					(GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain));
-#endif
 }
 
 void ScintillaGTK::NotifyParent(SCNotification scn) {
 	scn.nmhdr.hwndFrom = PWidget(wMain);
 	scn.nmhdr.idFrom = GetCtrlID();
-#if GLIB_MAJOR_VERSION < 2
-	gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[NOTIFY_SIGNAL],
-	                GetCtrlID(), &scn);
-#else
 	g_signal_emit(G_OBJECT(sci), scintilla_signals[NOTIFY_SIGNAL], 0,
 	                GetCtrlID(), &scn);
-#endif
 }
 
 void ScintillaGTK::NotifyKey(int key, int modifiers) {
@@ -1336,6 +1255,149 @@ const char *ScintillaGTK::CharacterSetID() const {
 	return ::CharacterSetID(vs.styles[STYLE_DEFAULT].characterSet);
 }
 
+class CaseFolderUTF8 : public CaseFolderTable {
+public:
+	CaseFolderUTF8() {
+		StandardASCII();
+	}
+	virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
+		if ((lenMixed == 1) && (sizeFolded > 0)) {
+			folded[0] = mapping[static_cast<unsigned char>(mixed[0])];
+			return 1;
+		} else {
+			gchar *mapped = g_utf8_casefold(mixed, lenMixed);
+			size_t lenMapped = strlen(mapped);
+			if (lenMapped < sizeFolded) {
+				memcpy(folded, mapped,  lenMapped);
+			} else {
+				lenMapped = 0;
+			}
+			g_free(mapped);
+			return lenMapped;
+		}
+	}
+};
+
+class CaseFolderDBCS : public CaseFolderTable {
+	const char *charSet;
+public:
+	CaseFolderDBCS(const char *charSet_) : charSet(charSet_) {
+		StandardASCII();
+	}
+	virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
+		if ((lenMixed == 1) && (sizeFolded > 0)) {
+			folded[0] = mapping[static_cast<unsigned char>(mixed[0])];
+			return 1;
+		} else if (*charSet) {
+			int convertedLength = lenMixed;
+			char *sUTF8 = ConvertText(&convertedLength, const_cast<char *>(mixed), lenMixed,
+				"UTF-8", charSet, false);
+			if (sUTF8) {
+				gchar *mapped = g_utf8_casefold(sUTF8, strlen(sUTF8));
+				size_t lenMapped = strlen(mapped);
+				if (lenMapped < sizeFolded) {
+					memcpy(folded, mapped,  lenMapped);
+				} else {
+					folded[0] = '\0';
+					lenMapped = 1;
+				}
+				g_free(mapped);
+				delete []sUTF8;
+				return lenMapped;
+			}
+		}
+		// Something failed so return a single NUL byte
+		folded[0] = '\0';
+		return 1;
+	}
+};
+
+CaseFolder *ScintillaGTK::CaseFolderForEncoding() {
+	if (pdoc->dbcsCodePage == SC_CP_UTF8) {
+		return new CaseFolderUTF8();
+	} else {
+		const char *charSetBuffer = CharacterSetID();
+		if (charSetBuffer) {
+			if (pdoc->dbcsCodePage == 0) {
+				CaseFolderTable *pcf = new CaseFolderTable();
+				pcf->StandardASCII();
+				// Only for single byte encodings
+				for (int i=0x80; i<0x100; i++) {
+					char sCharacter[2] = "A";
+					sCharacter[0] = i;
+					int convertedLength = 1;
+					const char *sUTF8 = ConvertText(&convertedLength, sCharacter, 1,
+						"UTF-8", charSetBuffer, false);
+					if (sUTF8) {
+						gchar *mapped = g_utf8_casefold(sUTF8, strlen(sUTF8));
+						if (mapped) {
+							int mappedLength = strlen(mapped);
+							const char *mappedBack = ConvertText(&mappedLength, mapped,
+								mappedLength, charSetBuffer, "UTF-8", false, true);
+							if (mappedBack && (strlen(mappedBack) == 1) && (mappedBack[0] != sCharacter[0])) {
+								pcf->SetTranslation(sCharacter[0], mappedBack[0]);
+							}
+							delete []mappedBack;
+							g_free(mapped);
+						}
+					}
+					delete []sUTF8;
+				}
+				return pcf;
+			} else {
+				return new CaseFolderDBCS(charSetBuffer);
+			}
+		}
+		return 0;
+	}
+}
+
+std::string ScintillaGTK::CaseMapString(const std::string &s, int caseMapping) {
+	if (s.size() == 0)
+		return std::string();
+
+	if (caseMapping == cmSame)
+		return s;
+
+	const char *needsFree1 = 0;	// Must be freed with delete []
+	const char *charSetBuffer = CharacterSetID();
+	const char *sUTF8 = s.c_str();
+	int rangeBytes = s.size();
+
+	int convertedLength = rangeBytes;
+	// Change text to UTF-8
+	if (!IsUnicodeMode()) {
+		// Need to convert
+		if (*charSetBuffer) {
+			sUTF8 = ConvertText(&convertedLength, const_cast<char *>(s.c_str()), rangeBytes,
+				"UTF-8", charSetBuffer, false);
+			needsFree1 = sUTF8;
+		}
+	}
+	gchar *mapped;	// Must be freed with g_free
+	if (caseMapping == cmUpper) {
+		mapped = g_utf8_strup(sUTF8, convertedLength);
+	} else {
+		mapped = g_utf8_strdown(sUTF8, convertedLength);
+	}
+	int mappedLength = strlen(mapped);
+	char *mappedBack = mapped;
+
+	char *needsFree2 = 0;	// Must be freed with delete []
+	if (!IsUnicodeMode()) {
+		if (*charSetBuffer) {
+			mappedBack = ConvertText(&mappedLength, mapped, mappedLength, charSetBuffer, "UTF-8", false);
+			needsFree2 = mappedBack;
+		}
+	}
+
+	std::string ret(mappedBack, mappedLength);
+	g_free(mapped);
+	delete []needsFree1;
+	delete []needsFree2;
+	return ret;
+}
+
 int ScintillaGTK::KeyDefault(int key, int modifiers) {
 	if (!(modifiers & SCI_CTRL) && !(modifiers & SCI_ALT)) {
 		if (key < 256) {
@@ -1401,62 +1463,51 @@ void ScintillaGTK::CreateCallTipWindow(PRectangle rc) {
 		ct.wDraw = gtk_drawing_area_new();
 		GtkWidget *widcdrw = PWidget(ct.wDraw);	//	// No code inside the G_OBJECT macro
 		gtk_container_add(GTK_CONTAINER(PWidget(ct.wCallTip)), widcdrw);
-#if GLIB_MAJOR_VERSION < 2
-		gtk_signal_connect(GTK_OBJECT(widcdrw), "expose_event",
-				   GtkSignalFunc(ScintillaGTK::ExposeCT), &ct);
-		gtk_signal_connect(GTK_OBJECT(widcdrw), "button_press_event",
-				   GtkSignalFunc(ScintillaGTK::PressCT), static_cast<void *>(this));
+#if GTK_CHECK_VERSION(3,0,0)
+		g_signal_connect(G_OBJECT(widcdrw), "draw",
+				   G_CALLBACK(ScintillaGTK::DrawCT), &ct);
 #else
 		g_signal_connect(G_OBJECT(widcdrw), "expose_event",
 				   G_CALLBACK(ScintillaGTK::ExposeCT), &ct);
+#endif
 		g_signal_connect(G_OBJECT(widcdrw), "button_press_event",
 				   G_CALLBACK(ScintillaGTK::PressCT), static_cast<void *>(this));
-#endif
 		gtk_widget_set_events(widcdrw,
 			GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
 	}
-	gtk_drawing_area_size(GTK_DRAWING_AREA(PWidget(ct.wDraw)),
-	                      rc.Width(), rc.Height());
+	gtk_widget_set_size_request(PWidget(ct.wDraw), rc.Width(), rc.Height());
 	ct.wDraw.Show();
-	if (PWidget(ct.wCallTip)->window) {
-		gdk_window_resize(PWidget(ct.wCallTip)->window, rc.Width(), rc.Height());
+	if (PWindow(ct.wCallTip)) {
+		gdk_window_resize(PWindow(ct.wCallTip), rc.Width(), rc.Height());
 	}
 }
 
 void ScintillaGTK::AddToPopUp(const char *label, int cmd, bool enabled) {
-	char fulllabel[200];
-	strcpy(fulllabel, "/");
-	strcat(fulllabel, label);
-	GtkItemFactoryCallback menuSig = GtkItemFactoryCallback(PopUpCB);
-	GtkItemFactoryEntry itemEntry = {
-	    fulllabel, NULL,
-	    menuSig,
-	    cmd,
-	    const_cast<gchar *>(label[0] ? "<Item>" : "<Separator>"),
-#if GTK_MAJOR_VERSION >= 2
-	    NULL
-#endif
-	};
-	gtk_item_factory_create_item(GTK_ITEM_FACTORY(popup.GetID()),
-	                             &itemEntry, this, 1);
+	GtkWidget *menuItem;
+	if (label[0])
+		menuItem = gtk_menu_item_new_with_label(label);
+	else
+		menuItem = gtk_separator_menu_item_new();
+	gtk_menu_shell_append(GTK_MENU_SHELL(popup.GetID()), menuItem);
+	g_object_set_data(G_OBJECT(menuItem), "CmdNum", reinterpret_cast<void *>(cmd));
+	g_signal_connect(G_OBJECT(menuItem),"activate", G_CALLBACK(PopUpCB), this);
+
 	if (cmd) {
-		GtkWidget *item = gtk_item_factory_get_widget_by_action(
-		                      reinterpret_cast<GtkItemFactory *>(popup.GetID()), cmd);
-		if (item)
-			gtk_widget_set_sensitive(item, enabled);
+		if (menuItem)
+			gtk_widget_set_sensitive(menuItem, enabled);
 	}
 }
 
 bool ScintillaGTK::OwnPrimarySelection() {
 	return ((gdk_selection_owner_get(GDK_SELECTION_PRIMARY)
-		== GTK_WIDGET(PWidget(wMain))->window) &&
-			(GTK_WIDGET(PWidget(wMain))->window != NULL));
+		== PWindow(wMain)) &&
+			(PWindow(wMain) != NULL));
 }
 
 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 (!sel.Empty() && GTK_WIDGET_REALIZED(GTK_WIDGET(PWidget(wMain)))) {
+	if (!sel.Empty() && IS_WIDGET_REALIZED(GTK_WIDGET(PWidget(wMain)))) {
 		primarySelection = true;
 		gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)),
 		                        GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
@@ -1471,11 +1522,23 @@ void ScintillaGTK::ClaimSelection() {
 	}
 }
 
+#if GTK_CHECK_VERSION(3,0,0)
+static const guchar *DataOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_data(sd); }
+static gint LengthOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_length(sd); }
+static GdkAtom TypeOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_data_type(sd); }
+static GdkAtom SelectionOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_selection(sd); }
+#else
+static const guchar *DataOfGSD(GtkSelectionData *sd) { return sd->data; }
+static gint LengthOfGSD(GtkSelectionData *sd) { return sd->length; }
+static GdkAtom TypeOfGSD(GtkSelectionData *sd) { return sd->type; }
+static GdkAtom SelectionOfGSD(GtkSelectionData *sd) { return sd->selection; }
+#endif
+
 // Detect rectangular text, convert line ends to current mode, convert from or to UTF-8
 void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, SelectionText &selText) {
-	char *data = reinterpret_cast<char *>(selectionData->data);
-	int len = selectionData->length;
-	GdkAtom selectionTypeData = selectionData->type;
+	const char *data = reinterpret_cast<const char *>(DataOfGSD(selectionData));
+	int len = LengthOfGSD(selectionData);
+	GdkAtom selectionTypeData = TypeOfGSD(selectionData);
 
 	// Return empty string if selection is not a string
 	if ((selectionTypeData != GDK_TARGET_STRING) && (selectionTypeData != atomUTF8)) {
@@ -1491,6 +1554,8 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio
 	isRectangular = ::IsClipboardFormatAvailable(cfColumnSelect) != 0;
 #else
 	isRectangular = ((len > 2) && (data[len - 1] == 0 && data[len - 2] == '\n'));
+	if (isRectangular)
+		len--;	// Forget the extra '\0'
 #endif
 
 	char *dest;
@@ -1510,35 +1575,32 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio
 	} else {	// UTF-8
 		dest = Document::TransformLineEnds(&len, data, len, pdoc->eolMode);
 		selText.Set(dest, len, SC_CP_UTF8, 0, isRectangular, false);
-#ifdef USE_CONVERTER
 		const char *charSetBuffer = CharacterSetID();
 		if (!IsUnicodeMode() && *charSetBuffer) {
-//fprintf(stderr, "Convert to locale %s\n", CharacterSetID());
-				// Convert to locale
-				dest = ConvertText(&len, selText.s, selText.len, charSetBuffer, "UTF-8", true);
-				selText.Set(dest, len, pdoc->dbcsCodePage,
-					vs.styles[STYLE_DEFAULT].characterSet, selText.rectangular, false);
+			// Convert to locale
+			dest = ConvertText(&len, selText.s, selText.len, charSetBuffer, "UTF-8", true);
+			selText.Set(dest, len, pdoc->dbcsCodePage,
+				vs.styles[STYLE_DEFAULT].characterSet, selText.rectangular, false);
 		}
-#endif
 	}
 }
 
 void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) {
 	try {
-		if ((selection_data->selection == atomClipboard) ||
-		        (selection_data->selection == GDK_SELECTION_PRIMARY)) {
-			if ((atomSought == atomUTF8) && (selection_data->length <= 0)) {
+		if ((SelectionOfGSD(selection_data) == atomClipboard) ||
+		        (SelectionOfGSD(selection_data) == GDK_SELECTION_PRIMARY)) {
+			if ((atomSought == atomUTF8) && (LengthOfGSD(selection_data) <= 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))) {
+				        SelectionOfGSD(selection_data), atomSought, GDK_CURRENT_TIME);
+			} else if ((LengthOfGSD(selection_data) > 0) &&
+			        ((TypeOfGSD(selection_data) == GDK_TARGET_STRING) || (TypeOfGSD(selection_data) == atomUTF8))) {
 				SelectionText selText;
 				GetGtkSelectionText(selection_data, selText);
 
 				UndoGroup ug(pdoc);
-				if (selection_data->selection != GDK_SELECTION_PRIMARY) {
-					ClearSelection();
+				if (SelectionOfGSD(selection_data) != GDK_SELECTION_PRIMARY) {
+					ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH);
 				}
 				SelectionPosition selStart = sel.IsRectangular() ?
 					sel.Rectangular().Start() :
@@ -1547,10 +1609,7 @@ void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) {
 				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);
-					}
+					InsertPaste(selStart, selText.s, selText.len);
 				}
 				EnsureCaretVisible();
 			}
@@ -1565,19 +1624,19 @@ void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) {
 
 void ScintillaGTK::ReceivedDrop(GtkSelectionData *selection_data) {
 	dragWasDropped = true;
-	if (selection_data->type == atomUriList || selection_data->type == atomDROPFILES_DND) {
-		char *ptr = new char[selection_data->length + 1];
-		ptr[selection_data->length] = '\0';
-		memcpy(ptr, selection_data->data, selection_data->length);
+	if (TypeOfGSD(selection_data) == atomUriList || TypeOfGSD(selection_data) == atomDROPFILES_DND) {
+		char *ptr = new char[LengthOfGSD(selection_data) + 1];
+		ptr[LengthOfGSD(selection_data)] = '\0';
+		memcpy(ptr, DataOfGSD(selection_data), LengthOfGSD(selection_data));
  		NotifyURIDropped(ptr);
 		delete []ptr;
-	} else if ((selection_data->type == GDK_TARGET_STRING) || (selection_data->type == atomUTF8)) {
-		if (selection_data->length > 0) {
+	} else if ((TypeOfGSD(selection_data) == GDK_TARGET_STRING) || (TypeOfGSD(selection_data) == atomUTF8)) {
+		if (TypeOfGSD(selection_data) > 0) {
 			SelectionText selText;
 			GetGtkSelectionText(selection_data, selText);
 			DropAt(posDrop, selText.s, false, selText.rectangular);
 		}
-	} else if (selection_data->length > 0) {
+	} else if (LengthOfGSD(selection_data) > 0) {
 		//~ fprintf(stderr, "ReceivedDrop other %p\n", static_cast<void *>(selection_data->type));
 	}
 	Redraw();
@@ -1600,7 +1659,6 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se
 	}
 #endif
 
-#if GTK_MAJOR_VERSION >= 2
 	// Convert text to utf8 if it isn't already
 	SelectionText *converted = 0;
 	if ((text->codePage != SC_CP_UTF8) && (info == TARGET_UTF8_STRING)) {
@@ -1637,64 +1695,6 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se
 	}
 	delete converted;
 
-#else /* Gtk 1 */
-	char *selBuffer = text->s;
-
-	char *tmputf = 0;
-	if ((info == TARGET_UTF8_STRING) || (info == TARGET_STRING)) {
-		int len = strlen(selBuffer);
-#ifdef USE_CONVERTER
-		// Possible character set conversion
-		const char *charSetBuffer = ::CharacterSetID(text->characterSet);
-		if (info == TARGET_UTF8_STRING) {
-			//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);
-				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);
-				// Convert to locale
-				tmputf = ConvertText(&len, selBuffer, len, charSetBuffer, "UTF-8", true);
-				selBuffer = tmputf;
-			}
-		}
-#endif
-
-		// Here is a somewhat evil kludge.
-		// As I can not work out how to store data on the clipboard in multiple formats
-		// and need some way to mark the clipping as being stream or rectangular,
-		// 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)
-#if PLAT_GTK_WIN32 == 0
-		if (text->rectangular)
-			len++;
-#endif
-		gtk_selection_data_set(selection_data,
-					(info == TARGET_STRING) ?
-					static_cast<GdkAtom>(GDK_SELECTION_TYPE_STRING) : atomUTF8,
-		                       8, reinterpret_cast<unsigned char *>(selBuffer),
-		                       len);
-	} else if ((info == TARGET_TEXT) || (info == TARGET_COMPOUND_TEXT)) {
-		guchar *text;
-		GdkAtom encoding;
-		gint format;
-		gint new_length;
-
-		gdk_string_to_compound_text(reinterpret_cast<char *>(selBuffer),
-		                            &encoding, &format, &text, &new_length);
-		gtk_selection_data_set(selection_data, encoding, format, text, new_length);
-		gdk_free_compound_text(text);
-	}
-
-	delete []tmputf;
-#endif /* Gtk >= 2 */
-
 #if PLAT_GTK_WIN32
 	delete newline_normalized;
 #endif
@@ -1744,8 +1744,16 @@ void ScintillaGTK::Resize(int width, int height) {
 	//printf("Resize %d %d\n", width, height);
 
 	// Not always needed, but some themes can have different sizes of scrollbars
+#if GTK_CHECK_VERSION(3,0,0)
+	GtkRequisition requisition;
+	gtk_widget_get_requisition(PWidget(scrollbarv), &requisition);
+	scrollBarWidth = requisition.width;
+	gtk_widget_get_requisition(PWidget(scrollbarh), &requisition);
+	scrollBarHeight = requisition.height;
+#else
 	scrollBarWidth = GTK_WIDGET(PWidget(scrollbarv))->requisition.width;
 	scrollBarHeight = GTK_WIDGET(PWidget(scrollbarh))->requisition.height;
+#endif
 
 	// These allocations should never produce negative sizes as they would wrap around to huge
 	// unsigned numbers inside GTK+ causing warnings.
@@ -1753,16 +1761,13 @@ void ScintillaGTK::Resize(int width, int height) {
 	int horizontalScrollBarHeight = scrollBarHeight;
 	if (!showSBHorizontal)
 		horizontalScrollBarHeight = 0;
-	int verticalScrollBarHeight = scrollBarWidth;
-	if (!verticalScrollBarVisible)
-		verticalScrollBarHeight = 0;
 
 	GtkAllocation alloc;
 	if (showSBHorizontal) {
 		gtk_widget_show(GTK_WIDGET(PWidget(scrollbarh)));
 		alloc.x = 0;
 		alloc.y = height - scrollBarHeight;
-		alloc.width = Platform::Maximum(1, width - scrollBarWidth) + 1;
+		alloc.width = Platform::Maximum(1, width - scrollBarWidth);
 		alloc.height = horizontalScrollBarHeight;
 		gtk_widget_size_allocate(GTK_WIDGET(PWidget(scrollbarh)), &alloc);
 	} else {
@@ -1774,14 +1779,14 @@ void ScintillaGTK::Resize(int width, int height) {
 		alloc.x = width - scrollBarWidth;
 		alloc.y = 0;
 		alloc.width = scrollBarWidth;
-		alloc.height = Platform::Maximum(1, height - scrollBarHeight) + 1;
+		alloc.height = Platform::Maximum(1, height - scrollBarHeight);
 		if (!showSBHorizontal)
 			alloc.height += scrollBarWidth-1;
 		gtk_widget_size_allocate(GTK_WIDGET(PWidget(scrollbarv)), &alloc);
 	} else {
 		gtk_widget_hide(GTK_WIDGET(PWidget(scrollbarv)));
 	}
-	if (GTK_WIDGET_MAPPED(PWidget(wMain))) {
+	if (IS_WIDGET_MAPPED(PWidget(wMain))) {
 		ChangeSize();
 	}
 
@@ -1796,10 +1801,16 @@ void ScintillaGTK::Resize(int width, int height) {
 	gtk_widget_size_allocate(GTK_WIDGET(PWidget(wText)), &alloc);
 }
 
-static void SetAdjustmentValue(GtkObject *object, int value) {
+static void SetAdjustmentValue(GtkAdjustment *object, int value) {
 	GtkAdjustment *adjustment = GTK_ADJUSTMENT(object);
+#if GTK_CHECK_VERSION(3,0,0)
+	int maxValue = static_cast<int>(
+		gtk_adjustment_get_upper(adjustment) - gtk_adjustment_get_page_size(adjustment));
+#else
 	int maxValue = static_cast<int>(
 		adjustment->upper - adjustment->page_size);
+#endif
+
 	if (value > maxValue)
 		value = maxValue;
 	if (value < 0)
@@ -1817,7 +1828,7 @@ static int modifierTranslated(int sciModifier) {
 			return GDK_MOD1_MASK;
 		case SCMOD_SUPER:
 			return GDK_MOD4_MASK;
-		default: 
+		default:
 			return 0;
 	}
 }
@@ -1854,21 +1865,24 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) {
 			        (event->state & modifierTranslated(rectangularSelectionModifier)) != 0);
 		} else if (event->button == 2) {
 			// Grab the primary selection if it exists
-			SelectionPosition pos = SPositionFromLocation(pt);
+			SelectionPosition pos = SPositionFromLocation(pt, false, false, UserVirtualSpace());
 			if (OwnPrimarySelection() && primary.s == NULL)
 				CopySelectionRange(&primary);
 
+			sel.Clear();
 			SetSelection(pos, pos);
 			atomSought = atomUTF8;
 			gtk_selection_convert(GTK_WIDGET(PWidget(wMain)), GDK_SELECTION_PRIMARY,
 			        atomSought, event->time);
 		} else if (event->button == 3) {
+			if (!PointInSelection(pt))
+				SetEmptySelection(PositionFromLocation(pt));
 			if (displayPopupMenu) {
 				// PopUp menu
 				// Convert to screen
 				int ox = 0;
 				int oy = 0;
-				gdk_window_get_origin(PWidget(wMain)->window, &ox, &oy);
+				gdk_window_get_origin(PWindow(wMain), &ox, &oy);
 				ContextMenu(Point(pt.x + ox, pt.y + oy));
 			} else {
 				return FALSE;
@@ -1889,15 +1903,11 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) {
 	} catch (...) {
 		errorStatus = SC_STATUS_FAILURE;
 	}
-#if GTK_MAJOR_VERSION >= 2
 	return TRUE;
-#else
-	return FALSE;
-#endif
 }
 
 gint ScintillaGTK::Press(GtkWidget *widget, GdkEventButton *event) {
-	if (event->window != widget->window)
+	if (event->window != WindowFromWidget(widget))
 		return FALSE;
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
 	return sciThis->PressThis(event);
@@ -1915,7 +1925,7 @@ gint ScintillaGTK::MouseRelease(GtkWidget *widget, GdkEventButton *event) {
 			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 (event->window != PWindow(sciThis->wMain))
 				// 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;
@@ -1929,7 +1939,6 @@ gint ScintillaGTK::MouseRelease(GtkWidget *widget, GdkEventButton *event) {
 
 // win32gtk and GTK >= 2 use SCROLL_* events instead of passing the
 // button4/5/6/7 events to the GTK app
-#if PLAT_GTK_WIN32 || (GTK_MAJOR_VERSION >= 2)
 gint ScintillaGTK::ScrollEvent(GtkWidget *widget,
                                GdkEventScroll *event) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
@@ -2006,13 +2015,12 @@ gint ScintillaGTK::ScrollEvent(GtkWidget *widget,
 	}
 	return FALSE;
 }
-#endif
 
 gint ScintillaGTK::Motion(GtkWidget *widget, GdkEventMotion *event) {
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
 	try {
 		//Platform::DebugPrintf("Motion %x %d\n",sciThis,event->time);
-		if (event->window != widget->window)
+		if (event->window != WindowFromWidget(widget))
 			return FALSE;
 		int x = 0;
 		int y = 0;
@@ -2037,6 +2045,75 @@ gint ScintillaGTK::Motion(GtkWidget *widget, GdkEventMotion *event) {
 // Map the keypad keys to their equivalent functions
 static int KeyTranslate(int keyIn) {
 	switch (keyIn) {
+#if GTK_CHECK_VERSION(3,0,0)
+	case GDK_KEY_ISO_Left_Tab:
+		return SCK_TAB;
+	case GDK_KEY_KP_Down:
+		return SCK_DOWN;
+	case GDK_KEY_KP_Up:
+		return SCK_UP;
+	case GDK_KEY_KP_Left:
+		return SCK_LEFT;
+	case GDK_KEY_KP_Right:
+		return SCK_RIGHT;
+	case GDK_KEY_KP_Home:
+		return SCK_HOME;
+	case GDK_KEY_KP_End:
+		return SCK_END;
+	case GDK_KEY_KP_Page_Up:
+		return SCK_PRIOR;
+	case GDK_KEY_KP_Page_Down:
+		return SCK_NEXT;
+	case GDK_KEY_KP_Delete:
+		return SCK_DELETE;
+	case GDK_KEY_KP_Insert:
+		return SCK_INSERT;
+	case GDK_KEY_KP_Enter:
+		return SCK_RETURN;
+
+	case GDK_KEY_Down:
+		return SCK_DOWN;
+	case GDK_KEY_Up:
+		return SCK_UP;
+	case GDK_KEY_Left:
+		return SCK_LEFT;
+	case GDK_KEY_Right:
+		return SCK_RIGHT;
+	case GDK_KEY_Home:
+		return SCK_HOME;
+	case GDK_KEY_End:
+		return SCK_END;
+	case GDK_KEY_Page_Up:
+		return SCK_PRIOR;
+	case GDK_KEY_Page_Down:
+		return SCK_NEXT;
+	case GDK_KEY_Delete:
+		return SCK_DELETE;
+	case GDK_KEY_Insert:
+		return SCK_INSERT;
+	case GDK_KEY_Escape:
+		return SCK_ESCAPE;
+	case GDK_KEY_BackSpace:
+		return SCK_BACK;
+	case GDK_KEY_Tab:
+		return SCK_TAB;
+	case GDK_KEY_Return:
+		return SCK_RETURN;
+	case GDK_KEY_KP_Add:
+		return SCK_ADD;
+	case GDK_KEY_KP_Subtract:
+		return SCK_SUBTRACT;
+	case GDK_KEY_KP_Divide:
+		return SCK_DIVIDE;
+	case GDK_KEY_Super_L:
+		return SCK_WIN;
+	case GDK_KEY_Super_R:
+		return SCK_RWIN;
+	case GDK_KEY_Menu:
+		return SCK_MENU;
+
+#else
+
 	case GDK_ISO_Left_Tab:
 		return SCK_TAB;
 	case GDK_KP_Down:
@@ -2102,6 +2179,7 @@ static int KeyTranslate(int keyIn) {
 		return SCK_RWIN;
 	case GDK_Menu:
 		return SCK_MENU;
+#endif
 	default:
 		return keyIn;
 	}
@@ -2111,11 +2189,9 @@ gboolean ScintillaGTK::KeyThis(GdkEventKey *event) {
 	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;
 		}
@@ -2126,16 +2202,16 @@ gboolean ScintillaGTK::KeyThis(GdkEventKey *event) {
 		guint key = event->keyval;
 		if (ctrl && (key < 128))
 			key = toupper(key);
+#if GTK_CHECK_VERSION(3,0,0)
+		else if (!ctrl && (key >= GDK_KEY_KP_Multiply && key <= GDK_KEY_KP_9))
+#else
 		else if (!ctrl && (key >= GDK_KP_Multiply && key <= GDK_KP_9))
+#endif
 			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;
@@ -2165,7 +2241,6 @@ gboolean ScintillaGTK::KeyRelease(GtkWidget *, GdkEventKey * /*event*/) {
 	return FALSE;
 }
 
-#if GTK_MAJOR_VERSION >= 2
 gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose) {
 	try {
 		gchar *str;
@@ -2176,12 +2251,13 @@ gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose)
 		PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str);
 		pango_layout_set_attributes(layout, attrs);
 
+#ifndef USE_CAIRO
 		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_colormap_alloc_color(gdk_colormap_get_system(), color, FALSE, TRUE);
+		gdk_colormap_alloc_color(gdk_colormap_get_system(), color + 1, FALSE, TRUE);
 
 		gdk_gc_set_foreground(gc, color + 1);
 		gdk_draw_rectangle(widget->window, gc, TRUE, ose->area.x, ose->area.y,
@@ -2190,8 +2266,8 @@ gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose)
 		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_object_unref(gc);
+#endif
 		g_free(str);
 		pango_attr_list_unref(attrs);
 		g_object_unref(layout);
@@ -2256,7 +2332,7 @@ void ScintillaGTK::PreeditChangedThis() {
 			g_object_unref(layout);
 
 			gint x, y;
-			gdk_window_get_origin((PWidget(wText))->window, &x, &y);
+			gdk_window_get_origin(PWindow(wText), &x, &y);
 
 			Point pt = PointMainCaret();
 			if (pt.x < 0)
@@ -2281,26 +2357,23 @@ void ScintillaGTK::PreeditChangedThis() {
 void ScintillaGTK::PreeditChanged(GtkIMContext *, ScintillaGTK *sciThis) {
 	sciThis->PreeditChangedThis();
 }
-#endif
-
-gint ScintillaGTK::StyleSetText(GtkWidget *widget, GtkStyle *, void*) {
-	if (widget->window != NULL)
-		gdk_window_set_back_pixmap(widget->window, NULL, FALSE);
-	return FALSE;
-}
 
-gint ScintillaGTK::RealizeText(GtkWidget *widget, void*) {
-	if (widget->window != NULL)
-		gdk_window_set_back_pixmap(widget->window, NULL, FALSE);
-	return FALSE;
+void ScintillaGTK::StyleSetText(GtkWidget *widget, GtkStyle *, void*) {
+	RealizeText(widget, NULL);
 }
 
-#if GLIB_MAJOR_VERSION < 2
-void ScintillaGTK::Destroy(GtkObject *object)
+void ScintillaGTK::RealizeText(GtkWidget *widget, void*) {
+	// Set NULL background to avoid automatic clearing so Scintilla responsible for all drawing
+	if (WindowFromWidget(widget)) {
+#if GTK_CHECK_VERSION(3,0,0)
+		gdk_window_set_background_pattern(WindowFromWidget(widget), NULL);
 #else
-void ScintillaGTK::Destroy(GObject *object)
+		gdk_window_set_back_pixmap(WindowFromWidget(widget), NULL, FALSE);
 #endif
-{
+	}
+}
+
+void ScintillaGTK::Destroy(GObject *object) {
 	try {
 		ScintillaObject *scio = reinterpret_cast<ScintillaObject *>(object);
 		// This avoids a double destruction
@@ -2310,13 +2383,6 @@ void ScintillaGTK::Destroy(GObject *object)
 		//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);
-#else
-		// IS ANYTHING NEEDED ?
-#endif
-
 		delete sciThis;
 		scio->pscin = 0;
 	} catch (...) {
@@ -2324,56 +2390,34 @@ void ScintillaGTK::Destroy(GObject *object)
 	}
 }
 
-static void DrawChild(GtkWidget *widget, GdkRectangle *area) {
-	GdkRectangle areaIntersect;
-	if (widget &&
-	        GTK_WIDGET_DRAWABLE(widget) &&
-	        gtk_widget_intersect(widget, area, &areaIntersect)) {
-		gtk_widget_draw(widget, &areaIntersect);
-	}
-}
-
-void ScintillaGTK::Draw(GtkWidget *widget, GdkRectangle *area) {
-	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	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);
-		}
+#if GTK_CHECK_VERSION(3,0,0)
 
-#ifdef INTERNATIONAL_INPUT
-		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) {
+gboolean ScintillaGTK::DrawTextThis(cairo_t *cr) {
 	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 = GetClientRectangle();
 
 		PLATFORM_ASSERT(rgnUpdate == NULL);
-#if GTK_MAJOR_VERSION >= 2
-		rgnUpdate = gdk_region_copy(ose->region);
-#endif
+		rgnUpdate = cairo_copy_clip_rectangle_list(cr);
+		if (rgnUpdate && rgnUpdate->status != CAIRO_STATUS_SUCCESS) {
+			// If not successful then ignore
+			fprintf(stderr, "DrawTextThis failed to copy update region %d [%d]\n", rgnUpdate->status, rgnUpdate->num_rectangles);
+			cairo_rectangle_list_destroy(rgnUpdate);
+			rgnUpdate = 0;
+		}
+
+		double x1, y1, x2, y2;
+		cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
+		rcPaint.left = x1;
+		rcPaint.top = y1;
+		rcPaint.right = x2;
+		rcPaint.bottom = y2;
 		PRectangle rcClient = GetClientRectangle();
 		paintingAllText = rcPaint.Contains(rcClient);
 		Surface *surfaceWindow = Surface::Allocate();
 		if (surfaceWindow) {
-			surfaceWindow->Init(PWidget(wText)->window, PWidget(wText));
+			surfaceWindow->Init(cr, PWidget(wText));
 			Paint(surfaceWindow, rcPaint);
 			surfaceWindow->Release();
 			delete surfaceWindow;
@@ -2385,9 +2429,10 @@ gint ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) {
 		paintState = notPainting;
 
 		if (rgnUpdate) {
-			gdk_region_destroy(rgnUpdate);
+			cairo_rectangle_list_destroy(rgnUpdate);
 		}
 		rgnUpdate = 0;
+		paintState = notPainting;
 	} catch (...) {
 		errorStatus = SC_STATUS_FAILURE;
 	}
@@ -2395,24 +2440,31 @@ gint ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) {
 	return FALSE;
 }
 
-gint ScintillaGTK::ExposeText(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis) {
-	return sciThis->ExposeTextThis(widget, ose);
+gboolean ScintillaGTK::DrawText(GtkWidget *, cairo_t *cr, ScintillaGTK *sciThis) {
+	return sciThis->DrawTextThis(cr);
 }
 
-gint ScintillaGTK::ExposeMain(GtkWidget *widget, GdkEventExpose *ose) {
-	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
-	//Platform::DebugPrintf("Expose Main %0d,%0d %0d,%0d\n",
-	//ose->area.x, ose->area.y, ose->area.width, ose->area.height);
-	return sciThis->Expose(widget, ose);
+gboolean ScintillaGTK::DrawThis(cairo_t *cr) {
+	try {
+		gtk_container_propagate_draw(
+		    GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarh), cr);
+		gtk_container_propagate_draw(
+		    GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarv), cr);
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
+	}
+	return FALSE;
 }
 
-gint ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) {
-	try {
-		//fprintf(stderr, "Expose %0d,%0d %0d,%0d\n",
-		//ose->area.x, ose->area.y, ose->area.width, ose->area.height);
+gboolean ScintillaGTK::DrawMain(GtkWidget *widget, cairo_t *cr) {
+	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
+	return sciThis->DrawThis(cr);
+}
 
-#if GTK_MAJOR_VERSION < 2
+#else
 
+gboolean ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) {
+	try {
 		paintState = painting;
 
 		rcPaint.left = ose->area.x;
@@ -2420,26 +2472,14 @@ gint ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) {
 		rcPaint.right = ose->area.x + ose->area.width;
 		rcPaint.bottom = ose->area.y + ose->area.height;
 
+		PLATFORM_ASSERT(rgnUpdate == NULL);
+		rgnUpdate = gdk_region_copy(ose->region);
 		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->Init(PWindow(wText), PWidget(wText));
+			Paint(surfaceWindow, rcPaint);
 			surfaceWindow->Release();
 			delete surfaceWindow;
 		}
@@ -2449,13 +2489,38 @@ gint ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) {
 		}
 		paintState = notPainting;
 
-#else
-		// For GTK+ 2, the text is painted in ExposeText
+		if (rgnUpdate) {
+			gdk_region_destroy(rgnUpdate);
+		}
+		rgnUpdate = 0;
+	} catch (...) {
+		errorStatus = SC_STATUS_FAILURE;
+	}
+
+	return FALSE;
+}
+
+gboolean ScintillaGTK::ExposeText(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis) {
+	return sciThis->ExposeTextThis(widget, ose);
+}
+
+gboolean ScintillaGTK::ExposeMain(GtkWidget *widget, GdkEventExpose *ose) {
+	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
+	//Platform::DebugPrintf("Expose Main %0d,%0d %0d,%0d\n",
+	//ose->area.x, ose->area.y, ose->area.width, ose->area.height);
+	return sciThis->Expose(widget, ose);
+}
+
+gboolean ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) {
+	try {
+		//fprintf(stderr, "Expose %0d,%0d %0d,%0d\n",
+		//ose->area.x, ose->area.y, ose->area.width, ose->area.height);
+
+		// 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;
@@ -2463,9 +2528,15 @@ gint ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) {
 	return FALSE;
 }
 
+#endif
+
 void ScintillaGTK::ScrollSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) {
 	try {
+#if GTK_CHECK_VERSION(3,0,0)
+		sciThis->ScrollTo(static_cast<int>(gtk_adjustment_get_value(adj)), false);
+#else
 		sciThis->ScrollTo(static_cast<int>(adj->value), false);
+#endif
 	} catch (...) {
 		sciThis->errorStatus = SC_STATUS_FAILURE;
 	}
@@ -2473,7 +2544,11 @@ void ScintillaGTK::ScrollSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) {
 
 void ScintillaGTK::ScrollHSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) {
 	try {
+#if GTK_CHECK_VERSION(3,0,0)
+		sciThis->HorizontalScrollTo(static_cast<int>(gtk_adjustment_get_value(adj) * 2));
+#else
 		sciThis->HorizontalScrollTo(static_cast<int>(adj->value * 2));
+#endif
 	} catch (...) {
 		sciThis->errorStatus = SC_STATUS_FAILURE;
 	}
@@ -2491,7 +2566,7 @@ void ScintillaGTK::SelectionGet(GtkWidget *widget,
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
 	try {
 		//Platform::DebugPrintf("Selection get\n");
-		if (selection_data->selection == GDK_SELECTION_PRIMARY) {
+		if (SelectionOfGSD(selection_data) == GDK_SELECTION_PRIMARY) {
 			if (sciThis->primary.s == NULL) {
 				sciThis->CopySelectionRange(&sciThis->primary);
 			}
@@ -2511,15 +2586,11 @@ gint ScintillaGTK::SelectionClear(GtkWidget *widget, GdkEventSelection *selectio
 	ScintillaGTK *sciThis = ScintillaFromWidget(widget);
 	//Platform::DebugPrintf("Selection clear\n");
 	sciThis->UnclaimSelection(selection_event);
-	return gtk_selection_clear(widget, selection_event);
-}
-
-#if GTK_MAJOR_VERSION < 2
-gint ScintillaGTK::SelectionNotify(GtkWidget *widget, GdkEventSelection *selection_event) {
-	//Platform::DebugPrintf("Selection notify\n");
-	return gtk_selection_notify(widget, selection_event);
+	if (GTK_WIDGET_CLASS(sciThis->parentClass)->selection_clear_event) {
+		return GTK_WIDGET_CLASS(sciThis->parentClass)->selection_clear_event(widget, selection_event);
+	}
+	return TRUE;
 }
-#endif
 
 void ScintillaGTK::DragBegin(GtkWidget *, GdkDragContext *) {
 	//Platform::DebugPrintf("DragBegin\n");
@@ -2530,13 +2601,19 @@ gboolean ScintillaGTK::DragMotionThis(GdkDragContext *context,
 	try {
 		Point npt(x, y);
 		SetDragPosition(SPositionFromLocation(npt, false, false, UserVirtualSpace()));
+#if GTK_CHECK_VERSION(3,0,0)
+		GdkDragAction preferredAction = gdk_drag_context_get_suggested_action(context);
+		GdkDragAction actions = gdk_drag_context_get_actions(context);
+#else
 		GdkDragAction preferredAction = context->suggested_action;
+		GdkDragAction actions = context->actions;
+#endif
 		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>
+		} else if (actions == static_cast<GdkDragAction>
 		        (GDK_ACTION_COPY | GDK_ACTION_MOVE)) {
 			preferredAction = GDK_ACTION_MOVE;
 		}
@@ -2608,7 +2685,12 @@ void ScintillaGTK::DragDataGet(GtkWidget *widget, GdkDragContext *context,
 		if (!sciThis->sel.Empty()) {
 			sciThis->GetSelection(selection_data, info, &sciThis->drag);
 		}
-		if (context->action == GDK_ACTION_MOVE) {
+#if GTK_CHECK_VERSION(3,0,0)
+		GdkDragAction action = gdk_drag_context_get_selected_action(context);
+#else
+		GdkDragAction action = context->action;
+#endif
+		if (action == GDK_ACTION_MOVE) {
 			for (size_t r=0; r<sciThis->sel.Count(); r++) {
 				if (sciThis->posDrop >= sciThis->sel.Range(r).Start()) {
 					if (sciThis->posDrop > sciThis->sel.Range(r).End()) {
@@ -2631,9 +2713,10 @@ int ScintillaGTK::TimeOut(ScintillaGTK *sciThis) {
 	return 1;
 }
 
-int ScintillaGTK::IdleCallback(ScintillaGTK *sciThis) {
-	// Idler will be automatically stoped, if there is nothing
+gboolean ScintillaGTK::IdleCallback(ScintillaGTK *sciThis) {
+	// Idler will be automatically stopped, if there is nothing
 	// to do while idle.
+	gdk_threads_enter();
 	bool ret = sciThis->Idle();
 	if (ret == false) {
 		// FIXME: This will remove the idler from GTK, we don't want to
@@ -2641,18 +2724,38 @@ int ScintillaGTK::IdleCallback(ScintillaGTK *sciThis) {
 		// returns false (although, it should be harmless).
 		sciThis->SetIdle(false);
 	}
+	gdk_threads_leave();
 	return ret;
 }
 
-void ScintillaGTK::PopUpCB(ScintillaGTK *sciThis, guint action, GtkWidget *) {
+gboolean ScintillaGTK::StyleIdle(ScintillaGTK *sciThis) {
+	gdk_threads_enter();
+	sciThis->IdleStyling();
+	gdk_threads_leave();
+	// Idler will be automatically stopped
+	return FALSE;
+}
+
+void ScintillaGTK::QueueStyling(int upTo) {
+	Editor::QueueStyling(upTo);
+	if (!styleNeeded.active) {
+		// Only allow one style needed to be queued
+		styleNeeded.active = true;
+		g_idle_add_full(G_PRIORITY_HIGH_IDLE,
+			reinterpret_cast<GSourceFunc>(StyleIdle), this, NULL);
+	}
+}
+
+void ScintillaGTK::PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis) {
+	guint action = (sptr_t)(g_object_get_data(G_OBJECT(menuItem), "CmdNum"));
 	if (action) {
 		sciThis->Command(action);
 	}
 }
 
-gint ScintillaGTK::PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGTK *sciThis) {
+gboolean ScintillaGTK::PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGTK *sciThis) {
 	try {
-		if (event->window != widget->window)
+		if (event->window != WindowFromWidget(widget))
 			return FALSE;
 		if (event->type != GDK_BUTTON_PRESS)
 			return FALSE;
@@ -2663,18 +2766,35 @@ gint ScintillaGTK::PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGT
 		sciThis->CallTipClick();
 	} catch (...) {
 	}
-#if GTK_MAJOR_VERSION >= 2
 	return TRUE;
-#else
-	return FALSE;
-#endif
 }
 
-gint ScintillaGTK::ExposeCT(GtkWidget *widget, GdkEventExpose * /*ose*/, CallTip *ctip) {
+#if GTK_CHECK_VERSION(3,0,0)
+
+gboolean ScintillaGTK::DrawCT(GtkWidget *widget, cairo_t *cr, CallTip *ctip) {
+	try {
+		Surface *surfaceWindow = Surface::Allocate();
+		if (surfaceWindow) {
+			surfaceWindow->Init(cr, 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;
+}
+
+#else
+
+gboolean ScintillaGTK::ExposeCT(GtkWidget *widget, GdkEventExpose * /*ose*/, CallTip *ctip) {
 	try {
 		Surface *surfaceWindow = Surface::Allocate();
 		if (surfaceWindow) {
-			surfaceWindow->Init(widget->window, widget);
+			surfaceWindow->Init(WindowFromWidget(widget), widget);
 			surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ctip->codePage);
 			surfaceWindow->SetDBCSMode(ctip->codePage);
 			ctip->PaintCT(surfaceWindow);
@@ -2687,6 +2807,8 @@ gint ScintillaGTK::ExposeCT(GtkWidget *widget, GdkEventExpose * /*ose*/, CallTip
 	return TRUE;
 }
 
+#endif
+
 sptr_t ScintillaGTK::DirectFunction(
     ScintillaGTK *sciThis, unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
 	return sciThis->WndProc(iMessage, wParam, lParam);
@@ -2703,32 +2825,6 @@ static void scintilla_init(ScintillaObject *sci);
 extern void Platform_Initialise();
 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
-			};
-
-			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 {
@@ -2758,11 +2854,11 @@ GType scintilla_get_type() {
 	}
 	return scintilla_type;
 }
-#endif
 
 void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class) {
-#if GLIB_MAJOR_VERSION >= 2
 	Platform_Initialise();
+#ifdef SCI_LEXER
+	Scintilla_LinkLexers();
 #endif
 	atomClipboard = gdk_atom_intern("CLIPBOARD", FALSE);
 	atomUTF8 = gdk_atom_intern("UTF8_STRING", FALSE);
@@ -2774,23 +2870,23 @@ void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_
 	// of the signal handlers here (those that currently attached to wDraw
 	// in Initialise() may require coordinate translation?)
 
-#if GLIB_MAJOR_VERSION < 2
-	object_class->destroy = Destroy;
-#else
 	object_class->finalize = Destroy;
-#endif
+#if GTK_CHECK_VERSION(3,0,0)
+	widget_class->get_preferred_width = GetPreferredWidth;
+	widget_class->get_preferred_height = GetPreferredHeight;
+#else
 	widget_class->size_request = SizeRequest;
+#endif
 	widget_class->size_allocate = SizeAllocate;
+#if GTK_CHECK_VERSION(3,0,0)
+	widget_class->draw = DrawMain;
+#else
 	widget_class->expose_event = ExposeMain;
-#if GTK_MAJOR_VERSION < 2
-	widget_class->draw = Draw;
 #endif
 	widget_class->motion_notify_event = Motion;
 	widget_class->button_press_event = Press;
 	widget_class->button_release_event = MouseRelease;
-#if PLAT_GTK_WIN32 || (GTK_MAJOR_VERSION >= 2)
 	widget_class->scroll_event = ScrollEvent;
-#endif
 	widget_class->key_press_event = KeyPress;
 	widget_class->key_release_event = KeyRelease;
 	widget_class->focus_in_event = FocusIn;
@@ -2798,9 +2894,6 @@ void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_
 	widget_class->selection_received = SelectionReceived;
 	widget_class->selection_get = SelectionGet;
 	widget_class->selection_clear_event = SelectionClear;
-#if GTK_MAJOR_VERSION < 2
-	widget_class->selection_notify_event = SelectionNotify;
-#endif
 
 	widget_class->drag_data_received = DragDataReceived;
 	widget_class->drag_motion = DragMotion;
@@ -2817,14 +2910,8 @@ void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_
 	container_class->forall = MainForAll;
 }
 
-#if GLIB_MAJOR_VERSION < 2
-#define GTK_CLASS_TYPE(c) (c->type)
-#define SIG_MARSHAL gtk_marshal_NONE__INT_POINTER
-#define MARSHAL_ARGUMENTS GTK_TYPE_INT, GTK_TYPE_POINTER
-#else
 #define SIG_MARSHAL scintilla_marshal_NONE__INT_POINTER
 #define MARSHAL_ARGUMENTS G_TYPE_INT, G_TYPE_POINTER
-#endif
 
 static void scintilla_class_init(ScintillaClass *klass) {
 	try {
@@ -2832,29 +2919,6 @@ static void scintilla_class_init(ScintillaClass *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);
-#else
 		GSignalFlags sigflags = GSignalFlags(G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST);
 		scintilla_signals[COMMAND_SIGNAL] = g_signal_new(
 		            "command",
@@ -2877,7 +2941,7 @@ static void scintilla_class_init(ScintillaClass *klass) {
 		            SIG_MARSHAL,
 		            G_TYPE_NONE,
 		            2, MARSHAL_ARGUMENTS);
-#endif
+
 		klass->command = NULL;
 		klass->notify = NULL;
 
@@ -2888,18 +2952,18 @@ static void scintilla_class_init(ScintillaClass *klass) {
 
 static void scintilla_init(ScintillaObject *sci) {
 	try {
+#if GTK_CHECK_VERSION(2,20,0)
+		gtk_widget_set_can_focus(GTK_WIDGET(sci), TRUE);
+#else
 		GTK_WIDGET_SET_FLAGS(sci, GTK_CAN_FOCUS);
+#endif
 		sci->pscin = new ScintillaGTK(sci);
 	} catch (...) {
 	}
 }
 
 GtkWidget* scintilla_new() {
-#if GLIB_MAJOR_VERSION < 2
-	return GTK_WIDGET(gtk_type_new(scintilla_get_type()));
-#else
 	return GTK_WIDGET(g_object_new(scintilla_get_type(), NULL));
-#endif
 }
 
 void scintilla_set_id(ScintillaObject *sci, uptr_t id) {
diff --git a/plugins/scintilla/scintilla/Selection.cxx b/plugins/scintilla/scintilla/Selection.cxx
index 2cdbe60..305d721 100644
--- a/plugins/scintilla/scintilla/Selection.cxx
+++ b/plugins/scintilla/scintilla/Selection.cxx
@@ -20,6 +20,9 @@ using namespace Scintilla;
 #endif
 
 void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) {
+	if (position == startChange) {
+		virtualSpace = 0;
+	}
 	if (insertion) {
 		if (position > startChange) {
 			position += length;
@@ -31,6 +34,7 @@ void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int
 				position -= length;
 			} else {
 				position = startChange;
+				virtualSpace = 0;
 			}
 		}
 	}
@@ -127,7 +131,7 @@ bool SelectionRange::Trim(SelectionRange range) {
 		} else if (start <= startRange) {
 			// Trim end
 			end = startRange;
-		} else { // 
+		} else { //
 			PLATFORM_ASSERT(end >= endRange);
 			// Trim start
 			start = endRange;
@@ -267,7 +271,7 @@ 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++) {
+			for (size_t j=i; j<ranges.size()-1; j++) {
 				ranges[j] = ranges[j+1];
 				if (j == mainRange-1)
 					mainRange--;
@@ -291,6 +295,11 @@ void Selection::AddSelection(SelectionRange range) {
 	mainRange = ranges.size() - 1;
 }
 
+void Selection::AddSelectionWithoutTrim(SelectionRange range) {
+	ranges.push_back(range);
+	mainRange = ranges.size() - 1;
+}
+
 void Selection::TentativeSelection(SelectionRange range) {
 	if (!tentativeMain) {
 		rangesSaved = ranges;
diff --git a/plugins/scintilla/scintilla/Selection.h b/plugins/scintilla/scintilla/Selection.h
index a3bac72..d7c7d79 100644
--- a/plugins/scintilla/scintilla/Selection.h
+++ b/plugins/scintilla/scintilla/Selection.h
@@ -57,10 +57,10 @@ public:
 };
 
 // Ordered range to make drawing simpler
-struct SelectionSegment {	
+struct SelectionSegment {
 	SelectionPosition start;
 	SelectionPosition end;
-	SelectionSegment() {
+	SelectionSegment() : start(), end() {
 	}
 	SelectionSegment(SelectionPosition a, SelectionPosition b) {
 		if (a < b) {
@@ -86,7 +86,7 @@ struct SelectionRange {
 	SelectionPosition caret;
 	SelectionPosition anchor;
 
-	SelectionRange() {
+	SelectionRange() : caret(), anchor() {
 	}
 	SelectionRange(SelectionPosition single) : caret(single), anchor(single) {
 	}
@@ -148,7 +148,7 @@ public:
 	int MainAnchor() const;
 	SelectionRange &Rectangular();
 	SelectionSegment Limits() const;
-	// This is for when you want to move the caret in response to a 
+	// This is for when you want to move the caret in response to a
 	// user direction command - for rectangular selections, use the range
 	// that covers all selected text otherwise return the main selection.
 	SelectionSegment LimitsForRectangularElseMain() const;
@@ -166,6 +166,7 @@ public:
 	void TrimSelection(SelectionRange range);
 	void SetSelection(SelectionRange range);
 	void AddSelection(SelectionRange range);
+	void AddSelectionWithoutTrim(SelectionRange range);
 	void TentativeSelection(SelectionRange range);
 	void CommitTentative();
 	int CharacterInSelection(int posCharacter) const;
diff --git a/plugins/scintilla/scintilla/SparseState.h b/plugins/scintilla/scintilla/SparseState.h
new file mode 100644
index 0000000..655d742
--- /dev/null
+++ b/plugins/scintilla/scintilla/SparseState.h
@@ -0,0 +1,110 @@
+// Scintilla source code edit control
+/** @file SparseState.h
+ ** Hold lexer state that may change rarely.
+ ** This is often per-line state such as whether a particular type of section has been entered.
+ ** A state continues until it is changed.
+ **/
+// Copyright 2011 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef SPARSESTATE_H
+#define SPARSESTATE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+template <typename T>
+class SparseState {
+	struct State {
+		int position;
+		T value;
+		State(int position_, T value_) : position(position_), value(value_) {
+		}
+		inline bool operator<(const State &other) const {
+			return position < other.position;
+		}
+		inline bool operator==(const State &other) const {
+			return (position == other.position) && (value == other.value);
+		}
+	};
+	int positionFirst;
+	typedef std::vector<State> stateVector;
+	stateVector states;
+
+	typename stateVector::iterator Find(int position) {
+		State searchValue(position, T());
+		return std::lower_bound(states.begin(), states.end(), searchValue);
+	}
+
+public:
+	SparseState(int positionFirst_=-1) {
+		positionFirst = positionFirst_;
+	}
+	void Set(int position, T value) {
+		Delete(position);
+		if (states.empty() || (value != states[states.size()-1].value)) {
+			states.push_back(State(position, value));
+		}
+	}
+	T ValueAt(int position) {
+		if (states.empty())
+			return T();
+		if (position < states[0].position)
+			return T();
+		typename stateVector::iterator low = Find(position);
+		if (low == states.end()) {
+			return states[states.size()-1].value;
+		} else {
+			if (low->position > position) {
+				--low;
+			}
+			return low->value;
+		}
+	}
+	bool Delete(int position) {
+		typename stateVector::iterator low = Find(position);
+		if (low != states.end()) {
+			states.erase(low, states.end());
+			return true;
+		}
+		return false;
+	}
+	size_t size() const {
+		return states.size();
+	}
+
+	// Returns true if Merge caused a significant change
+	bool Merge(const SparseState<T> &other, int ignoreAfter) {
+		// Changes caused beyond ignoreAfter are not significant
+		Delete(ignoreAfter+1);
+
+		bool different = true;
+		bool changed = false;
+		typename stateVector::iterator low = Find(other.positionFirst);
+		if (static_cast<size_t>(states.end() - low) == other.states.size()) {
+			// Same number in other as after positionFirst in this
+			different = !std::equal(low, states.end(), other.states.begin());
+		}
+		if (different) {
+			if (low != states.end()) {
+				states.erase(low, states.end());
+				changed = true;
+			}
+			typename stateVector::const_iterator startOther = other.states.begin();
+			if (!states.empty() && states.back().value == startOther->value)
+				++startOther;
+			if (startOther != other.states.end()) {
+				states.insert(states.end(), startOther, other.states.end());
+				changed = true;
+			}
+		}
+		return changed;
+	}
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/SplitVector.h b/plugins/scintilla/scintilla/SplitVector.h
index af4e890..44d5ddc 100644
--- a/plugins/scintilla/scintilla/SplitVector.h
+++ b/plugins/scintilla/scintilla/SplitVector.h
@@ -1,6 +1,6 @@
 // Scintilla source code edit control
 /** @file SplitVector.h
- ** Main data structure for holding arrays that handle insertions 
+ ** Main data structure for holding arrays that handle insertions
  ** and deletions efficiently.
  **/
 // Copyright 1998-2007 by Neil Hodgson <neilh scintilla org>
@@ -97,7 +97,7 @@ public:
 
 	/// Retrieve the character at a particular position.
 	/// Retrieving positions outside the range of the buffer returns 0.
-	/// The assertions here are disabled since calling code can be 
+	/// The assertions here are disabled since calling code can be
 	/// simpler if out of range access works and returns 0.
 	T ValueAt(int position) const {
 		if (position < part1Length) {
@@ -135,7 +135,7 @@ public:
 		}
 	}
 
-	T& operator[](int position) const {
+	T &operator[](int position) const {
 		PLATFORM_ASSERT(position >= 0 && position < lengthBody);
 		if (position < part1Length) {
 			return body[position];
@@ -182,14 +182,14 @@ public:
 		}
 	}
 
-	/// Ensure at least length elements allocated, 
+	/// Ensure at least length elements allocated,
 	/// appending zero valued elements if needed.
 	void EnsureLength(int wantedLength) {
 		if (Length() < wantedLength) {
 			InsertValue(Length(), wantedLength - Length(), 0);
 		}
 	}
-	
+
 	/// Insert text into the buffer from an array.
 	void InsertFromArray(int positionToInsert, const T s[], int positionFrom, int insertLength) {
 		PLATFORM_ASSERT((positionToInsert >= 0) && (positionToInsert <= lengthBody));
@@ -238,7 +238,24 @@ public:
 		DeleteRange(0, lengthBody);
 	}
 
-	T* BufferPointer() {
+	// Retrieve a range of elements into an array
+	void GetRange(T *buffer, int position, int retrieveLength) const {
+		// Split into up to 2 ranges, before and after the split then use memcpy on each.
+		int range1Length = 0;
+		if (position < part1Length) {
+			int part1AfterPosition = part1Length - position;
+			range1Length = retrieveLength;
+			if (range1Length > part1AfterPosition)
+				range1Length = part1AfterPosition;
+		}
+		memcpy(buffer, body + position, range1Length * sizeof(T));
+		buffer += range1Length;
+		position = position + range1Length + gapLength;
+		int range2Length = retrieveLength - range1Length;
+		memcpy(buffer, body + position, range2Length * sizeof(T));
+	}
+
+	T *BufferPointer() {
 		RoomFor(1);
 		GapTo(lengthBody);
 		body[lengthBody] = 0;
diff --git a/plugins/scintilla/scintilla/Style.cxx b/plugins/scintilla/scintilla/Style.cxx
index 4314dec..25efcd6 100644
--- a/plugins/scintilla/scintilla/Style.cxx
+++ b/plugins/scintilla/scintilla/Style.cxx
@@ -16,8 +16,45 @@
 using namespace Scintilla;
 #endif
 
+FontAlias::FontAlias() {
+}
+
+FontAlias::~FontAlias() {
+	SetID(0);
+	// ~Font will not release the actual font resource sine it is now 0
+}
+
+void FontAlias::MakeAlias(Font &fontOrigin) {
+	SetID(fontOrigin.GetID());
+}
+
+void FontAlias::ClearFont() {
+	SetID(0);
+}
+
+bool FontSpecification::EqualTo(const FontSpecification &other) const {
+	return bold == other.bold &&
+	       italic == other.italic &&
+	       size == other.size &&
+	       characterSet == other.characterSet &&
+	       fontName == other.fontName;
+}
+
+FontMeasurements::FontMeasurements() {
+	Clear();
+}
+
+void FontMeasurements::Clear() {
+	lineHeight = 2;
+	ascent = 1;
+	descent = 1;
+	externalLeading = 0;
+	aveCharWidth = 1;
+	spaceWidth = 1;
+	sizeZoomed = 2;
+}
+
 Style::Style() {
-	aliasOfDefaultFont = true;
 	Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
 	      Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT,
 	      false, false, false, false, caseMixed, true, true, false);
@@ -42,11 +79,6 @@ Style::Style(const Style &source) {
 }
 
 Style::~Style() {
-	if (aliasOfDefaultFont)
-		font.SetID(0);
-	else
-		font.Release();
-	aliasOfDefaultFont = false;
 }
 
 Style &Style::operator=(const Style &source) {
@@ -70,10 +102,10 @@ Style &Style::operator=(const Style &source) {
 }
 
 void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
-                  const char *fontName_, int characterSet_,
-                  bool bold_, bool italic_, bool eolFilled_,
-                  bool underline_, ecaseForced caseForce_,
-		  bool visible_, bool changeable_, bool hotspot_) {
+        const char *fontName_, int characterSet_,
+        bool bold_, bool italic_, bool eolFilled_,
+        bool underline_, ecaseForced caseForce_,
+        bool visible_, bool changeable_, bool hotspot_) {
 	fore.desired = fore_;
 	back.desired = back_;
 	characterSet = characterSet_;
@@ -87,72 +119,31 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
 	visible = visible_;
 	changeable = changeable_;
 	hotspot = hotspot_;
-	if (aliasOfDefaultFont)
-		font.SetID(0);
-	else
-		font.Release();
-	aliasOfDefaultFont = false;
+	font.ClearFont();
+	FontMeasurements::Clear();
 }
 
 void Style::ClearTo(const Style &source) {
 	Clear(
-		source.fore.desired,
-		source.back.desired,
-		source.size,
-		source.fontName,
-		source.characterSet,
-		source.bold,
-		source.italic,
-		source.eolFilled,
-		source.underline,
-		source.caseForce,
-		source.visible,
-		source.changeable,
-		source.hotspot);
+	    source.fore.desired,
+	    source.back.desired,
+	    source.size,
+	    source.fontName,
+	    source.characterSet,
+	    source.bold,
+	    source.italic,
+	    source.eolFilled,
+	    source.underline,
+	    source.caseForce,
+	    source.visible,
+	    source.changeable,
+	    source.hotspot);
 }
 
-bool Style::EquivalentFontTo(const Style *other) const {
-	if (bold != other->bold ||
-	        italic != other->italic ||
-	        size != other->size ||
-	        characterSet != other->characterSet)
-		return false;
-	if (fontName == other->fontName)
-		return true;
-	if (!fontName)
-		return false;
-	if (!other->fontName)
-		return false;
-	return strcmp(fontName, other->fontName) == 0;
-}
-
-void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle, int extraFontFlag) {
-	sizeZoomed = size + zoomLevel;
-	if (sizeZoomed <= 2)	// Hangs if sizeZoomed <= 1
-		sizeZoomed = 2;
-
-	if (aliasOfDefaultFont)
-		font.SetID(0);
-	else
-		font.Release();
-	int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
-	aliasOfDefaultFont = defaultStyle &&
-	                     (EquivalentFontTo(defaultStyle) || !fontName);
-	if (aliasOfDefaultFont) {
-		font.SetID(defaultStyle->font.GetID());
-	} else if (fontName) {
-		font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
-	} else {
-		font.SetID(0);
-	}
-
+void Style::Copy(Font &font_, const FontMeasurements &fm_) {
+	font.MakeAlias(font_);
+	(FontMeasurements &)(*this) = fm_;
+#if PLAT_WX
 	ascent = surface.Ascent(font);
-	descent = surface.Descent(font);
-	// Probably more typographically correct to include leading
-	// but that means more complex drawing as leading must be erased
-	//lineHeight = surface.ExternalLeading() + surface.Height();
-	externalLeading = surface.ExternalLeading(font);
-	lineHeight = surface.Height(font);
-	aveCharWidth = surface.AverageCharWidth(font);
-	spaceWidth = surface.WidthChar(font, ' ');
+#endif
 }
diff --git a/plugins/scintilla/scintilla/Style.h b/plugins/scintilla/scintilla/Style.h
index 0be3d4f..29122b0 100644
--- a/plugins/scintilla/scintilla/Style.h
+++ b/plugins/scintilla/scintilla/Style.h
@@ -12,18 +12,54 @@
 namespace Scintilla {
 #endif
 
+struct FontSpecification {
+	const char *fontName;
+	bool bold;
+	bool italic;
+	int size;
+	int characterSet;
+	int extraFontFlag;
+	FontSpecification() :
+		fontName(0),
+		bold(false),
+		italic(false),
+		size(10),
+		characterSet(0),
+		extraFontFlag(0) {
+	}
+	bool EqualTo(const FontSpecification &other) const;
+};
+
+// Just like Font but only has a copy of the FontID so should not delete it
+class FontAlias : public Font {
+	// Private so FontAlias objects can not be copied
+	FontAlias(const FontAlias &);
+	FontAlias &operator=(const FontAlias &);
+public:
+	FontAlias();
+	virtual ~FontAlias();
+	void MakeAlias(Font &fontOrigin);
+	void ClearFont();
+};
+
+struct FontMeasurements {
+	unsigned int lineHeight;
+	unsigned int ascent;
+	unsigned int descent;
+	unsigned int externalLeading;
+	unsigned int aveCharWidth;
+	unsigned int spaceWidth;
+	int sizeZoomed;
+	FontMeasurements();
+	void Clear();
+};
+
 /**
  */
-class Style {
+class Style : public FontSpecification, public FontMeasurements {
 public:
 	ColourPair fore;
 	ColourPair back;
-	bool aliasOfDefaultFont;
-	bool bold;
-	bool italic;
-	int size;
-	const char *fontName;
-	int characterSet;
 	bool eolFilled;
 	bool underline;
 	enum ecaseForced {caseMixed, caseUpper, caseLower};
@@ -32,14 +68,7 @@ public:
 	bool changeable;
 	bool hotspot;
 
-	Font font;
-	int sizeZoomed;
-	unsigned int lineHeight;
-	unsigned int ascent;
-	unsigned int descent;
-	unsigned int externalLeading;
-	unsigned int aveCharWidth;
-	unsigned int spaceWidth;
+	FontAlias font;
 
 	Style();
 	Style(const Style &source);
@@ -52,9 +81,8 @@ public:
 	           bool underline_, ecaseForced caseForce_,
 		   bool visible_, bool changeable_, bool hotspot_);
 	void ClearTo(const Style &source);
-	bool EquivalentFontTo(const Style *other) const;
-	void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, int extraFontFlag = 0);
-	bool IsProtected() const { return !(changeable && visible);};
+	void Copy(Font &font_, const FontMeasurements &fm_);
+	bool IsProtected() const { return !(changeable && visible);}
 };
 
 #ifdef SCI_NAMESPACE
diff --git a/plugins/scintilla/scintilla/StyleContext.cxx b/plugins/scintilla/scintilla/StyleContext.cxx
old mode 100755
new mode 100644
index 4a1f716..cf59fdd
--- a/plugins/scintilla/scintilla/StyleContext.cxx
+++ b/plugins/scintilla/scintilla/StyleContext.cxx
@@ -9,10 +9,11 @@
 #include <string.h>
 #include <ctype.h>
 #include <stdio.h>
+#include <assert.h>
 
-#include "Platform.h"
+#include "ILexer.h"
 
-#include "PropSet.h"
+#include "LexAccessor.h"
 #include "Accessor.h"
 #include "StyleContext.h"
 
@@ -22,7 +23,7 @@ using namespace Scintilla;
 
 static void getRange(unsigned int start,
 		unsigned int end,
-		Accessor &styler,
+		LexAccessor &styler,
 		char *s,
 		unsigned int len) {
 	unsigned int i = 0;
@@ -39,7 +40,7 @@ void StyleContext::GetCurrent(char *s, unsigned int len) {
 
 static void getRangeLowered(unsigned int start,
 		unsigned int end,
-		Accessor &styler,
+		LexAccessor &styler,
 		char *s,
 		unsigned int len) {
 	unsigned int i = 0;
diff --git a/plugins/scintilla/scintilla/StyleContext.h b/plugins/scintilla/scintilla/StyleContext.h
old mode 100755
new mode 100644
index 9342ebd..15d216b
--- a/plugins/scintilla/scintilla/StyleContext.h
+++ b/plugins/scintilla/scintilla/StyleContext.h
@@ -5,18 +5,28 @@
 // Copyright 1998-2004 by Neil Hodgson <neilh scintilla org>
 // This file is in the public domain.
 
+#ifndef STYLECONTEXT_H
+#define STYLECONTEXT_H
+
 #ifdef SCI_NAMESPACE
 namespace Scintilla {
 #endif
 
+static inline int MakeLowerCase(int ch) {
+	if (ch < 'A' || ch > 'Z')
+		return ch;
+	else
+		return ch - 'A' + 'a';
+}
+
 // All languages handled so far can treat all characters >= 0x80 as one class
 // which just continues the current token or starts an identifier if in default.
 // DBCS treated specially as the second character can be < 0x80 and hence
 // syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80
 class StyleContext {
-	Accessor &styler;
+	LexAccessor &styler;
 	unsigned int endPos;
-	StyleContext& operator=(const StyleContext&);
+	StyleContext &operator=(const StyleContext &);
 	void GetNextChar(unsigned int pos) {
 		chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
 		if (styler.IsLeadByte(static_cast<char>(chNext))) {
@@ -41,7 +51,7 @@ public:
 	int chNext;
 
 	StyleContext(unsigned int startPos, unsigned int length,
-                        int initStyle, Accessor &styler_, char chMask=31) :
+                        int initStyle, LexAccessor &styler_, char chMask=31) :
 		styler(styler_),
 		endPos(startPos + length),
 		currentPos(startPos),
@@ -64,8 +74,9 @@ public:
 	}
 	void Complete() {
 		styler.ColourTo(currentPos - 1, state);
+		styler.Flush();
 	}
-	bool More() {
+	bool More() const {
 		return currentPos < endPos;
 	}
 	void Forward() {
@@ -108,10 +119,10 @@ public:
 	int GetRelative(int n) {
 		return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n));
 	}
-	bool Match(char ch0) {
+	bool Match(char ch0) const {
 		return ch == static_cast<unsigned char>(ch0);
 	}
-	bool Match(char ch0, char ch1) {
+	bool Match(char ch0, char ch1) const {
 		return (ch == static_cast<unsigned char>(ch0)) && (chNext == static_cast<unsigned char>(ch1));
 	}
 	bool Match(const char *s) {
@@ -131,15 +142,15 @@ public:
 		return true;
 	}
 	bool MatchIgnoreCase(const char *s) {
-		if (tolower(ch) != static_cast<unsigned char>(*s))
+		if (MakeLowerCase(ch) != static_cast<unsigned char>(*s))
 			return false;
 		s++;
-		if (tolower(chNext) != static_cast<unsigned char>(*s))
+		if (MakeLowerCase(chNext) != static_cast<unsigned char>(*s))
 			return false;
 		s++;
 		for (int n=2; *s; n++) {
 			if (static_cast<unsigned char>(*s) !=
-				tolower(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n))))
+				MakeLowerCase(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n))))
 				return false;
 			s++;
 		}
@@ -154,24 +165,4 @@ public:
 }
 #endif
 
-inline bool IsASpace(unsigned int ch) {
-    return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
-}
-
-inline bool IsASpaceOrTab(unsigned int ch) {
-	return (ch == ' ') || (ch == '\t');
-}
-
-inline bool IsADigit(unsigned int ch) {
-	return (ch >= '0') && (ch <= '9');
-}
-
-inline bool IsADigit(unsigned int ch, unsigned int base) {
-	if (base <= 10) {
-		return (ch >= '0') && (ch < '0' + base);
-	} else {
-		return ((ch >= '0') && (ch <= '9')) ||
-		       ((ch >= 'A') && (ch < 'A' + base - 10)) ||
-		       ((ch >= 'a') && (ch < 'a' + base - 10));
-	}
-}
+#endif
diff --git a/plugins/scintilla/scintilla/UniConversion.cxx b/plugins/scintilla/scintilla/UniConversion.cxx
index 7dbe9e2..2ef7584 100644
--- a/plugins/scintilla/scintilla/UniConversion.cxx
+++ b/plugins/scintilla/scintilla/UniConversion.cxx
@@ -1,6 +1,6 @@
 // Scintilla source code edit control
 /** @file UniConversion.cxx
- ** Functions to handle UFT-8 and UCS-2 strings.
+ ** Functions to handle UTF-8 and UTF-16 strings.
  **/
 // Copyright 1998-2001 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
@@ -61,10 +61,22 @@ void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned
 	putf[len] = '\0';
 }
 
+unsigned int UTF8CharLength(unsigned char ch) {
+	if (ch < 0x80) {
+		return 1;
+	} else if (ch < 0x80 + 0x40 + 0x20) {
+		return 2;
+	} else if (ch < 0x80 + 0x40 + 0x20 + 0x10) {
+		return 3;
+	} else {
+		return 4;
+	}
+}
+
 unsigned int UTF16Length(const char *s, unsigned int len) {
 	unsigned int ulen = 0;
 	unsigned int charLen;
-	for (unsigned int i=0;i<len;) {
+	for (unsigned int i=0; i<len;) {
 		unsigned char ch = static_cast<unsigned char>(s[i]);
 		if (ch < 0x80) {
 			charLen = 1;
diff --git a/plugins/scintilla/scintilla/UniConversion.h b/plugins/scintilla/scintilla/UniConversion.h
index fd420a6..2de2ef3 100644
--- a/plugins/scintilla/scintilla/UniConversion.h
+++ b/plugins/scintilla/scintilla/UniConversion.h
@@ -1,12 +1,13 @@
 // Scintilla source code edit control
 /** @file UniConversion.h
- ** Functions to handle UFT-8 and UCS-2 strings.
+ ** Functions to handle UTF-8 and UTF-16 strings.
  **/
 // Copyright 1998-2001 by Neil Hodgson <neilh scintilla org>
 // The License.txt file describes the conditions under which this software may be distributed.
 
 unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen);
 void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len);
+unsigned int UTF8CharLength(unsigned char ch);
 unsigned int UTF16Length(const char *s, unsigned int len);
 unsigned int UTF16FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsigned int tlen);
 
diff --git a/plugins/scintilla/scintilla/ViewStyle.cxx b/plugins/scintilla/scintilla/ViewStyle.cxx
index 8e9c4a4..58e0ede 100644
--- a/plugins/scintilla/scintilla/ViewStyle.cxx
+++ b/plugins/scintilla/scintilla/ViewStyle.cxx
@@ -24,7 +24,7 @@ using namespace Scintilla;
 #endif
 
 MarginStyle::MarginStyle() :
-	style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false) {
+	style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false), cursor(SC_CURSORREVERSEARROW) {
 }
 
 // A list of the fontnames - avoids wasting space in each style
@@ -41,7 +41,7 @@ FontNames::~FontNames() {
 }
 
 void FontNames::Clear() {
-	for (int i=0;i<max;i++) {
+	for (int i=0; i<max; i++) {
 		delete []names[i];
 	}
 	max = 0;
@@ -50,7 +50,7 @@ void FontNames::Clear() {
 const char *FontNames::Save(const char *name) {
 	if (!name)
 		return 0;
-	for (int i=0;i<max;i++) {
+	for (int i=0; i<max; i++) {
 		if (strcmp(names[i], name) == 0) {
 			return names[i];
 		}
@@ -59,7 +59,7 @@ const char *FontNames::Save(const char *name) {
 		// Grow array
 		int sizeNew = size * 2;
 		char **namesNew = new char *[sizeNew];
-		for (int j=0;j<max;j++) {
+		for (int j=0; j<max; j++) {
 			namesNew[j] = names[j];
 		}
 		delete []names;
@@ -72,21 +72,75 @@ const char *FontNames::Save(const char *name) {
 	return names[max-1];
 }
 
+FontRealised::FontRealised(const FontSpecification &fs) {
+	frNext = NULL;
+	(FontSpecification &)(*this) = fs;
+}
+
+FontRealised::~FontRealised() {
+	delete frNext;
+	frNext = 0;
+}
+
+void FontRealised::Realise(Surface &surface, int zoomLevel) {
+	PLATFORM_ASSERT(fontName);
+	sizeZoomed = size + zoomLevel;
+	if (sizeZoomed <= 2)	// Hangs if sizeZoomed <= 1
+		sizeZoomed = 2;
+
+	int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
+	font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
+
+	ascent = surface.Ascent(font);
+	descent = surface.Descent(font);
+	externalLeading = surface.ExternalLeading(font);
+	lineHeight = surface.Height(font);
+	aveCharWidth = surface.AverageCharWidth(font);
+	spaceWidth = surface.WidthChar(font, ' ');
+	if (frNext) {
+		frNext->Realise(surface, zoomLevel);
+	}
+}
+
+FontRealised *FontRealised::Find(const FontSpecification &fs) {
+	if (!fs.fontName)
+		return this;
+	FontRealised *fr = this;
+	while (fr) {
+		if (fr->EqualTo(fs))
+			return fr;
+		fr = fr->frNext;
+	}
+	return 0;
+}
+
+void FontRealised::FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent) {
+	FontRealised *fr = this;
+	while (fr) {
+		if (maxAscent < fr->ascent)
+			maxAscent = fr->ascent;
+		if (maxDescent < fr->descent)
+			maxDescent = fr->descent;
+		fr = fr->frNext;
+	}
+}
+
 ViewStyle::ViewStyle() {
 	Init();
 }
 
 ViewStyle::ViewStyle(const ViewStyle &source) {
+	frFirst = NULL;
 	Init(source.stylesSize);
-	for (unsigned int sty=0;sty<source.stylesSize;sty++) {
+	for (unsigned int sty=0; sty<source.stylesSize; sty++) {
 		styles[sty] = source.styles[sty];
 		// Can't just copy fontname as its lifetime is relative to its owning ViewStyle
 		styles[sty].fontName = fontNames.Save(source.styles[sty].fontName);
 	}
-	for (int mrk=0;mrk<=MARKER_MAX;mrk++) {
+	for (int mrk=0; mrk<=MARKER_MAX; mrk++) {
 		markers[mrk] = source.markers[mrk];
 	}
-	for (int ind=0;ind<=INDIC_MAX;ind++) {
+	for (int ind=0; ind<=INDIC_MAX; ind++) {
 		indicators[ind] = source.indicators[ind];
 	}
 
@@ -129,9 +183,10 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
 	caretStyle = source.caretStyle;
 	caretWidth = source.caretWidth;
 	someStylesProtected = false;
+	someStylesForceCase = false;
 	leftMarginWidth = source.leftMarginWidth;
 	rightMarginWidth = source.rightMarginWidth;
-	for (int i=0;i < margins; i++) {
+	for (int i=0; i < margins; i++) {
 		ms[i] = source.ms[i];
 	}
 	symbolMargin = source.symbolMargin;
@@ -149,14 +204,21 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
 	marginStyleOffset = source.marginStyleOffset;
 	annotationVisible = source.annotationVisible;
 	annotationStyleOffset = source.annotationStyleOffset;
+	braceHighlightIndicatorSet = source.braceHighlightIndicatorSet;
+	braceHighlightIndicator = source.braceHighlightIndicator;
+	braceBadLightIndicatorSet = source.braceBadLightIndicatorSet;
+	braceBadLightIndicator = source.braceBadLightIndicator;
 }
 
 ViewStyle::~ViewStyle() {
 	delete []styles;
 	styles = NULL;
+	delete frFirst;
+	frFirst = NULL;
 }
 
 void ViewStyle::Init(size_t stylesSize_) {
+	frFirst = NULL;
 	stylesSize = 0;
 	styles = NULL;
 	AllocStyles(stylesSize_);
@@ -213,6 +275,7 @@ void ViewStyle::Init(size_t stylesSize_) {
 	caretStyle = CARETSTYLE_LINE;
 	caretWidth = 1;
 	someStylesProtected = false;
+	someStylesForceCase = false;
 
 	hotspotForegroundSet = false;
 	hotspotForeground.desired = ColourDesired(0, 0, 0xff);
@@ -253,18 +316,22 @@ void ViewStyle::Init(size_t stylesSize_) {
 	marginStyleOffset = 0;
 	annotationVisible = ANNOTATION_HIDDEN;
 	annotationStyleOffset = 0;
+	braceHighlightIndicatorSet = false;
+	braceHighlightIndicator = 0;
+	braceBadLightIndicatorSet = false;
+	braceBadLightIndicator = 0;
 }
 
 void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
 	unsigned int i;
-	for (i=0;i<stylesSize;i++) {
+	for (i=0; i<stylesSize; i++) {
 		pal.WantFind(styles[i].fore, want);
 		pal.WantFind(styles[i].back, want);
 	}
-	for (i=0;i<(sizeof(indicators)/sizeof(indicators[0]));i++) {
+	for (i=0; i<(sizeof(indicators)/sizeof(indicators[0])); i++) {
 		pal.WantFind(indicators[i].fore, want);
 	}
-	for (i=0;i<(sizeof(markers)/sizeof(markers[0]));i++) {
+	for (i=0; i<(sizeof(markers)/sizeof(markers[0])); i++) {
 		markers[i].RefreshColourPalette(pal, want);
 	}
 	pal.WantFind(selforeground, want);
@@ -288,29 +355,59 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
 	pal.WantFind(hotspotBackground, want);
 }
 
+void ViewStyle::CreateFont(const FontSpecification &fs) {
+	if (fs.fontName) {
+		for (FontRealised *cur=frFirst; cur; cur=cur->frNext) {
+			if (cur->EqualTo(fs))
+				return;
+			if (!cur->frNext) {
+				cur->frNext = new FontRealised(fs);
+				return;
+			}
+		}
+		frFirst = new FontRealised(fs);
+	}
+}
+
 void ViewStyle::Refresh(Surface &surface) {
+	delete frFirst;
+	frFirst = NULL;
 	selbar.desired = Platform::Chrome();
 	selbarlight.desired = Platform::ChromeHighlight();
-	styles[STYLE_DEFAULT].Realise(surface, zoomLevel, NULL, extraFontFlag);
-	maxAscent = styles[STYLE_DEFAULT].ascent;
-	maxDescent = styles[STYLE_DEFAULT].descent;
-	someStylesProtected = false;
+
 	for (unsigned int i=0; i<stylesSize; i++) {
-		if (i != STYLE_DEFAULT) {
-			styles[i].Realise(surface, zoomLevel, &styles[STYLE_DEFAULT], extraFontFlag);
-			if (maxAscent < styles[i].ascent)
-				maxAscent = styles[i].ascent;
-			if (maxDescent < styles[i].descent)
-				maxDescent = styles[i].descent;
-		}
-		if (styles[i].IsProtected()) {
-			someStylesProtected = true;
-		}
+		styles[i].extraFontFlag = extraFontFlag;
+	}
+
+	CreateFont(styles[STYLE_DEFAULT]);
+	for (unsigned int j=0; j<stylesSize; j++) {
+		CreateFont(styles[j]);
 	}
+
+	frFirst->Realise(surface, zoomLevel);
+
+	for (unsigned int k=0; k<stylesSize; k++) {
+		FontRealised *fr = frFirst->Find(styles[k]);
+		styles[k].Copy(fr->font, *fr);
+	}
+	maxAscent = 1;
+	maxDescent = 1;
+	frFirst->FindMaxAscentDescent(maxAscent, maxDescent);
 	maxAscent += extraAscent;
 	maxDescent += extraDescent;
-
 	lineHeight = maxAscent + maxDescent;
+
+	someStylesProtected = false;
+	someStylesForceCase = false;
+	for (unsigned int l=0; l<stylesSize; l++) {
+		if (styles[l].IsProtected()) {
+			someStylesProtected = true;
+		}
+		if (styles[l].caseForce != Style::caseMixed) {
+			someStylesForceCase = true;
+		}
+	}
+
 	aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
 	spaceWidth = styles[STYLE_DEFAULT].spaceWidth;
 
@@ -355,10 +452,10 @@ void ViewStyle::EnsureStyle(size_t index) {
 
 void ViewStyle::ResetDefaultStyle() {
 	styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0),
-		ColourDesired(0xff,0xff,0xff),
-		Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
-		SC_CHARSET_DEFAULT,
-		false, false, false, false, Style::caseMixed, true, true, false);
+	        ColourDesired(0xff,0xff,0xff),
+	        Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
+	        SC_CHARSET_DEFAULT,
+	        false, false, false, false, Style::caseMixed, true, true, false);
 }
 
 void ViewStyle::ClearStyles() {
diff --git a/plugins/scintilla/scintilla/ViewStyle.h b/plugins/scintilla/scintilla/ViewStyle.h
index 22e365b..b038a9b 100644
--- a/plugins/scintilla/scintilla/ViewStyle.h
+++ b/plugins/scintilla/scintilla/ViewStyle.h
@@ -20,6 +20,7 @@ public:
 	int width;
 	int mask;
 	bool sensitive;
+	int cursor;
 	MarginStyle();
 };
 
@@ -38,6 +39,20 @@ public:
 	const char *Save(const char *name);
 };
 
+class FontRealised : public FontSpecification, public FontMeasurements {
+	// Private so FontRealised objects can not be copied
+	FontRealised(const FontRealised &);
+	FontRealised &operator=(const FontRealised &);
+public:
+	Font font;
+	FontRealised *frNext;
+	FontRealised(const FontSpecification &fs);
+	virtual ~FontRealised();
+	void Realise(Surface &surface, int zoomLevel);
+	FontRealised *Find(const FontSpecification &fs);
+	void FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent);
+};
+
 enum IndentView {ivNone, ivReal, ivLookForward, ivLookBoth};
 
 enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2};
@@ -47,6 +62,7 @@ enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterInden
 class ViewStyle {
 public:
 	FontNames fontNames;
+	FontRealised *frFirst;
 	size_t stylesSize;
 	Style *styles;
 	LineMarker markers[MARKER_MAX + 1];
@@ -106,17 +122,23 @@ public:
 	int caretStyle;
 	int caretWidth;
 	bool someStylesProtected;
+	bool someStylesForceCase;
 	int extraFontFlag;
 	int extraAscent;
 	int extraDescent;
 	int marginStyleOffset;
 	int annotationVisible;
 	int annotationStyleOffset;
+	bool braceHighlightIndicatorSet;
+	int braceHighlightIndicator;
+	bool braceBadLightIndicatorSet;
+	int braceBadLightIndicator;
 
 	ViewStyle();
 	ViewStyle(const ViewStyle &source);
 	~ViewStyle();
 	void Init(size_t stylesSize_=64);
+	void CreateFont(const FontSpecification &fs);
 	void RefreshColourPalette(Palette &pal, bool want);
 	void Refresh(Surface &surface);
 	void AllocStyles(size_t sizeNew);
diff --git a/plugins/scintilla/scintilla/WordList.cxx b/plugins/scintilla/scintilla/WordList.cxx
new file mode 100644
index 0000000..cda35ec
--- /dev/null
+++ b/plugins/scintilla/scintilla/WordList.cxx
@@ -0,0 +1,205 @@
+// Scintilla source code edit control
+/** @file KeyWords.cxx
+ ** Colourise for particular languages.
+ **/
+// 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 "WordList.h"
+
+#ifdef SCI_NAMESPACE
+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;
+}
+
+bool WordList::operator!=(const WordList &other) const {
+	if (len != other.len)
+		return true;
+	for (int i=0; i<len; i++) {
+		if (strcmp(words[i], other.words[i]) != 0)
+			return true;
+	}
+	return false;
+}
+
+void WordList::Clear() {
+	if (words) {
+		delete []list;
+		delete []words;
+	}
+	words = 0;
+	list = 0;
+	len = 0;
+}
+
+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);
+}
+
+void WordList::Set(const char *s) {
+	Clear();
+	list = new char[strlen(s) + 1];
+	strcpy(list, s);
+	words = ArrayFromWordList(list, &len, onlyLineEnds);
+	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;
+	}
+}
+
+/** Check whether a string is in the list.
+ * List elements are either exact matches or prefixes.
+ * Prefix elements start with '^' and match all strings that start with the rest of the element
+ * so '^GTK_' matches 'GTK_X', 'GTK_MAJOR_VERSION', and 'GTK_'.
+ */
+bool WordList::InList(const char *s) const {
+	if (0 == words)
+		return false;
+	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) const {
+	if (0 == words)
+		return false;
+	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;
+}
diff --git a/plugins/scintilla/scintilla/WordList.h b/plugins/scintilla/scintilla/WordList.h
new file mode 100644
index 0000000..ea5be1d
--- /dev/null
+++ b/plugins/scintilla/scintilla/WordList.h
@@ -0,0 +1,41 @@
+// Scintilla source code edit control
+/** @file WordList.h
+ ** Hold a list of words.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef WORDLIST_H
+#define WORDLIST_H
+
+#ifdef SCI_NAMESPACE
+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
+	int starts[256];
+	WordList(bool onlyLineEnds_ = false) :
+		words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_)
+		{}
+	~WordList() { Clear(); }
+	operator bool() const { return len ? true : false; }
+	bool operator!=(const WordList &other) const;
+	void Clear();
+	void Set(const char *s);
+	bool InList(const char *s) const;
+	bool InListAbbreviated(const char *s, const char marker) const;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/XPM.cxx b/plugins/scintilla/scintilla/XPM.cxx
old mode 100755
new mode 100644
index 7fc05bb..d1389ef
--- a/plugins/scintilla/scintilla/XPM.cxx
+++ b/plugins/scintilla/scintilla/XPM.cxx
@@ -38,7 +38,7 @@ static size_t MeasureLength(const char *s) {
 	return i;
 }
 
-ColourAllocated XPM::ColourFromCode(int ch) {
+ColourAllocated XPM::ColourFromCode(int ch) const {
 	return colourCodeTable[ch]->allocated;
 #ifdef SLOW
 	for (int i=0; i<nColours; i++) {
@@ -62,7 +62,7 @@ XPM::XPM(const char *textForm) :
 	Init(textForm);
 }
 
-XPM::XPM(const char * const *linesForm) :
+XPM::XPM(const char *const *linesForm) :
 	data(0), codes(0), colours(0), lines(0) {
 	Init(linesForm);
 }
@@ -88,7 +88,7 @@ void XPM::Init(const char *textForm) {
 	}
 }
 
-void XPM::Init(const char * const *linesForm) {
+void XPM::Init(const char *const *linesForm) {
 	Clear();
 	height = 1;
 	width = 1;
@@ -185,7 +185,7 @@ void XPM::Draw(Surface *surface, PRectangle &rc) {
 	// Centre the pixmap
 	int startY = rc.top + (rc.Height() - height) / 2;
 	int startX = rc.left + (rc.Width() - width) / 2;
-	for (int y=0;y<height;y++) {
+	for (int y=0; y<height; y++) {
 		int prevCode = 0;
 		int xStartRun = 0;
 		for (int x=0; x<width; x++) {
diff --git a/plugins/scintilla/scintilla/XPM.h b/plugins/scintilla/scintilla/XPM.h
old mode 100755
new mode 100644
index 07cb580..cb05aae
--- a/plugins/scintilla/scintilla/XPM.h
+++ b/plugins/scintilla/scintilla/XPM.h
@@ -24,16 +24,16 @@ class XPM {
 	char codeTransparent;
 	char *codes;
 	ColourPair *colours;
-	ColourAllocated ColourFromCode(int ch);
+	ColourAllocated ColourFromCode(int ch) const;
 	void FillRun(Surface *surface, int code, int startX, int y, int x);
 	char **lines;
 	ColourPair *colourCodeTable[256];
 public:
 	XPM(const char *textForm);
-	XPM(const char * const *linesForm);
+	XPM(const char *const *linesForm);
 	~XPM();
 	void Init(const char *textForm);
-	void Init(const char * const *linesForm);
+	void Init(const char *const *linesForm);
 	void Clear();
 	/// Similar to same named method in ViewStyle:
 	void RefreshColourPalette(Palette &pal, bool want);
@@ -43,9 +43,9 @@ public:
 	void Draw(Surface *surface, PRectangle &rc);
 	char **InLinesForm() { return lines; }
 	void SetId(int pid_) { pid = pid_; }
-	int GetId() { return pid; }
-	int GetHeight() { return height; }
-	int GetWidth() { return width; }
+	int GetId() const { return pid; }
+	int GetHeight() const { return height; }
+	int GetWidth() const { return width; }
 	static const char **LinesFormFromTextForm(const char *textForm);
 };
 
diff --git a/plugins/scintilla/scintilla/include/HFacer.py b/plugins/scintilla/scintilla/include/HFacer.py
index 62a8273..074ce96 100755
--- a/plugins/scintilla/scintilla/include/HFacer.py
+++ b/plugins/scintilla/scintilla/include/HFacer.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
 # 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*/
diff --git a/plugins/scintilla/scintilla/include/ILexer.h b/plugins/scintilla/scintilla/include/ILexer.h
new file mode 100644
index 0000000..b119ff6
--- /dev/null
+++ b/plugins/scintilla/scintilla/include/ILexer.h
@@ -0,0 +1,69 @@
+// Scintilla source code edit control
+/** @file ILexer.h
+ ** Interface between Scintilla and lexers.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef ILEXER_H
+#define ILEXER_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+#ifdef _WIN32
+	#define SCI_METHOD __stdcall
+#else
+	#define SCI_METHOD
+#endif
+
+enum { dvOriginal=0 };
+
+class IDocument {
+public:
+	virtual int SCI_METHOD Version() const = 0;
+	virtual void SCI_METHOD SetErrorStatus(int status) = 0;
+	virtual int SCI_METHOD Length() const = 0;
+	virtual void SCI_METHOD GetCharRange(char *buffer, int position, int lengthRetrieve) const = 0;
+	virtual char SCI_METHOD StyleAt(int position) const = 0;
+	virtual int SCI_METHOD LineFromPosition(int position) const = 0;
+	virtual int SCI_METHOD LineStart(int line) const = 0;
+	virtual int SCI_METHOD GetLevel(int line) const = 0;
+	virtual int SCI_METHOD SetLevel(int line, int level) = 0;
+	virtual int SCI_METHOD GetLineState(int line) const = 0;
+	virtual int SCI_METHOD SetLineState(int line, int state) = 0;
+	virtual void SCI_METHOD StartStyling(int position, char mask) = 0;
+	virtual bool SCI_METHOD SetStyleFor(int length, char style) = 0;
+	virtual bool SCI_METHOD SetStyles(int length, const char *styles) = 0;
+	virtual void SCI_METHOD DecorationSetCurrentIndicator(int indicator) = 0;
+	virtual void SCI_METHOD DecorationFillRange(int position, int value, int fillLength) = 0;
+	virtual void SCI_METHOD ChangeLexerState(int start, int end) = 0;
+	virtual int SCI_METHOD CodePage() const = 0;
+	virtual bool SCI_METHOD IsDBCSLeadByte(char ch) const = 0;
+	virtual const char * SCI_METHOD BufferPointer() = 0;
+	virtual int SCI_METHOD GetLineIndentation(int line) = 0;
+};
+
+enum { lvOriginal=0 };
+
+class ILexer {
+public:
+	virtual int SCI_METHOD Version() const = 0;
+	virtual void SCI_METHOD Release() = 0;
+	virtual const char * SCI_METHOD PropertyNames() = 0;
+	virtual int SCI_METHOD PropertyType(const char *name) = 0;
+	virtual const char * SCI_METHOD DescribeProperty(const char *name) = 0;
+	virtual int SCI_METHOD PropertySet(const char *key, const char *val) = 0;
+	virtual const char * SCI_METHOD DescribeWordListSets() = 0;
+	virtual int SCI_METHOD WordListSet(int n, const char *wl) = 0;
+	virtual void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+	virtual void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+	virtual void * SCI_METHOD PrivateCall(int operation, void *pointer) = 0;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/include/Platform.h b/plugins/scintilla/scintilla/include/Platform.h
index b5d6d9b..fd36a32 100644
--- a/plugins/scintilla/scintilla/include/Platform.h
+++ b/plugins/scintilla/scintilla/include/Platform.h
@@ -255,8 +255,8 @@ class Palette {
 	int allocatedLen;
 #endif
 	// Private so Palette objects can not be copied
-	Palette(const Palette &) {}
-	Palette &operator=(const Palette &) { return *this; }
+	Palette(const Palette &);
+	Palette &operator=(const Palette &);
 public:
 #if PLAT_WIN
 	void *hpal;
@@ -288,8 +288,8 @@ protected:
 	int ascent;
 #endif
 	// Private so Font objects can not be copied
-	Font(const Font &) {}
-	Font &operator=(const Font &) { fid=0; return *this; }
+	Font(const Font &);
+	Font &operator=(const Font &);
 public:
 	Font();
 	virtual ~Font();
@@ -302,7 +302,7 @@ public:
 	// Alias another font - caller guarantees not to Release
 	void SetID(FontID fid_) { fid = fid_; }
 	friend class Surface;
-        friend class SurfaceImpl;
+	friend class SurfaceImpl;
 };
 
 /**
@@ -314,8 +314,8 @@ private:
 	Surface(const Surface &) {}
 	Surface &operator=(const Surface &) { return *this; }
 public:
-	Surface() {};
-	virtual ~Surface() {};
+	Surface() {}
+	virtual ~Surface() {}
 	static Surface *Allocate();
 
 	virtual void Init(WindowID wid)=0;
@@ -411,8 +411,8 @@ public:
 	void SetTitle(const char *s);
 	PRectangle GetMonitorRect(Point pt);
 #if PLAT_MACOSX
-	void SetWindow(void *ref) { windowRef = ref; };
-	void SetControl(void *_control) { control = _control; };
+	void SetWindow(void *ref) { windowRef = ref; }
+	void SetControl(void *_control) { control = _control; }
 #endif
 private:
 	Cursor cursorLast;
@@ -474,7 +474,7 @@ public:
  */
 class DynamicLibrary {
 public:
-	virtual ~DynamicLibrary() {};
+	virtual ~DynamicLibrary() {}
 
 	/// @return Pointer to function "name", or NULL on failure.
 	virtual Function FindFunction(const char *name) = 0;
diff --git a/plugins/scintilla/scintilla/include/SciLexer.h b/plugins/scintilla/scintilla/include/SciLexer.h
index ced86f4..1d5b69e 100644
--- a/plugins/scintilla/scintilla/include/SciLexer.h
+++ b/plugins/scintilla/scintilla/include/SciLexer.h
@@ -111,6 +111,9 @@
 #define SCLEX_NIMROD 96
 #define SCLEX_SML 97
 #define SCLEX_MARKDOWN 98
+#define SCLEX_TXT2TAGS 99
+#define SCLEX_A68K 100
+#define SCLEX_MODULA 101
 #define SCLEX_AUTOMATIC 1000
 #define SCE_P_DEFAULT 0
 #define SCE_P_COMMENTLINE 1
@@ -148,6 +151,8 @@
 #define SCE_C_COMMENTDOCKEYWORD 17
 #define SCE_C_COMMENTDOCKEYWORDERROR 18
 #define SCE_C_GLOBALCLASS 19
+#define SCE_C_STRINGRAW 20
+#define SCE_C_TRIPLEVERBATIM 21
 #define SCE_D_DEFAULT 0
 #define SCE_D_COMMENT 1
 #define SCE_D_COMMENTLINE 2
@@ -600,6 +605,7 @@
 #define SCE_ASM_CHARACTER 12
 #define SCE_ASM_STRINGEOL 13
 #define SCE_ASM_EXTINSTRUCTION 14
+#define SCE_ASM_COMMENTDIRECTIVE 15
 #define SCE_F_DEFAULT 0
 #define SCE_F_COMMENT 1
 #define SCE_F_NUMBER 2
@@ -637,6 +643,7 @@
 #define SCE_CSS_EXTENDED_IDENTIFIER 19
 #define SCE_CSS_EXTENDED_PSEUDOCLASS 20
 #define SCE_CSS_EXTENDED_PSEUDOELEMENT 21
+#define SCE_CSS_MEDIA 22
 #define SCE_POV_DEFAULT 0
 #define SCE_POV_COMMENT 1
 #define SCE_POV_COMMENTLINE 2
@@ -1081,11 +1088,19 @@
 #define SCE_FS_DATE 16
 #define SCE_FS_STRINGEOL 17
 #define SCE_FS_CONSTANT 18
-#define SCE_FS_ASM 19
-#define SCE_FS_LABEL 20
-#define SCE_FS_ERROR 21
-#define SCE_FS_HEXNUMBER 22
-#define SCE_FS_BINNUMBER 23
+#define SCE_FS_WORDOPERATOR 19
+#define SCE_FS_DISABLEDCODE 20
+#define SCE_FS_DEFAULT_C 21
+#define SCE_FS_COMMENTDOC_C 22
+#define SCE_FS_COMMENTLINEDOC_C 23
+#define SCE_FS_KEYWORD_C 24
+#define SCE_FS_KEYWORD2_C 25
+#define SCE_FS_NUMBER_C 26
+#define SCE_FS_STRING_C 27
+#define SCE_FS_PREPROCESSOR_C 28
+#define SCE_FS_OPERATOR_C 29
+#define SCE_FS_IDENTIFIER_C 30
+#define SCE_FS_STRINGEOL_C 31
 #define SCE_CSOUND_DEFAULT 0
 #define SCE_CSOUND_COMMENT 1
 #define SCE_CSOUND_NUMBER 2
@@ -1266,6 +1281,9 @@
 #define SCE_POWERSHELL_KEYWORD 8
 #define SCE_POWERSHELL_CMDLET 9
 #define SCE_POWERSHELL_ALIAS 10
+#define SCE_POWERSHELL_FUNCTION 11
+#define SCE_POWERSHELL_USER1 12
+#define SCE_POWERSHELL_COMMENTSTREAM 13
 #define SCE_MYSQL_DEFAULT 0
 #define SCE_MYSQL_COMMENT 1
 #define SCE_MYSQL_COMMENTLINE 2
@@ -1376,6 +1394,69 @@
 #define SCE_MARKDOWN_CODE 19
 #define SCE_MARKDOWN_CODE2 20
 #define SCE_MARKDOWN_CODEBK 21
+#define SCE_TXT2TAGS_DEFAULT 0
+#define SCE_TXT2TAGS_LINE_BEGIN 1
+#define SCE_TXT2TAGS_STRONG1 2
+#define SCE_TXT2TAGS_STRONG2 3
+#define SCE_TXT2TAGS_EM1 4
+#define SCE_TXT2TAGS_EM2 5
+#define SCE_TXT2TAGS_HEADER1 6
+#define SCE_TXT2TAGS_HEADER2 7
+#define SCE_TXT2TAGS_HEADER3 8
+#define SCE_TXT2TAGS_HEADER4 9
+#define SCE_TXT2TAGS_HEADER5 10
+#define SCE_TXT2TAGS_HEADER6 11
+#define SCE_TXT2TAGS_PRECHAR 12
+#define SCE_TXT2TAGS_ULIST_ITEM 13
+#define SCE_TXT2TAGS_OLIST_ITEM 14
+#define SCE_TXT2TAGS_BLOCKQUOTE 15
+#define SCE_TXT2TAGS_STRIKEOUT 16
+#define SCE_TXT2TAGS_HRULE 17
+#define SCE_TXT2TAGS_LINK 18
+#define SCE_TXT2TAGS_CODE 19
+#define SCE_TXT2TAGS_CODE2 20
+#define SCE_TXT2TAGS_CODEBK 21
+#define SCE_TXT2TAGS_COMMENT 22
+#define SCE_TXT2TAGS_OPTION 23
+#define SCE_TXT2TAGS_PREPROC 24
+#define SCE_TXT2TAGS_POSTPROC 25
+#define SCE_A68K_DEFAULT 0
+#define SCE_A68K_COMMENT 1
+#define SCE_A68K_NUMBER_DEC 2
+#define SCE_A68K_NUMBER_BIN 3
+#define SCE_A68K_NUMBER_HEX 4
+#define SCE_A68K_STRING1 5
+#define SCE_A68K_OPERATOR 6
+#define SCE_A68K_CPUINSTRUCTION 7
+#define SCE_A68K_EXTINSTRUCTION 8
+#define SCE_A68K_REGISTER 9
+#define SCE_A68K_DIRECTIVE 10
+#define SCE_A68K_MACRO_ARG 11
+#define SCE_A68K_LABEL 12
+#define SCE_A68K_STRING2 13
+#define SCE_A68K_IDENTIFIER 14
+#define SCE_A68K_MACRO_DECLARATION 15
+#define SCE_A68K_COMMENT_WORD 16
+#define SCE_A68K_COMMENT_SPECIAL 17
+#define SCE_A68K_COMMENT_DOXYGEN 18
+#define SCE_MODULA_DEFAULT 0
+#define SCE_MODULA_COMMENT 1
+#define SCE_MODULA_DOXYCOMM 2
+#define SCE_MODULA_DOXYKEY 3
+#define SCE_MODULA_KEYWORD 4
+#define SCE_MODULA_RESERVED 5
+#define SCE_MODULA_NUMBER 6
+#define SCE_MODULA_BASENUM 7
+#define SCE_MODULA_FLOAT 8
+#define SCE_MODULA_STRING 9
+#define SCE_MODULA_STRSPEC 10
+#define SCE_MODULA_CHAR 11
+#define SCE_MODULA_CHARSPEC 12
+#define SCE_MODULA_PROC 13
+#define SCE_MODULA_PRAGMA 14
+#define SCE_MODULA_PRGKEY 15
+#define SCE_MODULA_OPERATOR 16
+#define SCE_MODULA_BADSTR 17
 /* --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 2359212..f1c4fa9 100644
--- a/plugins/scintilla/scintilla/include/Scintilla.h
+++ b/plugins/scintilla/scintilla/include/Scintilla.h
@@ -11,18 +11,14 @@
 #ifndef SCINTILLA_H
 #define SCINTILLA_H
 
-#if LCCWIN
-typedef BOOL bool;
-#endif
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#if PLAT_WIN
+#if defined(_WIN32)
 /* Return false on failure: */
-bool Scintilla_RegisterClasses(void *hInstance);
-bool Scintilla_ReleaseResources();
+int Scintilla_RegisterClasses(void *hInstance);
+int Scintilla_ReleaseResources();
 #endif
 int Scintilla_LinkLexers();
 
@@ -36,11 +32,6 @@ int Scintilla_LinkLexers();
 #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;
@@ -48,7 +39,6 @@ typedef LONG_PTR sptr_t;
 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);
 
@@ -101,7 +91,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_SETTABWIDTH 2036
 #define SCI_GETTABWIDTH 2121
 #define SC_CP_UTF8 65001
-#define SC_CP_DBCS 1
 #define SCI_SETCODEPAGE 2037
 #define SCI_SETUSEPALETTE 2039
 #define MARKER_MAX 31
@@ -147,6 +136,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_MARKERDEFINE 2040
 #define SCI_MARKERSETFORE 2041
 #define SCI_MARKERSETBACK 2042
+#define SCI_MARKERSETBACKSELECTED 2292
+#define SCI_MARKERENABLEHIGHLIGHT 2293
 #define SCI_MARKERADD 2043
 #define SCI_MARKERDELETE 2044
 #define SCI_MARKERDELETEALL 2045
@@ -170,6 +161,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_GETMARGINMASKN 2245
 #define SCI_SETMARGINSENSITIVEN 2246
 #define SCI_GETMARGINSENSITIVEN 2247
+#define SCI_SETMARGINCURSORN 2248
+#define SCI_GETMARGINCURSORN 2249
 #define STYLE_DEFAULT 32
 #define STYLE_LINENUMBER 33
 #define STYLE_BRACELIGHT 34
@@ -254,6 +247,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define INDIC_HIDDEN 5
 #define INDIC_BOX 6
 #define INDIC_ROUNDBOX 7
+#define INDIC_STRAIGHTBOX 8
 #define INDIC_MAX 31
 #define INDIC_CONTAINER 8
 #define INDIC0_MASK 0x20
@@ -492,6 +486,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_SETFONTQUALITY 2611
 #define SCI_GETFONTQUALITY 2612
 #define SCI_SETFIRSTVISIBLELINE 2613
+#define SC_MULTIPASTE_ONCE 0
+#define SC_MULTIPASTE_EACH 1
+#define SCI_SETMULTIPASTE 2614
+#define SCI_GETMULTIPASTE 2615
+#define SCI_GETTAG 2616
 #define SCI_TARGETFROMSELECTION 2287
 #define SCI_LINESJOIN 2288
 #define SCI_LINESSPLIT 2289
@@ -558,7 +557,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_MOVECARETINSIDEVIEW 2401
 #define SCI_LINELENGTH 2350
 #define SCI_BRACEHIGHLIGHT 2351
+#define SCI_BRACEHIGHLIGHTINDICATOR 2498
 #define SCI_BRACEBADLIGHT 2352
+#define SCI_BRACEBADLIGHTINDICATOR 2499
 #define SCI_BRACEMATCH 2353
 #define SCI_GETVIEWEOL 2355
 #define SCI_SETVIEWEOL 2356
@@ -596,7 +597,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_SETMOUSEDOWNCAPTURES 2384
 #define SCI_GETMOUSEDOWNCAPTURES 2385
 #define SC_CURSORNORMAL -1
+#define SC_CURSORARROW 2
 #define SC_CURSORWAIT 4
+#define SC_CURSORREVERSEARROW 7
 #define SCI_SETCURSOR 2386
 #define SCI_GETCURSOR 2387
 #define SCI_SETCONTROLCHARSYMBOL 2388
@@ -674,6 +677,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_FINDCOLUMN 2456
 #define SCI_GETCARETSTICKY 2457
 #define SCI_SETCARETSTICKY 2458
+#define SC_CARETSTICKY_OFF 0
+#define SC_CARETSTICKY_ON 1
+#define SC_CARETSTICKY_WHITESPACE 2
 #define SCI_TOGGLECARETSTICKY 2459
 #define SCI_SETPASTECONVERTENDINGS 2467
 #define SCI_GETPASTECONVERTENDINGS 2468
@@ -706,6 +712,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_GETKEYSUNICODE 2522
 #define SCI_INDICSETALPHA 2523
 #define SCI_INDICGETALPHA 2524
+#define SCI_INDICSETOUTLINEALPHA 2558
+#define SCI_INDICGETOUTLINEALPHA 2559
 #define SCI_SETEXTRAASCENT 2525
 #define SCI_GETEXTRAASCENT 2526
 #define SCI_SETEXTRADESCENT 2527
@@ -788,6 +796,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_GETADDITIONALCARETFORE 2605
 #define SCI_ROTATESELECTION 2606
 #define SCI_SWAPMAINANCHORCARET 2607
+#define SCI_CHANGELEXERSTATE 2617
+#define SCI_CONTRACTEDFOLDNEXT 2618
+#define SCI_VERTICALCENTRECARET 2619
+#define SCI_MOVESELECTEDLINESUP 2620
+#define SCI_MOVESELECTEDLINESDOWN 2621
 #define SCI_STARTRECORD 3001
 #define SCI_STOPRECORD 3002
 #define SCI_SETLEXER 4001
@@ -803,6 +816,14 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCI_GETPROPERTYINT 4010
 #define SCI_GETSTYLEBITSNEEDED 4011
 #define SCI_GETLEXERLANGUAGE 4012
+#define SCI_PRIVATELEXERCALL 4013
+#define SCI_PROPERTYNAMES 4014
+#define SC_TYPE_BOOLEAN 0
+#define SC_TYPE_INTEGER 1
+#define SC_TYPE_STRING 2
+#define SCI_PROPERTYTYPE 4015
+#define SCI_DESCRIBEPROPERTY 4016
+#define SCI_DESCRIBEKEYWORDSETS 4017
 #define SC_MOD_INSERTTEXT 0x1
 #define SC_MOD_DELETETEXT 0x2
 #define SC_MOD_CHANGESTYLE 0x4
@@ -822,7 +843,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_MOD_CHANGEMARGIN 0x10000
 #define SC_MOD_CHANGEANNOTATION 0x20000
 #define SC_MOD_CONTAINER 0x40000
-#define SC_MODEVENTMASKALL 0x7FFFF
+#define SC_MOD_LEXERSTATE 0x80000
+#define SC_MODEVENTMASKALL 0xFFFFF
+#define SC_UPDATE_CONTENT 0x1
+#define SC_UPDATE_SELECTION 0x2
+#define SC_UPDATE_V_SCROLL 0x4
+#define SC_UPDATE_H_SCROLL 0x8
 #define SCEN_CHANGE 768
 #define SCEN_SETFOCUS 512
 #define SCEN_KILLFOCUS 256
@@ -877,6 +903,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SCN_INDICATORRELEASE 2024
 #define SCN_AUTOCCANCELLED 2025
 #define SCN_AUTOCCHARDELETED 2026
+#define SCN_HOTSPOTRELEASECLICK 2027
 /* --Autogenerated -- end of section automatically generated from Scintilla.iface */
 
 /* These structures are defined to be exactly the same shape as the Win32
@@ -907,23 +934,28 @@ struct Sci_TextToFind {
 #define TextRange Sci_TextRange
 #define TextToFind Sci_TextToFind
 
-#ifdef PLATFORM_H
+typedef void *Sci_SurfaceID;
+
+struct Sci_Rectangle {
+	int left;
+	int top;
+	int right;
+	int bottom;
+};
 
 /* This structure is used in printing and requires some of the graphics types
  * from Platform.h.  Not needed by most client code. */
 
 struct Sci_RangeToFormat {
-	SurfaceID hdc;
-	SurfaceID hdcTarget;
-	PRectangle rc;
-	PRectangle rcPage;
-	Sci_CharacterRange chrg;
+	Sci_SurfaceID hdc;
+	Sci_SurfaceID hdcTarget;
+	struct Sci_Rectangle rc;
+	struct Sci_Rectangle rcPage;
+	struct Sci_CharacterRange chrg;
 };
 
 #define RangeToFormat Sci_RangeToFormat
 
-#endif
-
 struct Sci_NotifyHeader {
 	/* Compatible with Windows NMHDR.
 	 * hwndFrom is really an environment specific window handle or pointer
@@ -937,11 +969,22 @@ struct Sci_NotifyHeader {
 
 struct SCNotification {
 	struct Sci_NotifyHeader nmhdr;
-	int position;	/* SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND */
+	int position;
+	/* SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_MARGINCLICK, */
+	/* SCN_NEEDSHOWN, SCN_DWELLSTART, SCN_DWELLEND, SCN_CALLTIPCLICK, */
+	/* SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK, */
+	/* SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
+	/* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
+
 	int ch;		/* SCN_CHARADDED, SCN_KEY */
-	int modifiers;	/* SCN_KEY */
+	int modifiers;
+	/* SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, */
+	/* SCN_HOTSPOTRELEASECLICK, SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
+
 	int modificationType;	/* SCN_MODIFIED */
-	const char *text;	/* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
+	const char *text;
+	/* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */
+
 	int length;		/* SCN_MODIFIED */
 	int linesAdded;	/* SCN_MODIFIED */
 	int message;	/* SCN_MACRORECORD */
@@ -955,11 +998,18 @@ struct SCNotification {
 	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 */
+	int annotationLinesAdded;	/* SCN_MODIFIED with SC_MOD_CHANGEANNOTATION */
+	int updated;	/* SCN_UPDATEUI */
 };
 
 #ifdef SCI_NAMESPACE
 }
 #endif
 
+#ifdef INCLUDE_DEPRECATED_FEATURES
+
+#define SC_CP_DBCS 1
+
+#endif
+
 #endif
diff --git a/plugins/scintilla/scintilla/include/Scintilla.iface b/plugins/scintilla/scintilla/include/Scintilla.iface
old mode 100755
new mode 100644
index f2c8f1e..8cd3ab5
--- a/plugins/scintilla/scintilla/include/Scintilla.iface
+++ b/plugins/scintilla/scintilla/include/Scintilla.iface
@@ -224,9 +224,6 @@ get int GetTabWidth=2121(,)
 # This is the same value as CP_UTF8 in Windows
 val SC_CP_UTF8=65001
 
-# The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+.
-val SC_CP_DBCS=1
-
 # Set the code page used to interpret the bytes of the document as characters.
 # The SC_CP_UTF8 value can be used to enter Unicode mode.
 set void SetCodePage=2037(int codePage,)
@@ -262,7 +259,7 @@ val SC_MARK_CIRCLEPLUSCONNECTED=19
 val SC_MARK_CIRCLEMINUS=20
 val SC_MARK_CIRCLEMINUSCONNECTED=21
 
-# Invisible mark that only sets the line background color.
+# Invisible mark that only sets the line background colour.
 val SC_MARK_BACKGROUND=22
 val SC_MARK_DOTDOTDOT=23
 val SC_MARK_ARROWS=24
@@ -295,6 +292,12 @@ fun void MarkerSetFore=2041(int markerNumber, colour fore)
 # Set the background colour used for a particular marker number.
 fun void MarkerSetBack=2042(int markerNumber, colour back)
 
+# Set the background colour used for a particular marker number when its folding block is selected.
+fun void MarkerSetBackSelected=2292(int markerNumber, colour back)
+
+# Enable/disable highlight for current folding bloc (smallest one that contains the caret)
+fun void MarkerEnableHighlight=2293(bool enabled,)
+
 # Add a marker to a line, returning an ID which can be used to find or delete the marker.
 fun int MarkerAdd=2043(int line, int markerNumber)
 
@@ -307,7 +310,8 @@ fun void MarkerDeleteAll=2045(int markerNumber,)
 # Get a bit mask of all the markers set on a line.
 fun int MarkerGet=2046(int line,)
 
-# Find the next line after lineStart that includes a marker in mask.
+# Find the next line at or after lineStart that includes a marker in mask.
+# Return -1 when no more lines.
 fun int MarkerNext=2047(int lineStart, int markerMask)
 
 # Find the previous line before lineStart that includes a marker in mask.
@@ -354,6 +358,12 @@ set void SetMarginSensitiveN=2246(int margin, bool sensitive)
 # Retrieve the mouse click sensitivity of a margin.
 get bool GetMarginSensitiveN=2247(int margin,)
 
+# Set the cursor shown when the mouse is inside a margin.
+set void SetMarginCursorN=2248(int margin, int cursor)
+
+# Retrieve the cursor shown in a margin.
+get int GetMarginCursorN=2249(int margin,)
+
 # Styles in range 32..38 are predefined for parts of the UI and are not used as normal styles.
 # Style 39 is for future use.
 enu StylesCommon=STYLE_
@@ -540,6 +550,7 @@ val INDIC_STRIKE=4
 val INDIC_HIDDEN=5
 val INDIC_BOX=6
 val INDIC_ROUNDBOX=7
+val INDIC_STRAIGHTBOX=8
 val INDIC_MAX=31
 val INDIC_CONTAINER=8
 val INDIC0_MASK=0x20
@@ -1223,6 +1234,19 @@ get int GetFontQuality=2612(,)
 # Scroll so that a display line is at the top of the display.
 set void SetFirstVisibleLine=2613(int lineDisplay,)
 
+enu MultiPaste=SC_MULTIPASTE_
+val SC_MULTIPASTE_ONCE=0
+val SC_MULTIPASTE_EACH=1
+
+# Change the effect of pasting when there are multiple selections.
+set void SetMultiPaste=2614(int multiPaste,)
+
+# Retrieve the effect of pasting when there are multiple selections..
+get int GetMultiPaste=2615(,)
+
+# Retrieve the value of a tag from a regular expression search.
+fun int GetTag=2616(int tagNumber, stringresult tagValue)
+
 # Make the target range start and end be the same as the selection range start and end.
 fun void TargetFromSelection=2287(,)
 
@@ -1423,9 +1447,15 @@ fun int LineLength=2350(int line,)
 # Highlight the characters at two positions.
 fun void BraceHighlight=2351(position pos1, position pos2)
 
+# Use specified indicator to highlight matching braces instead of changing their style.
+fun void BraceHighlightIndicator=2498(bool useBraceHighlightIndicator, int indicator)
+
 # Highlight the character at a position indicating there is no matching brace.
 fun void BraceBadLight=2352(position pos,)
 
+# Use specified indicator to highlight non matching brace instead of changing its style.
+fun void BraceBadLightIndicator=2499(bool useBraceBadLightIndicator, int indicator)
+
 # Find the position of a matching brace or INVALID_POSITION if no match.
 fun position BraceMatch=2353(position pos,)
 
@@ -1529,7 +1559,9 @@ get bool GetMouseDownCaptures=2385(,)
 
 enu CursorShape=SC_CURSOR
 val SC_CURSORNORMAL=-1
+val SC_CURSORARROW=2
 val SC_CURSORWAIT=4
+val SC_CURSORREVERSEARROW=7
 # Sets the cursor to one of the SC_CURSOR* values.
 set void SetCursor=2386(int cursorType,)
 # Get cursor type.
@@ -1767,10 +1799,15 @@ fun int EncodedFromUTF8=2449(string utf8, stringresult encoded)
 fun int FindColumn=2456(int line, int column)
 
 # Can the caret preferred x position only be changed by explicit movement commands?
-get bool GetCaretSticky=2457(,)
+get int GetCaretSticky=2457(,)
 
 # Stop the caret preferred x position changing when the user types.
-set void SetCaretSticky=2458(bool useCaretStickyBehaviour,)
+set void SetCaretSticky=2458(int useCaretStickyBehaviour,)
+
+enu CaretSticky=SC_CARETSTICKY_
+val SC_CARETSTICKY_OFF=0
+val SC_CARETSTICKY_ON=1
+val SC_CARETSTICKY_WHITESPACE=2
 
 # Switch between sticky and non-sticky: meant to be bound to a key.
 fun void ToggleCaretSticky=2459(,)
@@ -1860,6 +1897,12 @@ set void IndicSetAlpha=2523(int indicator, int alpha)
 # Get the alpha fill colour of the given indicator.
 get int IndicGetAlpha=2524(int indicator,)
 
+# Set the alpha outline colour of the given indicator.
+set void IndicSetOutlineAlpha=2558(int indicator, int alpha)
+
+# Get the alpha outline colour of the given indicator.
+get int IndicGetOutlineAlpha=2559(int indicator,)
+
 # Set extra ascent for each line
 set void SetExtraAscent=2525(int extraAscent,)
 
@@ -2071,6 +2114,23 @@ fun void RotateSelection=2606(,)
 # Swap that caret and anchor of the main selection.
 fun void SwapMainAnchorCaret=2607(,)
 
+# Indicate that the internal state of a lexer has changed over a range and therefore
+# there may be a need to redraw.
+fun int ChangeLexerState=2617(position start, position end)
+
+# Find the next line at or after lineStart that is a contracted fold header line.
+# Return -1 when no more lines.
+fun int ContractedFoldNext=2618(int lineStart,)
+
+# Centre current line in window.
+fun void VerticalCentreCaret=2619(,)
+
+# Move the selected lines up one line, shifting the line above after the selection
+fun void MoveSelectedLinesUp=2620(,)
+
+# Move the selected lines down one line, shifting the line below before the selection
+fun void MoveSelectedLinesDown=2621(,)
+
 # Start notifying the container of all key presses and commands.
 fun void StartRecord=3001(,)
 
@@ -2119,6 +2179,26 @@ get int GetStyleBitsNeeded=4011(,)
 # Return the length of the text.
 get int GetLexerLanguage=4012(, stringresult text)
 
+# For private communication between an application and a known lexer.
+fun int PrivateLexerCall=4013(int operation, int pointer)
+
+# Retrieve a '\n' separated list of properties understood by the current lexer.
+fun int PropertyNames=4014(, stringresult names)
+
+enu TypeProperty=SC_TYPE_
+val SC_TYPE_BOOLEAN=0
+val SC_TYPE_INTEGER=1
+val SC_TYPE_STRING=2
+
+# Retrieve the type of a property.
+fun int PropertyType=4015(string name,)
+
+# Describe a property.
+fun int DescribeProperty=4016(string name, stringresult description)
+
+# Retrieve a '\n' separated list of descriptions of the keyword sets understood by the current lexer.
+fun int DescribeKeyWordSets=4017(, stringresult descriptions)
+
 # Notifications
 # Type of modification and the action which caused the modification.
 # These are defined as a bit mask to make it easy to specify which notifications are wanted.
@@ -2143,7 +2223,14 @@ val SC_MOD_CHANGELINESTATE=0x8000
 val SC_MOD_CHANGEMARGIN=0x10000
 val SC_MOD_CHANGEANNOTATION=0x20000
 val SC_MOD_CONTAINER=0x40000
-val SC_MODEVENTMASKALL=0x7FFFF
+val SC_MOD_LEXERSTATE=0x80000
+val SC_MODEVENTMASKALL=0xFFFFF
+
+enu Update=SC_UPDATE_
+val SC_UPDATE_CONTENT=0x1
+val SC_UPDATE_SELECTION=0x2
+val SC_UPDATE_V_SCROLL=0x4
+val SC_UPDATE_H_SCROLL=0x8
 
 # For compatibility, these go through the COMMAND notification rather than NOTIFY
 # and should have had exactly the same values as the EN_* constants.
@@ -2286,6 +2373,9 @@ val SCLEX_POWERPRO=95
 val SCLEX_NIMROD=96
 val SCLEX_SML=97
 val SCLEX_MARKDOWN=98
+val SCLEX_TXT2TAGS=99
+val SCLEX_A68K=100
+val SCLEX_MODULA=101
 
 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
 # value assigned in sequence from SCLEX_AUTOMATIC+1.
@@ -2332,6 +2422,8 @@ val SCE_C_WORD2=16
 val SCE_C_COMMENTDOCKEYWORD=17
 val SCE_C_COMMENTDOCKEYWORDERROR=18
 val SCE_C_GLOBALCLASS=19
+val SCE_C_STRINGRAW=20
+val SCE_C_TRIPLEVERBATIM=21
 # Lexical states for SCLEX_D
 lex D=SCLEX_D SCE_D_
 val SCE_D_DEFAULT=0
@@ -2851,6 +2943,7 @@ val SCE_ASM_COMMENTBLOCK=11
 val SCE_ASM_CHARACTER=12
 val SCE_ASM_STRINGEOL=13
 val SCE_ASM_EXTINSTRUCTION=14
+val SCE_ASM_COMMENTDIRECTIVE=15
 # Lexical states for SCLEX_FORTRAN
 lex Fortran=SCLEX_FORTRAN SCE_F_
 lex F77=SCLEX_F77 SCE_F_
@@ -2893,6 +2986,7 @@ val SCE_CSS_PSEUDOELEMENT=18
 val SCE_CSS_EXTENDED_IDENTIFIER=19
 val SCE_CSS_EXTENDED_PSEUDOCLASS=20
 val SCE_CSS_EXTENDED_PSEUDOELEMENT=21
+val SCE_CSS_MEDIA=22
 # Lexical states for SCLEX_POV
 lex POV=SCLEX_POV SCE_POV_
 val SCE_POV_DEFAULT=0
@@ -3375,7 +3469,7 @@ val SCE_ST_ASSIGN=14
 val SCE_ST_CHARACTER=15
 val SCE_ST_SPEC_SEL=16
 # Lexical states for SCLEX_FLAGSHIP (clipper)
-lex FlagShip=SCLEX_FLAGSHIP SCE_B_
+lex FlagShip=SCLEX_FLAGSHIP SCE_FS_
 val SCE_FS_DEFAULT=0
 val SCE_FS_COMMENT=1
 val SCE_FS_COMMENTLINE=2
@@ -3395,11 +3489,19 @@ val SCE_FS_IDENTIFIER=15
 val SCE_FS_DATE=16
 val SCE_FS_STRINGEOL=17
 val SCE_FS_CONSTANT=18
-val SCE_FS_ASM=19
-val SCE_FS_LABEL=20
-val SCE_FS_ERROR=21
-val SCE_FS_HEXNUMBER=22
-val SCE_FS_BINNUMBER=23
+val SCE_FS_WORDOPERATOR=19
+val SCE_FS_DISABLEDCODE=20
+val SCE_FS_DEFAULT_C=21
+val SCE_FS_COMMENTDOC_C=22
+val SCE_FS_COMMENTLINEDOC_C=23
+val SCE_FS_KEYWORD_C=24
+val SCE_FS_KEYWORD2_C=25
+val SCE_FS_NUMBER_C=26
+val SCE_FS_STRING_C=27
+val SCE_FS_PREPROCESSOR_C=28
+val SCE_FS_OPERATOR_C=29
+val SCE_FS_IDENTIFIER_C=30
+val SCE_FS_STRINGEOL_C=31
 # Lexical states for SCLEX_CSOUND
 lex Csound=SCLEX_CSOUND SCE_CSOUND_
 val SCE_CSOUND_DEFAULT=0
@@ -3606,6 +3708,9 @@ val SCE_POWERSHELL_IDENTIFIER=7
 val SCE_POWERSHELL_KEYWORD=8
 val SCE_POWERSHELL_CMDLET=9
 val SCE_POWERSHELL_ALIAS=10
+val SCE_POWERSHELL_FUNCTION=11
+val SCE_POWERSHELL_USER1=12
+val SCE_POWERSHELL_COMMENTSTREAM=13
 # Lexical state for SCLEX_MYSQL
 lex MySQL=SCLEX_MYSQL SCE_MYSQL_
 val SCE_MYSQL_DEFAULT=0
@@ -3730,6 +3835,75 @@ val SCE_MARKDOWN_LINK=18
 val SCE_MARKDOWN_CODE=19
 val SCE_MARKDOWN_CODE2=20
 val SCE_MARKDOWN_CODEBK=21
+# Lexical state for SCLEX_TXT2TAGS
+lex Txt2tags=SCLEX_TXT2TAGS SCE_TXT2TAGS_
+val SCE_TXT2TAGS_DEFAULT=0
+val SCE_TXT2TAGS_LINE_BEGIN=1
+val SCE_TXT2TAGS_STRONG1=2
+val SCE_TXT2TAGS_STRONG2=3
+val SCE_TXT2TAGS_EM1=4
+val SCE_TXT2TAGS_EM2=5
+val SCE_TXT2TAGS_HEADER1=6
+val SCE_TXT2TAGS_HEADER2=7
+val SCE_TXT2TAGS_HEADER3=8
+val SCE_TXT2TAGS_HEADER4=9
+val SCE_TXT2TAGS_HEADER5=10
+val SCE_TXT2TAGS_HEADER6=11
+val SCE_TXT2TAGS_PRECHAR=12
+val SCE_TXT2TAGS_ULIST_ITEM=13
+val SCE_TXT2TAGS_OLIST_ITEM=14
+val SCE_TXT2TAGS_BLOCKQUOTE=15
+val SCE_TXT2TAGS_STRIKEOUT=16
+val SCE_TXT2TAGS_HRULE=17
+val SCE_TXT2TAGS_LINK=18
+val SCE_TXT2TAGS_CODE=19
+val SCE_TXT2TAGS_CODE2=20
+val SCE_TXT2TAGS_CODEBK=21
+val SCE_TXT2TAGS_COMMENT=22
+val SCE_TXT2TAGS_OPTION=23
+val SCE_TXT2TAGS_PREPROC=24
+val SCE_TXT2TAGS_POSTPROC=25
+# Lexical states for SCLEX_A68K
+lex A68k=SCLEX_A68K SCE_A68K_
+val SCE_A68K_DEFAULT=0
+val SCE_A68K_COMMENT=1
+val SCE_A68K_NUMBER_DEC=2
+val SCE_A68K_NUMBER_BIN=3
+val SCE_A68K_NUMBER_HEX=4
+val SCE_A68K_STRING1=5
+val SCE_A68K_OPERATOR=6
+val SCE_A68K_CPUINSTRUCTION=7
+val SCE_A68K_EXTINSTRUCTION=8
+val SCE_A68K_REGISTER=9
+val SCE_A68K_DIRECTIVE=10
+val SCE_A68K_MACRO_ARG=11
+val SCE_A68K_LABEL=12
+val SCE_A68K_STRING2=13
+val SCE_A68K_IDENTIFIER=14
+val SCE_A68K_MACRO_DECLARATION=15
+val SCE_A68K_COMMENT_WORD=16
+val SCE_A68K_COMMENT_SPECIAL=17
+val SCE_A68K_COMMENT_DOXYGEN=18
+# Lexical states for SCLEX_MODULA
+lex Modula=SCLEX_MODULA SCE_MODULA_
+val SCE_MODULA_DEFAULT=0
+val SCE_MODULA_COMMENT=1
+val SCE_MODULA_DOXYCOMM=2
+val SCE_MODULA_DOXYKEY=3
+val SCE_MODULA_KEYWORD=4
+val SCE_MODULA_RESERVED=5
+val SCE_MODULA_NUMBER=6
+val SCE_MODULA_BASENUM=7
+val SCE_MODULA_FLOAT=8
+val SCE_MODULA_STRING=9
+val SCE_MODULA_STRSPEC=10
+val SCE_MODULA_CHAR=11
+val SCE_MODULA_CHARSPEC=12
+val SCE_MODULA_PROC=13
+val SCE_MODULA_PRAGMA=14
+val SCE_MODULA_PRGKEY=15
+val SCE_MODULA_OPERATOR=16
+val SCE_MODULA_BADSTR=17
 
 # Events
 
@@ -3740,23 +3914,30 @@ evt void SavePointLeft=2003(void)
 evt void ModifyAttemptRO=2004(void)
 # GTK+ Specific to work around focus and accelerator problems:
 evt void Key=2005(int ch, int modifiers)
-evt void DoubleClick=2006(void)
-evt void UpdateUI=2007(void)
-evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev)
+evt void DoubleClick=2006(int modifiers, int position, int line)
+evt void UpdateUI=2007(int updated)
+evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev, int token, int annotationLinesAdded)
 evt void MacroRecord=2009(int message, int wParam, int lParam)
 evt void MarginClick=2010(int modifiers, int position, int margin)
 evt void NeedShown=2011(int position, int length)
 evt void Painted=2013(void)
-evt void UserListSelection=2014(int listType, string text)
+evt void UserListSelection=2014(int listType, string text, int position)
 evt void URIDropped=2015(string text)
-evt void DwellStart=2016(int position)
-evt void DwellEnd=2017(int position)
+evt void DwellStart=2016(int position, int x, int y)
+evt void DwellEnd=2017(int position, int x, int y)
 evt void Zoom=2018(void)
 evt void HotSpotClick=2019(int modifiers, int position)
 evt void HotSpotDoubleClick=2020(int modifiers, int position)
 evt void CallTipClick=2021(int position)
-evt void AutoCSelection=2022(string text)
+evt void AutoCSelection=2022(string text, int position)
 evt void IndicatorClick=2023(int modifiers, int position)
 evt void IndicatorRelease=2024(int modifiers, int position)
 evt void AutoCCancelled=2025(void)
 evt void AutoCCharDeleted=2026(void)
+evt void HotSpotReleaseClick=2027(int modifiers, int position)
+
+cat Deprecated
+
+# Deprecated in 2.21
+# The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+.
+val SC_CP_DBCS=1
diff --git a/plugins/scintilla/scintilla/include/ScintillaWidget.h b/plugins/scintilla/scintilla/include/ScintillaWidget.h
index eccc983..d1df6cf 100644
--- a/plugins/scintilla/scintilla/include/ScintillaWidget.h
+++ b/plugins/scintilla/scintilla/include/ScintillaWidget.h
@@ -9,14 +9,14 @@
 #ifndef SCINTILLAWIDGET_H
 #define SCINTILLAWIDGET_H
 
-#if PLAT_GTK
+#if defined(GTK)
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #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 SCINTILLA_CLASS(klass)  GTK_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;
@@ -34,21 +34,13 @@ struct _ScintillaClass {
 	void (* notify) (ScintillaObject *ttt);
 };
 
-#if GLIB_MAJOR_VERSION < 2
-GtkType		scintilla_get_type	(void);
-#else
 GType		scintilla_get_type	(void);
-#endif
 GtkWidget*	scintilla_new		(void);
 void		scintilla_set_id	(ScintillaObject *sci, uptr_t id);
 sptr_t		scintilla_send_message	(ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam);
 void		scintilla_release_resources(void);
 
-#if GTK_MAJOR_VERSION < 2
-#define SCINTILLA_NOTIFY "notify"
-#else
 #define SCINTILLA_NOTIFY "sci-notify"
-#endif
 
 #ifdef __cplusplus
 }
diff --git a/plugins/scintilla/scintilla/lexers.make b/plugins/scintilla/scintilla/lexers.make
index ddebba0..fa32e55 100644
--- a/plugins/scintilla/scintilla/lexers.make
+++ b/plugins/scintilla/scintilla/lexers.make
@@ -1,6 +1,7 @@
 ## Lexers make file
 LEXER_OBJS = \
 	StyleContext.o\
+	LexA68k.o\
 	LexAbaqus.o\
 	LexAda.o\
 	LexAPDL.o\
@@ -24,7 +25,11 @@ LEXER_OBJS = \
 	LexCSS.o\
 	LexD.o\
 	LexEiffel.o\
+	LexerBase.o\
 	LexErlang.o\
+	LexerModule.o\
+	LexerNoExceptions.o\
+	LexerSimple.o\
 	LexEScript.o\
 	LexFlagship.o\
 	LexForth.o\
@@ -43,6 +48,7 @@ LEXER_OBJS = \
 	LexMatlab.o\
 	LexMetapost.o\
 	LexMMIXAL.o\
+	LexModula.o\
 	LexMPT.o\
 	LexMSSQL.o\
 	LexMySQL.o\
@@ -75,12 +81,14 @@ LEXER_OBJS = \
 	LexTAL.o\
 	LexTCL.o\
 	LexTeX.o\
+	LexTxt2tags.o\
 	LexVB.o\
 	LexVerilog.o\
 	LexVHDL.o\
 	LexYAML.o
 
 LEXER_SRCS = \
+	LexA68k.cxx\
 	LexAbaqus.cxx\
 	LexAda.cxx\
 	LexAPDL.cxx\
@@ -104,7 +112,11 @@ LEXER_SRCS = \
 	LexCSS.cxx\
 	LexD.cxx\
 	LexEiffel.cxx\
+	LexerBase.cxx\
 	LexErlang.cxx\
+	LexerModule.cxx\
+	LexerNoExceptions.cxx\
+	LexerSimple.cxx\
 	LexEScript.cxx\
 	LexFlagship.cxx\
 	LexForth.cxx\
@@ -123,6 +135,7 @@ LEXER_SRCS = \
 	LexMatlab.cxx\
 	LexMetapost.cxx\
 	LexMMIXAL.cxx\
+	LexModula.cxx\
 	LexMPT.cxx\
 	LexMSSQL.cxx\
 	LexMySQL.cxx\
@@ -155,6 +168,7 @@ LEXER_SRCS = \
 	LexTAL.cxx\
 	LexTCL.cxx\
 	LexTeX.cxx\
+	LexTxt2tags.cxx\
 	LexVB.cxx\
 	LexVerilog.cxx\
 	LexVHDL.cxx\
diff --git a/plugins/scintilla/scintilla/test-scintilla.cxx b/plugins/scintilla/scintilla/test-scintilla.cxx
index c4cdd4a..e27b62d 100644
--- a/plugins/scintilla/scintilla/test-scintilla.cxx
+++ b/plugins/scintilla/scintilla/test-scintilla.cxx
@@ -8,6 +8,40 @@
 #include <Scintilla.h>
 #include <ScintillaWidget.h>
 
+
+static int IntFromHexDigit(int ch) {
+        if ((ch >= '0') && (ch <= '9')) {
+                return ch - '0';
+        } else if (ch >= 'A' && ch <= 'F') {
+                return ch - 'A' + 10;
+        } else if (ch >= 'a' && ch <= 'f') {
+                return ch - 'a' + 10;
+        } else {
+                return 0;
+        }
+}
+
+static int IntFromHexByte(const char *hexByte) {
+        return IntFromHexDigit(hexByte[0]) * 16 + IntFromHexDigit(hexByte[1]);
+}
+
+typedef long Colour;
+Colour ColourRGB(unsigned int red, unsigned int green, unsigned int blue)
+{
+	return red | (green << 8) | (blue << 16);
+}
+
+static Colour ColourFromString(const char *s) {
+        if ((s != NULL) && (*s != '\0')) {
+                int r = IntFromHexByte(s + 1);
+                int g = IntFromHexByte(s + 3);
+                int b = IntFromHexByte(s + 5);
+                return ColourRGB(r, g, b);
+        } else {
+                return 0;
+        }
+}
+
 void SetOneStyle(GtkWidget *sci, int style, const char *s) {
 	char *val = strdup(s);
 	char *opt = val;
@@ -29,11 +63,11 @@ void SetOneStyle(GtkWidget *sci, int style, const char *s) {
 		if (0 == strcmp(opt, "font"))
 			scintilla_send_message(SCINTILLA(sci), SCI_STYLESETFONT, style, reinterpret_cast<long>(colon));
 		if (0 == strcmp(opt, "fore"))
-			//scintilla_send_message(SCINTILLA(sci), SCI_STYLESETFORE, style, ColourFromString(colon).AsLong());
+			scintilla_send_message(SCINTILLA(sci), SCI_STYLESETFORE, style, ColourFromString(colon));
 		if (0 == strcmp(opt, "back"))
-			//scintilla_send_message(SCINTILLA(sci), SCI_STYLESETBACK, style, ColourFromString(colon).AsLong());
+			scintilla_send_message(SCINTILLA(sci), SCI_STYLESETBACK, style, ColourFromString(colon));
 		if (0 == strcmp(opt, "size"))
-			scintilla_send_message(SCINTILLA(sci), SCI_STYLESETSIZE, style, atoi(colon));
+				scintilla_send_message(SCINTILLA(sci), SCI_STYLESETSIZE, style, atoi(colon));
 		if (0 == strcmp(opt, "eolfilled"))
 			scintilla_send_message(SCINTILLA(sci), SCI_STYLESETEOLFILLED, style, 1);
 		if (0 == strcmp(opt, "noteolfilled"))
@@ -91,7 +125,7 @@ int main(int argc, char **argv)
 	scintilla_send_message(SCINTILLA(sci), SCI_SETHSCROLLBAR, 0, 0);
 	scintilla_send_message(SCINTILLA(sci), SCI_SETCODEPAGE, SC_CP_UTF8, 0);
 	scintilla_send_message(SCINTILLA(sci), SCI_SETMARGINWIDTHN, 0, 40);
-	//scintilla_set_id(SCINTILLA(sci), 0);
+	scintilla_set_id(SCINTILLA(sci), 0);
 	gtk_container_add (GTK_CONTAINER(win), sci);
 	g_signal_connect (G_OBJECT (win), "delete-event",
 					  G_CALLBACK (gtk_main_quit), NULL);
diff --git a/plugins/scintilla/style-editor.c b/plugins/scintilla/style-editor.c
index a64f8fa..ff54584 100644
--- a/plugins/scintilla/style-editor.c
+++ b/plugins/scintilla/style-editor.c
@@ -572,7 +572,7 @@ on_hilite_style_entry_changed (GtkComboBox * combobox, gpointer user_data)
 	g_return_if_fail (user_data);
 	p = user_data;
 
-	style_item = gtk_combo_box_get_active_text (combobox);
+	style_item = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combobox));
 	if (!style_item || strlen (style_item) <= 0)
 		return;
 	if (p->priv->current_style)
@@ -917,7 +917,7 @@ create_style_editor_gui (StyleEditor * se)
 	{
 		if (hilite_style[i] == NULL)
 			break;
-		gtk_combo_box_append_text (GTK_COMBO_BOX (se->priv->hilite_item_combobox), hilite_style[i]);
+		gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (se->priv->hilite_item_combobox), hilite_style[i]);
 
 	}
 	
diff --git a/plugins/scintilla/text_editor_cbs.c b/plugins/scintilla/text_editor_cbs.c
index 07cbe48..f6ee56e 100644
--- a/plugins/scintilla/text_editor_cbs.c
+++ b/plugins/scintilla/text_editor_cbs.c
@@ -76,7 +76,7 @@ on_text_editor_text_keyrelease_event (GtkWidget * widget,
 									   GdkEventKey * event,
 									   gpointer user_data)
 {
-    if (event->keyval == GDK_BackSpace)
+    if (event->keyval == GDK_KEY_BackSpace)
     {
         TextEditor *te = user_data;
         g_signal_emit_by_name(G_OBJECT(te), "backspace");
@@ -120,14 +120,15 @@ static void
 scintilla_uri_dropped (TextEditor *te, const char *uri)
 {
 	GtkWidget *parent;
-	GtkSelectionData tmp;
-	
-	tmp.data = (guchar *) uri;
+	// FIXME: Not possible to create a selection data anymore
+	//GtkSelectionData tmp;
+
+	//tmp.data = (guchar *) uri;
 
 	parent = gtk_widget_get_toplevel (GTK_WIDGET (te));
-	if (parent)
-		g_signal_emit_by_name (G_OBJECT (parent), "drag_data_received",
-							   NULL, 0, 0, &tmp, 0, 0);
+	//if (parent)
+	//	g_signal_emit_by_name (G_OBJECT (parent), "drag_data_received",
+	//							   NULL, 0, 0, &tmp, 0, 0);
 	return;
 }
 



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