>From 8cb68e93b0cb5b56d8327d073ad665ddf8fec44f Mon Sep 17 00:00:00 2001
From: Matthew Brush <matthewbrush@gmail.com>
Date: Sat, 2 Apr 2011 19:09:12 -0700
Subject: [PATCH 1/2] Upgrade to Scintilla 2.25

---
 scintilla/Makefile.am             |   97 ++-----
 scintilla/README                  |   76 +++++-
 scintilla/gtk/PlatGTK.cxx         |  309 +++++++++++++++++++++--
 scintilla/gtk/ScintillaGTK.cxx    |   47 +---
 scintilla/gtk/scintilla-marshal.c |    8 +-
 scintilla/include/Face.py         |  110 ++++++++
 scintilla/include/HFacer.py       |   76 ++++++
 scintilla/include/Platform.h      |    8 +-
 scintilla/include/SciLexer.h      |   42 +++
 scintilla/include/Scintilla.h     |    9 +
 scintilla/include/Scintilla.iface |   60 +++++
 scintilla/lexers/LexAda.cxx       |    1 -
 scintilla/lexers/LexAsm.cxx       |  326 ++++++++++++++++++++++--
 scintilla/lexers/LexBash.cxx      |    9 +-
 scintilla/lexers/LexBasic.cxx     |  372 ++++++++++++++++++---------
 scintilla/lexers/LexCOBOL.cxx     |    1 -
 scintilla/lexers/LexCPP.cxx       |  123 ++++++++--
 scintilla/lexers/LexCSS.cxx       |    1 -
 scintilla/lexers/LexCmake.cxx     |    1 -
 scintilla/lexers/LexConf.cxx      |  192 ++++++++++++++
 scintilla/lexers/LexD.cxx         |  277 ++++++++++++++++----
 scintilla/lexers/LexErlang.cxx    |    1 -
 scintilla/lexers/LexForth.cxx     |    1 -
 scintilla/lexers/LexFortran.cxx   |    3 +-
 scintilla/lexers/LexHTML.cxx      |   15 +-
 scintilla/lexers/LexLisp.cxx      |    1 -
 scintilla/lexers/LexLua.cxx       |    1 -
 scintilla/lexers/LexMarkdown.cxx  |    1 -
 scintilla/lexers/LexMatlab.cxx    |    1 -
 scintilla/lexers/LexNsis.cxx      |    1 -
 scintilla/lexers/LexOthers.cxx    |    7 +-
 scintilla/lexers/LexPascal.cxx    |    1 -
 scintilla/lexers/LexPerl.cxx      |    1 -
 scintilla/lexers/LexPython.cxx    |    1 -
 scintilla/lexers/LexR.cxx         |    1 -
 scintilla/lexers/LexRuby.cxx      |   11 +-
 scintilla/lexers/LexSQL.cxx       |  514 +++++++++++++++++++++++++++++++------
 scintilla/lexers/LexTCL.cxx       |    1 -
 scintilla/lexers/LexTxt2tags.cxx  |    1 -
 scintilla/lexers/LexVHDL.cxx      |    1 -
 scintilla/lexers/LexVerilog.cxx   |    1 -
 scintilla/lexers/LexYAML.cxx      |    1 -
 scintilla/lexlib/CharacterSet.h   |    4 +-
 scintilla/lexlib/LexerBase.h      |    2 +-
 scintilla/lexlib/OptionSet.h      |    2 +
 scintilla/lexlib/SparseState.h    |  110 ++++++++
 scintilla/lexlib/WordList.cxx     |    5 +
 scintilla/src/AutoComplete.cxx    |    2 +-
 scintilla/src/CallTip.cxx         |    3 +
 scintilla/src/Catalogue.cxx       |    4 +-
 scintilla/src/Catalogue.cxx.orig  |  186 +++++++++++++
 scintilla/src/Catalogue.cxx.rej   |  102 ++++++++
 scintilla/src/Document.cxx        |   22 +-
 scintilla/src/Document.h          |    2 +-
 scintilla/src/Editor.cxx          |  173 +++++++++----
 scintilla/src/Editor.h            |   10 +-
 scintilla/src/ExternalLexer.cxx   |    1 -
 scintilla/src/ExternalLexer.h     |    5 +-
 scintilla/src/LexGen.py           |  304 ++++++++++++++++++++++
 scintilla/src/Partitioning.h      |    5 +
 scintilla/src/PositionCache.cxx   |    2 +
 scintilla/src/RunStyles.cxx       |    4 +-
 scintilla/src/SciTE.properties    |    6 +
 scintilla/src/Selection.cxx       |    9 +
 scintilla/src/Selection.h         |    5 +-
 scintilla/src/SplitVector.h       |    2 +-
 scintilla/src/ViewStyle.cxx       |    2 +-
 scintilla/src/ViewStyle.h         |    1 +
 scintilla/version.txt             |    1 +
 69 files changed, 3143 insertions(+), 542 deletions(-)
 create mode 100644 scintilla/include/Face.py
 create mode 100755 scintilla/include/HFacer.py
 create mode 100644 scintilla/lexers/LexConf.cxx
 create mode 100644 scintilla/lexlib/SparseState.h
 create mode 100644 scintilla/src/Catalogue.cxx.orig
 create mode 100644 scintilla/src/Catalogue.cxx.rej
 create mode 100755 scintilla/src/LexGen.py
 create mode 100644 scintilla/src/SciTE.properties
 create mode 100644 scintilla/version.txt

diff --git a/scintilla/Makefile.am b/scintilla/Makefile.am
index 4a92eb6..09c80b0 100644
--- a/scintilla/Makefile.am
+++ b/scintilla/Makefile.am
@@ -15,6 +15,7 @@ lexers/LexCPP.cxx \
 lexers/LexCSS.cxx \
 lexers/LexCaml.cxx \
 lexers/LexCmake.cxx \
+lexers/LexConf.cxx \
 lexers/LexD.cxx \
 lexers/LexErlang.cxx \
 lexers/LexForth.cxx \
@@ -40,81 +41,41 @@ lexers/LexVerilog.cxx \
 lexers/LexYAML.cxx
 
 SRCS= \
-gtk/Converter.h \
-gtk/PlatGTK.cxx \
-gtk/ScintillaGTK.cxx \
-gtk/scintilla-marshal.c \
-gtk/scintilla-marshal.h \
-lexlib/Accessor.cxx \
-lexlib/Accessor.h \
-lexlib/CharacterSet.cxx \
-lexlib/CharacterSet.h \
-lexlib/LexAccessor.h \
-lexlib/LexerBase.cxx \
-lexlib/LexerBase.h \
-lexlib/LexerModule.cxx \
-lexlib/LexerModule.h \
-lexlib/LexerNoExceptions.cxx \
-lexlib/LexerNoExceptions.h \
-lexlib/LexerSimple.cxx \
-lexlib/LexerSimple.h \
-lexlib/OptionSet.h \
-lexlib/PropSetSimple.cxx \
-lexlib/PropSetSimple.h \
-lexlib/StyleContext.cxx \
-lexlib/StyleContext.h \
-lexlib/WordList.cxx \
-lexlib/WordList.h \
-src/AutoComplete.cxx \
-src/AutoComplete.h \
-src/CallTip.cxx \
-src/CallTip.h \
-src/Catalogue.cxx \
-src/Catalogue.h \
-src/CellBuffer.cxx \
-src/CellBuffer.h \
+src/PositionCache.cxx \
+src/Indicator.cxx \
+src/Style.cxx \
+src/ScintillaBase.cxx \
 src/CharClassify.cxx \
-src/CharClassify.h \
 src/ContractionState.cxx \
-src/ContractionState.h \
-src/Decoration.cxx \
-src/Decoration.h \
 src/Document.cxx \
-src/Document.h \
-src/Editor.cxx \
-src/Editor.h \
-src/ExternalLexer.cxx \
-src/ExternalLexer.h \
-src/FontQuality.h \
-src/Indicator.cxx \
-src/Indicator.h \
-src/KeyMap.cxx \
-src/KeyMap.h \
-src/LineMarker.cxx \
-src/LineMarker.h \
-src/Partitioning.h \
 src/PerLine.cxx \
-src/PerLine.h \
-src/PositionCache.cxx \
-src/PositionCache.h \
+src/AutoComplete.cxx \
+src/ViewStyle.cxx \
+src/ExternalLexer.cxx \
+src/XPM.cxx \
+src/CellBuffer.cxx \
 src/RESearch.cxx \
-src/RESearch.h \
+src/KeyMap.cxx \
+src/Catalogue.cxx \
 src/RunStyles.cxx \
-src/RunStyles.h \
-src/SVector.h \
-src/ScintillaBase.cxx \
-src/ScintillaBase.h \
-src/Selection.cxx \
-src/Selection.h \
-src/SplitVector.h \
-src/Style.cxx \
-src/Style.h \
 src/UniConversion.cxx \
-src/UniConversion.h \
-src/ViewStyle.cxx \
-src/ViewStyle.h \
-src/XPM.cxx \
-src/XPM.h \
+src/LineMarker.cxx \
+src/Editor.cxx \
+src/CallTip.cxx \
+src/Selection.cxx \
+src/Decoration.cxx \
+gtk/PlatGTK.cxx \
+gtk/scintilla-marshal.c \
+gtk/ScintillaGTK.cxx \
+lexlib/LexerBase.cxx \
+lexlib/Accessor.cxx \
+lexlib/StyleContext.cxx \
+lexlib/LexerModule.cxx \
+lexlib/WordList.cxx \
+lexlib/PropSetSimple.cxx \
+lexlib/LexerSimple.cxx \
+lexlib/CharacterSet.cxx \
+lexlib/LexerNoExceptions.cxx \
 $(LEXER_SRCS)
 
 libscintilla_a_SOURCES = $(SRCS)
diff --git a/scintilla/README b/scintilla/README
index 2a78b3b..d7efc69 100644
--- a/scintilla/README
+++ b/scintilla/README
@@ -1,16 +1,70 @@
-These files are from the Scintilla project, http://www.scintilla.org.
+README for building of Scintilla and SciTE
 
-See License.txt for the Scintilla license.
+Scintilla can be built by itself.
+To build SciTE, Scintilla must first be built.
 
-We try to keep these files in sync with the official project; any
-changes should be sent there first. Otherwise changes could cause
-conflicts when we next update Scintilla.
 
+*** GTK+/Linux version ***
 
-Public header constants (include/*.h)
--------------------------------------
-You should not add constants in header files - instead use
-Scintilla.iface and HFacer.py.
+You must first have GTK+ 2.0 or later and GCC (4.1 or better) installed.
+GTK+ 1.x will not work.
+Other C++ compilers may work but may require tweaking the make file.
 
-Do not change the value of constants in header files as this will
-break Scintilla's ABI.
+To build Scintilla, use the makefile located in the scintilla/gtk directory
+	cd scintilla/gtk
+	make
+	cd ../..
+
+To build and install SciTE, use the makefile located in the scite/gtk directory
+	cd scite/gtk
+	make
+	make install
+
+This installs SciTE into $prefix/bin. The value of $prefix is determined from
+the location of Gnome if it is installed. This is usually /usr if installed
+with Linux or /usr/local if built from source. If Gnome is not installed
+/usr/bin is used as the prefix. The prefix can be overridden on the command
+line like "make prefix=/opt" but the same value should be used for both make
+and make install as this location is compiled into the executable. The global
+properties file is installed at $prefix/share/scite/SciTEGlobal.properties.
+The language specific properties files are also installed into this directory.
+
+To remove SciTE
+	make uninstall
+
+To clean the object files which may be needed to change $prefix
+	make clean
+
+The current make file only supports static linking between SciTE and Scintilla.
+
+
+*** Windows version ***
+
+A C++ compiler is required. Visual Studio .NET 2010 is the development system
+used for most development although TDM Mingw32 4.4.1 is also supported.
+
+To build Scintilla, make in the scintilla/win32 directory
+		cd scintilla\win32
+GCC:		mingw32-make
+VS .NET:	nmake -f scintilla.mak
+		cd ..\..
+
+To build SciTE, use the makefiles located in the scite/win32 directory
+		cd scite\win32
+GCC:		mingw32-make
+VS .NET: 	nmake -f scite.mak
+
+An executable SciTE will now be in scite\bin.
+
+The Visual C++ 6.0 project (.dsp) and make files are no longer supported but are left
+in the download for people that are prepared to update them.
+
+*** GTK+/Windows version ***
+
+Mingw32 is known to work. Other compilers will probably not work.
+
+Only Scintilla will build with GTK+ on Windows. SciTE will not work.
+
+To build Scintilla, make in the scintilla/gtk directory
+	cd scintilla\gtk
+	mingw32-make
diff --git a/scintilla/gtk/PlatGTK.cxx b/scintilla/gtk/PlatGTK.cxx
index bcc965a..651805e 100644
--- a/scintilla/gtk/PlatGTK.cxx
+++ b/scintilla/gtk/PlatGTK.cxx
@@ -7,6 +7,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
+#include <math.h>
 
 #include <glib.h>
 #include <gmodule.h>
@@ -39,6 +40,14 @@
 #define IS_WIDGET_FOCUSSED(w) (GTK_WIDGET_HAS_FOCUS(w))
 #endif
 
+#if GTK_CHECK_VERSION(2,22,0)
+#define USE_CAIRO 1
+#endif
+
+#ifdef USE_CAIRO
+#define DISABLE_GDK_FONT 1
+#endif
+
 #ifdef _MSC_VER
 // Ignore unreferenced local functions in GTK+ headers
 #pragma warning(disable: 4505)
@@ -688,9 +697,14 @@ namespace Scintilla {
 #endif
 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;
@@ -806,7 +820,15 @@ void SurfaceImpl::SetConverter(int characterSet_) {
 	}
 }
 
-SurfaceImpl::SurfaceImpl() : et(singleByte), drawable(0), gc(0), ppixmap(0),
+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) {
 }
@@ -817,15 +839,28 @@ SurfaceImpl::~SurfaceImpl() {
 
 void SurfaceImpl::Release() {
 	et = singleByte;
+#ifndef USE_CAIRO
 	drawable = 0;
+#endif
 	if (createdGC) {
 		createdGC = false;
+#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)
 		g_object_unref(ppixmap);
 	ppixmap = 0;
+#endif
 	if (layout)
 		g_object_unref(layout);
 	layout = 0;
@@ -847,10 +882,28 @@ bool SurfaceImpl::Initialised() {
 void SurfaceImpl::Init(WindowID wid) {
 	Release();
 	PLATFORM_ASSERT(wid);
+#ifdef USE_CAIRO
+	GdkDrawable *drawable_ = GDK_DRAWABLE(PWidget(wid)->window);
+	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;
+	pcontext = pango_cairo_create_context(context);
+	PLATFORM_ASSERT(pcontext);
+	layout = pango_cairo_create_layout(context);
+	PLATFORM_ASSERT(layout);
+#else
 	pcontext = gtk_widget_create_pango_context(PWidget(wid));
 	PLATFORM_ASSERT(pcontext);
 	layout = pango_layout_new(pcontext);
 	PLATFORM_ASSERT(layout);
+#endif
 	inited = true;
 }
 
@@ -859,12 +912,27 @@ void SurfaceImpl::Init(SurfaceID sid, WindowID wid) {
 	GdkDrawable *drawable_ = reinterpret_cast<GdkDrawable *>(sid);
 	Release();
 	PLATFORM_ASSERT(wid);
+#ifdef USE_CAIRO
+	context = gdk_cairo_create(drawable_);
+#else
+	gc = gdk_gc_new(drawable_);
+#endif
+#ifdef USE_CAIRO
+	pcontext = pango_cairo_create_context(context);
+	PLATFORM_ASSERT(pcontext);
+	layout = pango_cairo_create_layout(context);
+	PLATFORM_ASSERT(layout);
+#else
 	pcontext = gtk_widget_create_pango_context(PWidget(wid));
 	layout = pango_layout_new(pcontext);
 	drawable = drawable_;
-	gc = gdk_gc_new(drawable_);
+#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;
 }
@@ -873,8 +941,23 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID
 	PLATFORM_ASSERT(surface_);
 	Release();
 	SurfaceImpl *surfImpl = static_cast<SurfaceImpl *>(surface_);
-	PLATFORM_ASSERT(surfImpl->drawable);
 	PLATFORM_ASSERT(wid);
+#ifdef USE_CAIRO
+	context = cairo_reference(surfImpl->context);
+#else
+	PLATFORM_ASSERT(surfImpl->drawable);
+	gc = gdk_gc_new(surfImpl->drawable);
+#endif
+#ifdef USE_CAIRO
+	pcontext = pango_cairo_create_context(context);
+	PLATFORM_ASSERT(pcontext);
+	layout = pango_cairo_create_layout(context);
+	PLATFORM_ASSERT(layout);
+	if (height > 0 && width > 0)
+		psurf = gdk_window_create_similar_surface(
+			gtk_widget_get_window(PWidget(wid)),
+			CAIRO_CONTENT_COLOR_ALPHA, width, height);
+#else
 	pcontext = gtk_widget_create_pango_context(PWidget(wid));
 	PLATFORM_ASSERT(pcontext);
 	layout = pango_layout_new(pcontext);
@@ -882,19 +965,42 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID
 	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());
+		cairo_set_source_rgb(context,
+			cdFore.GetBlue() / 255.0,
+			cdFore.GetGreen() / 255.0,
+			cdFore.GetRed() / 255.0);
+	}
+#else
 	if (gc) {
 		GdkColor co;
 		co.pixel = fore.AsLong();
 		gdk_gc_set_foreground(gc, &co);
 	}
+#endif
 }
 
 int SurfaceImpl::LogPixelsY() {
@@ -911,18 +1017,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++) {
@@ -934,35 +1093,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;
@@ -971,12 +1157,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;
+#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 {
@@ -1005,6 +1197,21 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAl
 	}
 }
 
+#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) {
 	pixels[y*stride+x] = val;
@@ -1013,18 +1220,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;
-}
-
 static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
 	union {
 		guint8 pixVal[4];
@@ -1037,8 +1232,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();
@@ -1078,10 +1306,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,
@@ -1093,16 +1329,30 @@ 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) {
+	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
 	}
 }
 
@@ -1232,7 +1482,11 @@ 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;
 		if (PFont(font_)->pfd) {
 			char *utfForm = 0;
@@ -1256,12 +1510,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 {
@@ -1717,9 +1979,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() {}
@@ -1875,7 +2142,6 @@ 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);
 
@@ -1894,6 +2160,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
@@ -1936,7 +2203,7 @@ public:
 	CallBackAction doubleClickAction;
 	void *doubleClickActionData;
 
-	ListBoxX() : list(0), pixhash(NULL), pixbuf_renderer(0),
+	ListBoxX() : list(0), scroller(0), pixhash(NULL), pixbuf_renderer(0),
 		desiredVisibleRows(5), maxItemCharacters(0),
 		aveCharWidth(1), doubleClickAction(NULL), doubleClickActionData(NULL) {
 	}
diff --git a/scintilla/gtk/ScintillaGTK.cxx b/scintilla/gtk/ScintillaGTK.cxx
index 1cf96b8..873bc4c 100644
--- a/scintilla/gtk/ScintillaGTK.cxx
+++ b/scintilla/gtk/ScintillaGTK.cxx
@@ -75,6 +75,10 @@
 #define IS_WIDGET_VISIBLE(w) (GTK_WIDGET_VISIBLE(w))
 #endif
 
+#if GTK_CHECK_VERSION(2,22,0)
+#define USE_CAIRO 1
+#endif
+
 #ifdef _MSC_VER
 // Constant conditional expressions are because of GTK+ headers
 #pragma warning(disable: 4127)
@@ -416,26 +420,6 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) {
 	gtk_widget_realize(widtxt);
 	gtk_widget_realize(PWidget(scrollbarv));
 	gtk_widget_realize(PWidget(scrollbarh));
-
-	cursor = gdk_cursor_new(GDK_XTERM);
-	gdk_window_set_cursor(PWidget(wText)->window, cursor);
-	gdk_cursor_unref(cursor);
-
-	cursor = gdk_cursor_new(GDK_LEFT_PTR);
-	gdk_window_set_cursor(PWidget(scrollbarv)->window, cursor);
-	gdk_cursor_unref(cursor);
-
-	cursor = gdk_cursor_new(GDK_LEFT_PTR);
-	gdk_window_set_cursor(PWidget(scrollbarh)->window, 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) {
@@ -445,14 +429,6 @@ void ScintillaGTK::Realize(GtkWidget *widget) {
 
 void ScintillaGTK::UnRealizeThis(GtkWidget *widget) {
 	try {
-
-		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);
 		}
@@ -559,7 +535,6 @@ void ScintillaGTK::MainForAll(GtkContainer *container, gboolean include_internal
 
 gint ScintillaGTK::FocusInThis(GtkWidget *widget) {
 	try {
-		GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
 		SetFocusState(true);
 		if (im_context != NULL) {
 			gchar *str = NULL;
@@ -590,7 +565,6 @@ gint ScintillaGTK::FocusIn(GtkWidget *widget, GdkEventFocus * /*event*/) {
 
 gint ScintillaGTK::FocusOutThis(GtkWidget *widget) {
 	try {
-		GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
 		SetFocusState(false);
 
 		if (PWidget(wPreedit) != NULL)
@@ -696,6 +670,14 @@ void ScintillaGTK::Initialise() {
 
 	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));
@@ -1442,7 +1424,7 @@ void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) {
 
 				UndoGroup ug(pdoc);
 				if (selection_data->selection != GDK_SELECTION_PRIMARY) {
-					ClearSelection();
+					ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH);
 				}
 				SelectionPosition selStart = sel.IsRectangular() ?
 					sel.Rectangular().Start() :
@@ -2003,6 +1985,7 @@ 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}
@@ -2017,8 +2000,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);
-
 		g_object_unref(gc);
+#endif
 		g_free(str);
 		pango_attr_list_unref(attrs);
 		g_object_unref(layout);
diff --git a/scintilla/gtk/scintilla-marshal.c b/scintilla/gtk/scintilla-marshal.c
index be57b7c..cee3e73 100644
--- a/scintilla/gtk/scintilla-marshal.c
+++ b/scintilla/gtk/scintilla-marshal.c
@@ -35,8 +35,8 @@
 #define g_marshal_value_peek_ulong(v)    (v)->data[0].v_ulong
 #define g_marshal_value_peek_int64(v)    (v)->data[0].v_int64
 #define g_marshal_value_peek_uint64(v)   (v)->data[0].v_uint64
-#define g_marshal_value_peek_enum(v)     (v)->data[0].v_int
-#define g_marshal_value_peek_flags(v)    (v)->data[0].v_uint
+#define g_marshal_value_peek_enum(v)     (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v)    (v)->data[0].v_ulong
 #define g_marshal_value_peek_float(v)    (v)->data[0].v_float
 #define g_marshal_value_peek_double(v)   (v)->data[0].v_double
 #define g_marshal_value_peek_string(v)   (v)->data[0].v_pointer
@@ -50,10 +50,10 @@
 /* NONE:INT,POINTER (scintilla-marshal.list:1) */
 void
 scintilla_marshal_VOID__INT_POINTER (GClosure     *closure,
-                                     GValue       *return_value,
+                                     GValue       *return_value G_GNUC_UNUSED,
                                      guint         n_param_values,
                                      const GValue *param_values,
-                                     gpointer      invocation_hint,
+                                     gpointer      invocation_hint G_GNUC_UNUSED,
                                      gpointer      marshal_data)
 {
   typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer     data1,
diff --git a/scintilla/include/Face.py b/scintilla/include/Face.py
new file mode 100644
index 0000000..52c9b8d
--- /dev/null
+++ b/scintilla/include/Face.py
@@ -0,0 +1,110 @@
+# Module for reading and parsing Scintilla.iface file
+
+def sanitiseLine(line):
+	if line[-1:] == '\n': line = line[:-1]
+	if line.find("##") != -1:
+		line = line[:line.find("##")]
+	line = line.strip()
+	return line
+	
+def decodeFunction(featureVal):
+	retType, rest = featureVal.split(" ", 1)
+	nameIdent, params = rest.split("(")
+	name, value = nameIdent.split("=")
+	params, rest = params.split(")")
+	param1, param2 = params.split(",")[0:2]
+	return retType, name, value, param1, param2
+	
+def decodeEvent(featureVal):
+	retType, rest = featureVal.split(" ", 1)
+	nameIdent, params = rest.split("(")
+	name, value = nameIdent.split("=")
+	return retType, name, value
+	
+def decodeParam(p):
+	param = p.strip()
+	type = ""
+	name = ""
+	value = ""
+	if " " in param:
+		type, nv = param.split(" ")
+		if "=" in nv:
+			name, value = nv.split("=")
+		else:
+			name = nv
+	return type, name, value
+
+class Face:
+
+	def __init__(self):
+		self.order = []
+		self.features = {}
+		self.values = {}
+		self.events = {}
+		
+	def ReadFromFile(self, name):
+		currentCategory = ""
+		currentComment = []
+		currentCommentFinished = 0
+		file = open(name)
+		for line in file.readlines():
+			line = sanitiseLine(line)
+			if line:
+				if line[0] == "#":
+					if line[1] == " ":
+						if currentCommentFinished:
+							currentComment = []
+							currentCommentFinished = 0
+						currentComment.append(line[2:])
+				else:
+					currentCommentFinished = 1
+					featureType, featureVal = line.split(" ", 1)
+					if featureType in ["fun", "get", "set"]:
+						retType, name, value, param1, param2 = decodeFunction(featureVal)
+						p1 = decodeParam(param1)
+						p2 = decodeParam(param2)
+						self.features[name] = { 
+							"FeatureType": featureType, 
+							"ReturnType": retType,
+							"Value": value, 
+							"Param1Type": p1[0], "Param1Name": p1[1], "Param1Value": p1[2], 
+							"Param2Type": p2[0],	"Param2Name": p2[1], "Param2Value": p2[2],
+							"Category": currentCategory, "Comment": currentComment
+						}
+						if value in self.values:
+							raise "Duplicate value " + value + " " + name
+						self.values[value] = 1
+						self.order.append(name)
+					elif featureType == "evt":
+						retType, name, value = decodeEvent(featureVal)
+						self.features[name] = { 
+							"FeatureType": featureType, 
+							"ReturnType": retType,
+							"Value": value, 
+							"Category": currentCategory, "Comment": currentComment
+						}
+						if value in self.events:
+							raise "Duplicate event " + value + " " + name
+						self.events[value] = 1
+						self.order.append(name)
+					elif featureType == "cat":
+						currentCategory = featureVal
+					elif featureType == "val":
+						try:
+							name, value = featureVal.split("=", 1)
+						except ValueError:
+							print("Failure %s" % featureVal)
+							raise
+						self.features[name] = { 
+							"FeatureType": featureType, 
+							"Category": currentCategory, 
+							"Value": value }
+						self.order.append(name)
+					elif featureType == "enu" or featureType == "lex":
+						name, value = featureVal.split("=", 1)
+						self.features[name] = { 
+							"FeatureType": featureType, 
+							"Category": currentCategory, 
+							"Value": value }
+						self.order.append(name)
+
diff --git a/scintilla/include/HFacer.py b/scintilla/include/HFacer.py
new file mode 100755
index 0000000..074ce96
--- /dev/null
+++ b/scintilla/include/HFacer.py
@@ -0,0 +1,76 @@
+#!/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*/
+# comment and a /* --Autogenerated*/ comment which is generated by the printHFile and printLexHFile
+# functions. After the temporary file is created, it is copied back to the original file name.
+
+import sys
+import os
+import Face
+
+def Contains(s,sub):
+	return s.find(sub) != -1
+
+def printLexHFile(f,out):
+	for name in f.order:
+		v = f.features[name]
+		if v["FeatureType"] in ["val"]:
+			if Contains(name, "SCE_") or Contains(name, "SCLEX_"):
+				out.write("#define " + name + " " + v["Value"] + "\n")
+
+def printHFile(f,out):
+	for name in f.order:
+		v = f.features[name]
+		if v["Category"] != "Deprecated":
+			if v["FeatureType"] in ["fun", "get", "set"]:
+				featureDefineName = "SCI_" + name.upper()
+				out.write("#define " + featureDefineName + " " + v["Value"] + "\n")
+			elif v["FeatureType"] in ["evt"]:
+				featureDefineName = "SCN_" + name.upper()
+				out.write("#define " + featureDefineName + " " + v["Value"] + "\n")
+			elif v["FeatureType"] in ["val"]:
+				if not (Contains(name, "SCE_") or Contains(name, "SCLEX_")):
+					out.write("#define " + name + " " + v["Value"] + "\n")
+
+def CopyWithInsertion(input, output, genfn, definition):
+	copying = 1
+	for line in input.readlines():
+		if copying:
+			output.write(line)
+		if Contains(line, "/* ++Autogenerated"):
+			copying = 0
+			genfn(definition, output)
+		if Contains(line, "/* --Autogenerated"):
+			copying = 1
+			output.write(line)
+
+def contents(filename):
+	f = open(filename)
+	t = f.read()
+	f.close()
+	return t
+
+def Regenerate(filename, genfn, definition):
+	inText = contents(filename)
+	tempname = "HFacer.tmp"
+	out = open(tempname,"w")
+	hfile = open(filename)
+	CopyWithInsertion(hfile, out, genfn, definition)
+	out.close()
+	hfile.close()
+	outText = contents(tempname)
+	if inText == outText:
+		os.unlink(tempname)
+	else:
+		os.unlink(filename)
+		os.rename(tempname, filename)
+
+f = Face.Face()
+try:
+	f.ReadFromFile("Scintilla.iface")
+	Regenerate("Scintilla.h", printHFile, f)
+	Regenerate("SciLexer.h", printLexHFile, f)
+	print("Maximum ID is %s" % max([x for x in f.values if int(x) < 3000]))
+except:
+	raise
diff --git a/scintilla/include/Platform.h b/scintilla/include/Platform.h
index ea9f972..b70ffc3 100644
--- a/scintilla/include/Platform.h
+++ b/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();
diff --git a/scintilla/include/SciLexer.h b/scintilla/include/SciLexer.h
index 3aa2c38..1d5b69e 100644
--- a/scintilla/include/SciLexer.h
+++ b/scintilla/include/SciLexer.h
@@ -112,6 +112,8 @@
 #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
@@ -149,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
@@ -601,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
@@ -1415,6 +1420,43 @@
 #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/scintilla/include/Scintilla.h b/scintilla/include/Scintilla.h
index 0e1159b..ed11020 100644
--- a/scintilla/include/Scintilla.h
+++ b/scintilla/include/Scintilla.h
@@ -159,6 +159,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
@@ -590,7 +592,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
@@ -832,6 +836,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
 #define SC_MOD_CONTAINER 0x40000
 #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
@@ -971,6 +979,7 @@ struct SCNotification {
 	int y;		/* SCN_DWELLSTART, SCN_DWELLEND */
 	int token;		/* SCN_MODIFIED with SC_MOD_CONTAINER */
 	int annotationLinesAdded;	/* SC_MOD_CHANGEANNOTATION */
+	int updated;	/* SCN_UPDATEUI */
 };
 
 #ifdef SCI_NAMESPACE
diff --git a/scintilla/include/Scintilla.iface b/scintilla/include/Scintilla.iface
index 6103139..0d3644d 100644
--- a/scintilla/include/Scintilla.iface
+++ b/scintilla/include/Scintilla.iface
@@ -352,6 +352,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_
@@ -1540,7 +1546,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.
@@ -2193,6 +2201,12 @@ val SC_MOD_CONTAINER=0x40000
 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.
 # Unfortunately the SETFOCUS and KILLFOCUS are flipped over from EN_*
@@ -2335,6 +2349,8 @@ 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.
@@ -2381,6 +2397,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
@@ -2900,6 +2918,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_
@@ -3819,6 +3838,47 @@ 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
 
diff --git a/scintilla/lexers/LexAda.cxx b/scintilla/lexers/LexAda.cxx
index 64c8d1c..e109514 100644
--- a/scintilla/lexers/LexAda.cxx
+++ b/scintilla/lexers/LexAda.cxx
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexAsm.cxx b/scintilla/lexers/LexAsm.cxx
index 8c0f998..946d47a 100644
--- a/scintilla/lexers/LexAsm.cxx
+++ b/scintilla/lexers/LexAsm.cxx
@@ -4,6 +4,7 @@
  ** 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.
@@ -15,17 +16,24 @@
 #include <assert.h>
 #include <ctype.h>
 
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
+
+#include <string>
+#include <map>
+#include <set>
+
 #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"
+#include "OptionSet.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -54,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
+
+// 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);
 
-	WordList &cpuInstruction = *keywordlists[0];
-	WordList &mathInstruction = *keywordlists[1];
-	WordList &registers = *keywordlists[2];
-	WordList &directive = *keywordlists[3];
-	WordList &directiveOperand = *keywordlists[4];
-	WordList &extInstruction = *keywordlists[5];
+		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)
@@ -96,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);
 			}
@@ -104,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);
@@ -113,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);
 			}
@@ -170,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/scintilla/lexers/LexBash.cxx b/scintilla/lexers/LexBash.cxx
index 1c844a6..165e104 100644
--- a/scintilla/lexers/LexBash.cxx
+++ b/scintilla/lexers/LexBash.cxx
@@ -16,7 +16,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
@@ -640,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/scintilla/lexers/LexBasic.cxx b/scintilla/lexers/LexBasic.cxx
index fc1c6c7..55641ed 100644
--- a/scintilla/lexers/LexBasic.cxx
+++ b/scintilla/lexers/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.
@@ -21,18 +22,25 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <assert.h>
+#include <ctype.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
+
+#include <string>
+#include <map>
 
 #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"
+#include "OptionSet.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -89,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);
 
@@ -114,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]);
 						}
 					}
@@ -205,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
@@ -294,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);
@@ -311,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/scintilla/lexers/LexCOBOL.cxx b/scintilla/lexers/LexCOBOL.cxx
index b9c8f4d..a9a8f55 100644
--- a/scintilla/lexers/LexCOBOL.cxx
+++ b/scintilla/lexers/LexCOBOL.cxx
@@ -19,7 +19,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexCPP.cxx b/scintilla/lexers/LexCPP.cxx
index bc7bb37..f573bef 100644
--- a/scintilla/lexers/LexCPP.cxx
+++ b/scintilla/lexers/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.
@@ -15,10 +16,6 @@
 #ifdef _MSC_VER
 #pragma warning(disable: 4786)
 #endif
-#ifdef __BORLANDC__
-// Borland C++ displays warnings in vector header without this
-#pragma option -w-ccc -w-rch
-#endif
 
 #include <string>
 #include <vector>
@@ -29,7 +26,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
@@ -37,6 +33,7 @@
 #include "CharacterSet.h"
 #include "LexerModule.h"
 #include "OptionSet.h"
+#include "SparseState.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -212,8 +209,13 @@ struct OptionsCPP {
 	bool trackPreprocessor;
 	bool updatePreprocessor;
 	bool fold;
+	bool foldSyntaxBased;
 	bool foldComment;
+	bool foldCommentMultiline;
 	bool foldCommentExplicit;
+	std::string foldExplicitStart;
+	std::string foldExplicitEnd;
+	bool foldExplicitAnywhere;
 	bool foldPreprocessor;
 	bool foldCompact;
 	bool foldAtElse;
@@ -223,8 +225,13 @@ struct OptionsCPP {
 		trackPreprocessor = true;
 		updatePreprocessor = true;
 		fold = false;
+		foldSyntaxBased = true;
 		foldComment = false;
+		foldCommentMultiline = true;
 		foldCommentExplicit = true;
+		foldExplicitStart = "";
+		foldExplicitEnd = "";
+		foldExplicitAnywhere = false;
 		foldPreprocessor = false;
 		foldCompact = false;
 		foldAtElse = false;
@@ -258,14 +265,29 @@ struct OptionSetCPP : public OptionSet<OptionsCPP> {
 
 		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.");
@@ -288,7 +310,6 @@ class LexerCPP : public ILexer {
 	CharacterSet setLogicalOp;
 	PPStates vlls;
 	std::vector<PPDefinition> ppDefineHistory;
-	PropSetSimple props;
 	WordList keywords;
 	WordList keywords2;
 	WordList keywords3;
@@ -297,6 +318,7 @@ class LexerCPP : public ILexer {
 	std::map<std::string, std::string> preprocessorDefinitionsStart;
 	OptionsCPP options;
 	OptionSetCPP osCPP;
+	SparseState<std::string> rawStringTerminators;
 public:
 	LexerCPP(bool caseSensitive_) :
 		caseSensitive(caseSensitive_),
@@ -419,7 +441,6 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
 	CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]");
 
 	CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
-	CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
 
 	if (options.identifiersAllowDollars) {
 		setWordStart.Add('$');
@@ -483,16 +504,18 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
 	}
 
 	const int maskActivity = 0x3F;
+	std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
+	SparseState<std::string> rawSTNew(lineCurrent);
 
 	int activitySet = preproc.IsInactive() ? 0x40 : 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.
@@ -515,6 +538,9 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
 		if (sc.atLineEnd) {
 			lineCurrent++;
 			vlls.Add(lineCurrent, preproc);
+			if (rawStringTerminator != "") {
+				rawSTNew.Set(lineCurrent-1, rawStringTerminator);
+			}
 		}
 
 		// Handle line continuation generically.
@@ -558,6 +584,23 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
 					} else if (keywords4.InList(s)) {
 						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|activitySet);
 				}
 				break;
@@ -642,6 +685,14 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
 					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|activitySet);
@@ -682,6 +733,14 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
 					}
 				}
 				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|activitySet);
@@ -699,6 +758,9 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
 			if (sc.Match('@', '\"')) {
 				sc.SetState(SCE_C_VERBATIM|activitySet);
 				sc.Forward();
+			} else if (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|activitySet);
@@ -733,7 +795,19 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
 				       || !FollowsPostfixOperator(sc, styler))) {
 				sc.SetState(SCE_C_REGEX|activitySet);	// JavaScript's RegEx
 			} else if (sc.ch == '\"') {
-				sc.SetState(SCE_C_STRING|activitySet);
+				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|activitySet);
@@ -828,10 +902,10 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
 		}
 		continuationLine = false;
 	}
-	if (definitionsChanged)
+	const bool rawStringsChanged = rawStringTerminators.Merge(rawSTNew, lineCurrent);
+	if (definitionsChanged || rawStringsChanged)
 		styler.ChangeLexerState(startPos, startPos + length);
 	sc.Complete();
-	styler.Flush();
 }
 
 // Store both the current line's fold level and the next lines in the
@@ -856,6 +930,7 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
 	char chNext = styler[startPos];
 	int styleNext = styler.StyleAt(startPos);
 	int style = 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);
@@ -863,7 +938,7 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
 		style = styleNext;
 		styleNext = styler.StyleAt(i + 1);
 		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-		if (options.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) {
@@ -871,14 +946,22 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
 				levelNext--;
 			}
 		}
-		if (options.foldComment && options.foldCommentExplicit && (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 (options.foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
@@ -894,7 +977,7 @@ void SCI_METHOD LexerCPP::Fold(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 {"
@@ -910,7 +993,7 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
 			visibleChars++;
 		if (atEOL || (i == endPos-1)) {
 			int levelUse = levelCurrent;
-			if (options.foldAtElse) {
+			if (options.foldSyntaxBased && options.foldAtElse) {
 				levelUse = levelMinCurrent;
 			}
 			int lev = levelUse | levelNext << 16;
diff --git a/scintilla/lexers/LexCSS.cxx b/scintilla/lexers/LexCSS.cxx
index fba8dac..8fbca38 100644
--- a/scintilla/lexers/LexCSS.cxx
+++ b/scintilla/lexers/LexCSS.cxx
@@ -18,7 +18,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexCmake.cxx b/scintilla/lexers/LexCmake.cxx
index c43974d..70e9dee 100644
--- a/scintilla/lexers/LexCmake.cxx
+++ b/scintilla/lexers/LexCmake.cxx
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexConf.cxx b/scintilla/lexers/LexConf.cxx
new file mode 100644
index 0000000..5e1bd19
--- /dev/null
+++ b/scintilla/lexers/LexConf.cxx
@@ -0,0 +1,192 @@
+// Scintilla source code edit control
+/** @file LexConf.cxx
+ ** Lexer for Apache Configuration Files.
+ **
+ ** First working version contributed by Ahmad Zawawi <zeus_go64@hotmail.com> on October 28, 2000.
+ ** i created this lexer because i needed something pretty when dealing
+ ** when Apache Configuration files...
+ **/
+// Copyright 1998-2001 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 "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 void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
+{
+	int state = SCE_CONF_DEFAULT;
+	char chNext = styler[startPos];
+	int lengthDoc = startPos + length;
+	// create a buffer large enough to take the largest chunk...
+	char *buffer = new char[length];
+	int bufferCount = 0;
+
+	// this assumes that we have 2 keyword list in conf.properties
+	WordList &directives = *keywordLists[0];
+	WordList &params = *keywordLists[1];
+
+	// go through all provided text segment
+	// using the hand-written state machine shown below
+	styler.StartAt(startPos);
+	styler.StartSegment(startPos);
+	for (int i = startPos; i < lengthDoc; i++) {
+		char ch = chNext;
+		chNext = styler.SafeGetCharAt(i + 1);
+
+		if (styler.IsLeadByte(ch)) {
+			chNext = styler.SafeGetCharAt(i + 2);
+			i++;
+			continue;
+		}
+		switch(state) {
+			case SCE_CONF_DEFAULT:
+				if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
+					// whitespace is simply ignored here...
+					styler.ColourTo(i,SCE_CONF_DEFAULT);
+					break;
+				} else if( ch == '#' ) {
+					// signals the start of a comment...
+					state = SCE_CONF_COMMENT;
+					styler.ColourTo(i,SCE_CONF_COMMENT);
+				} else if( ch == '.' /*|| ch == '/'*/) {
+					// signals the start of a file...
+					state = SCE_CONF_EXTENSION;
+					styler.ColourTo(i,SCE_CONF_EXTENSION);
+				} else if( ch == '"') {
+					state = SCE_CONF_STRING;
+					styler.ColourTo(i,SCE_CONF_STRING);
+				} 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( 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( isascii(ch) && isdigit(ch) ) {
+					// signals the start of a number
+					bufferCount = 0;
+					buffer[bufferCount++] = ch;
+					//styler.ColourTo(i,SCE_CONF_NUMBER);
+					state = SCE_CONF_NUMBER;
+				} else {
+					// style it the default style..
+					styler.ColourTo(i,SCE_CONF_DEFAULT);
+				}
+				break;
+
+			case SCE_CONF_COMMENT:
+				// if we find a newline here,
+				// we simply go to default state
+				// else continue to work on it...
+				if( ch == '\n' || ch == '\r' ) {
+					state = SCE_CONF_DEFAULT;
+				} else {
+					styler.ColourTo(i,SCE_CONF_COMMENT);
+				}
+				break;
+
+			case SCE_CONF_EXTENSION:
+				// if we find a non-alphanumeric char,
+				// we simply go to default state
+				// else we're still dealing with an extension...
+				if( (isascii(ch) && isalnum(ch)) || (ch == '_') ||
+					(ch == '-') || (ch == '$') ||
+					(ch == '/') || (ch == '.') || (ch == '*') )
+				{
+					styler.ColourTo(i,SCE_CONF_EXTENSION);
+				} else {
+					state = SCE_CONF_DEFAULT;
+					chNext = styler[i--];
+				}
+				break;
+
+			case SCE_CONF_STRING:
+				// if we find the end of a string char, we simply go to default state
+				// else we're still dealing with an string...
+				if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') || (ch == '\n') || (ch == '\r') ) {
+					state = SCE_CONF_DEFAULT;
+				}
+				styler.ColourTo(i,SCE_CONF_STRING);
+				break;
+
+			case SCE_CONF_IDENTIFIER:
+				// stay  in CONF_IDENTIFIER state until we find a non-alphanumeric
+				if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
+					buffer[bufferCount++] = static_cast<char>(tolower(ch));
+				} else {
+					state = SCE_CONF_DEFAULT;
+					buffer[bufferCount] = '\0';
+
+					// check if the buffer contains a keyword, and highlight it if it is a keyword...
+					if(directives.InList(buffer)) {
+						styler.ColourTo(i-1,SCE_CONF_DIRECTIVE );
+					} else if(params.InList(buffer)) {
+						styler.ColourTo(i-1,SCE_CONF_PARAMETER );
+					} else if(strchr(buffer,'/') || strchr(buffer,'.')) {
+						styler.ColourTo(i-1,SCE_CONF_EXTENSION);
+					} else {
+						styler.ColourTo(i-1,SCE_CONF_DEFAULT);
+					}
+
+					// push back the faulty character
+					chNext = styler[i--];
+
+				}
+				break;
+
+			case SCE_CONF_NUMBER:
+				// stay  in CONF_NUMBER state until we find a non-numeric
+				if( (isascii(ch) && isdigit(ch)) || ch == '.') {
+					buffer[bufferCount++] = ch;
+				} else {
+					state = SCE_CONF_DEFAULT;
+					buffer[bufferCount] = '\0';
+
+					// Colourize here...
+					if( strchr(buffer,'.') ) {
+						// it is an IP address...
+						styler.ColourTo(i-1,SCE_CONF_IP);
+					} else {
+						// normal number
+						styler.ColourTo(i-1,SCE_CONF_NUMBER);
+					}
+
+					// push back a character
+					chNext = styler[i--];
+				}
+				break;
+
+		}
+	}
+	delete []buffer;
+}
+
+static const char * const confWordListDesc[] = {
+	"Directives",
+	"Parameters",
+	0
+};
+
+LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc);
diff --git a/scintilla/lexers/LexD.cxx b/scintilla/lexers/LexD.cxx
index 78b23dc..5b8f9e7 100644
--- a/scintilla/lexers/LexD.cxx
+++ b/scintilla/lexers/LexD.cxx
@@ -2,6 +2,7 @@
  ** 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.
@@ -13,17 +14,23 @@
 #include <assert.h>
 #include <ctype.h>
 
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
+
+#include <string>
+#include <map>
+
 #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"
+#include "OptionSet.h"
 
 #ifdef SCI_NAMESPACE
 using namespace Scintilla;
@@ -59,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;
+}
+
+// An individual named option for use in an OptionSet
+
+// 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 void ColouriseDoc(unsigned int startPos, int length, int initStyle,
-	WordList *keywordlists[], Accessor &styler, bool caseSensitive) {
+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,
+		};
 
-	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];
+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;
 
@@ -294,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);
@@ -323,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);
@@ -330,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) {
@@ -338,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 {"
@@ -350,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;
@@ -379,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/scintilla/lexers/LexErlang.cxx b/scintilla/lexers/LexErlang.cxx
index 00f18b5..5f52258 100644
--- a/scintilla/lexers/LexErlang.cxx
+++ b/scintilla/lexers/LexErlang.cxx
@@ -19,7 +19,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexForth.cxx b/scintilla/lexers/LexForth.cxx
index da52338..0e9875c 100644
--- a/scintilla/lexers/LexForth.cxx
+++ b/scintilla/lexers/LexForth.cxx
@@ -16,7 +16,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexFortran.cxx b/scintilla/lexers/LexFortran.cxx
index 67a58a0..6c61c54 100644
--- a/scintilla/lexers/LexFortran.cxx
+++ b/scintilla/lexers/LexFortran.cxx
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
@@ -267,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/scintilla/lexers/LexHTML.cxx b/scintilla/lexers/LexHTML.cxx
index e025c2b..546f5ad 100644
--- a/scintilla/lexers/LexHTML.cxx
+++ b/scintilla/lexers/LexHTML.cxx
@@ -16,7 +16,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
@@ -745,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--;
diff --git a/scintilla/lexers/LexLisp.cxx b/scintilla/lexers/LexLisp.cxx
index 4c5f3a8..08f765a 100644
--- a/scintilla/lexers/LexLisp.cxx
+++ b/scintilla/lexers/LexLisp.cxx
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexLua.cxx b/scintilla/lexers/LexLua.cxx
index ac3d6d5..a299d32 100644
--- a/scintilla/lexers/LexLua.cxx
+++ b/scintilla/lexers/LexLua.cxx
@@ -18,7 +18,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexMarkdown.cxx b/scintilla/lexers/LexMarkdown.cxx
index e3ffa66..3937120 100644
--- a/scintilla/lexers/LexMarkdown.cxx
+++ b/scintilla/lexers/LexMarkdown.cxx
@@ -44,7 +44,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexMatlab.cxx b/scintilla/lexers/LexMatlab.cxx
index af26ff9..0d2064e 100644
--- a/scintilla/lexers/LexMatlab.cxx
+++ b/scintilla/lexers/LexMatlab.cxx
@@ -21,7 +21,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexNsis.cxx b/scintilla/lexers/LexNsis.cxx
index 820a5d1..cd74d54 100644
--- a/scintilla/lexers/LexNsis.cxx
+++ b/scintilla/lexers/LexNsis.cxx
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexOthers.cxx b/scintilla/lexers/LexOthers.cxx
index 3449f07..2062b1b 100644
--- a/scintilla/lexers/LexOthers.cxx
+++ b/scintilla/lexers/LexOthers.cxx
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
@@ -510,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);
@@ -930,8 +929,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] == '+') {
diff --git a/scintilla/lexers/LexPascal.cxx b/scintilla/lexers/LexPascal.cxx
index 1243d38..867b00e 100644
--- a/scintilla/lexers/LexPascal.cxx
+++ b/scintilla/lexers/LexPascal.cxx
@@ -118,7 +118,6 @@ contains requires
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexPerl.cxx b/scintilla/lexers/LexPerl.cxx
index 9d76847..bc313a9 100644
--- a/scintilla/lexers/LexPerl.cxx
+++ b/scintilla/lexers/LexPerl.cxx
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexPython.cxx b/scintilla/lexers/LexPython.cxx
index 5e7c5b2..5020d71 100644
--- a/scintilla/lexers/LexPython.cxx
+++ b/scintilla/lexers/LexPython.cxx
@@ -16,7 +16,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexR.cxx b/scintilla/lexers/LexR.cxx
index 9947c72..d18fffb 100644
--- a/scintilla/lexers/LexR.cxx
+++ b/scintilla/lexers/LexR.cxx
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexRuby.cxx b/scintilla/lexers/LexRuby.cxx
index 2241084..4545bfa 100644
--- a/scintilla/lexers/LexRuby.cxx
+++ b/scintilla/lexers/LexRuby.cxx
@@ -16,7 +16,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
@@ -1729,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)
@@ -1765,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/scintilla/lexers/LexSQL.cxx b/scintilla/lexers/LexSQL.cxx
index 6ec32d0..ebcd72c 100644
--- a/scintilla/lexers/LexSQL.cxx
+++ b/scintilla/lexers/LexSQL.cxx
@@ -2,7 +2,7 @@
 /** @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>
@@ -12,24 +12,36 @@
 #include <assert.h>
 #include <ctype.h>
 
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
+
+#include <string>
+#include <vector>
+#include <map>
+#include <algorithm>
+
 #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"
+#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) {
@@ -47,31 +59,289 @@ 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("lexer.sql.fold.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();
+	}
+
+	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;
+	}
 
-	// property sql.backslash.escapes
-	//	Enables backslash as an escape character in SQL.
-	bool sqlBackslashEscapes = styler.GetPropertyInt("sql.backslash.escapes", 0) != 0;
+	OptionsSQL options;
+	OptionSetSQL osSQL;
+	SQLStates sqlStates;
 
-	bool sqlBackticksIdentifier = styler.GetPropertyInt("lexer.sql.backticks.identifier", 0) != 0;
+	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:
@@ -84,7 +354,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));
@@ -161,7 +431,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 == '\"') {
@@ -191,7 +461,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
@@ -204,9 +474,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);
@@ -220,25 +490,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);
@@ -251,6 +506,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);
@@ -258,7 +521,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 || (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) {
@@ -266,7 +538,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);
@@ -280,14 +552,18 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
 		}
 		if (style == SCE_SQL_OPERATOR) {
 			if (ch == '(') {
-				levelNext++;
+				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++) {
@@ -302,33 +578,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;
@@ -338,7 +714,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++;
@@ -346,16 +724,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/scintilla/lexers/LexTCL.cxx b/scintilla/lexers/LexTCL.cxx
index 0e196cb..de309f2 100644
--- a/scintilla/lexers/LexTCL.cxx
+++ b/scintilla/lexers/LexTCL.cxx
@@ -16,7 +16,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexTxt2tags.cxx b/scintilla/lexers/LexTxt2tags.cxx
index 3bed55b..8f8e181 100644
--- a/scintilla/lexers/LexTxt2tags.cxx
+++ b/scintilla/lexers/LexTxt2tags.cxx
@@ -27,7 +27,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexVHDL.cxx b/scintilla/lexers/LexVHDL.cxx
index fc4d1de..58bcd1a 100644
--- a/scintilla/lexers/LexVHDL.cxx
+++ b/scintilla/lexers/LexVHDL.cxx
@@ -21,7 +21,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexVerilog.cxx b/scintilla/lexers/LexVerilog.cxx
index a73edfb..8de04ff 100644
--- a/scintilla/lexers/LexVerilog.cxx
+++ b/scintilla/lexers/LexVerilog.cxx
@@ -17,7 +17,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexers/LexYAML.cxx b/scintilla/lexers/LexYAML.cxx
index 8e2ff74..727e8af 100644
--- a/scintilla/lexers/LexYAML.cxx
+++ b/scintilla/lexers/LexYAML.cxx
@@ -16,7 +16,6 @@
 #include "Scintilla.h"
 #include "SciLexer.h"
 
-#include "PropSetSimple.h"
 #include "WordList.h"
 #include "LexAccessor.h"
 #include "Accessor.h"
diff --git a/scintilla/lexlib/CharacterSet.h b/scintilla/lexlib/CharacterSet.h
index 18cb0aa..7240560 100644
--- a/scintilla/lexlib/CharacterSet.h
+++ b/scintilla/lexlib/CharacterSet.h
@@ -50,8 +50,8 @@ public:
 		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);
 			assert(val >= 0);
 			assert(val < size);
diff --git a/scintilla/lexlib/LexerBase.h b/scintilla/lexlib/LexerBase.h
index 02fc34d..2998d24 100644
--- a/scintilla/lexlib/LexerBase.h
+++ b/scintilla/lexlib/LexerBase.h
@@ -20,7 +20,7 @@ protected:
 	WordList *keyWordLists[numWordLists+1];
 public:
 	LexerBase();
-	~LexerBase();
+	virtual ~LexerBase();
 	void SCI_METHOD Release();
 	int SCI_METHOD Version() const;
 	const char * SCI_METHOD PropertyNames();
diff --git a/scintilla/lexlib/OptionSet.h b/scintilla/lexlib/OptionSet.h
index 277ca7a..873ac8b 100644
--- a/scintilla/lexlib/OptionSet.h
+++ b/scintilla/lexlib/OptionSet.h
@@ -80,6 +80,8 @@ class OptionSet {
 		names += name;
 	}
 public:
+	virtual ~OptionSet() {
+	}
 	void DefineProperty(const char *name, plcob pb, std::string description="") {
 		nameToDef[name] = Option(pb, description);
 		AppendName(name);
diff --git a/scintilla/lexlib/SparseState.h b/scintilla/lexlib/SparseState.h
new file mode 100644
index 0000000..94aa929
--- /dev/null
+++ b/scintilla/lexlib/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.size() == 0) || (value != states[states.size()-1].value)) {
+			states.push_back(State(position, value));
+		}
+	}
+	T ValueAt(int position) {
+		if (!states.size())
+			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/scintilla/lexlib/WordList.cxx b/scintilla/lexlib/WordList.cxx
index b50c694..cda35ec 100644
--- a/scintilla/lexlib/WordList.cxx
+++ b/scintilla/lexlib/WordList.cxx
@@ -110,6 +110,11 @@ void WordList::Set(const char *s) {
 	}
 }
 
+/** 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;
diff --git a/scintilla/src/AutoComplete.cxx b/scintilla/src/AutoComplete.cxx
index 32cf7b2..f6a291f 100644
--- a/scintilla/src/AutoComplete.cxx
+++ b/scintilla/src/AutoComplete.cxx
@@ -129,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/scintilla/src/CallTip.cxx b/scintilla/src/CallTip.cxx
index 18a5247..604304b 100644
--- a/scintilla/src/CallTip.cxx
+++ b/scintilla/src/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() {
diff --git a/scintilla/src/Catalogue.cxx b/scintilla/src/Catalogue.cxx
index a34f834..21e574d 100644
--- a/scintilla/src/Catalogue.cxx
+++ b/scintilla/src/Catalogue.cxx
@@ -86,9 +86,8 @@ int Scintilla_LinkLexers() {
 	LINK_LEXER(lmBash);
 	LINK_LEXER(lmCaml);
 	LINK_LEXER(lmCmake);
-	LINK_LEXER(lmCOBOL);
 	LINK_LEXER(lmCPP);
-	LINK_LEXER(lmCss);
+	LINK_LEXER(lmCPPNoCase);
 	LINK_LEXER(lmD);
 	LINK_LEXER(lmDiff);
 	LINK_LEXER(lmErlang);
@@ -103,7 +102,6 @@ int Scintilla_LinkLexers() {
 	LINK_LEXER(lmLua);
 	LINK_LEXER(lmMake);
 	LINK_LEXER(lmMarkdown);
-	// We use Octave instead of Matlab
 	LINK_LEXER(lmNsis);
 	LINK_LEXER(lmNull);
 	LINK_LEXER(lmOctave);
diff --git a/scintilla/src/Catalogue.cxx.orig b/scintilla/src/Catalogue.cxx.orig
new file mode 100644
index 0000000..00785d5
--- /dev/null
+++ b/scintilla/src/Catalogue.cxx.orig
@@ -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/scintilla/src/Catalogue.cxx.rej b/scintilla/src/Catalogue.cxx.rej
new file mode 100644
index 0000000..4e5e781
--- /dev/null
+++ b/scintilla/src/Catalogue.cxx.rej
@@ -0,0 +1,102 @@
+--- src/Catalogue.cxx	2010-09-04 12:03:35.000000000 +0200
++++ src/Catalogue.cxx	2010-11-21 18:00:07.000000000 +0100
+@@ -81,98 +81,41 @@
+ 
+ //++Autogenerated -- run src/LexGen.py to regenerate
+ //**\(\tLINK_LEXER(\*);\n\)
+-	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(lmMSSQL);
+-	LINK_LEXER(lmMySQL);
+-	LINK_LEXER(lmNimrod);
+-	LINK_LEXER(lmNncrontab);
++	// We use Octave instead of Matlab
+ 	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);
diff --git a/scintilla/src/Document.cxx b/scintilla/src/Document.cxx
index bae33b9..34e6a99 100644
--- a/scintilla/src/Document.cxx
+++ b/scintilla/src/Document.cxx
@@ -14,14 +14,6 @@
 #include <string>
 #include <vector>
 
-// With Borland C++ 5.5, including <string> includes Windows.h leading to defining
-// FindText to FindTextA which makes calls here to Document::FindText fail.
-#ifdef __BORLANDC__
-#ifdef FindText
-#undef FindText
-#endif
-#endif
-
 #include "Platform.h"
 
 #include "ILexer.h"
@@ -95,7 +87,7 @@ void LexInterface::Colourise(int start, int end) {
 
 Document::Document() {
 	refCount = 0;
-#ifdef unix
+#ifdef __unix__
 	eolMode = SC_EOL_LF;
 #else
 	eolMode = SC_EOL_CRLF;
@@ -552,7 +544,7 @@ int Document::NextPosition(int pos, int moveDir) const {
 				// 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 posStartLine - 1;
+					return pos - 1;
 				} else if (IsDBCSLeadByte(cb.CharAt(pos - 1))) {
 					// Must actually be trail byte
 					return pos - 2;
@@ -1317,7 +1309,11 @@ long Document::FindText(int minPos, int maxPos, const char *search,
 
 		//Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
 		const int limitPos = Platform::Maximum(startPos, endPos);
-		int pos = forward ? startPos : (startPos - 1);
+		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;
@@ -1526,8 +1522,8 @@ void Document::EnsureStyledTo(int pos) {
 		IncrementStyleClock();
 		if (pli && !pli->UseContainerLexing()) {
 			int lineEndStyled = LineFromPosition(GetEndStyled());
-			int endStyled = LineStart(lineEndStyled);
-			pli->Colourise(endStyled, pos);
+			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++) {
diff --git a/scintilla/src/Document.h b/scintilla/src/Document.h
index 78f00a7..ecdf5ff 100644
--- a/scintilla/src/Document.h
+++ b/scintilla/src/Document.h
@@ -357,6 +357,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);
@@ -368,7 +369,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);
diff --git a/scintilla/src/Editor.cxx b/scintilla/src/Editor.cxx
index 4608055..bc5e80c 100644
--- a/scintilla/src/Editor.cxx
+++ b/scintilla/src/Editor.cxx
@@ -16,14 +16,6 @@
 #include <algorithm>
 #include <memory>
 
-// With Borland C++ 5.5, including <string> includes Windows.h leading to defining
-// FindText to FindTextA which makes calls here to Document::FindText fail.
-#ifdef __BORLANDC__
-#ifdef FindText
-#undef FindText
-#endif
-#endif
-
 #include "Platform.h"
 
 #include "ILexer.h"
@@ -141,6 +133,9 @@ Editor::Editor() {
 	lastXChosen = 0;
 	lineAnchor = 0;
 	originalAnchorPos = 0;
+	wordSelectAnchorStartPos = 0;
+	wordSelectAnchorEndPos = 0;
+	wordSelectInitialCaretPos = -1;
 
 	primarySelection = true;
 
@@ -183,7 +178,8 @@ Editor::Editor() {
 
 	lengthForEncode = -1;
 
-	needUpdateUI = true;
+	needUpdateUI = 0;
+	ContainerNeedsUpdate(SC_UPDATE_CONTENT);
 	braces[0] = invalidPosition;
 	braces[1] = invalidPosition;
 	bracesMatchStyle = STYLE_BRACEBAD;
@@ -442,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));
 }
 
@@ -706,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);
 		}
 	}
 }
@@ -749,7 +748,7 @@ 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);
 }
 
@@ -990,6 +989,7 @@ void Editor::HorizontalScrollTo(int xPos) {
 		xPos = 0;
 	if ((wrapState == eWrapNone) && (xOffset != xPos)) {
 		xOffset = xPos;
+		ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
 		SetHorizontalScrollPos();
 		RedrawRect(GetClientRectangle());
 	}
@@ -1299,6 +1299,7 @@ void Editor::SetXYScroll(XYScrollPosition newXY) {
 		}
 		if (newXY.xOffset != xOffset) {
 			xOffset = newXY.xOffset;
+			ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
 			if (newXY.xOffset > 0) {
 				PRectangle rcText = GetTextRectangle();
 				if (horizontalScrollBarVisible &&
@@ -2042,7 +2043,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
 			ll->edgeColumn = -1;
 		}
 
-		char styleByte = 0;
+		char styleByte;
 		const int styleMask = pdoc->stylingBitsMask;
 		ll->styleBitsSet = 0;
 		// Fill base line layout
@@ -3043,7 +3044,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);
@@ -3165,11 +3166,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);
+			}
 		}
 	}
 
@@ -3183,10 +3184,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);
 		}
 	}
 
@@ -3316,7 +3316,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
 		surfaceWindow->SetPalette(&palTemp, true);
 
 		NotifyUpdateUI();
-		needUpdateUI = false;
+		needUpdateUI = 0;
 
 		RefreshStyleData();
 		RefreshPixMaps(surfaceWindow);
@@ -3921,8 +3921,8 @@ void Editor::InsertPaste(SelectionPosition selStart, const char *text, int len)
 	}
 }
 
-void Editor::ClearSelection() {
-	if (!sel.IsRectangular())
+void Editor::ClearSelection(bool retainMultipleSelections) {
+	if (!sel.IsRectangular() && !retainMultipleSelections)
 		FilterSelections();
 	UndoGroup ug(pdoc);
 	for (size_t r=0; r<sel.Count(); r++) {
@@ -4222,6 +4222,7 @@ void Editor::NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool
 void Editor::NotifyUpdateUI() {
 	SCNotification scn = {0};
 	scn.nmhdr.code = SCN_UPDATEUI;
+	scn.updated = needUpdateUI;
 	NotifyParent(scn);
 }
 
@@ -4338,7 +4339,7 @@ static inline int MovePositionForDeletion(int position, int startDeletion, int l
 }
 
 void Editor::NotifyModified(Document *, DocModification mh, void *) {
-	needUpdateUI = true;
+	ContainerNeedsUpdate(SC_UPDATE_CONTENT);
 	if (paintState == painting) {
 		CheckForChangeOutsidePaint(Range(mh.position, mh.position + mh.length));
 	}
@@ -4620,6 +4621,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.
  *
@@ -4727,7 +4733,6 @@ void Editor::Duplicate(bool forLine) {
 		forLine = true;
 	}
 	UndoGroup ug(pdoc, sel.Count() > 1);
-	SelectionPosition last;
 	const char *eol = "";
 	int eolLen = 0;
 	if (forLine) {
@@ -5131,6 +5136,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
@@ -5230,6 +5236,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());
 		}
@@ -5836,6 +5843,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),
@@ -5849,6 +5866,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;
@@ -5910,13 +5951,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));
@@ -5981,7 +6042,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);
 					}
@@ -6098,7 +6160,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
@@ -6108,12 +6170,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
@@ -6151,7 +6210,7 @@ void Editor::ButtonMove(Point pt) {
 	} 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
 			}
@@ -6177,6 +6236,8 @@ 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;
@@ -6184,7 +6245,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
 	}
 	if (HaveMouseCapture()) {
 		if (PointInSelMargin(pt)) {
-			DisplayCursor(Window::cursorReverseArrow);
+			DisplayCursor(GetMarginCursor(pt));
 		} else {
 			DisplayCursor(Window::cursorText);
 			SetHotSpotRange(NULL);
@@ -6344,7 +6405,7 @@ void Editor::IdleStyling() {
 
 	if (needUpdateUI) {
 		NotifyUpdateUI();
-		needUpdateUI = false;
+		needUpdateUI = 0;
 	}
 	styleNeeded.Reset();
 }
@@ -7001,6 +7062,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;
@@ -7315,7 +7377,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: {
@@ -7466,6 +7527,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;
@@ -7786,6 +7848,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();
diff --git a/scintilla/src/Editor.h b/scintilla/src/Editor.h
index 50948e2..db8a36a 100644
--- a/scintilla/src/Editor.h
+++ b/scintilla/src/Editor.h
@@ -201,6 +201,9 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	int lastXChosen;
 	int lineAnchor;
 	int originalAnchorPos;
+	int wordSelectAnchorStartPos;
+	int wordSelectAnchorEndPos;
+	int wordSelectInitialCaretPos;
 	int targetStart;
 	int targetEnd;
 	int searchFlags;
@@ -208,7 +211,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;
@@ -391,7 +394,7 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	void AddChar(char ch);
 	virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false);
 	void InsertPaste(SelectionPosition selStart, const char *text, int len);
-	void ClearSelection();
+	void ClearSelection(bool retainMultipleSelections=false);
 	void ClearAll();
 	void ClearDocumentStyle();
 	void Cut();
@@ -438,6 +441,7 @@ protected:	// ScintillaBase subclass needs access to much of Editor
 	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);
 	enum { cmSame, cmUpper, cmLower } caseMap;
 	virtual std::string CaseMapString(const std::string &s, int caseMapping);
@@ -479,7 +483,9 @@ 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);
diff --git a/scintilla/src/ExternalLexer.cxx b/scintilla/src/ExternalLexer.cxx
index 02b7eaa..bb48464 100644
--- a/scintilla/src/ExternalLexer.cxx
+++ b/scintilla/src/ExternalLexer.cxx
@@ -38,7 +38,6 @@ LexerManager *LexerManager::theInstance = NULL;
 void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) {
 	fneFactory = fFactory;
 	fnFactory = fFactory(index);
-	externalLanguage = index;
 }
 
 //------------------------------------------
diff --git a/scintilla/src/ExternalLexer.h b/scintilla/src/ExternalLexer.h
index 98d543e..bf175a6 100644
--- a/scintilla/src/ExternalLexer.h
+++ b/scintilla/src/ExternalLexer.h
@@ -27,11 +27,12 @@ typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned i
 class ExternalLexerModule : public LexerModule {
 protected:
 	GetLexerFactoryFunction fneFactory;
-	int externalLanguage;
 	char name[100];
 public:
 	ExternalLexerModule(int language_, LexerFunction fnLexer_,
-		const char *languageName_=0, LexerFunction fnFolder_=0) : LexerModule(language_, fnLexer_, 0, fnFolder_) {
+		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;
diff --git a/scintilla/src/LexGen.py b/scintilla/src/LexGen.py
new file mode 100755
index 0000000..22cdaae
--- /dev/null
+++ b/scintilla/src/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/scintilla/src/Partitioning.h b/scintilla/src/Partitioning.h
index 17925b9..07f3c5d 100644
--- a/scintilla/src/Partitioning.h
+++ b/scintilla/src/Partitioning.h
@@ -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/scintilla/src/PositionCache.cxx b/scintilla/src/PositionCache.cxx
index 548b4d9..2ed1524 100644
--- a/scintilla/src/PositionCache.cxx
+++ b/scintilla/src/PositionCache.cxx
@@ -68,6 +68,8 @@ LineLayout::LineLayout(int maxLineLength_) :
 	widthLine(wrapWidthInfinite),
 	lines(1),
 	wrapIndent(0) {
+	bracePreviousStyles[0] = 0;
+	bracePreviousStyles[1] = 0;
 	Resize(maxLineLength_);
 }
 
diff --git a/scintilla/src/RunStyles.cxx b/scintilla/src/RunStyles.cxx
index ae32c73..460d5d2 100644
--- a/scintilla/src/RunStyles.cxx
+++ b/scintilla/src/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/scintilla/src/SciTE.properties b/scintilla/src/SciTE.properties
new file mode 100644
index 0000000..c323f52
--- /dev/null
+++ b/scintilla/src/SciTE.properties
@@ -0,0 +1,6 @@
+# SciTE.properties is the per directory local options file and can be used to override
+# settings made in SciTEGlobal.properties
+command.build.directory.*.cxx=..\win32
+command.build.directory.*.h=..\win32
+command.build.*.cxx=nmake -f scintilla.mak QUIET=1 DEBUG=0
+command.build.*.h=nmake -f scintilla.mak QUIET=1 DEBUG=0
diff --git a/scintilla/src/Selection.cxx b/scintilla/src/Selection.cxx
index 6f3267d..305d721 100644
--- a/scintilla/src/Selection.cxx
+++ b/scintilla/src/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;
 			}
 		}
 	}
@@ -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/scintilla/src/Selection.h b/scintilla/src/Selection.h
index bb29266..d7c7d79 100644
--- a/scintilla/src/Selection.h
+++ b/scintilla/src/Selection.h
@@ -60,7 +60,7 @@ public:
 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) {
 	}
@@ -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/scintilla/src/SplitVector.h b/scintilla/src/SplitVector.h
index 2e17ba3..44d5ddc 100644
--- a/scintilla/src/SplitVector.h
+++ b/scintilla/src/SplitVector.h
@@ -238,7 +238,7 @@ public:
 		DeleteRange(0, lengthBody);
 	}
 
-	// Retrieve a range of elemetns into an array
+	// 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;
diff --git a/scintilla/src/ViewStyle.cxx b/scintilla/src/ViewStyle.cxx
index 1b315d1..78ba1f7 100644
--- a/scintilla/src/ViewStyle.cxx
+++ b/scintilla/src/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
diff --git a/scintilla/src/ViewStyle.h b/scintilla/src/ViewStyle.h
index cd6dc1a..6ca488d 100644
--- a/scintilla/src/ViewStyle.h
+++ b/scintilla/src/ViewStyle.h
@@ -20,6 +20,7 @@ public:
 	int width;
 	int mask;
 	bool sensitive;
+	int cursor;
 	MarginStyle();
 };
 
diff --git a/scintilla/version.txt b/scintilla/version.txt
new file mode 100644
index 0000000..188ccfe
--- /dev/null
+++ b/scintilla/version.txt
@@ -0,0 +1 @@
+225
-- 
1.7.1

