diff --git a/addons/src/Makefile.am b/addons/src/Makefile.am
index 9826a98..69ba684 100644
--- a/addons/src/Makefile.am
+++ b/addons/src/Makefile.am
@@ -5,11 +5,13 @@ geanyplugins_LTLIBRARIES = \
 
 addons_la_SOURCES = \
 	addons.h \
+	ao_blanklines.h \
 	ao_doclist.h \
 	ao_openuri.h \
 	ao_systray.h \
 	tasks.h \
 	addons.c \
+	ao_blanklines.c \
 	ao_doclist.c \
 	ao_openuri.c \
 	ao_systray.c \
diff --git a/addons/src/addons.c b/addons/src/addons.c
index 423a146..33405f8 100644
--- a/addons/src/addons.c
+++ b/addons/src/addons.c
@@ -24,6 +24,7 @@
 
 #include "geanyplugin.h"
 
+#include "ao_blanklines.h"
 #include "ao_doclist.h"
 #include "ao_openuri.h"
 #include "ao_systray.h"
@@ -36,7 +37,7 @@ GeanyData		*geany_data;
 GeanyFunctions	*geany_functions;
 
 
-PLUGIN_VERSION_CHECK(147)
+PLUGIN_VERSION_CHECK(154)
 PLUGIN_SET_INFO(_("Addons"), _("Various small addons for Geany."), VERSION,
 	"Enrico Tr��ger, Bert Vermeulen")
 
@@ -49,6 +50,7 @@ typedef struct
 	gboolean enable_openuri;
 	gboolean enable_tasks;
 	gboolean enable_systray;
+	gboolean strip_trailing_blank_lines;
 
 	/* instances and variables of components */
 	AoDocList *doclist;
@@ -65,13 +67,15 @@ static void ao_update_editor_menu_cb(GObject *obj, const gchar *word, gint pos,
 
 PluginCallback plugin_callbacks[] =
 {
-    { "update-editor-menu", (GCallback) &ao_update_editor_menu_cb, FALSE, NULL },
+	{ "update-editor-menu", (GCallback) &ao_update_editor_menu_cb, FALSE, NULL },
 
 	{ "editor-notify", (GCallback) &tasks_on_editor_notify, TRUE, NULL },
 	{ "document-open", (GCallback) &tasks_on_document_open, TRUE, NULL },
 	{ "document-close", (GCallback) &tasks_on_document_close, TRUE, NULL },
 	{ "document-activate", (GCallback) &tasks_on_document_activate, TRUE, NULL },
 
+	{ "document-before-save", (GCallback) &ao_blanklines_on_document_before_save, TRUE, NULL },
+
 	{ NULL, NULL, FALSE, NULL }
 };
 
@@ -114,6 +118,8 @@ void plugin_init(GeanyData *data)
 		"addons", "enable_tasks", TRUE);
 	ao_info->enable_systray = utils_get_setting_boolean(config,
 		"addons", "enable_systray", FALSE);
+	ao_info->strip_trailing_blank_lines = utils_get_setting_boolean(config,
+		"addons", "strip_trailing_blank_lines", FALSE);
 
 	main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
 	plugin_module_make_resident(geany_plugin);
@@ -123,6 +129,7 @@ void plugin_init(GeanyData *data)
 	ao_info->systray = ao_systray_new(ao_info->enable_systray);
 
 	tasks_set_enable(ao_info->enable_tasks);
+	ao_blanklines_set_enable(ao_info->strip_trailing_blank_lines);
 }
 
 
@@ -142,6 +149,8 @@ static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer
 			g_object_get_data(G_OBJECT(dialog), "check_tasks"))));
 		ao_info->enable_systray = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
 			g_object_get_data(G_OBJECT(dialog), "check_systray"))));
+		ao_info->strip_trailing_blank_lines = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+			g_object_get_data(G_OBJECT(dialog), "check_blanklines"))));
 
 		g_key_file_load_from_file(config, ao_info->config_file, G_KEY_FILE_NONE, NULL);
 		g_key_file_set_boolean(config, "addons",
@@ -149,11 +158,14 @@ static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer
 		g_key_file_set_boolean(config, "addons", "enable_openuri", ao_info->enable_openuri);
 		g_key_file_set_boolean(config, "addons", "enable_tasks", ao_info->enable_tasks);
 		g_key_file_set_boolean(config, "addons", "enable_systray", ao_info->enable_systray);
+		g_key_file_set_boolean(config, "addons",
+			"strip_trailing_blank_lines", ao_info->strip_trailing_blank_lines);
 
 		g_object_set(ao_info->doclist, "enable-doclist", ao_info->show_toolbar_doclist_item, NULL);
 		g_object_set(ao_info->openuri, "enable-openuri", ao_info->enable_openuri, NULL);
 		g_object_set(ao_info->systray, "enable-systray", ao_info->enable_systray, NULL);
 		tasks_set_enable(ao_info->enable_tasks);
+		ao_blanklines_set_enable(ao_info->strip_trailing_blank_lines);
 
 		if (! g_file_test(config_dir, G_FILE_TEST_IS_DIR) && utils_mkdir(config_dir, TRUE) != 0)
 		{
@@ -175,7 +187,7 @@ static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer
 
 GtkWidget *plugin_configure(GtkDialog *dialog)
 {
-	GtkWidget *vbox, *check_doclist, *check_openuri, *check_tasks, *check_systray;
+	GtkWidget *vbox, *check_doclist, *check_openuri, *check_tasks, *check_systray, *check_blanklines;
 
 	vbox = gtk_vbox_new(FALSE, 6);
 
@@ -204,10 +216,17 @@ GtkWidget *plugin_configure(GtkDialog *dialog)
 		ao_info->enable_systray);
 	gtk_box_pack_start(GTK_BOX(vbox), check_systray, FALSE, FALSE, 3);
 
+	check_blanklines = gtk_check_button_new_with_label(
+		_("Strip trailing blank lines"));
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_blanklines),
+		ao_info->strip_trailing_blank_lines);
+	gtk_box_pack_start(GTK_BOX(vbox), check_blanklines, FALSE, FALSE, 3);
+
 	g_object_set_data(G_OBJECT(dialog), "check_doclist", check_doclist);
 	g_object_set_data(G_OBJECT(dialog), "check_openuri", check_openuri);
 	g_object_set_data(G_OBJECT(dialog), "check_tasks", check_tasks);
 	g_object_set_data(G_OBJECT(dialog), "check_systray", check_systray);
+	g_object_set_data(G_OBJECT(dialog), "check_blanklines", check_blanklines);
 	g_signal_connect(dialog, "response", G_CALLBACK(ao_configure_response_cb), NULL);
 
 	gtk_widget_show_all(vbox);
@@ -227,6 +246,7 @@ void plugin_cleanup(void)
 	g_object_unref(ao_info->systray);
 
 	tasks_set_enable(FALSE);
+	ao_blanklines_set_enable(FALSE);
 
 	g_free(ao_info->config_file);
 	g_free(ao_info);
diff --git a/addons/src/ao_blanklines.c b/addons/src/ao_blanklines.c
new file mode 100644
index 0000000..0ae0e65
--- /dev/null
+++ b/addons/src/ao_blanklines.c
@@ -0,0 +1,92 @@
+/*
+ *			ao_blanklines.c - this file is part of Addons, a Geany plugin
+ *
+ *			Copyright 2009 Eugene Arshinov <earshinov@gmail.com>
+ *
+ *			This program is free software; you can redistribute it and/or modify
+ *			it under the terms of the GNU General Public License as published by
+ *			the Free Software Foundation; either version 2 of the License, or
+ *			(at your option) any later version.
+ *
+ *			This program is distributed in the hope that it will be useful,
+ *			but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *			MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+ *			GNU General Public License for more details.
+ *
+ *			You should have received a copy of the GNU General Public License
+ *			along with this program; if not, write to the Free Software
+ *			Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *			MA 02110-1301, USA.
+ */
+
+#include "geanyplugin.h"
+
+#include "addons.h"
+#include "ao_blanklines.h"
+
+static gboolean enabled = FALSE;
+
+static void editor_strip_trailing_newlines(GeanyEditor *editor)
+{
+	const gint maxline = sci_get_line_count(editor->sci) - 1;
+	const gint maxpos = sci_get_line_end_position(editor->sci, maxline);
+
+	gint line, start, end, pos;
+	gchar ch;
+
+	/*
+	 * Store index of the last non-empty line in `line' and position of the first
+	 * of its trailing spaces in `pos'. If all lines are empty, `line' will
+	 * contain -1, and `pos' will be undefined. If `line' does not contain
+	 * trailing spaces, `pos' will be its end position.
+	 */
+	for (line = maxline; line >= 0; line--)
+	{
+		start = sci_get_position_from_line(editor->sci, line);
+		end = sci_get_line_end_position(editor->sci, line);
+
+		/*
+		 * We can't be sure that `geany_data->file_prefs->strip_trailing_spaces'
+		 * setting is set, so we should check for trailing spaces manually.
+		 * Performance overhead of the for loop below is very small anyway,
+		 * so it does not worth checking the setting manually and writing
+		 * additional code.
+		 */
+
+		for (pos = end-1; pos >= start; pos--)
+		{
+			ch = sci_get_char_at(editor->sci, pos);
+			if (ch != ' ' && ch != '\t')
+				break;
+		}
+		++pos;
+		if (pos > start)
+			break;
+	}
+
+	if (line == -1 || geany_data->file_prefs->final_new_line)
+	{
+		/* leave one newline */
+		line++;
+		pos = sci_get_position_from_line(editor->sci, line);
+	}
+
+	if (pos < maxpos)
+	{
+		/* there are some lines to be removed */
+		sci_set_target_start(editor->sci, pos);
+		sci_set_target_end(editor->sci, maxpos);
+		sci_replace_target(editor->sci, "", FALSE);
+	}
+}
+
+void ao_blanklines_set_enable(gboolean enabled_)
+{
+	enabled = enabled_;
+}
+
+void ao_blanklines_on_document_before_save(GObject *object, GeanyDocument *doc, gpointer data)
+{
+	if (enabled)
+		editor_strip_trailing_newlines(doc->editor);
+}
\ No newline at end of file
diff --git a/addons/src/ao_blanklines.h b/addons/src/ao_blanklines.h
new file mode 100644
index 0000000..08d89c9
--- /dev/null
+++ b/addons/src/ao_blanklines.h
@@ -0,0 +1,30 @@
+/*
+ *			ao_blanklines.h - this file is part of Addons, a Geany plugin
+ *
+ *			Copyright 2009 Eugene Arshinov <earshinov@gmail.com>
+ *
+ *			This program is free software; you can redistribute it and/or modify
+ *			it under the terms of the GNU General Public License as published by
+ *			the Free Software Foundation; either version 2 of the License, or
+ *			(at your option) any later version.
+ *
+ *			This program is distributed in the hope that it will be useful,
+ *			but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *			MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+ *			GNU General Public License for more details.
+ *
+ *			You should have received a copy of the GNU General Public License
+ *			along with this program; if not, write to the Free Software
+ *			Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *			MA 02110-1301, USA.
+ */
+
+#ifndef __AO_BLANKLINES_H__
+#define __AO_BLANKLINES_H__
+
+
+void ao_blanklines_set_enable(gboolean enabled_);
+
+void ao_blanklines_on_document_before_save(GObject *object, GeanyDocument *doc, gpointer data);
+
+#endif
