diff --git a/regex_filter/__init__.py b/regex_filter/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..11d068ec0ee3465ec85d4298e0e340693ea6b151
--- /dev/null
+++ b/regex_filter/__init__.py
@@ -0,0 +1 @@
+from regex_filter import RegexFilterPlugin
diff --git a/regex_filter/manifest.ini b/regex_filter/manifest.ini
new file mode 100644
index 0000000000000000000000000000000000000000..76a28828a5274b740192f6c3a30e799c1ef630ee
--- /dev/null
+++ b/regex_filter/manifest.ini
@@ -0,0 +1,9 @@
+[info]
+name: Regex Filter
+short_name: regex_filter
+version: 0.1
+description: Filter incoming messages using regex.
+authors: Yann Leboulanger <asterix@lagaule.org>
+homepage: http://gajim.org
+
+
diff --git a/regex_filter/regex_filter.py b/regex_filter/regex_filter.py
new file mode 100644
index 0000000000000000000000000000000000000000..6a4f818371c5a9e3468dc068682f59a1ed3e8062
--- /dev/null
+++ b/regex_filter/regex_filter.py
@@ -0,0 +1,136 @@
+# -*- coding: utf-8 -*-
+
+## This file is part of Gajim.
+##
+## Gajim 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; version 3 only.
+##
+## Gajim 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 Gajim.  If not, see <http://www.gnu.org/licenses/>.
+##
+
+'''
+Regex Filter plugin.
+
+:author: Yann Leboulanger <asterix@lagaule.org>
+:since: 23th September 2011
+:copyright: Copyright (2011) Yann Leboulanger <asterix@lagaule.org>
+:license: GPLv3
+'''
+
+import re
+
+from plugins import GajimPlugin
+from plugins.helpers import log, log_calls
+
+from common import gajim
+from common import ged
+from command_system.framework import CommandContainer, command, doc
+from command_system.implementation.hosts import *
+
+class RegexFilterPlugin(GajimPlugin):
+
+    @log_calls('RegexFilterPlugin')
+    def init(self):
+        self.description = _('Regex Filter Plugin.')
+        self.config_dialog = None
+
+        self.events_handlers = {
+            'decrypted-message-received': (ged.PREGUI1,
+                self._nec_decrypted_message_received),
+            'gc-message-received': (ged.PREGUI1, self._nec_gc_message_received),
+        }
+
+        self.rules = {}
+        self.create_rules()
+
+    @log_calls('RegexFilterPlugin')
+    def activate(self):
+        FilterCommands.enable()
+
+    @log_calls('RegexFilterPlugin')
+    def deactivate(self):
+        FilterCommands.disable()
+
+    @log_calls('RegexFilterPlugin')
+    def create_rules(self):
+        for num, c in self.config.items():
+            self.rules[int(num)] = [re.compile(c[0], re.MULTILINE), c[1]]
+
+    @log_calls('RegexFilterPlugin')
+    def add_rule(self, search, replace):
+        if self.rules:
+            num = max(self.rules.keys()) + 1
+        else:
+            num = 0
+        self.config[str(num)] = [search, replace]
+        self.create_rules()
+
+    @log_calls('RegexFilterPlugin')
+    def remove_rule(self, num):
+        if num in self.config:
+            del self.config[num]
+            self.create_rules()
+            return True
+        return False
+
+    @log_calls('RegexFilterPlugin')
+    def get_rules(self):
+        return self.config
+
+    @log_calls('RegexFilterPlugin')
+    def _nec_all(self, obj):
+        if not obj.msgtxt:
+            return
+        rules_num = self.rules.keys()
+        rules_num.sort()
+        for num in rules_num:
+            rule = self.rules[num]
+            obj.msgtxt = rule[0].sub(rule[1], obj.msgtxt)
+
+    @log_calls('RegexFilterPlugin')
+    def _nec_decrypted_message_received(self, obj):
+        self._nec_all(obj)
+
+    @log_calls('RegexFilterPlugin')
+    def _nec_gc_message_received(self, obj):
+        self._nec_all(obj)
+
+class FilterCommands(CommandContainer):
+    AUTOMATIC = False
+    HOSTS = ChatCommands, PrivateChatCommands, GroupChatCommands
+
+    @command("add_filter", raw=True)
+    @doc(_("Add an incoming filter. First argument is the search regex, second argument is the replace regex."))
+    def add_filter(self, search, replace):
+        plugin = gajim.plugin_manager.get_active_plugin('regex_filter')
+        plugin.add_rule(search, replace)
+        return _('Added rule to replace %s by %s' % (search, replace))
+
+    @command("remove_filter", raw=True)
+    @doc(_("Remove an incoming filter. Argument is the rule number. See /list_rules command."))
+    def remove_filter(self, num):
+        plugin = gajim.plugin_manager.get_active_plugin('regex_filter')
+        if plugin.remove_rule(num):
+            return _('Rule number %s removed' % num)
+        return _('Rule number %s does not exist' % num)
+
+    @command("list_filters")
+    @doc(_("List incoming filters."))
+    def list_filters(self):
+        plugin = gajim.plugin_manager.get_active_plugin('regex_filter')
+        rules = plugin.get_rules()
+        st = ''
+        for num, rule in rules.items():
+            st += _('%(num)s: %(search)s -> %(replace)s') % {'num': num,
+                'search': rule[0], 'replace': rule[1]} + '\n'
+        if st:
+            return st[:-1]
+        else:
+            return _('No rule defined')