[packages/mono-tools] - merged partial update from git; obsoletes am and mono3 patches - added sdkver patch (allows to bui

qboosh qboosh at pld-linux.org
Sat Jan 11 18:52:35 CET 2014


commit d2d045d07c22571a40e7f5991cd2e5bc8c37c019
Author: Jakub Bogusz <qboosh at pld-linux.org>
Date:   Sat Jan 11 18:53:18 2014 +0100

    - merged partial update from git; obsoletes am and mono3 patches
    - added sdkver patch (allows to build with gtk-sharp2 2.12.x)
    - release 6 (now builds with mono 3.2.x)

 mono-tools-am.patch         |    72 -
 mono-tools-git-partial.diff | 28420 ++++++++++++++++++++++++++++++++++++++++++
 mono-tools-mono3.patch      |   741 --
 mono-tools-sdkver.patch     |    21 +
 mono-tools.spec             |    26 +-
 5 files changed, 28455 insertions(+), 825 deletions(-)
---
diff --git a/mono-tools.spec b/mono-tools.spec
index 83b6eca..8318203 100644
--- a/mono-tools.spec
+++ b/mono-tools.spec
@@ -1,4 +1,4 @@
-# NOTE: 2.11 tarball is broken
+# NOTE: upstream 2.11 tarball is broken; it seems 2.11 isn't finished yet
 #
 # Conditional build:
 %bcond_with	gecko		# don't build gecko html renderer
@@ -8,15 +8,15 @@ Summary:	Mono Tools
 Summary(pl.UTF-8):	Narzędzia do mono
 Name:		mono-tools
 Version:	2.10
-Release:	5
+Release:	6
 License:	GPL v2+
 Group:		Development/Tools
 Source0:	http://download.mono-project.com/sources/mono-tools/%{name}-%{version}.tar.bz2
 # Source0-md5:	da178df2c119c696c08c09dc9eb01994
-Patch0:		%{name}-pwd.patch
-Patch1:		%{name}-configure.patch
-Patch2:		%{name}-am.patch
-Patch3:		%{name}-mono3.patch
+Patch0:		%{name}-git-partial.diff
+Patch1:		%{name}-pwd.patch
+Patch2:		%{name}-configure.patch
+Patch3:		%{name}-sdkver.patch
 URL:		http://www.mono-project.com/
 BuildRequires:	autoconf
 BuildRequires:	automake
@@ -31,7 +31,7 @@ BuildRequires:	libgdiplus
 BuildRequires:	mono-compat-links
 BuildRequires:	mono-csharp
 BuildRequires:	mono-devel >= 2.10
-BuildRequires:	mono-monodoc >= 2.10
+BuildRequires:	mono-monodoc >= 3.2.5-2
 BuildRequires:	pkgconfig
 BuildRequires:	rpmbuild(monoautodeps)
 BuildRequires:	sed >= 4.0
@@ -164,6 +164,7 @@ zawartości.
 %{__sed} -i -e 's,mono/1.0,mono/2.0,' asn1view/gtk/Makefile.am
 
 %build
+%{__glib_gettextize}
 %{__aclocal}
 %{__autoconf}
 %{__automake}
@@ -175,8 +176,11 @@ rm -rf $RPM_BUILD_ROOT
 
 %{__make} install \
 	DESTDIR=$RPM_BUILD_ROOT \
-	pkglibdir=%{_prefix}/lib/mono-tools \
-	pkgconfigdir=%{_pkgconfigdir}
+	pkgconfigdir=%{_pkgconfigdir} \
+	pkglibdir=%{_prefix}/lib/mono-tools
+
+# debug
+%{__rm} $RPM_BUILD_ROOT%{_prefix}/lib/mono-tools/{Mono.Profiler.Widgets.dll,emveepee.exe}.mdb
 
 %find_lang %{name}
 
@@ -214,9 +218,7 @@ rm -rf $RPM_BUILD_ROOT
 %attr(755,root,root) %{_prefix}/lib/mperfmon/mperfmon.exe
 %dir %{_prefix}/lib/mono-tools
 %{_prefix}/lib/mono-tools/Mono.Profiler.Widgets.dll
-%exclude %{_prefix}/lib/mono-tools/Mono.Profiler.Widgets.dll.mdb
 %attr(755,root,root) %{_prefix}/lib/mono-tools/emveepee.exe
-%exclude %{_prefix}/lib/mono-tools/emveepee.exe.mdb
 %attr(755,root,root) %{_prefix}/lib/monodoc/browser.exe
 %{_prefix}/lib/monodoc/web
 %{_desktopdir}/gsharp.desktop
@@ -224,7 +226,7 @@ rm -rf $RPM_BUILD_ROOT
 %{_desktopdir}/monodoc.desktop
 %{_pixmapsdir}/ilcontrast.png
 %{_pixmapsdir}/monodoc.png
-%{_iconsdir}/hicolor/*/*/*.png
+%{_iconsdir}/hicolor/*x*/apps/monodoc.png
 %{_pkgconfigdir}/create-native-map.pc
 %{_mandir}/man1/create-native-map.1*
 %{_mandir}/man1/mperfmon.1*
diff --git a/mono-tools-am.patch b/mono-tools-am.patch
deleted file mode 100644
index 9cce9d2..0000000
--- a/mono-tools-am.patch
+++ /dev/null
@@ -1,72 +0,0 @@
---- mono-tools-2.10/Mono.Profiler/Mono.Profiler.Widgets/Makefile.am.orig	2011-02-12 17:32:47.000000000 +0100
-+++ mono-tools-2.10/Mono.Profiler/Mono.Profiler.Widgets/Makefile.am	2013-09-29 21:57:59.331555089 +0200
-@@ -9,7 +9,8 @@
- ASSEMBLY_MDB = 
- endif
- 
--pkglib_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
-+assdir = $(pkglibdir)
-+ass_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
- 
- CLEANFILES = $(ASSEMBLY) $(ASSEMBLY_MDB)
- 
---- mono-tools-2.10/Mono.Profiler/heap-snapshot-explorer/Makefile.am.orig	2011-02-12 17:32:47.000000000 +0100
-+++ mono-tools-2.10/Mono.Profiler/heap-snapshot-explorer/Makefile.am	2013-09-29 21:59:02.694493316 +0200
-@@ -9,7 +9,8 @@
- ASSEMBLY_MDB = 
- endif
- 
--pkglib_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
-+assdir = $(pkglibdir)
-+ass_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
- 
- CLEANFILES = $(ASSEMBLY) $(ASSEMBLY_MDB)
- 
---- mono-tools-2.10/Mono.Profiler/heap-snapshot-viewer/Makefile.am.orig	2011-02-12 17:32:47.000000000 +0100
-+++ mono-tools-2.10/Mono.Profiler/heap-snapshot-viewer/Makefile.am	2013-09-29 21:59:27.985666109 +0200
-@@ -8,7 +8,8 @@
- ASSEMBLY_MDB = 
- endif
- 
--pkglib_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
-+assdir = $(pkglibdir)
-+ass_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
- bin_SCRIPTS = mprof-heap-viewer
- man_MANS=man/man1/mprof-heap-viewer.1
- 
---- mono-tools-2.10/Mono.Profiler/mprof-gui/Makefile.am.orig	2011-02-12 17:32:47.000000000 +0100
-+++ mono-tools-2.10/Mono.Profiler/mprof-gui/Makefile.am	2013-09-29 22:00:02.557269251 +0200
-@@ -8,7 +8,8 @@
- ASSEMBLY_MDB = 
- endif
- 
--pkglib_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
-+assdir = $(pkglibdir)
-+ass_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
- bin_SCRIPTS = emveepee
- 
- CLEANFILES = $(ASSEMBLY) $(ASSEMBLY_MDB)
---- mono-tools-2.10/Mono.Profiler/profiler-decoder-library/Makefile.am.orig	2011-02-12 17:32:47.000000000 +0100
-+++ mono-tools-2.10/Mono.Profiler/profiler-decoder-library/Makefile.am	2013-09-30 18:44:47.911443506 +0200
-@@ -9,7 +9,8 @@
- ASSEMBLY_MDB = 
- endif
- 
--pkglib_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
-+assdir = $(pkglibdir)
-+ass_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
- 
- CLEANFILES = $(ASSEMBLY) $(ASSEMBLY_MDB)
- 
---- mono-tools-2.10/Mono.Profiler/profiler-file-decoder/Makefile.am.orig	2011-02-12 17:32:47.000000000 +0100
-+++ mono-tools-2.10/Mono.Profiler/profiler-file-decoder/Makefile.am	2013-09-30 18:45:34.606945410 +0200
-@@ -9,7 +9,8 @@
- ASSEMBLY_MDB = 
- endif
- 
--pkglib_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
-+assdir = $(pkglibdir)
-+ass_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
- bin_SCRIPTS = mprof-decoder
- man_MANS = man/man1/mprof-decoder.1 
- 
diff --git a/mono-tools-git-partial.diff b/mono-tools-git-partial.diff
new file mode 100644
index 0000000..d6f8baf
--- /dev/null
+++ b/mono-tools-git-partial.diff
@@ -0,0 +1,28420 @@
+diff --git a/Mono.Profiler/Mono.Profiler.Widgets/Makefile.am b/Mono.Profiler/Mono.Profiler.Widgets/Makefile.am
+index 7b91e6b..f0bf1ec 100644
+--- a/Mono.Profiler/Mono.Profiler.Widgets/Makefile.am
++++ b/Mono.Profiler/Mono.Profiler.Widgets/Makefile.am
+@@ -9,7 +9,8 @@ CSFLAGS =  -noconfig -codepage:utf8 -warn:4
+ ASSEMBLY_MDB = 
+ endif
+ 
+-pkglib_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
++programfilesdir = $(pkglibdir)
++programfiles_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
+ 
+ CLEANFILES = $(ASSEMBLY) $(ASSEMBLY_MDB)
+ 
+diff --git a/Mono.Profiler/heap-snapshot-explorer/Makefile.am b/Mono.Profiler/heap-snapshot-explorer/Makefile.am
+index 2bb2401..a9f34a3 100644
+--- a/Mono.Profiler/heap-snapshot-explorer/Makefile.am
++++ b/Mono.Profiler/heap-snapshot-explorer/Makefile.am
+@@ -9,7 +9,8 @@ CSFLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize+
+ ASSEMBLY_MDB = 
+ endif
+ 
+-pkglib_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
++programfilesdir = $(pkglibdir)
++programfiles_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
+ 
+ CLEANFILES = $(ASSEMBLY) $(ASSEMBLY_MDB)
+ 
+diff --git a/Mono.Profiler/heap-snapshot-viewer/Makefile.am b/Mono.Profiler/heap-snapshot-viewer/Makefile.am
+index 3b488be..f7b0888 100644
+--- a/Mono.Profiler/heap-snapshot-viewer/Makefile.am
++++ b/Mono.Profiler/heap-snapshot-viewer/Makefile.am
+@@ -8,7 +8,8 @@ CSFLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize+
+ ASSEMBLY_MDB = 
+ endif
+ 
+-pkglib_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
++programfilesdir = $(pkglibdir)
++programfiles_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
+ bin_SCRIPTS = mprof-heap-viewer
+ man_MANS=man/man1/mprof-heap-viewer.1
+ 
+diff --git a/Mono.Profiler/mprof-gui/Makefile.am b/Mono.Profiler/mprof-gui/Makefile.am
+index 5b00ea9..0369c2c 100644
+--- a/Mono.Profiler/mprof-gui/Makefile.am
++++ b/Mono.Profiler/mprof-gui/Makefile.am
+@@ -8,7 +8,8 @@ CSFLAGS =  -noconfig -codepage:utf8 -warn:4
+ ASSEMBLY_MDB = 
+ endif
+ 
+-pkglib_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
++programfilesdir = $(pkglibdir)
++programfiles_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
+ bin_SCRIPTS = emveepee
+ 
+ CLEANFILES = $(ASSEMBLY) $(ASSEMBLY_MDB)
+diff --git a/Mono.Profiler/profiler-decoder-library/Makefile.am b/Mono.Profiler/profiler-decoder-library/Makefile.am
+index 115f1a7..71d49ac 100644
+--- a/Mono.Profiler/profiler-decoder-library/Makefile.am
++++ b/Mono.Profiler/profiler-decoder-library/Makefile.am
+@@ -9,7 +9,8 @@ CSFLAGS =  -noconfig -codepage:utf8 -warn:4 -optimize+
+ ASSEMBLY_MDB = 
+ endif
+ 
+-pkglib_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
++programfilesdir = $(pkglibdir)
++programfiles_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
+ 
+ CLEANFILES = $(ASSEMBLY) $(ASSEMBLY_MDB)
+ 
+diff --git a/Mono.Profiler/profiler-file-decoder/Makefile.am b/Mono.Profiler/profiler-file-decoder/Makefile.am
+index 285267f..2365dc7 100644
+--- a/Mono.Profiler/profiler-file-decoder/Makefile.am
++++ b/Mono.Profiler/profiler-file-decoder/Makefile.am
+@@ -9,7 +9,8 @@ CSFLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+
+ ASSEMBLY_MDB = 
+ endif
+ 
+-pkglib_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
++programfilesdir = $(pkglibdir)
++programfiles_DATA = $(ASSEMBLY) $(ASSEMBLY_MDB)
+ bin_SCRIPTS = mprof-decoder
+ man_MANS = man/man1/mprof-decoder.1 
+ 
+diff --git a/README b/README
+index 3ad3752..a01a518 100644
+--- a/README
++++ b/README
+@@ -23,3 +23,12 @@ automatically executed):
+     make
+     make install
+ 
++Building on OSX with homebrew:
++------------------------------
++
++Have the following packages installed:
++autoconf pkg-config	readline automake gettext glib intltool libtool
++
++Run autogen like this:
++PKG_CONFIG_PATH=/Library/Frameworks/Mono.framework/Versions/Current/lib/pkgconfig/ ./autogen.sh 
++
+diff --git a/configure.in b/configure.in
+index 2a8870f..4771a2e 100644
+--- a/configure.in
++++ b/configure.in
+@@ -1,4 +1,4 @@
+-AC_INIT([mono-tools], [2.10])
++AC_INIT([mono-tools], [2.11])
+ AC_CONFIG_SRCDIR([README])
+ AC_CANONICAL_SYSTEM
+ AM_INIT_AUTOMAKE([tar-ustar -Wno-portability])
+@@ -272,6 +272,7 @@ gendarme/swf-wizard-runner/Makefile
+ gendarme/tools/Makefile
+ gendarme/tools/supported/Makefile
+ gendarme/tools/supported/gd2i/Makefile
++gendarme/tools/supported/templates/Makefile
+ gendarme/tools/unsupported/Makefile
+ gendarme/tools/unsupported/mapper/Makefile
+ gendarme/tools/unsupported/typeref/Makefile
+diff --git a/docbrowser/Makefile.am b/docbrowser/Makefile.am
+index a1a2626..065c430 100644
+--- a/docbrowser/Makefile.am
++++ b/docbrowser/Makefile.am
+@@ -40,6 +40,7 @@ browser_sources   = \
+ 	$(srcdir)/list.cs 		\
+ 	$(srcdir)/elabel.cs 		\
+ 	$(srcdir)/history.cs 		\
++	$(srcdir)/editing.cs            \
+ 	$(srcdir)/Contributions.cs	\
+ 	$(srcdir)/XmlNodeWriter.cs	\
+ 	$(srcdir)/IHtmlRender.cs	\
+@@ -67,7 +68,7 @@ admin_sources = \
+ 	$(srcdir)/admin.cs		\
+ 	$(srcdir)/Contributions.cs
+ 
+-browser_assemblies = $(GTK_SHARP_LIBS) $(MONODOC_LIBS) $(GNOME_SHARP_LIBS) -r:System.Web.Services
++browser_assemblies = $(GTK_SHARP_LIBS) $(MONODOC_LIBS) $(GNOME_SHARP_LIBS) -r:System.Web.Services -r:System.Web
+ # we insert gtkhtml libs if we have them for printing 
+ geckorender_assemblies = $(GTK_SHARP_LIBS) $(GTKHTML_SHARP_LIBS) $(GECKO_SHARP_LIBS) $(GNOME_SHARP_LIBS) $(MONODOC_LIBS) -r:browser.exe
+ gtkhtmlrender_assemblies = $(GTK_SHARP_LIBS) $(GTKHTML_SHARP_LIBS) $(GNOME_SHARP_LIBS) $(MONODOC_LIBS) -r:browser.exe
+diff --git a/docbrowser/browser.cs b/docbrowser/browser.cs
+index 5cc85e2..b9eb66f 100644
+--- a/docbrowser/browser.cs
++++ b/docbrowser/browser.cs
+@@ -60,7 +60,7 @@ class Driver {
+ 				v => sources.Add (v) },
+ 			{ "edit=",
+ 				"Edit mdoc(5) XML documentation found within {PATH}.",
+-				v => RootTree.UncompiledHelpSources.Add (v) },
++				v => RootTree.AddUncompiledSource (v) },
+ 			{ "engine=",
+ 				"Specify which HTML rendering {ENGINE} to use:\n" + 
+ 					"  " + string.Join ("\n  ", engines) + "\n" +
+@@ -119,6 +119,9 @@ class Driver {
+ 
+ 		List<string> topics = p.Parse (args);
+ 
++		if (basedir == null)
++			basedir = Directory.GetParent (System.Reflection.Assembly.GetExecutingAssembly ().Location).FullName;
++
+ 		if (show_version) {
+ 			Console.WriteLine ("Mono Documentation Browser");
+ 			Version ver = Assembly.GetExecutingAssembly ().GetName ().Version;
+@@ -132,7 +135,7 @@ class Driver {
+ 			return r;
+ 		}
+ 
+-		if (mergeConfigFile != null) {
++		/*if (mergeConfigFile != null) {
+ 			ArrayList targetDirs = new ArrayList ();
+ 			
+ 			for (int i = 0; i < topics.Count; i++)
+@@ -145,7 +148,7 @@ class Driver {
+ 
+ 			e.Merge ();
+ 			return 0;
+-		}
++		}*/
+ 		
+ 		if (r != 0 || !show_gui)
+ 			return r;
+@@ -257,6 +260,7 @@ public class Browser {
+ 	TreeView search_tree;
+ 	TreeStore search_store;
+ 	SearchableIndex search_index;
++	ArrayList searchResults = new ArrayList (20);
+ 	string highlight_text;
+ 	[Glade.Widget] VBox search_vbox;
+ 	ProgressPanel ppanel;
+@@ -578,6 +582,7 @@ public class Browser {
+ 		Result r = search_index.Search (term);
+ 		if (r == null)
+ 			return; //There was a problem with the index
++		searchResults.Add (r);
+ 		//insert the results in the tree
+ 		TreeIter iter;
+ 					
+@@ -622,7 +627,7 @@ public class Browser {
+ 			return;
+ 		int i_0 = p.Indices [0];
+ 		int i_1 = p.Indices [1];
+-		Result res = (Result) search_index.Results [i_0];
++		Result res = (Result) searchResults [i_0];
+ 		TreeIter parent;
+ 		model.IterParent (out parent, iter);
+ 		string term = (string) search_store.GetValue (parent, 0);
+@@ -648,21 +653,21 @@ public class Browser {
+ 	void TextLarger (object obj, EventArgs args)
+ 	{
+ 		SettingsHandler.Settings.preferred_font_size += 10;
+-		HelpSource.CssCode = null;
++		//HelpSource.CssCode = null;
+ 		Reload ();
+ 		SettingsHandler.Save ();
+ 	}
+ 	void TextSmaller (object obj, EventArgs args)
+ 	{
+ 		SettingsHandler.Settings.preferred_font_size -= 10;
+-		HelpSource.CssCode = null;
++		//HelpSource.CssCode = null;
+ 		Reload ();
+ 		SettingsHandler.Save ();
+ 	}
+ 	void TextNormal (object obj, EventArgs args)
+ 	{
+ 		SettingsHandler.Settings.preferred_font_size = 100;
+-		HelpSource.CssCode = null;
++		//HelpSource.CssCode = null;
+ 		Reload ();
+ 		SettingsHandler.Save ();
+ 	}
+@@ -733,6 +738,15 @@ public class Browser {
+ 		
+ 		Node node;
+ 		
++		/*
++		 * The webkit library converts the url titles (N:, T:, etc.) to lower case (n:, t:, etc.)
++		 * when clicking on a link. Therefore we need to convert them to upper case, since the
++		 * monodoc backend only understands upper case titles (except for root:, afaik).
++		 */
++		string[] urlParts = url.Split (':');
++		if (urlParts [0].Length == 1)
++			url = urlParts [0].ToUpper () + url.Substring (1);
++			
+ 		Console.Error.WriteLine ("Trying: {0}", url);
+ 		try {
+ 			string res = Browser.GetHtml (url, null, help_tree, out node);
+@@ -785,8 +799,8 @@ public class Browser {
+ 			//
+ 			string tabTitle;
+ 			tabTitle = matched_node.Caption; //Normal title
+-			string[] parts = matched_node.URL.Split('/', '#');
+-			if(matched_node.URL != null && matched_node.URL.StartsWith("ecma:")) {
++			string[] parts = matched_node.PublicUrl.Split('/', '#');
++			if(matched_node.PublicUrl != null && matched_node.PublicUrl.StartsWith("ecma:")) {
+ 				if(parts.Length == 3 && parts[2] != String.Empty) { //List of Members, properties, events, ...
+ 					tabTitle = parts[1] + ": " + matched_node.Caption;
+ 				} else if(parts.Length >= 4) { //Showing a concrete Member, property, ...					
+@@ -937,6 +951,7 @@ ExtLoop:
+ 	void delete_event_cb (object o, DeleteEventArgs args)
+ 	{
+ 		Application.Quit ();
++		args.RetVal = true;
+ 	}
+ 	void on_print_activate (object sender, EventArgs e) 
+ 	{
+@@ -1691,7 +1706,7 @@ ExtLoop:
+ 
+ 		void OnOkClicked (object sender, EventArgs a)
+ 		{
+-			CommentService service = new CommentService();
++			//CommentService service = new CommentService();
+ 			// todo
+ 			newcomment.Hide ();
+ 		}
+@@ -2010,7 +2025,7 @@ public class TreeBrowser {
+ 		if (tree_view.Selection.GetSelected (out model, out iter)){
+ 			Node n = (Node) iter_to_node [iter];
+ 			
+-			string url = n.URL;
++			string url = n.PublicUrl;
+ 			Node match;
+ 			string s;
+ 
+@@ -2038,7 +2053,7 @@ public class TreeBrowser {
+ 				return;
+ 			}
+ 
+-			((Browser)browser).Render ("<h1>Unhandled URL</h1>" + "<p>Functionality to view the resource <i>" + n.URL + "</i> is not available on your system or has not yet been implemented.</p>", null, url);
++			((Browser)browser).Render ("<h1>Unhandled URL</h1>" + "<p>Functionality to view the resource <i>" + n.PublicUrl + "</i> is not available on your system or has not yet been implemented.</p>", null, url);
+ 		}
+ 	}
+ }
+@@ -2702,7 +2717,7 @@ public class Tab : Notebook {
+ 		string [] uSplit = EditingUtils.ParseEditUrl (edit_url);
+ 		
+ 		if (uSplit[0].StartsWith ("monodoc:"))
+-			EditingUtils.SaveChange (edit_url, browser.help_tree, edit_node, EcmaHelpSource.GetNiceUrl (browser.CurrentTab.CurrentNode));
++			EditingUtils.SaveChange (edit_url, browser.help_tree, edit_node, GetNiceUrl (browser.CurrentTab.CurrentNode));
+ 		else if (uSplit[0].StartsWith ("file:"))
+ 			EditingUtils.SaveChange (edit_url, browser.help_tree, edit_node, String.Empty);
+ 		else
+@@ -2711,6 +2726,49 @@ public class Tab : Notebook {
+ 		history.ActivateCurrent ();
+ 	}
+ 
++	public static string GetNiceUrl (Node node) {
++		if (node.Element.StartsWith("N:"))
++			return node.Element;
++		string name, full;
++		int bk_pos = node.Caption.IndexOf (' ');
++		// node from an overview
++		if (bk_pos != -1) {
++			name = node.Caption.Substring (0, bk_pos);
++			full = node.Parent.Caption + "." + name.Replace ('.', '+');
++			return "T:" + full;
++		}
++		// node that lists constructors, methods, fields, ...
++		if ((node.Caption == "Constructors") || (node.Caption == "Fields") || (node.Caption == "Events") 
++			|| (node.Caption == "Members") || (node.Caption == "Properties") || (node.Caption == "Methods")
++			|| (node.Caption == "Operators")) {
++			bk_pos = node.Parent.Caption.IndexOf (' ');
++			name = node.Parent.Caption.Substring (0, bk_pos);
++			full = node.Parent.Parent.Caption + "." + name.Replace ('.', '+');
++			return "T:" + full + "/" + node.Element; 
++		}
++		int pr_pos = node.Caption.IndexOf ('(');
++		// node from a constructor
++		if (node.Parent.Element == "C") {
++			name = node.Parent.Parent.Parent.Caption;
++			int idx = node.PublicUrl.IndexOf ('/');
++			return node.PublicUrl[idx+1] + ":" + name + "." + node.Caption.Replace ('.', '+');
++		// node from a method with one signature, field, property, operator
++		} else if (pr_pos == -1) {
++			bk_pos = node.Parent.Parent.Caption.IndexOf (' ');
++			name = node.Parent.Parent.Caption.Substring (0, bk_pos);
++			full = node.Parent.Parent.Parent.Caption + "." + name.Replace ('.', '+');
++			int idx = node.PublicUrl.IndexOf ('/');
++			return node.PublicUrl[idx+1] + ":" + full + "." + node.Caption;
++		// node from a method with several signatures
++		} else {
++			bk_pos = node.Parent.Parent.Parent.Caption.IndexOf (' ');
++			name = node.Parent.Parent.Parent.Caption.Substring (0, bk_pos);
++			full = node.Parent.Parent.Parent.Parent.Caption + "." + name.Replace ('.', '+');
++			int idx = node.PublicUrl.IndexOf ('/');
++			return node.PublicUrl[idx+1] + ":" + full + "." + node.Caption;
++		}
++	}
++
+ 	void OnCancelEdits (object sender, EventArgs a)
+ 	{
+ 		SetMode (Mode.Viewer);
+@@ -2737,6 +2795,7 @@ public class Tab : Notebook {
+ 			
+ 			StringWriter sw = new StringWriter ();
+ 			XmlWriter w = new XmlTextWriter (sw);
++			var converter = new Monodoc.Generators.Html.Ecma2Html ();
+ 			
+ 			try {
+ 				edit_node.InnerXml = text_editor.Buffer.Text;
+@@ -2750,7 +2809,7 @@ public class Tab : Notebook {
+ 			}
+ 			browser.statusbar.Pop (browser.context_id);
+ 			browser.statusbar.Push (browser.context_id, "XML OK");
+-			string s = HelpSource.BuildHtml (EcmaHelpSource.css_ecma_code, sw.ToString ());
++			string s = converter.Export (sw.ToString (), new Dictionary<string, string> ());
+ 			html_preview.Render(s);
+ 
+ 			return false;
+diff --git a/docbrowser/editing.cs b/docbrowser/editing.cs
+new file mode 100644
+index 0000000..d7c1e32
+--- /dev/null
++++ b/docbrowser/editing.cs
+@@ -0,0 +1,519 @@
++//
++// editing.cs
++//
++// Author:
++//   Ben Maurer (bmaurer at users.sourceforge.net)
++//
++// (C) 2003 Ben Maurer
++//
++
++using System;
++using System.Collections;
++using System.Collections.Specialized;
++using System.IO;
++using System.Text;
++using System.Xml;
++using System.Xml.Serialization;
++using System.Xml.XPath;
++using System.Web;
++
++namespace Monodoc {
++	public class EditingUtils {
++		
++		public static string FormatEditUri (string document_identifier, string xpath)
++		{
++			return String.Format ("edit:{0}@{1}", HttpUtility.UrlEncode (document_identifier),
++				HttpUtility.UrlEncode (xpath));
++		}
++		
++		public static string GetXPath (XPathNavigator n)
++		{
++			switch (n.NodeType) {
++				case XPathNodeType.Root: return "/";
++				case XPathNodeType.Attribute: {
++					string ret = "@" + n.Name;
++					n.MoveToParent ();
++					string s = GetXPath (n);
++					return s + (s == "/" ? "" : "/") + ret;
++				}
++
++				case XPathNodeType.Element: {
++					string ret = n.Name;
++					int i = 1;
++					while (n.MoveToPrevious ()) {
++						if (n.NodeType == XPathNodeType.Element && n.Name == ret)
++							i++;
++					}
++					ret += "[" + i + "]";
++					if (n.MoveToParent ()) {
++						string s = GetXPath (n);
++						return s + (s == "/" ? "" : "/") + ret;
++					}
++				}
++				break;
++			}
++			throw new Exception ("node type not supported for editing");
++			
++		}
++		
++		public static XmlNode GetNodeFromUrl (string url, RootTree tree)
++		{
++			Console.WriteLine ("Url is: {0}", url);
++			string [] uSplit = ParseEditUrl (url);
++			Console.WriteLine ("Results are: {0}\n{1}\n{2}", uSplit [0], uSplit [1], uSplit [2]);
++			
++			string xp = uSplit [2];
++			string id =  uSplit [1];
++			
++			XmlDocument d;
++			
++			if (uSplit[0].StartsWith("monodoc:///")) {
++				int prov = int.Parse (uSplit [0].Substring("monodoc:///".Length));
++				d = tree.GetHelpSourceFromId (prov).GetHelpXmlWithChanges (id);
++			} else if (uSplit[0].StartsWith("file:")) {
++				d = new XmlDocument();
++				d.PreserveWhitespace = true;
++				d.Load(uSplit[0].Substring(5));
++			} else {
++				throw new NotImplementedException("Don't know how to load " + url); 
++			}			
++			
++			return d.SelectSingleNode (xp);
++				
++		}
++		
++		public static void SaveChange (string url, RootTree tree, XmlNode node, string node_url)
++		{
++			/*string [] uSplit = ParseEditUrl (url);
++		
++			string xp = uSplit [2];
++			string id =  uSplit [1];
++						
++			if (uSplit[0].StartsWith("monodoc:///")) {
++				int prov = int.Parse (uSplit [0].Substring("monodoc:///".Length));
++				HelpSource hs = tree.GetHelpSourceFromId (prov);
++				
++				changes.AddChange (hs.Name, hs.GetRealPath (id), xp, node, node_url);
++				changes.Save ();
++			} else if (uSplit[0].StartsWith("file:")) {
++				uSplit[0] = uSplit[0].Substring(5);
++				
++				XmlDocument d = new XmlDocument();
++				d.PreserveWhitespace = true;
++				d.Load(uSplit[0]);
++				
++				XmlNode original = d.SelectSingleNode(xp);
++				original.ParentNode.ReplaceChild(d.ImportNode(node, true), original);
++				
++				d.Save(uSplit[0]);
++			} else {				
++				throw new NotImplementedException("Don't know how to save to " + url); 
++			}*/
++		}
++
++		public static void RemoveChange (string url, RootTree tree)
++		{
++			/*string [] uSplit = ParseEditUrl (url);
++		
++			string xp = uSplit [2];
++			string id = uSplit [1];
++						
++			if (uSplit[0].StartsWith("monodoc:///")) {
++				int prov = int.Parse (uSplit [0].Substring("monodoc:///".Length));
++				HelpSource hs = tree.GetHelpSourceFromId (prov);
++				
++				changes.RemoveChange (hs.Name, hs.GetRealPath (id), xp);
++				changes.Save ();
++			} else if (uSplit[0].StartsWith("file:")) {
++				//TODO: Not implemented
++			}*/
++		}
++		
++		public static void RenderEditPreview (string url, RootTree tree, XmlNode new_node, XmlWriter w)
++		{
++			string [] uSplit = ParseEditUrl (url);
++		
++			if (uSplit[0].StartsWith("monodoc:///")) {
++				int prov = int.Parse (uSplit [0].Substring("monodoc:///".Length));
++				HelpSource hs = tree.GetHelpSourceFromId (prov);
++				hs.RenderPreviewDocs (new_node, w);
++			} else {
++				foreach (HelpSource hs in tree.HelpSources) {
++					if (hs is Monodoc.Providers.EcmaUncompiledHelpSource) {
++						// It doesn't matter which EcmaHelpSource is chosen.
++						hs.RenderPreviewDocs (new_node, w);
++						break;
++					}
++				}				
++			}
++		}
++		
++		public static string [] ParseEditUrl (string url)
++		{
++			if (!url.StartsWith ("edit:"))
++				throw new Exception ("wtf");
++			
++			string [] parts = url.Split ('@');
++			if (parts.Length != 2)
++				throw new Exception (String.Format ("invalid editing url {0}", parts.Length));
++			
++			string xp = HttpUtility.UrlDecode (parts [1]);
++			parts = HttpUtility.UrlDecode (parts [0]).Substring ("edit:".Length).Split ('@');
++			if (parts.Length == 1) {
++				string p = parts[0];
++				parts = new string[2];
++				parts[0] = p;
++				parts[1] = "";
++			}
++			
++			return new string [] {parts [0], parts [1], xp};
++		}
++		
++		public static void AccountForChanges (XmlDocument d, string doc_set, string real_file)
++		{
++			try {
++				FileChangeset fcs = changes.GetChangeset (doc_set, real_file);
++				if (fcs == null)
++					return;
++				
++				foreach (Change c in fcs.Changes) {
++					// Filter out old changes
++					if (c.FromVersion != RootTree.MonodocVersion)
++						continue;
++					
++					XmlNode old = d.SelectSingleNode (c.XPath);
++					if (old != null)
++						old.ParentNode.ReplaceChild (d.ImportNode (c.NewNode, true), old);
++				}
++			} catch {
++				return;
++			}
++		}
++	
++		public static GlobalChangeset changes = GlobalChangeset.Load ();
++
++		static public GlobalChangeset GetChangesFrom (int starting_serial_id)
++		{
++			return changes.GetFrom (starting_serial_id);
++		}
++	}
++
++#region Data Model
++	public class GlobalChangeset {
++
++		public static XmlSerializer serializer = new XmlSerializer (typeof (GlobalChangeset));
++		static string changeset_file = Path.Combine (SettingsHandler.Path, "changeset.xml");
++		static string changeset_backup_file = Path.Combine (SettingsHandler.Path, "changeset.xml~");
++	
++		public static GlobalChangeset Load ()
++		{
++			try {
++				if (File.Exists (changeset_file))
++					return LoadFromFile (changeset_file);
++			} catch {}
++			
++			return new GlobalChangeset ();
++		}
++		
++		public static GlobalChangeset LoadFromFile (string fileName)
++		{
++			using (Stream s = File.OpenRead (fileName)) {
++				return (GlobalChangeset) serializer.Deserialize (s);
++			}
++		}			
++		
++		public void Save ()
++		{
++			SettingsHandler.EnsureSettingsDirectory ();
++
++			try {    
++				if (File.Exists(changeset_file))  // create backup copy
++					File.Copy (changeset_file, changeset_backup_file, true);
++           
++				using (FileStream fs = File.Create (changeset_file)){
++					serializer.Serialize (fs, this);
++				}
++			} catch (Exception e) {
++				Console.WriteLine ("Error while saving changes. " + e);
++				if (File.Exists(changeset_backup_file))  // if saving fails then use backup if we have one				
++					File.Copy (changeset_backup_file, changeset_file, true);
++				else
++					File.Delete (changeset_file);   // if no backup, delete invalid changeset 
++			}
++		}
++		
++		static void VerifyDirectoryExists (DirectoryInfo d) {
++			if (d.Exists)
++				return;
++
++			VerifyDirectoryExists (d.Parent);
++			d.Create ();
++		}
++
++		[XmlElement ("DocSetChangeset", typeof (DocSetChangeset))]
++		public ArrayList DocSetChangesets = new ArrayList ();
++
++		public FileChangeset GetChangeset (string doc_set, string real_file)
++		{
++			foreach (DocSetChangeset dscs in DocSetChangesets) {
++				if (dscs.DocSet != doc_set) 
++					continue;
++			
++				foreach (FileChangeset fcs in dscs.FileChangesets) {
++					if (fcs.RealFile == real_file)
++						return fcs;
++				}
++			}
++			
++			return null;
++		}
++
++		public int Count {
++			get {
++				int count = 0;
++				
++				foreach (DocSetChangeset dscs in DocSetChangesets){
++					foreach (FileChangeset fcs in dscs.FileChangesets){
++						count += fcs.Changes.Count;
++					}
++				}
++
++				return count;
++			}
++		}
++
++		Change NewChange (string xpath, XmlNode new_node, string node_url)
++		{
++			Change new_change = new Change ();
++			new_change.XPath = xpath;
++			new_change.NewNode = new_node;
++			new_change.NodeUrl = node_url;
++
++			Console.WriteLine ("New serial:" + SettingsHandler.Settings.SerialNumber);
++			new_change.Serial = SettingsHandler.Settings.SerialNumber;
++
++			return new_change;
++		}
++		
++		public void AddChange (string doc_set, string real_file, string xpath, XmlNode new_node, string node_url)
++		{
++			FileChangeset new_file_change_set;
++			Change new_change = NewChange (xpath, new_node, node_url);
++			
++			if (real_file == null)
++				throw new Exception ("Could not find real_file. Please talk to Miguel or Ben about this");
++			
++			foreach (DocSetChangeset dscs in DocSetChangesets) {
++				if (dscs.DocSet != doc_set) 
++					continue;
++
++				foreach (FileChangeset fcs in dscs.FileChangesets) {
++					if (fcs.RealFile != real_file)
++						continue;
++					
++					foreach (Change c in fcs.Changes) {
++						if (c.XPath == xpath) {
++							c.NewNode = new_node;
++							c.Serial = SettingsHandler.Settings.SerialNumber;
++							return;
++						}
++					}
++
++					fcs.Changes.Add (new_change);
++					return;
++					
++				}
++				
++				new_file_change_set = new FileChangeset ();
++				new_file_change_set.RealFile = real_file;
++				new_file_change_set.Changes.Add (new_change);
++				dscs.FileChangesets.Add (new_file_change_set);
++				return;
++					
++			}
++			
++			DocSetChangeset new_dcs = new DocSetChangeset ();
++			new_dcs.DocSet = doc_set;
++			
++			new_file_change_set = new FileChangeset ();
++			new_file_change_set.RealFile = real_file;
++			
++			new_file_change_set.Changes.Add (new_change);
++			new_dcs.FileChangesets.Add (new_file_change_set);
++			DocSetChangesets.Add (new_dcs);
++		}
++
++		public void RemoveChange (string doc_set, string real_file, string xpath)
++		{
++			if (real_file == null)
++				throw new Exception ("Could not find real_file. Please talk to Miguel or Ben about this");
++			
++			for (int i = 0; i < DocSetChangesets.Count; i++) {
++				DocSetChangeset dscs = DocSetChangesets [i] as DocSetChangeset;
++				if (dscs.DocSet != doc_set) 
++					continue;
++
++				for (int j = 0; j < dscs.FileChangesets.Count; j++) {
++					FileChangeset fcs = dscs.FileChangesets [j] as FileChangeset;
++					if (fcs.RealFile != real_file)
++						continue;
++
++					for (int k = 0; k < fcs.Changes.Count; k++) {
++						Change c = fcs.Changes [k] as Change;
++						if (c.XPath == xpath) {
++							fcs.Changes.Remove (c);
++							break;
++						}
++					}
++					if (fcs.Changes.Count == 0)
++						dscs.FileChangesets.Remove (fcs);
++				}
++
++				if (dscs.FileChangesets.Count == 0)
++					DocSetChangesets.Remove (dscs);
++			}
++		}
++
++		public GlobalChangeset GetFrom (int starting_serial_id)
++		{
++			GlobalChangeset s = null;
++			
++			foreach (DocSetChangeset dscs in DocSetChangesets){
++				object o = dscs.GetFrom (starting_serial_id);
++				if (o == null)
++					continue;
++				if (s == null)
++					s = new GlobalChangeset ();
++				s.DocSetChangesets.Add (o);
++			}
++			return s;
++		}
++	}
++	
++	public class DocSetChangeset {
++		[XmlAttribute] public string DocSet;
++		
++		[XmlElement ("FileChangeset", typeof (FileChangeset))]
++		public ArrayList FileChangesets = new ArrayList ();
++
++		public DocSetChangeset GetFrom (int starting_serial_id)
++		{
++			DocSetChangeset dsc = null;
++			
++			foreach (FileChangeset fcs in FileChangesets){
++				object o = fcs.GetFrom (starting_serial_id);
++				if (o == null)
++					continue;
++				if (dsc == null){
++					dsc = new DocSetChangeset ();
++					dsc.DocSet = DocSet;
++				}
++				dsc.FileChangesets.Add (o);
++			}
++			return dsc;
++		}
++	}
++	
++	public class FileChangeset {
++		[XmlAttribute] public string RealFile;
++		
++		[XmlElement ("Change", typeof (Change))]
++		public ArrayList Changes = new ArrayList ();
++
++		public FileChangeset GetFrom (int starting_serial_id)
++		{
++			FileChangeset fcs = null;
++
++			foreach (Change c in Changes){
++				if (c.Serial < starting_serial_id)
++					continue;
++				if (fcs == null){
++					fcs = new FileChangeset ();
++					fcs.RealFile = RealFile;
++				}
++				fcs.Changes.Add (c);
++			}
++			return fcs;
++		}
++	}
++	
++	public class Change {
++		[XmlAttribute] public string XPath;
++		[XmlAttribute] public int FromVersion = RootTree.MonodocVersion;
++		[XmlAttribute] public string NodeUrl;
++		
++		public XmlNode NewNode;
++
++		public int Serial;
++
++		bool applied = false;
++		
++		//
++		// These are not a property, because we dont want them serialized;
++		// Only used by the Admin Client.
++		//
++		public bool Applied ()
++		{
++			return applied;
++		}
++
++		public void SetApplied (bool value)
++		{
++			applied = value;
++		}
++	}
++#endregion
++	
++	public class EditMerger {
++		GlobalChangeset changeset;
++		ArrayList targetDirs;
++		
++		public EditMerger (GlobalChangeset changeset, ArrayList targetDirs)
++		{
++			this.changeset = changeset;
++			this.targetDirs = targetDirs;
++		}
++		
++		public void Merge ()
++		{
++			foreach (DocSetChangeset dsc in changeset.DocSetChangesets) {
++				bool merged = false;
++				foreach (string path in targetDirs) {
++					if (File.Exists (Path.Combine (path, dsc.DocSet + ".source"))) {
++						Merge (dsc, path);
++						merged = true;
++						break;
++					}
++				}
++				if (!merged) Console.WriteLine ("Could not merge docset {0}", dsc.DocSet);
++			}
++		}
++		
++		void Merge (DocSetChangeset dsc, string path)
++		{
++			Console.WriteLine ("Merging changes in {0} ({1})", dsc.DocSet, path);
++			
++			foreach (FileChangeset fcs in dsc.FileChangesets) {
++				if (File.Exists (Path.Combine (path, fcs.RealFile)))
++					Merge (fcs, path);
++				else
++					Console.WriteLine ("\tCould not find file {0}", Path.Combine (path, fcs.RealFile));
++			}
++		}
++		
++		void Merge (FileChangeset fcs, string path)
++		{
++			XmlDocument d = new XmlDocument ();
++			d.Load (Path.Combine (path, fcs.RealFile));
++			
++			foreach (Change c in fcs.Changes) {
++				XmlNode old = d.SelectSingleNode (c.XPath);
++				if (old != null)
++					old.ParentNode.ReplaceChild (d.ImportNode (c.NewNode, true), old);
++			}
++			
++			d.Save (Path.Combine (path, fcs.RealFile));
++		}
++	}
++}
++
+diff --git a/docbrowser/monodoc.in b/docbrowser/monodoc.in
+index a532918..806b163 100644
+--- a/docbrowser/monodoc.in
++++ b/docbrowser/monodoc.in
+@@ -75,7 +75,7 @@ elif test x at MOZILLA_HOME@ != x; then
+     if [ -f @MOZILLA_HOME@/chrome/comm.jar ]; then
+         MOZILLA_HOME=@MOZILLA_HOME@
+     fi 
+-elif grep GRE_PATH /etc/gre.d/*.conf > /dev/null ; then
++elif grep -qs GRE_PATH /etc/gre.d/*.conf > /dev/null ; then
+ 	MOZILLA_HOME=$(grep -h GRE_PATH= /etc/gre.d/*.conf | cut -d '"' -f 2 -d = | head -n 1)
+ elif [ $(which xulrunner 2> /dev/null) ] > /dev/null ; then
+     MOZILLA_FIVE_HOME=`getdirectory xulrunner`
+diff --git a/gendarme/AssemblyStaticInfo.cs b/gendarme/AssemblyStaticInfo.cs
+index 2ca215e..130eb9d 100644
+--- a/gendarme/AssemblyStaticInfo.cs
++++ b/gendarme/AssemblyStaticInfo.cs
+@@ -18,10 +18,9 @@ using System.Security.Permissions;
+ [assembly: AssemblyCopyright ("Copyright (C) 2005-2011 Novell, Inc. and contributors")]
+ [assembly: AssemblyCompany ("Novell, Inc.")]
+ 
+-[assembly: PermissionSet (SecurityAction.RequestMinimum, Unrestricted = true)]
+ [assembly: CLSCompliant (false)]
+ [assembly: ComVisible (false)]
+ 
+ #if RELEASE
+-[assembly: AssemblyVersion ("2.10.0.0")]
++[assembly: AssemblyVersion ("2.11.0.0")]
+ #endif
+diff --git a/gendarme/MIT.X11 b/gendarme/MIT.X11
+index 8d90e9d..b3e59de 100644
+--- a/gendarme/MIT.X11
++++ b/gendarme/MIT.X11
+@@ -1,4 +1,4 @@
+-Copyright (c) 2005-2010 Novell, Inc and the individuals listed on the 
++Copyright (c) 2005-2011 Novell, Inc and the individuals listed on the 
+ ChangeLog entries.
+ 
+ Permission is hereby granted, free of charge, to any person obtaining
+diff --git a/gendarme/Makefile.am b/gendarme/Makefile.am
+index 890f0f2..2d96376 100644
+--- a/gendarme/Makefile.am
++++ b/gendarme/Makefile.am
+@@ -45,7 +45,8 @@ check-test: all bin/gendarme.exe.config test
+ 		--ignore=unit-test.ignore --severity=all --confidence=all @unit-test.list
+ 
+ test-regress: all
+-	mono --debug bin/gendarme.exe --config rules/rules.xml --set self-test --log regress.log testcases/*.dll testcases/*.exe
++	mono --debug bin/gendarme.exe --config rules/rules.xml --set self-test --log regress.log \
++		--severity=all --confidence=all testcases/*.dll testcases/*.exe
+ 	
+ TEST1 ?= AvoidVisibleConstantFieldTest
+ test1_file = $(shell find rules -name "\.svn" -prune -o  -name "*$(TEST1)*" -print)
+@@ -101,16 +102,3 @@ zip-bin: bin extra-bin
+ 	cd ..; \
+ 	rm -rf gendarme.$(GENDARME_VERSION);
+ 
+-instruct.xsd:
+-	wget http://www.ohloh.net/instruct.xsd
+-
+-push: instruct.xsd
+-	xmllint --schema instruct.xsd gendarme.xml
+-#	scp gendarme-2.8preview1-bin.zip $(USER)@upload.ohloh.net:gendarme/files; \
+-#	scp gendarme-2.8preview1-win32-setup.zip $(USER)@upload.ohloh.net:gendarme/files; \
+-#	scp gendarme.xml $(USER)@upload.ohloh.net:gendarme/instructs
+-
+-pull-log:
+-	scp $(USER)@upload.ohloh.net:gendarme/logs/upload.log .
+-	cat upload.log
+-
+diff --git a/gendarme/console/ConsoleRunner.cs b/gendarme/console/ConsoleRunner.cs
+index 97afccb..bf9814c 100644
+--- a/gendarme/console/ConsoleRunner.cs
++++ b/gendarme/console/ConsoleRunner.cs
+@@ -29,6 +29,7 @@
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
++using System.Globalization;
+ using System.IO;
+ using System.Linq;
+ using System.Reflection;
+@@ -53,21 +54,23 @@ namespace Gendarme {
+ 		private string log_file;
+ 		private string xml_file;
+ 		private string ignore_file;
+-		private string limit;
+-		private string severity_filter;
+-		private string confidence_filter;
+ 		private bool help;
+ 		private bool quiet;
+ 		private bool version;
++		private bool console;
+ 		private List<string> assembly_names;
+ 
++		static string [] SplitOptions (string value)
++		{
++			return value.ToUpperInvariant ().Split (new char [] { ',' }, StringSplitOptions.RemoveEmptyEntries);
++		}
++
+ 		// parse severity filter
+ 		// e.g. Audit,High+ == Audit, High and Critical
+-		void ParseSeverity ()
++		bool ParseSeverity (string filter)
+ 		{
+ 			SeverityBitmask.ClearAll ();
+-			string [] options = severity_filter.ToUpperInvariant ().Split (',');
+-			foreach (string option in options) {
++			foreach (string option in SplitOptions (filter)) {
+ 				Severity severity;
+ 
+ 				switch (option) {
+@@ -101,28 +104,26 @@ namespace Gendarme {
+ 					SeverityBitmask.SetAll ();
+ 					continue;
+ 				default:
+-					continue;
++					string msg = String.Format (CultureInfo.CurrentCulture, "Unknown severity level '{0}'", option);
++					throw new OptionException (msg, "severity");
+ 				}
+ 
+ 				char end = option [option.Length - 1];
+ 				if (end == '+') {
+ 					SeverityBitmask.SetDown (severity);
+-					Console.WriteLine ("SetDown {0} -> {1}", severity, SeverityBitmask);
+ 				} else if (end == '-') {
+ 					SeverityBitmask.SetUp (severity);
+-					Console.WriteLine ("SetUp {0} -> {1}", severity, SeverityBitmask);
+ 				} else {
+ 					SeverityBitmask.Set (severity);
+-					Console.WriteLine ("Set {0} -> {1}", severity, SeverityBitmask);
+ 				}
+ 			}
++			return true;
+ 		}
+ 
+-		void ParseConfidence ()
++		bool ParseConfidence (string filter)
+ 		{
+ 			ConfidenceBitmask.ClearAll ();
+-			string [] options = confidence_filter.ToUpperInvariant ().Split (',');
+-			foreach (string option in options) {
++			foreach (string option in SplitOptions (filter)) {
+ 				Confidence confidence;
+ 
+ 				switch (option) {
+@@ -151,7 +152,8 @@ namespace Gendarme {
+ 					ConfidenceBitmask.SetAll ();
+ 					continue;
+ 				default:
+-					continue;
++					string msg = String.Format (CultureInfo.CurrentCulture, "Unknown confidence level '{0}'", option);
++					throw new OptionException (msg, "confidence");
+ 				}
+ 
+ 				char end = option [option.Length - 1];
+@@ -163,48 +165,104 @@ namespace Gendarme {
+ 					ConfidenceBitmask.Set (confidence);
+ 				}
+ 			}
++			return true;
++		}
++
++		static string ValidateInputFile (string option, string file)
++		{
++			if (!File.Exists (file)) {
++				string msg = String.Format (CultureInfo.CurrentCulture, "File '{0}' could not be found", file);
++				throw new OptionException (msg, option);
++			}
++			return file;
++		}
++
++		static string ValidateOutputFile (string option, string file)
++		{
++			string msg = String.Empty;
++			if (file.Length > 0) {
++				string path = Path.GetDirectoryName (file);
++				if (path.Length > 0) {
++					if (path.IndexOfAny (Path.GetInvalidPathChars ()) != -1)
++						msg = String.Format (CultureInfo.CurrentCulture, "Invalid path '{0}'", file);
++					else if (!Directory.Exists (path))
++						msg = String.Format (CultureInfo.CurrentCulture, "Path '{0}' does not exists", file);
++				}
++			}
++
++			string fname = Path.GetFileName (file);
++			if ((fname.Length == 0) || (fname.IndexOfAny (Path.GetInvalidFileNameChars ()) != -1)) {
++				msg = String.Format (CultureInfo.CurrentCulture, "Filename '{0}' is not valid", fname);
++			}
++
++			if (msg.Length > 0)
++				throw new OptionException (msg, option);
++
++			return file;
++		}
++
++		static string ValidateRuleSet (string ruleSet)
++		{
++			if (String.IsNullOrEmpty (ruleSet)) {
++				throw new OptionException ("Missing rule set name", "set");
++			}
++			return ruleSet;
++		}
++
++		static int ValidateLimit (string limit)
++		{
++			int defects_limit;
++			if (String.IsNullOrEmpty (limit) || !Int32.TryParse (limit, out defects_limit)) {
++				string msg = String.Format (CultureInfo.CurrentCulture, "Invalid value '{0}' to limit defects", limit);
++				throw new OptionException (msg, "limit");
++			}
++			return defects_limit;
+ 		}
+ 
+ 		byte Parse (string [] args)
+ 		{
++			bool severity = false;
++			bool confidence = false;
++			// if supplied, use the user limit on defects (otherwise 2^31 is used)
++			DefectsLimit = Int32.MaxValue;
++
+ 			var p = new OptionSet () {
+-				{ "config=",	v => config_file = v },
+-				{ "set=",	v => rule_set = v },
+-				{ "log=",	v => log_file = v },
+-				{ "xml=",	v => xml_file = v },
+-				{ "html=",	v => html_file = v },
+-				{ "ignore=",	v => ignore_file = v },
+-				{ "limit=",	v => limit = v },
+-				{ "severity=",	v => severity_filter = v },
+-				{ "confidence=",v => confidence_filter = v },
++				{ "config=",	v => config_file = ValidateInputFile ("config", v) },
++				{ "set=",	v => rule_set = ValidateRuleSet (v) },
++				{ "log=",	v => log_file = ValidateOutputFile ("log", v) },
++				{ "xml=",	v => xml_file = ValidateOutputFile ("xml", v) },
++				{ "html=",	v => html_file = ValidateOutputFile ("html", v) },
++				{ "ignore=",	v => ignore_file = ValidateInputFile ("ignore", v) },
++				{ "limit=",	v => DefectsLimit = ValidateLimit (v) },
++				{ "severity=",	v => severity = ParseSeverity (v) },
++				{ "confidence=",v => confidence = ParseConfidence (v) },
+ 				{ "v|verbose",  v => ++VerbosityLevel },
++				{ "console",	v => console = v != null },
+ 				{ "quiet",	v => quiet = v != null },
+ 				{ "version",	v => version = v != null },
+ 				{ "h|?|help",	v => help = v != null },
+ 			};
+-			assembly_names = p.Parse (args);
+ 
+-			// if supplied, use the user limit on defects (otherwise 2^31 is used)
+-			int defects_limit;
+-			if (String.IsNullOrEmpty (limit) || !Int32.TryParse (limit, out defects_limit))
+-				defects_limit = Int32.MaxValue;
+-			DefectsLimit = defects_limit;
++			try {
++				assembly_names = p.Parse (args);
++			}
++			catch (OptionException e) {
++				Console.WriteLine ("Error parsing option '{0}' : {1}", e.OptionName, e.Message);
++				Console.WriteLine ();
++				return 1;
++			}
+ 
+ 			// by default the runner will ignore Audit and Low severity defects
+-			if (String.IsNullOrEmpty (severity_filter)) {
++			if (!severity) {
+ 				SeverityBitmask.SetAll ();
+ 				SeverityBitmask.Clear (Severity.Audit);
+ 				SeverityBitmask.Clear (Severity.Low);
+-			} else {
+-				ParseSeverity ();
+ 			}
+ 
+ 			// by default the runner will ignore Low confidence defects
+-			if (String.IsNullOrEmpty (confidence_filter)) {
++			if (!confidence) {
+ 				ConfidenceBitmask.SetAll ();
+ 				ConfidenceBitmask.Clear (Confidence.Low);
+-			} else {
+-				ParseConfidence ();
+ 			}
+ 
+ 			return (byte) ((assembly_names.Count > 0) ? 0 : 1);
+@@ -281,7 +339,7 @@ namespace Gendarme {
+ 			}
+ 
+ 			// generate text report (default, to console, if xml and html aren't specified)
+-			if ((log_file != null) || ((xml_file == null) && (html_file == null))) {
++			if (console || (log_file != null) || ((xml_file == null) && (html_file == null))) {
+ 				using (TextResultWriter writer = new TextResultWriter (this, log_file)) {
+ 					writer.Report ();
+ 				}
+@@ -380,7 +438,7 @@ namespace Gendarme {
+ 		private static string TimeToString (TimeSpan time)
+ 		{
+ 			if (time >= TimeSpan.FromMilliseconds (100))
+-				return string.Format ("{0:0.0} seconds", time.TotalSeconds);
++				return String.Format (CultureInfo.CurrentCulture, "{0:0.0} seconds", time.TotalSeconds);
+ 			else
+ 				return "<0.1 seconds";
+ 		}
+@@ -441,9 +499,10 @@ namespace Gendarme {
+ 				if (null != log_file || null != xml_file || null != html_file) {
+ 					List<string> files = new List<string> (new string [] { log_file, xml_file, html_file });
+ 					files.RemoveAll (string.IsNullOrEmpty);
+-					hint = string.Format ("Report{0} written to: {1}.",
++					hint = String.Format (CultureInfo.CurrentCulture, "Report{0} written to: {1}.",
+ 						(files.Count > 1) ? "s" : string.Empty,
+-						string.Join (",", files.Select (file => string.Format ("`{0}'", file)).ToArray ()));
++						string.Join (",", files.Select (file => 
++							String.Format (CultureInfo.CurrentCulture, "`{0}'", file)).ToArray ()));
+ 				}
+ 
+ 				if (Defects.Count == 0)
+@@ -519,6 +578,7 @@ namespace Gendarme {
+ 			Console.WriteLine ("  --confidence [all | [[low | normal | high | total][+|-]],...");
+ 			Console.WriteLine ("\t\t\tFilter defects for the specified confidence levels.");
+ 			Console.WriteLine ("\t\t\tDefault is 'normal+'");
++			Console.WriteLine ("  --console\t\tShow defects on the console even if --log, --xml or --html are specified.");
+ 			Console.WriteLine ("  --quiet\t\tUsed to disable progress and other information which is normally written to stdout.");
+ 			Console.WriteLine ("  --v\t\t\tWhen present additional progress information is written to stdout (can be used multiple times).");
+ 			Console.WriteLine ("  assemblies\t\tSpecify the assemblies to verify.");
+diff --git a/gendarme/console/Helpers.cs b/gendarme/console/Helpers.cs
+index c399452..3ef8361 100644
+--- a/gendarme/console/Helpers.cs
++++ b/gendarme/console/Helpers.cs
+@@ -38,7 +38,7 @@ namespace Gendarme {
+ 		{
+ 			Assembly executing = Assembly.GetExecutingAssembly ();
+ 			foreach (string resource in executing.GetManifestResourceNames ()) {
+-				if (resource.EndsWith (resourceName))
++				if (resource.EndsWith (resourceName, StringComparison.Ordinal))
+ 					return executing.GetManifestResourceStream (resource);
+ 			}
+ 			return null;
+diff --git a/gendarme/console/IgnoreFileList.cs b/gendarme/console/IgnoreFileList.cs
+index acf0d1d..b714ded 100644
+--- a/gendarme/console/IgnoreFileList.cs
++++ b/gendarme/console/IgnoreFileList.cs
+@@ -61,13 +61,13 @@ namespace Gendarme {
+ 
+ 		private void Parse ()
+ 		{
++			char [] buffer = new char [4096];
+ 			while (files.Count > 0) {
+ 				string fileName = files.Pop ();
+-				using (StreamReader sr = new StreamReader (fileName)) {
+-					string s = sr.ReadLine ();
+-					while (s != null) {
+-						ProcessLine (s);
+-						s = sr.ReadLine ();
++				using (StreamLineReader sr = new StreamLineReader (fileName)) {
++					while (!sr.EndOfStream) {
++						int length = sr.ReadLine (buffer, 0, buffer.Length);
++						ProcessLine (buffer, length);
+ 					}
+ 				}
+ 			}
+@@ -87,19 +87,33 @@ namespace Gendarme {
+ 			rules.Add (rule);
+ 		}
+ 
+-		private void ProcessLine (string line)
++		static string GetString (char [] buffer, int length)
+ 		{
+-			if (line.Length < 1)
++			// skip the 'type' + ':' characters when looking for whitespace separator(s)
++			int start = 2;
++			while (Char.IsWhiteSpace (buffer [start]) && (start < buffer.Length))
++				start++;
++
++			int end = length;
++			while (Char.IsWhiteSpace (buffer [end]) && (end >= start))
++				end--;
++
++			return new string (buffer, start, end - start);
++		}
++
++		private void ProcessLine (char [] buffer, int length)
++		{
++			if (length < 1)
+ 				return;
+ 
+-			switch (line [0]) {
++			switch (buffer [0]) {
+ 			case '#': // comment
+ 				break;
+ 			case 'R': // rule
+-				current_rule = line.Substring (line.LastIndexOf (' ') + 1);
++				current_rule = GetString (buffer, length);
+ 				break;
+ 			case 'A': // assembly - we support Name, FullName and *
+-				string target = line.Substring (2).Trim ();
++				string target = GetString (buffer, length);
+ 				if (target == "*") {
+ 					foreach (AssemblyDefinition assembly in Runner.Assemblies) {
+ 						Add (assemblies, current_rule, assembly.Name.FullName);
+@@ -109,19 +123,19 @@ namespace Gendarme {
+ 				}
+ 				break;
+ 			case 'T': // type (no space allowed)
+-				Add (types, current_rule, line.Substring (line.LastIndexOf (' ') + 1));
++				Add (types, current_rule, GetString (buffer, length));
+ 				break;
+ 			case 'M': // method
+-				Add (methods, current_rule, line.Substring (2).Trim ());
++				Add (methods, current_rule, GetString (buffer, length));
+ 				break;
+ 			case 'N': // namespace - special case (no need to resolve)
+-				base.Add (current_rule, NamespaceDefinition.GetDefinition (line.Substring (2).Trim ()));
++				base.Add (current_rule, NamespaceDefinition.GetDefinition (GetString (buffer, length)));
+ 				break;
+ 			case '@': // include file
+-				files.Push (line.Substring (2).Trim ());
++				files.Push (GetString (buffer, length));
+ 				break;
+ 			default:
+-				Console.Error.WriteLine ("Bad ignore entry : '{0}'", line);
++				Console.Error.WriteLine ("Bad ignore entry : '{0}'", new string (buffer));
+ 				break;
+ 			}
+ 		}
+@@ -148,14 +162,13 @@ namespace Gendarme {
+ 
+ 				foreach (ModuleDefinition module in assembly.Modules) {
+ 					foreach (TypeDefinition type in module.GetAllTypes ()) {
+-						if (types.TryGetValue (type.FullName, out rules)) {
++						if (types.TryGetValue (type.GetFullName (), out rules)) {
+ 							AddList (type, rules);
+ 						}
+ 
+ 						if (type.HasMethods) {
+ 							foreach (MethodDefinition method in type.Methods) {
+-								// FIXME avoid (allocations in) ToString call
+-								if (methods.TryGetValue (method.ToString (), out rules)) {
++								if (methods.TryGetValue (method.GetFullName (), out rules)) {
+ 									AddList (method, rules);
+ 								}
+ 							}
+diff --git a/gendarme/console/Makefile.am b/gendarme/console/Makefile.am
+index f74ab23..43c0a4a 100644
+--- a/gendarme/console/Makefile.am
++++ b/gendarme/console/Makefile.am
+@@ -30,7 +30,7 @@ gendarme_prefix_resources = $(addprefix $(srcdir)/, $(gendarme_resources))
+ gendarme_build_resources = $(foreach res,$(gendarme_prefix_resources), $(addprefix -resource:,$(res)),$(notdir $(res)))
+ 
+ ../bin/gendarme.exe: $(gendarme_build_sources) $(gendarme_prefix_resources)
+-	$(GMCS) $(GENDARME_OPTIONS) -r:$(CECIL_ASM) -r:System.Xml.Linq -r:../bin/Gendarme.Framework.dll \
++	$(MCS) $(GENDARME_OPTIONS) -r:$(CECIL_ASM) -r:System.Xml.Linq -r:../bin/Gendarme.Framework.dll \
+ 		-out:$@ $(gendarme_build_sources) $(gendarme_build_resources)
+ 
+ self-test: ../bin/gendarme.exe
+diff --git a/gendarme/console/Settings.cs b/gendarme/console/Settings.cs
+index 3ecafec..23b5429 100644
+--- a/gendarme/console/Settings.cs
++++ b/gendarme/console/Settings.cs
+@@ -4,7 +4,7 @@
+ // Authors:
+ //	Sebastien Pouliot <sebastien at ximian.com>
+ //
+-// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
++// Copyright (C) 2008, 2011 Novell, Inc (http://www.novell.com)
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining
+ // a copy of this software and associated documentation files (the
+@@ -27,6 +27,7 @@
+ //
+ 
+ using System;
++using System.Globalization;
+ using System.IO;
+ using System.Reflection;
+ using System.Collections.Generic;
+@@ -150,7 +151,8 @@ namespace Gendarme {
+ 
+ 		private void OnValidationErrors (object sender, ValidationEventArgs args)
+ 		{
+-			validation_errors.Add (args.Exception.Message.Replace ("XmlSchema error", String.Format ("Error in the configuration file {0}", config_file)));
++			validation_errors.Add (args.Exception.Message.Replace ("XmlSchema error", 
++				String.Format (CultureInfo.CurrentCulture, "Error in the configuration file {0}", config_file)));
+ 		}
+ 
+ 		private void ValidateXmlDocument ()
+@@ -228,7 +230,8 @@ namespace Gendarme {
+ 
+ 		static Exception GetException (string message, string ruleName, string propertyName, string value)
+ 		{
+-			return new XmlException (String.Format (message + ".  Review your configuration file.", ruleName, propertyName, value));
++			return new XmlException (String.Format (CultureInfo.CurrentCulture, 
++				message + ".  Review your configuration file.", ruleName, propertyName, value));
+ 		}
+ 
+ 		public bool Load ()
+diff --git a/gendarme/console/XmlResultWriter.cs b/gendarme/console/XmlResultWriter.cs
+index 3a5e0f4..3dcdff1 100644
+--- a/gendarme/console/XmlResultWriter.cs
++++ b/gendarme/console/XmlResultWriter.cs
+@@ -31,6 +31,7 @@
+ //
+ 
+ using System;
++using System.Globalization;
+ using System.IO;
+ using System.Linq;
+ using System.Text;
+@@ -70,7 +71,7 @@ namespace Gendarme {
+ 		{
+ 			writer.WriteStartDocument ();
+ 			writer.WriteStartElement ("gendarme-output");
+-			writer.WriteAttributeString ("date", DateTime.UtcNow.ToString ());
++			writer.WriteAttributeString ("date", DateTime.UtcNow.ToString (CultureInfo.InvariantCulture));
+ 		}
+ 
+ 		protected override void Write ()
+diff --git a/gendarme/console/gendarme.csproj b/gendarme/console/gendarme.csproj
+index 4f70bf5..eefae5e 100755
+--- a/gendarme/console/gendarme.csproj
++++ b/gendarme/console/gendarme.csproj
+@@ -1,5 +1,5 @@
+ <?xml version="1.0" encoding="utf-8"?>
+-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
++<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+   <PropertyGroup>
+     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+@@ -12,9 +12,13 @@
+     <AssemblyName>gendarme</AssemblyName>
+     <FileUpgradeFlags>
+     </FileUpgradeFlags>
+-    <OldToolsVersion>2.0</OldToolsVersion>
++    <OldToolsVersion>3.5</OldToolsVersion>
+     <UpgradeBackupLocation>
+     </UpgradeBackupLocation>
++    <IsWebBootstrapper>true</IsWebBootstrapper>
++    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
++    <SignAssembly>false</SignAssembly>
++    <AssemblyOriginatorKeyFile>gendarme.snk</AssemblyOriginatorKeyFile>
+     <PublishUrl>http://localhost/gendarme/</PublishUrl>
+     <Install>true</Install>
+     <InstallFrom>Web</InstallFrom>
+@@ -27,12 +31,9 @@
+     <MapFileExtensions>true</MapFileExtensions>
+     <ApplicationRevision>0</ApplicationRevision>
+     <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+-    <IsWebBootstrapper>true</IsWebBootstrapper>
+     <UseApplicationTrust>false</UseApplicationTrust>
+     <BootstrapperEnabled>true</BootstrapperEnabled>
+-    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+-    <SignAssembly>false</SignAssembly>
+-    <AssemblyOriginatorKeyFile>gendarme.snk</AssemblyOriginatorKeyFile>
++    <TargetFrameworkProfile />
+   </PropertyGroup>
+   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+     <DebugSymbols>true</DebugSymbols>
+@@ -42,6 +43,7 @@
+     <DefineConstants>TRACE;DEBUG</DefineConstants>
+     <ErrorReport>prompt</ErrorReport>
+     <WarningLevel>4</WarningLevel>
++    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+   </PropertyGroup>
+   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+     <DebugType>pdbonly</DebugType>
+@@ -50,6 +52,7 @@
+     <DefineConstants>TRACE;RELEASE</DefineConstants>
+     <ErrorReport>prompt</ErrorReport>
+     <WarningLevel>4</WarningLevel>
++    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+   </PropertyGroup>
+   <ItemGroup>
+     <Reference Include="System" />
+@@ -88,6 +91,10 @@
+       <Project>{CD6818D5-B398-486C-B180-92A07B143AFD}</Project>
+       <Name>Gendarme.Framework</Name>
+     </ProjectReference>
++    <ProjectReference Include="..\..\..\cecil\symbols\mdb\Mono.Cecil.Mdb.csproj">
++      <Project>{8559DD7F-A16F-46D0-A05A-9139FAEBA8FD}</Project>
++      <Name>Mono.Cecil.Mdb</Name>
++    </ProjectReference>
+   </ItemGroup>
+   <ItemGroup>
+     <None Include="ChangeLog" />
+@@ -95,30 +102,53 @@
+     <EmbeddedResource Include="gendarme.xsl" />
+   </ItemGroup>
+   <ItemGroup>
++    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
++      <Visible>False</Visible>
++      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
++      <Install>false</Install>
++    </BootstrapperPackage>
+     <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+       <Visible>False</Visible>
++      <ProductName>
++      </ProductName>
++      <Install>false</Install>
+     </BootstrapperPackage>
+     <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+       <Visible>False</Visible>
++      <ProductName>
++      </ProductName>
++      <Install>false</Install>
+     </BootstrapperPackage>
+     <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+       <Visible>False</Visible>
++      <ProductName>
++      </ProductName>
++      <Install>false</Install>
++    </BootstrapperPackage>
++    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
++      <Visible>False</Visible>
++      <ProductName>.NET Framework 3.5 SP1</ProductName>
++      <Install>false</Install>
+     </BootstrapperPackage>
+   </ItemGroup>
+   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+        Other similar extension points exist, see Microsoft.Common.targets.
+-  <Target Name="BeforeBuild">
+-  </Target>
+-  <Target Name="AfterBuild">
+-  </Target>
++  <Target Name="BeforeBuild">
++  </Target>
+   -->
++  <Target Name="AfterBuild">
++    <Copy
++      SourceFiles="$(TargetDir)..\..\..\rules\rules.xml"
++      DestinationFolder="$(TargetDir)"
++      SkipUnchangedFiles="True"
++    />
++  </Target>
+   <PropertyGroup>
+     <PreBuildEvent>
+     </PreBuildEvent>
+-    <PostBuildEvent>copy "$(TargetDir)..\..\..\rules\rules.xml" "$(TargetDir)"
+-copy "$(TargetDir)..\..\..\..\..\cecil\bin\net_3_5_Release\Mono.Cecil.Pdb.*" "$(TargetDir)"
+-copy "$(TargetDir)..\..\..\..\..\cecil\bin\net_3_5_Release\Mono.Cecil.Mdb.*" "$(TargetDir)"</PostBuildEvent>
++    <PostBuildEvent>
++    </PostBuildEvent>
+   </PropertyGroup>
+   <ProjectExtensions>
+     <MonoDevelop>
+diff --git a/gendarme/framework/Gendarme.Framework.Engines/SuppressMessageEngine.cs b/gendarme/framework/Gendarme.Framework.Engines/SuppressMessageEngine.cs
+index a98a6bc..70ef7ba 100644
+--- a/gendarme/framework/Gendarme.Framework.Engines/SuppressMessageEngine.cs
++++ b/gendarme/framework/Gendarme.Framework.Engines/SuppressMessageEngine.cs
+@@ -71,7 +71,7 @@ namespace Gendarme.Framework.Engines {
+ 		{
+ 			// we only need to check the custom attributes if [SuppressMessage] is referenced (note: won't work for mscorlib)
+ 			AssemblyDefinition assembly = (sender as AssemblyDefinition);
+-			if (assembly.MainModule.HasTypeReference (SuppressMessage)) {
++			if (assembly.MainModule.AnyTypeReference ((TypeReference tr) => { return tr.IsNamed ("System.Diagnostics.CodeAnalysis", "SuppressMessageAttribute"); })) {
+ 				Controller.BuildingCustomAttributes += new EventHandler<EngineEventArgs> (OnCustomAttributes);
+ 			} else {
+ 				Controller.BuildingCustomAttributes -= new EventHandler<EngineEventArgs> (OnCustomAttributes);
+@@ -103,7 +103,7 @@ namespace Gendarme.Framework.Engines {
+ 			foreach (CustomAttribute ca in cap.CustomAttributes) {
+ 				if (!ca.HasConstructorArguments)
+ 					continue;
+-				if (ca.AttributeType.FullName != SuppressMessage)
++				if (!ca.AttributeType.IsNamed ("System.Diagnostics.CodeAnalysis", "SuppressMessageAttribute"))
+ 					continue;
+ 
+ 				var arguments = ca.ConstructorArguments;
+@@ -200,7 +200,7 @@ namespace Gendarme.Framework.Engines {
+ 				foreach (ModuleDefinition module in assembly.Modules) {
+ 					// TODO ...
+ 					foreach (TypeDefinition type in module.GetAllTypes ()) {
+-						if (targets.TryGetValue (type.FullName, out rules))
++						if (targets.TryGetValue (type.GetFullName (), out rules))
+ 							Add (type, rules);
+ 
+ 						if (type.HasMethods) {
+@@ -213,11 +213,11 @@ namespace Gendarme.Framework.Engines {
+ 			targets.Clear ();
+ 		}
+ 
+-		private void ResolveMethod (IMetadataTokenProvider method)
++		private void ResolveMethod (MemberReference method)
+ 		{
+ 			HashSet<string> rules;
+ 
+-			string m = method.ToString ();
++			string m = method.GetFullName ();
+ 			m = m.Substring (m.IndexOf (' ') + 1);
+ 
+ 			if (targets.TryGetValue (m, out rules))
+diff --git a/gendarme/framework/Gendarme.Framework.Helpers/Log.cs b/gendarme/framework/Gendarme.Framework.Helpers/Log.cs
+index 262c7e9..759ba9f 100644
+--- a/gendarme/framework/Gendarme.Framework.Helpers/Log.cs
++++ b/gendarme/framework/Gendarme.Framework.Helpers/Log.cs
+@@ -30,6 +30,7 @@ using System.Diagnostics;
+ using System.Collections.Generic;
+ 
+ using Mono.Cecil;
++using Gendarme.Framework.Rocks;
+ 
+ namespace Gendarme.Framework.Helpers {
+ 
+@@ -83,9 +84,9 @@ namespace Gendarme.Framework.Helpers {
+ 		}
+ 		
+ 		[Conditional ("DEBUG")]
+-		public static void WriteLine<T> (T category, MethodDefinition method)
++		public static void WriteLine<T> (T category, MemberReference member)
+ 		{
+-			WriteLine (typeof (T).Name, method);
++			WriteLine (typeof (T).Name, member);
+ 		}
+ 		
+ 		// WriteLine (string)
+@@ -104,10 +105,15 @@ namespace Gendarme.Framework.Helpers {
+ 		}
+ 		
+ 		[Conditional ("DEBUG")]
+-		public static void WriteLine (string category, MethodDefinition method)
++		public static void WriteLine (string category, MemberReference member)
+ 		{
+-			if (IsEnabled (category))
+-				Debug.WriteLine (new MethodPrinter (method).ToString ());
++			if (IsEnabled (category)) {
++				MethodDefinition md = (member as MethodDefinition);
++				if (md != null)
++					Debug.WriteLine (new MethodPrinter (md).ToString ());
++				else
++					Debug.WriteLine (member.GetFullName ());
++			}
+ 		}
+ 		
+ 		// Misc
+diff --git a/gendarme/framework/Gendarme.Framework.Helpers/MethodPrinter.cs b/gendarme/framework/Gendarme.Framework.Helpers/MethodPrinter.cs
+index af3638c..ef40dcc 100644
+--- a/gendarme/framework/Gendarme.Framework.Helpers/MethodPrinter.cs
++++ b/gendarme/framework/Gendarme.Framework.Helpers/MethodPrinter.cs
+@@ -15,6 +15,7 @@ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Diagnostics;
++using System.Globalization;
+ using System.Text;
+ using Mono.Cecil;
+ using Mono.Cecil.Cil;
+@@ -60,17 +61,28 @@ namespace Gendarme.Framework.Helpers {
+ 						buffer.Append ("* ");
+ 					else
+ 						buffer.Append ("  ");
+-					buffer.AppendFormat ("  {0}: {1}", instr.Offset.ToString ("X4"),
+-							instr.OpCode.Name);
++
++					buffer.Append ("  ");
++					buffer.Append (instr.Offset.ToString ("X4", CultureInfo.InvariantCulture));
++					buffer.Append (": ");
++					buffer.Append (instr.OpCode.Name);
++
+ 					int[] targets = BranchTargets (instr);
+-					if (targets != null)
+-						foreach (int target in targets)
+-							buffer.AppendFormat (" {0}", target.ToString ("X4"));
+-					else if (instr.Operand is string)
+-						buffer.AppendFormat (" \"{0}\"", instr.Operand.ToString ());
+-					else if (instr.Operand != null)
+-						buffer.AppendFormat (" {0}", instr.Operand.ToString ());
+-					buffer.AppendLine (string.Empty);
++					if (targets != null) {
++						foreach (int target in targets) {
++							buffer.Append (' ');
++							buffer.Append (target.ToString ("X4", CultureInfo.InvariantCulture));
++						}
++					} else if (instr.Operand is string) {
++						buffer.Append (" \"");
++						buffer.Append (instr.Operand);
++						buffer.Append ('"');
++					} else if (instr.Operand != null) {
++						buffer.Append (" ");
++						buffer.Append (instr.Operand);
++					}
++					buffer.AppendLine ();
++
+ 					prevInstr = instr;
+ 					if (EndsTryRegion (instr) != null)
+ 						buffer.AppendLine ("} (Try)");
+diff --git a/gendarme/framework/Gendarme.Framework.Helpers/MethodSignature.cs b/gendarme/framework/Gendarme.Framework.Helpers/MethodSignature.cs
+index e6fd265..a17ae07 100644
+--- a/gendarme/framework/Gendarme.Framework.Helpers/MethodSignature.cs
++++ b/gendarme/framework/Gendarme.Framework.Helpers/MethodSignature.cs
+@@ -34,6 +34,7 @@ using System.Collections.Generic;
+ using System.Text;
+ 
+ using Mono.Cecil;
++using Gendarme.Framework.Rocks;
+ 
+ namespace Gendarme.Framework.Helpers {
+ 
+@@ -49,7 +50,7 @@ namespace Gendarme.Framework.Helpers {
+ 	/// }
+ 	/// </code>
+ 	/// </example>
+-	// <seealso cref="Gendarme.Framework.Helpers.MethodSignatures"/>
++	/// <seealso cref="Gendarme.Framework.Helpers.MethodSignatures"/>
+ 	public class MethodSignature {
+ 
+ 		/// <summary>
+@@ -121,7 +122,7 @@ namespace Gendarme.Framework.Helpers {
+ 			if (Name != null && method.Name != Name)
+ 				return false;
+ 
+-			if (ReturnType != null && method.ReturnType.FullName != ReturnType)
++			if (ReturnType != null && !method.ReturnType.IsNamed (ReturnType))
+ 				return false;
+ 
+ 			if (Parameters != null) {
+@@ -132,7 +133,7 @@ namespace Gendarme.Framework.Helpers {
+ 					for (int i = 0; i < Parameters.Count; i++) {
+ 						if (Parameters [i] == null)
+ 							continue;//ignore parameter
+-						if (Parameters [i] != pdc [i].ParameterType.FullName) {
++						if (!pdc [i].ParameterType.IsNamed (Parameters [i])) {
+ 							return false;
+ 						}
+ 					}
+diff --git a/gendarme/framework/Gendarme.Framework.Helpers/MethodSignatures.cs b/gendarme/framework/Gendarme.Framework.Helpers/MethodSignatures.cs
+index 3b8b4ad..27116fa 100644
+--- a/gendarme/framework/Gendarme.Framework.Helpers/MethodSignatures.cs
++++ b/gendarme/framework/Gendarme.Framework.Helpers/MethodSignatures.cs
+@@ -32,6 +32,7 @@ using System;
+ using System.Collections.Generic;
+ 
+ using Mono.Cecil;
++using Gendarme.Framework.Rocks;
+ 
+ namespace Gendarme.Framework.Helpers {
+ 
+@@ -120,19 +121,23 @@ namespace Gendarme.Framework.Helpers {
+ 		// TryParse
+ 		public static readonly MethodSignature TryParse = new MethodSignature ("TryParse",
+ 			delegate (MethodReference method) {
+-				if (method.ReturnType.FullName != "System.Boolean")
++				if (!method.ReturnType.IsNamed ("System", "Boolean"))
+ 					return false;
+ 
+ 				IList<ParameterDefinition> pdc = method.Parameters;
+-				if (pdc [0].ParameterType.FullName != "System.String")
++				if (!pdc [0].ParameterType.IsNamed ("System", "String"))
+ 					return false;
+ 
+ 				TypeReference last = pdc [pdc.Count - 1].ParameterType;
+ 				if (!last.IsByReference)
+ 					return false;
+ 
+-				string pt_name = last.FullName;
+-				return (String.Compare (pt_name, 0, method.DeclaringType.FullName, 0, pt_name.Length - 1) == 0);
++				TypeReference mtype = method.DeclaringType;
++				if (last.Namespace != mtype.Namespace)
++					return false;
++
++				string pt_name = last.Name;
++				return (String.Compare (pt_name, 0, mtype.Name, 0, pt_name.Length - 1, StringComparison.Ordinal) == 0);
+ 			}
+ 		);
+ 
+@@ -141,9 +146,9 @@ namespace Gendarme.Framework.Helpers {
+ 			delegate (MethodReference method) {
+ 				if (!method.HasParameters)
+ 					return false;
+-				if (method.ReturnType.FullName != method.DeclaringType.FullName)
++				if (!method.ReturnType.IsNamed (method.DeclaringType.Namespace, method.DeclaringType.Name))
+ 					return false;
+-				return (method.Parameters [0].ParameterType.FullName == "System.String");
++				return method.Parameters [0].ParameterType.IsNamed ("System", "String");
+ 			}
+ 		);
+ 	}
+diff --git a/gendarme/framework/Gendarme.Framework.Helpers/OpCodeBitmask.cs b/gendarme/framework/Gendarme.Framework.Helpers/OpCodeBitmask.cs
+index f7ceeac..6058fbe 100644
+--- a/gendarme/framework/Gendarme.Framework.Helpers/OpCodeBitmask.cs
++++ b/gendarme/framework/Gendarme.Framework.Helpers/OpCodeBitmask.cs
+@@ -26,6 +26,7 @@
+ //
+ 
+ using System;
++using System.Globalization;
+ using System.Text;
+ 
+ using Mono.Cecil.Cil;
+@@ -144,12 +145,12 @@ namespace Gendarme.Framework.Helpers {
+ 			return Equals (obj as OpCodeBitmask);
+ 		}
+ 
+-		public bool Equals (OpCodeBitmask set)
++		public bool Equals (OpCodeBitmask other)
+ 		{
+-			if (set == null)
++			if (other == null)
+ 				return false;
+-			return ((mask [0] == set.mask [0]) || (mask [1] == set.mask [1]) ||
+-				(mask [2] == set.mask [2]) || (mask [3] == set.mask [3]));
++			return ((mask [0] == other.mask [0]) || (mask [1] == other.mask [1]) ||
++				(mask [2] == other.mask [2]) || (mask [3] == other.mask [3]));
+ 		}
+ 
+ 		public override int GetHashCode ()
+@@ -159,7 +160,8 @@ namespace Gendarme.Framework.Helpers {
+ 
+ 		public override string ToString ()
+ 		{
+-			return String.Format ("0x{0:X}:0x{1:X}:0x{2:X}:0x{3:X}", mask [0], mask [1], mask [2], mask [3]);
++			return String.Format (CultureInfo.InvariantCulture, "0x{0:X}:0x{1:X}:0x{2:X}:0x{3:X}", 
++				mask [0], mask [1], mask [2], mask [3]);
+ 		}
+ 
+ 
+diff --git a/gendarme/framework/Gendarme.Framework.Helpers/StackEntryAnalysis.cs b/gendarme/framework/Gendarme.Framework.Helpers/StackEntryAnalysis.cs
+index 61d5f9b..156aef1 100644
+--- a/gendarme/framework/Gendarme.Framework.Helpers/StackEntryAnalysis.cs
++++ b/gendarme/framework/Gendarme.Framework.Helpers/StackEntryAnalysis.cs
+@@ -97,9 +97,9 @@ namespace Gendarme.Framework.Helpers {
+ 				return this == other;
+ 			}
+ 
+-			public bool Equals (StoreSlot storeSlot)
++			public bool Equals (StoreSlot other)
+ 			{
+-				return this == storeSlot;
++				return this == other;
+ 			}
+ 
+ 			public override int GetHashCode ()
+@@ -182,40 +182,14 @@ namespace Gendarme.Framework.Helpers {
+ 				return false;
+ 			}
+ 
+-			public bool Equals (InstructionWithLeave iwl)
++			public bool Equals (InstructionWithLeave other)
+ 			{
+-				if (Instruction != iwl.Instruction)
+-					return false;
+-
+-				if (LeaveStack == null)
+-					return (iwl.LeaveStack == null);
+-
+-				if (iwl.LeaveStack == null)
+-					return false;
+-
+-				if (LeaveStack.Length != iwl.LeaveStack.Length)
+-					return false;
+-
+-				for (int i = 0; i < LeaveStack.Length; i++) {
+-					if (LeaveStack [i] != iwl.LeaveStack [i])
+-						return false;
+-				}
+-				return true;
++				return (Instruction == other.Instruction);
+ 			}
+ 
+ 			public override int GetHashCode ()
+ 			{
+-				int hc = 0;
+-				
+-				unchecked {
+-					hc ^= Instruction.GetHashCode ();
+-					if (LeaveStack != null) {
+-						foreach (Instruction ins in LeaveStack)
+-							hc ^= ins.GetHashCode ();
+-					}
+-				}
+-				
+-				return hc;
++				return Instruction.GetHashCode ();
+ 			}
+ 
+ 			public static bool operator == (InstructionWithLeave left, InstructionWithLeave right)
+@@ -527,7 +501,7 @@ namespace Gendarme.Framework.Helpers {
+ 				return new StoreSlot (StoreType.Argument, ins.OpCode.Code - Code.Ldarg_0);
+ 			case Code.Ldarg_S:
+ 			case Code.Ldarg: {
+-					int sequence = ((ParameterDefinition) ins.Operand).GetSequence ();
++					int sequence = ((ParameterDefinition) ins.Operand).Index + 1;
+ 					if (!this.Method.HasThis)
+ 						sequence--;
+ 					return new StoreSlot (StoreType.Argument, sequence);
+@@ -581,7 +555,7 @@ namespace Gendarme.Framework.Helpers {
+ 
+ 			case Code.Starg_S: //store arg (not ref / out etc)
+ 			case Code.Starg: {
+-					int sequence = ((ParameterDefinition) ins.Operand).GetSequence ();
++					int sequence = ((ParameterDefinition) ins.Operand).Index + 1;
+ 					if (!this.Method.HasThis)
+ 						sequence--;
+ 					return new StoreSlot (StoreType.Argument, sequence);
+diff --git a/gendarme/framework/Gendarme.Framework.Helpers/StackEntryUsageResult.cs b/gendarme/framework/Gendarme.Framework.Helpers/StackEntryUsageResult.cs
+index 1fa302f..9c69872 100644
+--- a/gendarme/framework/Gendarme.Framework.Helpers/StackEntryUsageResult.cs
++++ b/gendarme/framework/Gendarme.Framework.Helpers/StackEntryUsageResult.cs
+@@ -61,9 +61,9 @@ namespace Gendarme.Framework.Helpers {
+ 			return false;
+ 		}
+ 
+-		public bool Equals (StackEntryUsageResult usageResult)
++		public bool Equals (StackEntryUsageResult other)
+ 		{
+-			return (Instruction == usageResult.Instruction) && (StackOffset == usageResult.StackOffset);
++			return (Instruction == other.Instruction) && (StackOffset == other.StackOffset);
+ 		}
+ 
+ 		public override int GetHashCode ()
+diff --git a/gendarme/framework/Gendarme.Framework.Helpers/StreamLineReader.cs b/gendarme/framework/Gendarme.Framework.Helpers/StreamLineReader.cs
+new file mode 100644
+index 0000000..3242474
+--- /dev/null
++++ b/gendarme/framework/Gendarme.Framework.Helpers/StreamLineReader.cs
+@@ -0,0 +1,122 @@
++//
++// StreamLineReader - A StringReader-like class that avoid creating string
++//
++// Authors:
++//	Sebastien Pouliot <sebastien at ximian.com>
++//
++// Copyright (C) 2011 Novell, Inc (http://www.novell.com)
++//
++// Permission is hereby granted, free of charge, to any person obtaining
++// a copy of this software and associated documentation files (the
++// "Software"), to deal in the Software without restriction, including
++// without limitation the rights to use, copy, modify, merge, publish,
++// distribute, sublicense, and/or sell copies of the Software, and to
++// permit persons to whom the Software is furnished to do so, subject to
++// the following conditions:
++// 
++// The above copyright notice and this permission notice shall be
++// included in all copies or substantial portions of the Software.
++// 
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++//
++
++using System;
++using System.IO;
++
++namespace Gendarme.Framework.Helpers {
++
++	// note: inheriting from StreamReader was not possible since we cannot
++	// override EndOfStream and ensure integrity with other Read ops
++	public class StreamLineReader : IDisposable {
++
++		StreamReader sr;
++		char [] buff;
++		int n;
++		int max;
++
++		public StreamLineReader (string fileName)
++		{
++			sr = new StreamReader (fileName);
++			Initialize ();
++		}
++
++		public StreamLineReader (Stream stream)
++		{
++			sr = new StreamReader (stream);
++			Initialize ();
++		}
++
++		void Initialize ()
++		{
++			buff = new char [4096];
++			max = n = buff.Length;
++		}
++
++		public bool EndOfStream {
++			get { return (n == max || max == 0) && sr.EndOfStream; }
++		}
++
++		public int ReadLine (char [] buffer, int index, int count)
++		{
++			if (Disposed)
++				throw new ObjectDisposedException ("StreamLineReader");
++			if (buffer == null)
++				throw new ArgumentNullException ("buffer");
++			if (index < 0)
++				throw new ArgumentOutOfRangeException ("index", "< 0");
++			if (count < 0)
++				throw new ArgumentOutOfRangeException ("count", "< 0");
++			// ordered to avoid possible integer overflow
++			if (index > buffer.Length - count)
++				throw new ArgumentException ("index + count > buffer.Length");
++
++			int len = 0;
++			while (len < count) {
++				if (n == max) {
++					max = sr.ReadBlock (buff, 0, buff.Length);
++					if (max == 0) break;
++					n = 0;
++				}
++				char c = buff [n++];
++				switch (c) {
++				case '\r':
++					continue;
++				case '\n':
++					Array.Clear (buffer, len, buffer.Length - len);
++					return len;
++				default:
++					buffer [index++] = c;
++					len++;
++					break;
++				}
++			}
++			return len;
++		}
++
++		public void Dispose ()
++		{
++			Dispose (true);
++			GC.SuppressFinalize (this);
++		}
++
++		protected virtual void Dispose (bool disposing)
++		{
++			try {
++				if (!Disposed)
++					sr.Dispose ();
++			}
++			finally {
++				Disposed = true;
++			}
++		}
++
++		protected bool Disposed { get; private set; }
++	}
++}
++
+diff --git a/gendarme/framework/Gendarme.Framework.Rocks/CecilRocks.cs b/gendarme/framework/Gendarme.Framework.Rocks/CecilRocks.cs
+index a1b2cfc..12c6345 100644
+--- a/gendarme/framework/Gendarme.Framework.Rocks/CecilRocks.cs
++++ b/gendarme/framework/Gendarme.Framework.Rocks/CecilRocks.cs
+@@ -27,6 +27,7 @@
+ //
+ 
+ using System;
++using System.Collections.Generic;
+ 
+ using Mono.Cecil;
+ using Mono.Cecil.Metadata;
+@@ -157,5 +158,30 @@ namespace Gendarme.Framework.Rocks {
+ 			// compare assemblies tokens (but do not recurse)
+ 			return other == null ? false : self_assembly.MetadataToken.Equals (other_assembly.MetadataToken);
+ 		}
++
++		static Dictionary<MemberReference, string> full_name_cache = new Dictionary<MemberReference, string> ();
++
++		/// <summary>
++		/// Get the string value of the MemberReference FullName property without the cost 
++		/// of allocating a new string for each (or most) calls. 
++		/// </summary>
++		/// <param name="self">The MemberReference instance where the method is applied.</param>
++		/// <returns>The cached FullName property of the MemberReference</returns>
++		/// <remarks>Cecil needs to rebuild most of the FullName properties on each call in order to
++		/// be able to write assemblies. However this is a waste of memory when an application, like 
++		/// Gendarme, use it for read-only purposes.</remarks>
++		public static string GetFullName (this MemberReference self)
++		{
++			if (self == null)
++				return String.Empty;
++
++			string full_name;
++			if (!full_name_cache.TryGetValue (self, out full_name)) {
++				full_name = self.FullName;
++				full_name_cache.Add (self, full_name);
++			}
++
++			return full_name;
++		}
+ 	}
+ }
+diff --git a/gendarme/framework/Gendarme.Framework.Rocks/CustomAttributeRocks.cs b/gendarme/framework/Gendarme.Framework.Rocks/CustomAttributeRocks.cs
+index 26b6401..ebfb1ba 100644
+--- a/gendarme/framework/Gendarme.Framework.Rocks/CustomAttributeRocks.cs
++++ b/gendarme/framework/Gendarme.Framework.Rocks/CustomAttributeRocks.cs
+@@ -44,51 +44,16 @@ namespace Gendarme.Framework.Rocks {
+ 	/// </summary>
+ 	public static class CustomAttributeRocks {
+ 
+-		internal static string [] GeneratedCodeAttributes = {
+-			 "System.CodeDom.Compiler.GeneratedCodeAttribute",
+-			 "System.Runtime.CompilerServices.CompilerGeneratedAttribute"
+-		};
+-
+-		/// <summary>
+-		/// Check if the custom attribute collection contains an attribute of a specified type.
+-		/// </summary>
+-		/// <param name="self">The CustomAttribute enumerable on which the extension method can be called.</param>
+-		/// <param name="attributeTypeName">Full type name of the attribute class.</param>
+-		/// <returns>True if the collection contains an attribute of the same name,
+-		/// False otherwise.</returns>
+-		public static bool ContainsType (this IEnumerable<CustomAttribute> self, string attributeTypeName)
++		internal static bool HasAnyGeneratedCodeAttribute (this ICustomAttributeProvider self)
+ 		{
+-			if (attributeTypeName == null)
+-				throw new ArgumentNullException ("attributeTypeName");
+-			if (self == null)
++			if ((self == null) || !self.HasCustomAttributes)
+ 				return false;
+ 
+-			foreach (CustomAttribute ca in self) {
+-				if (ca.AttributeType.FullName == attributeTypeName)
++			foreach (CustomAttribute ca in self.CustomAttributes) {
++				TypeReference cat = ca.AttributeType;
++				if (cat.IsNamed ("System.CodeDom.Compiler", "GeneratedCodeAttribute") ||
++					cat.IsNamed ("System.Runtime.CompilerServices", "CompilerGeneratedAttribute")) {
+ 					return true;
+-			}
+-			return false;
+-		}
+-
+-		/// <summary>
+-		/// Check if the custom attribute collection contains any of the specified type.
+-		/// </summary>
+-		/// <param name="self">The CustomAttribute enumerable on which the extension method can be called.</param>
+-		/// <param name="attributeTypeNames">A strings array of full type names of the attributes.</param>
+-		/// <returns>True if the collection contains any attribute matching one specified,
+-		/// False otherwise.</returns>
+-		public static bool ContainsAnyType (this IEnumerable<CustomAttribute> self, string[] attributeTypeNames)
+-		{
+-			if (attributeTypeNames == null)
+-				throw new ArgumentNullException ("attributeTypeNames");
+-			if (self == null)
+-				return false;
+-
+-			foreach (CustomAttribute ca in self) {
+-				string fullname = ca.AttributeType.FullName;
+-				foreach (string attribute_full_name in attributeTypeNames) {
+-					if (fullname == attribute_full_name)
+-						return true;
+ 				}
+ 			}
+ 			return false;
+@@ -99,17 +64,25 @@ namespace Gendarme.Framework.Rocks {
+ 		/// </summary>
+ 		/// <param name="self">The ICustomAttributeProvider (e.g. AssemblyDefinition, TypeReference, MethodReference,
+ 		/// FieldReference...) on which the extension method can be called.</param>
+-		/// <param name="attributeName">Full name of the attribute class</param>
++		/// <param name="nameSpace">The namespace of the attribute to be matched</param>
++		/// <param name="name">The name of the attribute to be matched</param>
+ 		/// <returns>True if the provider contains an attribute of the same name,
+ 		/// False otherwise.</returns>
+-		public static bool HasAttribute (this ICustomAttributeProvider self, string attributeName)
++		public static bool HasAttribute (this ICustomAttributeProvider self, string nameSpace, string name)
+ 		{
+-			if (attributeName == null)
+-				throw new ArgumentNullException ("attributeName");
++			if (nameSpace == null)
++				throw new ArgumentNullException ("nameSpace");
++			if (name == null)
++				throw new ArgumentNullException ("name");
+ 
+ 			if ((self == null) || !self.HasCustomAttributes)
+ 				return false;
+-			return self.CustomAttributes.ContainsType (attributeName);
++
++			foreach (CustomAttribute ca in self.CustomAttributes) {
++				if (ca.AttributeType.IsNamed (nameSpace, name))
++					return true;
++			}
++			return false;
+ 		}
+ 	}
+ }
+diff --git a/gendarme/framework/Gendarme.Framework.Rocks/FieldRocks.cs b/gendarme/framework/Gendarme.Framework.Rocks/FieldRocks.cs
+index 39641f5..bf3b30b 100644
+--- a/gendarme/framework/Gendarme.Framework.Rocks/FieldRocks.cs
++++ b/gendarme/framework/Gendarme.Framework.Rocks/FieldRocks.cs
+@@ -49,10 +49,9 @@ namespace Gendarme.Framework.Rocks {
+ 			if (field == null)
+ 				return false;
+ 
+-			if (field.HasCustomAttributes) {
+-				if (field.CustomAttributes.ContainsAnyType (CustomAttributeRocks.GeneratedCodeAttributes))
+-					return true;
+-			}
++			if (field.HasAnyGeneratedCodeAttribute ())
++				return true;
++
+ 			return field.DeclaringType.IsGeneratedCode ();
+ 		}
+ 
+diff --git a/gendarme/framework/Gendarme.Framework.Rocks/InstructionRocks.cs b/gendarme/framework/Gendarme.Framework.Rocks/InstructionRocks.cs
+index 6c8aaf6..aef546a 100644
+--- a/gendarme/framework/Gendarme.Framework.Rocks/InstructionRocks.cs
++++ b/gendarme/framework/Gendarme.Framework.Rocks/InstructionRocks.cs
+@@ -27,6 +27,7 @@
+ // THE SOFTWARE.
+ 
+ using System;
++using System.Globalization;
+ 
+ using Mono.Cecil;
+ using Mono.Cecil.Cil;
+@@ -291,7 +292,7 @@ namespace Gendarme.Framework.Rocks {
+ 			case StackBehaviour.Varpop:
+ 				switch (self.OpCode.FlowControl) {
+ 				case FlowControl.Return:
+-					return method.ReturnType.FullName == "System.Void" ? 0 : 1;
++					return method.ReturnType.IsNamed ("System", "Void") ? 0 : 1;
+ 
+ 				case FlowControl.Call:
+ 					IMethodSignature calledMethod = (IMethodSignature) self.Operand;
+@@ -310,7 +311,8 @@ namespace Gendarme.Framework.Rocks {
+ 			case StackBehaviour.PopAll:
+ 				return -1;
+ 			default:
+-				string unknown = String.Format ("'{0}' is not a valid value for instruction '{1}'.",
++				string unknown = String.Format (CultureInfo.InvariantCulture,
++					"'{0}' is not a valid value for instruction '{1}'.",
+ 					self.OpCode.StackBehaviourPush, self.OpCode);
+ 				throw new InvalidOperationException (unknown);
+ 			}
+@@ -344,11 +346,12 @@ namespace Gendarme.Framework.Rocks {
+ 			case StackBehaviour.Varpush:
+ 				IMethodSignature calledMethod = (IMethodSignature) self.Operand;
+ 				if (calledMethod != null)
+-					return (calledMethod.ReturnType.FullName == "System.Void") ? 0 : 1;
++					return calledMethod.ReturnType.IsNamed ("System", "Void") ? 0 : 1;
+ 
+ 				throw new NotImplementedException ("Varpush not supported for this Instruction.");
+ 			default:
+-				string unknown = String.Format ("'{0}' is not a valid value for instruction '{1}'.",
++				string unknown = String.Format (CultureInfo.InvariantCulture,
++					"'{0}' is not a valid value for instruction '{1}'.",
+ 					self.OpCode.StackBehaviourPush, self.OpCode);
+ 				throw new InvalidOperationException (unknown);
+ 			}
+diff --git a/gendarme/framework/Gendarme.Framework.Rocks/MethodRocks.cs b/gendarme/framework/Gendarme.Framework.Rocks/MethodRocks.cs
+index f4a604c..eace40a 100644
+--- a/gendarme/framework/Gendarme.Framework.Rocks/MethodRocks.cs
++++ b/gendarme/framework/Gendarme.Framework.Rocks/MethodRocks.cs
+@@ -55,6 +55,15 @@ namespace Gendarme.Framework.Rocks {
+ 	/// </summary>
+ 	public static class MethodRocks {
+ 
++		public static bool IsNamed (this MemberReference self, string nameSpace, string typeName, string methodName)
++		{
++			if (methodName == null)
++				throw new ArgumentNullException ("methodName");
++			if (self == null)
++				return false;
++			return ((self.Name == methodName) && self.DeclaringType.IsNamed (nameSpace, typeName));
++		}
++
+ 		/// <summary>
+ 		/// Check if the MethodReference is defined as the entry point of it's assembly.
+ 		/// </summary>
+@@ -76,7 +85,7 @@ namespace Gendarme.Framework.Rocks {
+ 				return false;
+ 
+ 			return (self.HasThis && !self.HasParameters && (self.Name == "Finalize") &&
+-				(self.ReturnType.FullName == "System.Void"));
++				self.ReturnType.IsNamed ("System", "Void"));
+ 		}
+ 
+ 		/// <summary>
+@@ -91,10 +100,9 @@ namespace Gendarme.Framework.Rocks {
+ 				return false;
+ 
+ 			MethodDefinition method = self.Resolve ();
+-			if ((method != null) && method.HasCustomAttributes) {
+-				if (method.CustomAttributes.ContainsAnyType (CustomAttributeRocks.GeneratedCodeAttributes))
+-					return true;
+-			}
++			if (method.HasAnyGeneratedCodeAttribute ())
++				return true;
++
+ 			return self.DeclaringType.IsGeneratedCode ();
+ 		}
+ 
+@@ -161,27 +169,10 @@ namespace Gendarme.Framework.Rocks {
+ 			TypeDefinition parent = declaring.BaseType != null ? declaring.BaseType.Resolve () : null;
+ 			while (parent != null) {
+ 				string name = method.Name;
+-				string retval = method.ReturnType.FullName;
+-				int pcount = method.HasParameters ? method.Parameters.Count : 0;
+ 				foreach (MethodDefinition md in parent.Methods) {
+ 					if (name != md.Name)
+ 						continue;
+-					if (retval != md.ReturnType.FullName)
+-						continue;
+-					if (md.HasParameters && (pcount == 0))
+-						continue;
+-					IList<ParameterDefinition> ppdc = md.Parameters;
+-					if (pcount != ppdc.Count)
+-						continue;
+-
+-					bool ok = true;
+-					for (int i = 0; i < pcount; i++) {
+-						if (method.Parameters [i].ParameterType.FullName != ppdc [i].ParameterType.FullName) {
+-							ok = false;
+-							break;
+-						}
+-					}
+-					if (!ok)
++					if (!method.CompareSignature (md))
+ 						continue;
+ 
+ 					return md.IsVirtual;
+@@ -246,11 +237,11 @@ namespace Gendarme.Framework.Rocks {
+ 			TypeReference type = parameters [1].ParameterType;
+ 			GenericParameter gp = (type as GenericParameter);
+ 			if (gp == null)
+-				return type.Inherits ("System.EventArgs");
++				return type.Inherits ("System", "EventArgs");
+ 
+ 			if (gp.HasConstraints) {
+ 				IList<TypeReference> cc = gp.Constraints;
+-				return ((cc.Count == 1) && (cc [0].FullName == "System.EventArgs"));
++				return ((cc.Count == 1) && cc [0].IsNamed ("System", "EventArgs"));
+ 			}
+ 
+ 			return false;
+@@ -283,7 +274,7 @@ namespace Gendarme.Framework.Rocks {
+ 
+ 		private static bool AreSameElementTypes (TypeReference a, TypeReference b)
+ 		{
+-			return a.GetElementType ().FullName == b.GetElementType ().FullName;
++			return a.IsGenericParameter || b.IsGenericParameter || b.IsNamed (a.Namespace, a.Name);
+ 		}
+ 
+ 		/// <summary>
+diff --git a/gendarme/framework/Gendarme.Framework.Rocks/ModuleRocks.cs b/gendarme/framework/Gendarme.Framework.Rocks/ModuleRocks.cs
+index 06a946c..3aad117 100644
+--- a/gendarme/framework/Gendarme.Framework.Rocks/ModuleRocks.cs
++++ b/gendarme/framework/Gendarme.Framework.Rocks/ModuleRocks.cs
+@@ -4,7 +4,7 @@
+ // Authors:
+ //	Sebastien Pouliot  <sebastien at ximian.com>
+ //
+-// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
++// Copyright (C) 2008, 2011 Novell, Inc (http://www.novell.com)
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
+ // of this software and associated documentation files (the "Software"), to deal
+@@ -155,19 +155,58 @@ namespace Gendarme.Framework.Rocks {
+ 				yield return type;
+ 		}
+ 
+-		public static bool HasAnyTypeReference (this ModuleDefinition self, string [] typeNames)
++		static Dictionary<ModuleDefinition, IEnumerable<MemberReference>> member_ref_cache = new Dictionary<ModuleDefinition, IEnumerable<MemberReference>> ();
++
++		/// <summary>
++		/// Check if any MemberReference, referenced by the current ModuleDefinition, satisfies the
++		/// specified predicate.
++		/// </summary>
++		/// <param name="self">The ModuleDefinition on which the extension method can be called.</param>
++		/// <param name="predicate">The condition to execute on a provided MemberReference</param>
++		/// <returns>True if 'predicate' returns true for any MemberReference in the module's referenced types.</returns>
++		/// <remarks>Cecil's GetMemberReferences method will allocate a new array each time it is called.
++		/// This extension method will cache the IEnumerable, on the first use, to reduce memory consumption.</remarks>
++		public static bool AnyMemberReference (this ModuleDefinition self, Func<MemberReference, bool> predicate)
+ 		{
+ 			if (self == null)
+ 				return false;
+ 
+-			if (typeNames == null)
+-				throw new ArgumentNullException ("typeNames");
++			// since ModuleDefinition.GetMemberReferences allocates an array (always identical if the
++			// assembly is opened "read-only", like Gendarme does) we'll cache and retrieve the array
++			IEnumerable<MemberReference> refs;
++			if (!member_ref_cache.TryGetValue (self, out refs)) {
++				refs = self.GetMemberReferences ();
++				member_ref_cache.Add (self, refs);
++			}
++
++			return refs.Any (predicate);
++		}
++
++		static Dictionary<ModuleDefinition, IEnumerable<TypeReference>> type_ref_cache = new Dictionary<ModuleDefinition, IEnumerable<TypeReference>> ();
+ 
+-			foreach (var typeName in typeNames)
+-				if (self.HasTypeReference (typeName))
+-					return true;
++		/// <summary>
++		/// Check if any TypeReference, referenced by the current ModuleDefinition, satisfies the
++		/// specified predicate.
++		/// </summary>
++		/// <param name="self">The ModuleDefinition on which the extension method can be called.</param>
++		/// <param name="predicate">The condition to execute on a provided TypeReference</param>
++		/// <returns>True if 'predicate' returns true for any TypeReference in the module's referenced types.</returns>
++		/// <remarks>Cecil's GetTypeReferences method will allocate a new array each time it is called.
++		/// This extension method will cache the IEnumerable, on the first use, to reduce memory consumption.</remarks>
++		public static bool AnyTypeReference (this ModuleDefinition self, Func<TypeReference, bool> predicate)
++		{
++			if (self == null)
++				return false;
++
++			// since ModuleDefinition.GetTypeReferences allocates an array (always identical if the
++			// assembly is opened "read-only", like Gendarme does) we'll cache and retrieve the array
++			IEnumerable<TypeReference> refs;
++			if (!type_ref_cache.TryGetValue (self, out refs)) {
++				refs = self.GetTypeReferences ();
++				type_ref_cache.Add (self, refs);
++			}
+ 
+-			return false;
++			return refs.Any (predicate);
+ 		}
+ 	}
+ }
+diff --git a/gendarme/framework/Gendarme.Framework.Rocks/ParameterRocks.cs b/gendarme/framework/Gendarme.Framework.Rocks/ParameterRocks.cs
+index cfc87ca..7a41c01 100644
+--- a/gendarme/framework/Gendarme.Framework.Rocks/ParameterRocks.cs
++++ b/gendarme/framework/Gendarme.Framework.Rocks/ParameterRocks.cs
+@@ -39,22 +39,7 @@ namespace Gendarme.Framework.Rocks {
+ 		/// <returns>True if the parameter represents a list of parameters, false otherwise.</returns>
+ 		public static bool IsParams (this ParameterDefinition self)
+ 		{
+-			if (self == null || !self.HasCustomAttributes)
+-				return false;
+-			return self.CustomAttributes.ContainsType ("System.ParamArrayAttribute");
+-		}
+-
+-		/// <summary>
+-		/// Returns the sequence number as found in the metadata
+-		/// </summary>
+-		/// <param name="self">The ParameterDefinition on which the extension method can be called.</param>
+-		/// <returns>The integer value of the sequence number of the parameter.</returns>
+-		public static int GetSequence (this ParameterReference self)
+-		{
+-			if (self == null)
+-				return -1;
+-
+-			return self.Index + 1;
++			return self.HasAttribute ("System", "ParamArrayAttribute");
+ 		}
+ 	}
+ }
+diff --git a/gendarme/framework/Gendarme.Framework.Rocks/PropertyRocks.cs b/gendarme/framework/Gendarme.Framework.Rocks/PropertyRocks.cs
+index 293f9db..112d323 100644
+--- a/gendarme/framework/Gendarme.Framework.Rocks/PropertyRocks.cs
++++ b/gendarme/framework/Gendarme.Framework.Rocks/PropertyRocks.cs
+@@ -59,10 +59,9 @@ namespace Gendarme.Framework.Rocks {
+ 			if (self == null)
+ 				return false;
+ 
+-			if (self.HasCustomAttributes) {
+-				if (self.CustomAttributes.ContainsAnyType (CustomAttributeRocks.GeneratedCodeAttributes))
+-					return true;
+-			}
++			if (self.HasAnyGeneratedCodeAttribute ())
++				return true;
++
+ 			return self.DeclaringType.IsGeneratedCode ();
+ 		}
+ 	}
+diff --git a/gendarme/framework/Gendarme.Framework.Rocks/TypeRocks.cs b/gendarme/framework/Gendarme.Framework.Rocks/TypeRocks.cs
+index d549c63..efdcc0f 100644
+--- a/gendarme/framework/Gendarme.Framework.Rocks/TypeRocks.cs
++++ b/gendarme/framework/Gendarme.Framework.Rocks/TypeRocks.cs
+@@ -84,51 +84,6 @@ namespace Gendarme.Framework.Rocks {
+ 		}
+ 
+ 		/// <summary>
+-		/// Check if a type reference collection contains a type of a specific name.
+-		/// </summary>
+-		/// <param name="self">The TypeReferenceCollection on which the extension method can be called.</param>
+-		/// <param name="typeName">Full name of the type.</param>
+-		/// <returns>True if the collection contains an type of the same name,
+-		/// False otherwise.</returns>
+-		public static bool ContainsType (this IEnumerable<TypeReference> self, string typeName)
+-		{
+-			if (typeName == null)
+-				throw new ArgumentNullException ("typeName");
+-			if (self == null)
+-				return false;
+-
+-			foreach (TypeReference type in self) {
+-				if (type.FullName == typeName)
+-					return true;
+-			}
+-			return false;
+-		}
+-
+-		/// <summary>
+-		/// Check if a type reference collection contains any of the specified type names.
+-		/// </summary>
+-		/// <param name="self">The TypeReferenceCollection on which the extension method can be called.</param>
+-		/// <param name="typeNames">A string array of full type names.</param>
+-		/// <returns>True if the collection contains any types matching one specified,
+-		/// False otherwise.</returns>
+-		public static bool ContainsAnyType (this IEnumerable<TypeReference> self, string [] typeNames)
+-		{
+-			if (typeNames == null)
+-				throw new ArgumentNullException ("typeNames");
+-			if (self == null)
+-				return false;
+-
+-			foreach (TypeReference type in self) {
+-				string fullname = type.FullName;
+-				foreach (string type_full_name in typeNames) {
+-					if (fullname == type_full_name)
+-						return true;
+-				}
+-			}
+-			return false;
+-		}
+-
+-		/// <summary>
+ 		/// Returns the first MethodDefinition that satisfies a given MethodSignature.
+ 		/// </summary>
+ 		/// <param name="self">The TypeReference on which the extension method can be called.</param>
+@@ -177,7 +132,7 @@ namespace Gendarme.Framework.Rocks {
+ 					continue;
+ 				if ((method.Attributes & attributes) != attributes)
+ 					continue;
+-				if (returnType != null && method.ReturnType.FullName != returnType)
++				if (returnType != null && !method.ReturnType.IsNamed (returnType))
+ 					continue;
+ 				if (parameters != null) {
+ 					if (method.HasParameters) {
+@@ -188,7 +143,7 @@ namespace Gendarme.Framework.Rocks {
+ 						for (int i = 0; i < parameters.Length; i++) {
+ 							if (parameters [i] == null)
+ 								continue;//ignore parameter
+-							if (parameters [i] != pdc [i].ParameterType.GetElementType ().FullName) {
++							if (!pdc [i].ParameterType.GetElementType ().IsNamed (parameters [i])) {
+ 								parameterError = true;
+ 								break;
+ 							}
+@@ -284,13 +239,16 @@ namespace Gendarme.Framework.Rocks {
+ 		/// where the information resides could be unavailable. False is returned in this case.
+ 		/// </summary>
+ 		/// <param name="self">The TypeDefinition on which the extension method can be called.</param>
+-		/// <param name="interfaceName">Full name of the interface</param>
++		/// <param name="nameSpace">The namespace of the interface to be matched</param>
++		/// <param name="name">The name of the interface to be matched</param>
+ 		/// <returns>True if we found that the type implements the interface, False otherwise (either it
+ 		/// does not implement it, or we could not find where it does).</returns>
+-		public static bool Implements (this TypeReference self, string interfaceName)
++		public static bool Implements (this TypeReference self, string nameSpace, string name)
+ 		{
+-			if (interfaceName == null)
+-				throw new ArgumentNullException ("interfaceName");
++			if (nameSpace == null)
++				throw new ArgumentNullException ("nameSpace");
++			if (name == null)
++				throw new ArgumentNullException ("name");
+ 			if (self == null)
+ 				return false;
+ 
+@@ -299,23 +257,22 @@ namespace Gendarme.Framework.Rocks {
+ 				return false;	// not enough information available
+ 
+ 			// special case, check if we implement ourselves
+-			if (type.IsInterface && (type.FullName == interfaceName))
++			if (type.IsInterface && type.IsNamed (nameSpace, name))
+ 				return true;
+ 
+-			return Implements (type, interfaceName, (interfaceName.IndexOf ('`') >= 0));
++			return Implements (type, nameSpace, name);
+ 		}
+ 
+-		private static bool Implements (TypeDefinition type, string interfaceName, bool generic)
++		private static bool Implements (TypeDefinition type, string nameSpace, string iname)
+ 		{
+ 			while (type != null) {
+ 				// does the type implements it itself
+ 				if (type.HasInterfaces) {
+ 					foreach (TypeReference iface in type.Interfaces) {
+-						string fullname = (generic) ? iface.GetElementType ().FullName : iface.FullName;
+-						if (fullname == interfaceName)
++						if (iface.IsNamed (nameSpace, iname))
+ 							return true;
+ 						//if not, then maybe one of its parent interfaces does
+-						if (Implements (iface.Resolve (), interfaceName, generic))
++						if (Implements (iface.Resolve (), nameSpace, iname))
+ 							return true;
+ 					}
+ 				}
+@@ -331,21 +288,23 @@ namespace Gendarme.Framework.Rocks {
+ 		/// where the information resides could be unavailable.
+ 		/// </summary>
+ 		/// <param name="self">The TypeReference on which the extension method can be called.</param>
+-		/// <param name="className">Full name of the base class</param>
++		/// <param name="nameSpace">The namespace of the base class to be matched</param>
++		/// <param name="name">The name of the base class to be matched</param>
+ 		/// <returns>True if the type inherits from specified class, False otherwise</returns>
+-		public static bool Inherits (this TypeReference self, string className)
++		public static bool Inherits (this TypeReference self, string nameSpace, string name)
+ 		{
+-			if (className == null)
+-				throw new ArgumentNullException ("className");
++			if (nameSpace == null)
++				throw new ArgumentNullException ("nameSpace");
++			if (name == null)
++				throw new ArgumentNullException ("name");
+ 			if (self == null)
+ 				return false;
+ 
+ 			TypeReference current = self.Resolve ();
+ 			while (current != null) {
+-				string fullname = current.FullName;
+-				if (fullname == className)
++				if (current.IsNamed (nameSpace, name))
+ 					return true;
+-				if (fullname == "System.Object")
++				if (current.IsNamed ("System", "Object"))
+ 					return false;
+ 
+ 				TypeDefinition td = current.Resolve ();
+@@ -357,6 +316,70 @@ namespace Gendarme.Framework.Rocks {
+ 		}
+ 
+ 		/// <summary>
++		/// Check if the type and its namespace are named like the provided parameters.
++		/// This is preferred to checking the FullName property since the later can allocate (string) memory.
++		/// </summary>
++		/// <param name="self">The TypeReference on which the extension method can be called.</param>
++		/// <param name="nameSpace">The namespace to be matched</param>
++		/// <param name="name">The type name to be matched</param>
++		/// <returns>True if the type is namespace and name match the arguments, False otherwise</returns>
++		public static bool IsNamed (this TypeReference self, string nameSpace, string name)
++		{
++			if (nameSpace == null)
++				throw new ArgumentNullException ("nameSpace");
++			if (name == null)
++				throw new ArgumentNullException ("name");
++			if (self == null)
++				return false;
++
++			if (self.IsNested) {
++				int spos = name.LastIndexOf ('/');
++				if (spos == -1)
++					return false;
++				// GetFullName could be optimized away but it's a fairly uncommon case
++				return (nameSpace + "." + name == self.GetFullName ());
++			}
++
++			return ((self.Namespace == nameSpace) && (self.Name == name));
++		}
++
++		/// <summary>
++		/// Check if the type full name match the provided parameter.
++		/// Note: prefer the overload where the namespace and type name can be supplied individually
++		/// </summary>
++		/// <param name="self">The TypeReference on which the extension method can be called.</param>
++		/// <param name="fullName">The full name to be matched</param>
++		/// <returns>True if the type is namespace and name match the arguments, False otherwise</returns>
++		public static bool IsNamed (this TypeReference self, string fullName)
++		{
++			if (fullName == null)
++				throw new ArgumentNullException ("fullName");
++			if (self == null)
++				return false;
++
++			if (self.IsNested) {
++				int spos = fullName.LastIndexOf ('/');
++				if (spos == -1)
++					return false;
++				// FIXME: GetFullName could be optimized away but it's a fairly uncommon case
++				return (fullName == self.GetFullName ());
++			}
++
++			int dpos = fullName.LastIndexOf ('.');
++			string nspace = self.Namespace;
++			if (dpos != nspace.Length)
++				return false;
++
++			if (String.CompareOrdinal (nspace, 0, fullName, 0, dpos) != 0)
++				return false;
++
++			string name = self.Name;
++			if (fullName.Length - dpos - 1 != name.Length)
++				return false;
++			return (String.CompareOrdinal (name, 0, fullName, dpos + 1, fullName.Length - dpos - 1) == 0);
++		}
++
++		/// <summary>
+ 		/// Checks if type is attribute. Note that it is possible that
+ 		/// we might now be able to know all inheritance since the assembly where 
+ 		/// the information resides could be unavailable.
+@@ -369,7 +392,7 @@ namespace Gendarme.Framework.Rocks {
+ 			if (self == null)
+ 				return false;
+ 
+-			return self.Inherits ("System.Attribute");
++			return self.Inherits ("System", "Attribute");
+ 		}
+ 
+ 		/// <summary>
+@@ -387,13 +410,11 @@ namespace Gendarme.Framework.Rocks {
+ 			if (null == type || type.BaseType == null)
+ 				return false;
+ 
+-			switch (type.BaseType.FullName) {
+-			case "System.Delegate":
+-			case "System.MulticastDelegate":
+-				return true;
+-			default:
++			if (type.BaseType.Namespace != "System")
+ 				return false;
+-			}
++
++			string name = type.BaseType.Name;
++			return ((name == "Delegate") || (name == "MulticastDelegate"));
+ 		}
+ 
+ 		/// <summary>
+@@ -410,7 +431,7 @@ namespace Gendarme.Framework.Rocks {
+ 			if ((type == null) || !type.IsEnum || !type.HasCustomAttributes)
+ 				return false;
+ 
+-			return type.HasAttribute ("System.FlagsAttribute");
++			return type.HasAttribute ("System", "FlagsAttribute");
+ 		}
+ 
+ 		/// <summary>
+@@ -423,9 +444,11 @@ namespace Gendarme.Framework.Rocks {
+ 			if (self == null)
+ 				return false;
+ 
+-			string full_name = self.FullName;
+-			return ((full_name == "System.Single") ||
+-				(full_name == "System.Double"));
++			if (self.Namespace != "System")
++				return false;
++
++			string name = self.Name;
++			return ((name == "Single") || (name == "Double"));
+ 		}
+ 
+ 		/// <summary>
+@@ -443,7 +466,7 @@ namespace Gendarme.Framework.Rocks {
+ 				TypeDefinition type = self.Resolve ();
+ 				// both helpful attributes only exists in 2.0 and more recent frameworks
+ 				if (type.Module.Runtime >= TargetRuntime.Net_2_0) {
+-					if (type.CustomAttributes.ContainsAnyType (CustomAttributeRocks.GeneratedCodeAttributes))
++					if (type.HasAnyGeneratedCodeAttribute ())
+ 						return true;
+ 				}
+ 			}
+@@ -471,14 +494,11 @@ namespace Gendarme.Framework.Rocks {
+ 			if (self == null)
+ 				return false;
+ 
+-			switch (self.FullName) {
+-			case "System.IntPtr":
+-			case "System.UIntPtr":
+-			case "System.Runtime.InteropServices.HandleRef":
+-				return true;
+-			default:
+-				return false;
++			if (self.Namespace == "System") {
++				string name = self.Name;
++				return ((name == "IntPtr") || (name == "UIntPtr"));
+ 			}
++			return self.IsNamed ("System.Runtime.InteropServices", "HandleRef");
+ 		}
+ 
+ 		/// <summary>
+diff --git a/gendarme/framework/Gendarme.Framework.Rocks/VariableDefinitionRocks.cs b/gendarme/framework/Gendarme.Framework.Rocks/VariableDefinitionRocks.cs
+index 6749ebd..73e03e4 100644
+--- a/gendarme/framework/Gendarme.Framework.Rocks/VariableDefinitionRocks.cs
++++ b/gendarme/framework/Gendarme.Framework.Rocks/VariableDefinitionRocks.cs
+@@ -24,8 +24,9 @@
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ // THE SOFTWARE.
+ 
+-using Mono.Cecil.Cil;
+ using System;
++using System.Globalization;
++using Mono.Cecil.Cil;
+ 
+ namespace Gendarme.Framework.Rocks {
+ 	
+@@ -53,7 +54,7 @@ namespace Gendarme.Framework.Rocks {
+ 		{
+ 			if (self == null)
+ 				return String.Empty;
+-			return !string.IsNullOrEmpty (self.Name) ? self.Name : "V_" + self.Index.ToString ();
++			return !string.IsNullOrEmpty (self.Name) ? self.Name : "V_" + self.Index.ToString (CultureInfo.InvariantCulture);
+ 		}
+ 	}
+ }
+diff --git a/gendarme/framework/Gendarme.Framework.csproj b/gendarme/framework/Gendarme.Framework.csproj
+index f9976af..ff5851b 100755
+--- a/gendarme/framework/Gendarme.Framework.csproj
++++ b/gendarme/framework/Gendarme.Framework.csproj
+@@ -1,5 +1,5 @@
+ <?xml version="1.0" encoding="utf-8"?>
+-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
++<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+   <PropertyGroup>
+     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+@@ -12,9 +12,11 @@
+     <AssemblyName>Gendarme.Framework</AssemblyName>
+     <FileUpgradeFlags>
+     </FileUpgradeFlags>
+-    <OldToolsVersion>2.0</OldToolsVersion>
++    <OldToolsVersion>3.5</OldToolsVersion>
+     <UpgradeBackupLocation>
+     </UpgradeBackupLocation>
++    <IsWebBootstrapper>true</IsWebBootstrapper>
++    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+     <PublishUrl>http://localhost/Gendarme.Framework/</PublishUrl>
+     <Install>true</Install>
+     <InstallFrom>Web</InstallFrom>
+@@ -27,10 +29,9 @@
+     <MapFileExtensions>true</MapFileExtensions>
+     <ApplicationRevision>0</ApplicationRevision>
+     <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+-    <IsWebBootstrapper>true</IsWebBootstrapper>
+     <UseApplicationTrust>false</UseApplicationTrust>
+     <BootstrapperEnabled>true</BootstrapperEnabled>
+-    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
++    <TargetFrameworkProfile />
+   </PropertyGroup>
+   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+     <DebugSymbols>true</DebugSymbols>
+@@ -41,6 +42,7 @@
+     <ErrorReport>prompt</ErrorReport>
+     <WarningLevel>3</WarningLevel>
+     <StartupObject />
++    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+   </PropertyGroup>
+   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+     <DebugType>pdbonly</DebugType>
+@@ -50,6 +52,7 @@
+     <ErrorReport>prompt</ErrorReport>
+     <WarningLevel>4</WarningLevel>
+     <StartupObject />
++    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+   </PropertyGroup>
+   <ItemGroup>
+     <Reference Include="System" />
+@@ -58,12 +61,17 @@
+     </Reference>
+   </ItemGroup>
+   <ItemGroup>
++    <ProjectReference Include="..\..\..\cecil\Mono.Cecil.csproj">
++      <Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
++      <Name>Mono.Cecil</Name>
++    </ProjectReference>
+   </ItemGroup>
+   <ItemGroup>
+     <Compile Include="..\AssemblyStaticInfo.cs" />
+     <Compile Include="Gendarme.Framework.Engines\SuppressMessageEngine.cs" />
+     <Compile Include="Gendarme.Framework.Helpers\Log.cs" />
+     <Compile Include="Gendarme.Framework.Helpers\MethodPrinter.cs" />
++    <Compile Include="Gendarme.Framework.Helpers\StreamLineReader.cs" />
+     <Compile Include="Gendarme.Framework.Rocks\ParameterRocks.cs" />
+     <Compile Include="Gendarme.Framework.Rocks\PropertyRocks.cs" />
+     <Compile Include="Gendarme.Framework.Rocks\VariableDefinitionRocks.cs" />
+@@ -118,21 +126,34 @@
+     <None Include="ChangeLog" />
+   </ItemGroup>
+   <ItemGroup>
++    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
++      <Visible>False</Visible>
++      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
++      <Install>false</Install>
++    </BootstrapperPackage>
+     <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+       <Visible>False</Visible>
++      <ProductName>
++      </ProductName>
++      <Install>false</Install>
+     </BootstrapperPackage>
+     <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+       <Visible>False</Visible>
++      <ProductName>
++      </ProductName>
++      <Install>false</Install>
+     </BootstrapperPackage>
+     <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+       <Visible>False</Visible>
++      <ProductName>
++      </ProductName>
++      <Install>false</Install>
++    </BootstrapperPackage>
++    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
++      <Visible>False</Visible>
++      <ProductName>.NET Framework 3.5 SP1</ProductName>
++      <Install>false</Install>
+     </BootstrapperPackage>
+-  </ItemGroup>
+-  <ItemGroup>
+-    <ProjectReference Include="..\..\..\cecil\Mono.Cecil.csproj">
+-      <Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
+-      <Name>Mono.Cecil</Name>
+-    </ProjectReference>
+   </ItemGroup>
+   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+diff --git a/gendarme/framework/Gendarme.Framework/Symbols.cs b/gendarme/framework/Gendarme.Framework/Symbols.cs
+index 5e76c20..f572643 100644
+--- a/gendarme/framework/Gendarme.Framework/Symbols.cs
++++ b/gendarme/framework/Gendarme.Framework/Symbols.cs
+@@ -39,7 +39,7 @@ namespace Gendarme.Framework {
+ 		// http://blogs.msdn.com/jmstall/archive/2005/06/19/FeeFee_SequencePoints.aspx
+ 		private const int PdbHiddenLine = 0xFEEFEE;
+ 
+-		private static string AlmostEqualTo = new string (new char [] { '\u2248' });
++		private const string AlmostEqualTo = "\u2248";
+ 
+ 		private static Instruction ExtractFirst (TypeDefinition type)
+ 		{
+@@ -55,7 +55,7 @@ namespace Gendarme.Framework {
+ 
+ 		private static Instruction ExtractFirst (MethodDefinition method)
+ 		{
+-			if ((method == null) || !method.HasBody)
++			if ((method == null) || !method.HasBody || method.Body.Instructions.Count == 0)
+ 				return null;
+ 			Instruction ins = method.Body.Instructions [0];
+ 			// note that the first instruction often does not have a sequence point
+@@ -69,11 +69,11 @@ namespace Gendarme.Framework {
+ 		{
+ 			MethodDefinition method = (location as MethodDefinition);
+ 			if (method != null)
+-				return (method.DeclaringType as TypeDefinition);
++				return method.DeclaringType;
+ 
+ 			FieldDefinition field = (location as FieldDefinition);
+ 			if (field != null)
+-				return (field.DeclaringType as TypeDefinition);
++				return field.DeclaringType;
+ 
+ 			ParameterDefinition parameter = (location as ParameterDefinition);
+ 			if (parameter != null)
+@@ -112,7 +112,7 @@ namespace Gendarme.Framework {
+ 		// include line and column.
+ 		private static string FormatSequencePoint (string document, int line, int column, bool exact)
+ 		{
+-			string sline = (line == PdbHiddenLine) ? "unavailable" : line.ToString ();
++			string sline = (line == PdbHiddenLine) ? "unavailable" : line.ToString (CultureInfo.InvariantCulture);
+ 
+ 			// MDB (mono symbols) does not provide any column information (so we don't show any)
+ 			// there's also no point in showing a column number if we're not totally sure about the line
+@@ -177,7 +177,7 @@ namespace Gendarme.Framework {
+ 					return FormatSource (candidate);
+ 
+ 				// we may still be lucky to find the (a) source file for the type itself
+-				type = (method.DeclaringType as TypeDefinition);
++				type = method.DeclaringType;
+ 			}
+ 
+ 			// TypeDefinition, FieldDefinition
+diff --git a/gendarme/framework/Gendarme.Framework/ThreadModelAttribute.cs b/gendarme/framework/Gendarme.Framework/ThreadModelAttribute.cs
+index e40e34c..4c76f63 100644
+--- a/gendarme/framework/Gendarme.Framework/ThreadModelAttribute.cs
++++ b/gendarme/framework/Gendarme.Framework/ThreadModelAttribute.cs
+@@ -27,6 +27,7 @@
+ //
+ 
+ using System;
++using System.Globalization;
+ 
+ // Note that these types are extended version of what we recommend
+ // that users use. See DecorateThreadsRule documentation for a smaller version
+@@ -82,7 +83,7 @@ namespace Gendarme.Framework {
+ 		public override string ToString ()
+ 		{
+ 			if (AllowsEveryCaller)
+-				return string.Format ("{0} | AllowEveryCaller", Model);
++				return String.Format (CultureInfo.InvariantCulture, "{0} | AllowEveryCaller", Model);
+ 				
+ 			return Model.ToString ();
+ 		}
+@@ -96,9 +97,9 @@ namespace Gendarme.Framework {
+ 			return this == rhs;
+ 		}
+ 		
+-		public bool Equals (ThreadModelAttribute rhs)
++		public bool Equals (ThreadModelAttribute other)
+ 		{
+-			return this == rhs;
++			return this == other;
+ 		}
+ 		
+ 		public static bool operator== (ThreadModelAttribute lhs, ThreadModelAttribute rhs)
+diff --git a/gendarme/framework/Makefile.am b/gendarme/framework/Makefile.am
+index afbf5d9..13cbf9e 100644
+--- a/gendarme/framework/Makefile.am
++++ b/gendarme/framework/Makefile.am
+@@ -40,6 +40,7 @@ framework_sources =  \
+ 	Gendarme.Framework.Helpers/PrimitiveReferences.cs \
+ 	Gendarme.Framework.Helpers/StackEntryAnalysis.cs \
+ 	Gendarme.Framework.Helpers/StackEntryUsageResult.cs \
++	Gendarme.Framework.Helpers/StreamLineReader.cs \
+ 	Gendarme.Framework.Rocks/AssemblyRocks.cs \
+ 	Gendarme.Framework.Rocks/CecilRocks.cs \
+ 	Gendarme.Framework.Rocks/CommonRocks.cs \
+@@ -86,7 +87,7 @@ framework_build_sources += $(framework_generated_sources)
+ 
+ ../bin/Gendarme.Framework.dll: $(framework_build_sources) $(CECIL_ASM)
+ 	test -d ../bin || mkdir ../bin
+-	$(GMCS) $(GENDARME_OPTIONS) -target:library -doc:$(framework_SCRIPTS).doc -r:$(CECIL_ASM) \
++	$(MCS) $(GENDARME_OPTIONS) -target:library -doc:$(framework_SCRIPTS).doc -r:$(CECIL_ASM) \
+ 		-out:$@ $(framework_build_sources)
+ 
+ framework_test_sources = \
+@@ -108,14 +109,14 @@ framework_test_sources = \
+ framework_test_build_sources = $(addprefix $(srcdir)/Test/, $(framework_test_sources))
+ 
+ Test.Framework.dll: $(framework_test_build_sources) $(framework_rules_SCRIPTS) ../bin/Gendarme.Framework.dll $(CECIL_ASM)
+-	$(GMCS) $(TESTS_OPTIONS) -target:library -d:CODE_ANALYSIS -pkg:mono-nunit \
++	$(MCS) $(TESTS_OPTIONS) -target:library -d:CODE_ANALYSIS -pkg:mono-nunit \
+ 		-r:$(CECIL_ASM) -r:../bin/Gendarme.Framework.dll -r:../rules/Test.Rules/Test.Rules.dll \
+ 		-out:$@ $(framework_test_build_sources)
+ 
+ test: Test.Framework.dll
+ 
+ run-test: test
+-	MONO_PATH=../bin/:../rules/Test.Rules/:$(MONO_PATH) nunit-console2 -noshadow Test.Framework.dll
++	MONO_PATH=../bin/:../rules/Test.Rules/:$(MONO_PATH) $(prefix)/bin/mono $(prefix)/lib/mono/4.0/nunit-console.exe Test.Framework.dll
+ 
+ self-test: $(framework_SCRIPTS)
+ 	mono --debug ../bin/gendarme.exe $(framework_SCRIPTS)
+diff --git a/gendarme/framework/Test/Gendarme.Framework.Rocks/AssemblyRocksTest.cs b/gendarme/framework/Test/Gendarme.Framework.Rocks/AssemblyRocksTest.cs
+index c4bbafd..061bccd 100644
+--- a/gendarme/framework/Test/Gendarme.Framework.Rocks/AssemblyRocksTest.cs
++++ b/gendarme/framework/Test/Gendarme.Framework.Rocks/AssemblyRocksTest.cs
+@@ -49,16 +49,23 @@ namespace Test.Framework.Rocks {
+ 
+ 		[Test]
+ 		[ExpectedException (typeof (ArgumentNullException))]
+-		public void HasAttribute_Null ()
++		public void HasAttribute_Namespace_Null ()
+ 		{
+-			assembly.HasAttribute (null);
++			assembly.HasAttribute (null, "a");
++		}
++
++		[Test]
++		[ExpectedException (typeof (ArgumentNullException))]
++		public void HasAttribute_Name_Null ()
++		{
++			assembly.HasAttribute ("a", null);
+ 		}
+ 
+ 		[Test]
+ 		public void HasAttribute ()
+ 		{
+-			Assert.IsTrue (assembly.HasAttribute ("System.Runtime.CompilerServices.RuntimeCompatibilityAttribute"), "System.Runtime.CompilerServices.RuntimeCompatibilityAttribute");
+-			Assert.IsFalse (assembly.HasAttribute ("NUnit.Framework.TestFixtureAttribute"), "TestFixtureAttribute");
++			Assert.IsTrue (assembly.HasAttribute ("System.Runtime.CompilerServices", "RuntimeCompatibilityAttribute"), "System.Runtime.CompilerServices.RuntimeCompatibilityAttribute");
++			Assert.IsFalse (assembly.HasAttribute ("NUnit.Framework", "TestFixtureAttribute"), "TestFixtureAttribute");
+ 		}
+ 	}
+ }
+diff --git a/gendarme/framework/Test/Gendarme.Framework.Rocks/CustomAttributeRocksTest.cs b/gendarme/framework/Test/Gendarme.Framework.Rocks/CustomAttributeRocksTest.cs
+index 65a868e..78c6f81 100644
+--- a/gendarme/framework/Test/Gendarme.Framework.Rocks/CustomAttributeRocksTest.cs
++++ b/gendarme/framework/Test/Gendarme.Framework.Rocks/CustomAttributeRocksTest.cs
+@@ -50,59 +50,29 @@ namespace Test.Framework.Rocks {
+ 
+ 		[Test]
+ 		[ExpectedException (typeof (ArgumentNullException))]
+-		public void Contains_Null ()
+-		{
+-			Collection<CustomAttribute> cac = new Collection<CustomAttribute> ();
+-			cac.ContainsType ((string) null);
+-		}
+-
+-		[Test]
+-		public void Contains ()
+-		{
+-			TypeDefinition type = assembly.MainModule.GetType ("Test.Framework.Rocks.CustomAttributeRocksTest");
+-			Collection<CustomAttribute> cac = type.CustomAttributes;
+-			Assert.IsTrue (cac.ContainsType ("NUnit.Framework.TestFixtureAttribute"), "NUnit.Framework.TestFixtureAttribute");
+-			Assert.IsFalse (cac.ContainsType ("NUnit.Framework.TestFixture"), "NUnit.Framework.TestFixture");
+-		}
+-
+-		[Test]
+-		[ExpectedException (typeof (ArgumentNullException))]
+-		public void ContainsAny_Null ()
+-		{
+-			Collection<CustomAttribute> cac = new Collection<CustomAttribute> ();
+-			cac.ContainsAnyType (null);
+-		}
+-
+-		[Test]
+-		public void ContainsAny ()
++		public void HasAttribute_Namespace_Null ()
+ 		{
+ 			TypeDefinition type = assembly.MainModule.GetType ("Test.Framework.Rocks.CustomAttributeRocksTest");
+-			Collection<CustomAttribute> cac = type.CustomAttributes;
+-			Assert.IsTrue (cac.ContainsAnyType (new string[] {
+-				"NUnit.Framework.TestFixtureAttribute",
+-				null,
+-				"System.ICloneable"
+-			}), "NUnit.Framework.TestFixtureAttribute");
+-			Assert.IsFalse (cac.ContainsAnyType (new string[] {}), "NUnit.Framework.TestFixture");
++			type.HasAttribute (null, "a");
+ 		}
+ 
+ 		[Test]
+ 		[ExpectedException (typeof (ArgumentNullException))]
+-		public void HasAttribute_Null ()
++		public void HasAttribute_Name_Null ()
+ 		{
+ 			TypeDefinition type = assembly.MainModule.GetType ("Test.Framework.Rocks.CustomAttributeRocksTest");
+-			type.HasAttribute (null);
++			type.HasAttribute ("a", null);
+ 		}
+ 		
+ 		[Test]
+ 		public void HasAttribute ()
+ 		{
+ 			TypeDefinition type = null;
+-			Assert.IsFalse (type.HasAttribute ("NUnit.Framework.TestFixtureAttribute"), "null-type");
++			Assert.IsFalse (type.HasAttribute ("NUnit.Framework", "TestFixtureAttribute"), "null-type");
+ 
+ 			type = assembly.MainModule.GetType ("Test.Framework.Rocks.CustomAttributeRocksTest");
+-			Assert.IsTrue (type.HasAttribute ("NUnit.Framework.TestFixtureAttribute"), "true");
+-			Assert.IsFalse (type.HasAttribute ("NUnit.Framework.TestAttribute"), "false");
++			Assert.IsTrue (type.HasAttribute ("NUnit.Framework", "TestFixtureAttribute"), "true");
++			Assert.IsFalse (type.HasAttribute ("NUnit.Framework", "TestAttribute"), "false");
+ 		}
+ 	}
+ }
+diff --git a/gendarme/framework/Test/Gendarme.Framework.Rocks/FieldRocksTest.cs b/gendarme/framework/Test/Gendarme.Framework.Rocks/FieldRocksTest.cs
+index a790ed2..69ea851 100644
+--- a/gendarme/framework/Test/Gendarme.Framework.Rocks/FieldRocksTest.cs
++++ b/gendarme/framework/Test/Gendarme.Framework.Rocks/FieldRocksTest.cs
+@@ -74,16 +74,23 @@ namespace Test.Framework.Rocks {
+ 
+ 		[Test]
+ 		[ExpectedException (typeof (ArgumentNullException))]
+-		public void HasAttribute_Null ()
++		public void HasAttribute_Namespace_Null ()
+ 		{
+-			GetField ("assembly").HasAttribute (null);
++			GetField ("assembly").HasAttribute (null, "a");
++		}
++
++		[Test]
++		[ExpectedException (typeof (ArgumentNullException))]
++		public void HasAttribute_Name_Null ()
++		{
++			GetField ("assembly").HasAttribute ("a", null);
+ 		}
+ 
+ 		[Test]
+ 		public void HasAttribute ()
+ 		{
+-			Assert.IsTrue (GetField ("cga").HasAttribute ("System.Runtime.CompilerServices.CompilerGeneratedAttribute"), "CompilerGeneratedAttribute");
+-			Assert.IsFalse (GetField ("cga").HasAttribute ("NUnit.Framework.TestFixtureAttribute"), "TestFixtureAttribute");
++			Assert.IsTrue (GetField ("cga").HasAttribute ("System.Runtime.CompilerServices", "CompilerGeneratedAttribute"), "CompilerGeneratedAttribute");
++			Assert.IsFalse (GetField ("cga").HasAttribute ("NUnit.Framework", "TestFixtureAttribute"), "TestFixtureAttribute");
+ 		}
+ 
+ 		[Test]
+diff --git a/gendarme/framework/Test/Gendarme.Framework.Rocks/MethodRocksTest.cs b/gendarme/framework/Test/Gendarme.Framework.Rocks/MethodRocksTest.cs
+index c43d680..3202358 100644
+--- a/gendarme/framework/Test/Gendarme.Framework.Rocks/MethodRocksTest.cs
++++ b/gendarme/framework/Test/Gendarme.Framework.Rocks/MethodRocksTest.cs
+@@ -112,18 +112,26 @@ namespace Test.Framework.Rocks {
+ 
+ 		[Test]
+ 		[ExpectedException (typeof (ArgumentNullException))]
+-		public void HasAttribute_Null ()
++		public void HasAttribute_Namespace_Null ()
+ 		{
+ 			MethodDefinition method = GetMethod ("FixtureSetUp");
+-			method.HasAttribute ((string) null);
++			method.HasAttribute (null, "a");
++		}
++
++		[Test]
++		[ExpectedException (typeof (ArgumentNullException))]
++		public void HasAttribute_Name_Null ()
++		{
++			MethodDefinition method = GetMethod ("FixtureSetUp");
++			method.HasAttribute ("a", null);
+ 		}
+ 
+ 		[Test]
+ 		public void HasAttribute ()
+ 		{
+ 			MethodDefinition method = GetMethod ("FixtureSetUp");
+-			Assert.IsTrue (method.HasAttribute ("NUnit.Framework.TestFixtureSetUpAttribute"), "NUnit.Framework.TestFixtureSetUpAttribute");
+-			Assert.IsFalse (method.HasAttribute ("NUnit.Framework.TestFixtureSetUp"), "NUnit.Framework.TestFixtureSetUp");
++			Assert.IsTrue (method.HasAttribute ("NUnit.Framework", "TestFixtureSetUpAttribute"), "NUnit.Framework.TestFixtureSetUpAttribute");
++			Assert.IsFalse (method.HasAttribute ("NUnit.Framework", "TestFixtureSetUp"), "NUnit.Framework.TestFixtureSetUp");
+ 		}
+ 
+ 		[Test]
+diff --git a/gendarme/framework/Test/Gendarme.Framework.Rocks/RocksTest.cs b/gendarme/framework/Test/Gendarme.Framework.Rocks/RocksTest.cs
+index ed62b9c..4c746fa 100644
+--- a/gendarme/framework/Test/Gendarme.Framework.Rocks/RocksTest.cs
++++ b/gendarme/framework/Test/Gendarme.Framework.Rocks/RocksTest.cs
+@@ -49,6 +49,9 @@ namespace Test.Framework.Rocks {
+ 			public abstract void PublicMethod ();
+ 			protected abstract void ProtectedMethod ();
+ 			private void PrivateMethod () { }
++
++			public abstract class NestedNestedPublicType {
++			}
+ 		}
+ 
+ 		protected abstract class NestedProtectedType {
+diff --git a/gendarme/framework/Test/Gendarme.Framework.Rocks/TypeRocksTest.cs b/gendarme/framework/Test/Gendarme.Framework.Rocks/TypeRocksTest.cs
+index 51f782f..99366be 100644
+--- a/gendarme/framework/Test/Gendarme.Framework.Rocks/TypeRocksTest.cs
++++ b/gendarme/framework/Test/Gendarme.Framework.Rocks/TypeRocksTest.cs
+@@ -179,20 +179,27 @@ namespace Test.Framework.Rocks {
+ 
+ 		[Test]
+ 		[ExpectedException (typeof (ArgumentNullException))]
+-		public void HasAttribute_Null ()
++		public void HasAttribute_Namespace_Null ()
+ 		{
+-			GetType (String.Empty).HasAttribute (null);
++			GetType (String.Empty).HasAttribute (null, "a");
++		}
++
++		[Test]
++		[ExpectedException (typeof (ArgumentNullException))]
++		public void HasAttribute_Name_Null ()
++		{
++			GetType (String.Empty).HasAttribute ("a", null);
+ 		}
+ 
+ 		[Test]
+ 		public void HasAttribute ()
+ 		{
+-			Assert.IsTrue (GetType (String.Empty).HasAttribute ("NUnit.Framework.TestFixtureAttribute"), "TypeRocksTest");
+-			Assert.IsFalse (GetType ("/Enum").HasAttribute ("System.FlagsAttribute"), "Enum/System.FlagsAttribute");
+-			Assert.IsTrue (GetType ("/Flags").HasAttribute ("System.FlagsAttribute"), "Flags/System.FlagsAttribute");
++			Assert.IsTrue (GetType (String.Empty).HasAttribute ("NUnit.Framework", "TestFixtureAttribute"), "TypeRocksTest");
++			Assert.IsFalse (GetType ("/Enum").HasAttribute ("System", "FlagsAttribute"), "Enum/System.FlagsAttribute");
++			Assert.IsTrue (GetType ("/Flags").HasAttribute ("System", "FlagsAttribute"), "Flags/System.FlagsAttribute");
+ 			// fullname is required
+-			Assert.IsFalse (GetType ("/Flags").HasAttribute ("System.Flags"), "Flags/System.Flags");
+-			Assert.IsFalse (GetType ("/Flags").HasAttribute ("FlagsAttribute"), "Flags/FlagsAttribute");
++			Assert.IsFalse (GetType ("/Flags").HasAttribute ("System", "Flags"), "Flags/System.Flags");
++			Assert.IsFalse (GetType ("/Flags").HasAttribute ("", "FlagsAttribute"), "Flags/FlagsAttribute");
+ 		}
+ 
+ 		[Test]
+@@ -204,51 +211,65 @@ namespace Test.Framework.Rocks {
+ 
+ 		[Test]
+ 		[ExpectedException (typeof (ArgumentNullException))]
+-		public void Implements_Null ()
++		public void Implements_Namespace_Null ()
++		{
++			GetType (String.Empty).Implements (null, "a");
++		}
++
++		[Test]
++		[ExpectedException (typeof (ArgumentNullException))]
++		public void Implements_Name_Null ()
+ 		{
+-			GetType (String.Empty).Implements (null);
++			GetType (String.Empty).Implements ("a", null);
+ 		}
+ 
+ 		[Test]
+ 		public void Implements ()
+ 		{
+-			Assert.IsFalse (GetType (String.Empty).Implements ("System.ICloneable"), "ICloneable");
+-			Assert.IsTrue (GetType ("/IDeepCloneable").Implements ("Test.Framework.Rocks.TypeRocksTest/IDeepCloneable"), "itself");
+-			Assert.IsTrue (GetType ("/IDeepCloneable").Implements ("System.ICloneable"), "interface inheritance");
+-			Assert.IsTrue (GetType ("/Deep").Implements ("Test.Framework.Rocks.TypeRocksTest/IDeepCloneable"), "IDeepCloneable");
+-			Assert.IsTrue (GetType ("/Deep").Implements ("System.ICloneable"), "second-level ICloneable");
+-			Assert.IsTrue (GetType ("/Mixin").Implements ("Test.Framework.Rocks.TypeRocksTest/IDeepCloneable"), "parent interface inheritance");
++			Assert.IsFalse (GetType (String.Empty).Implements ("System", "ICloneable"), "ICloneable");
++			Assert.IsTrue (GetType ("/IDeepCloneable").Implements ("Test.Framework.Rocks", "TypeRocksTest/IDeepCloneable"), "itself");
++			Assert.IsTrue (GetType ("/IDeepCloneable").Implements ("System", "ICloneable"), "interface inheritance");
++			Assert.IsTrue (GetType ("/Deep").Implements ("Test.Framework.Rocks", "TypeRocksTest/IDeepCloneable"), "IDeepCloneable");
++			Assert.IsTrue (GetType ("/Deep").Implements ("System", "ICloneable"), "second-level ICloneable");
++			Assert.IsTrue (GetType ("/Mixin").Implements ("Test.Framework.Rocks", "TypeRocksTest/IDeepCloneable"), "parent interface inheritance");
+ 		}
+ 
+ 		[Test]
+ 		[ExpectedException (typeof (ArgumentNullException))]
+-		public void Inherits_Null ()
++		public void Inherits_Namespace_Null ()
+ 		{
+-			GetType (String.Empty).Inherits (null);
++			GetType (String.Empty).Inherits (null, "a");
++		}
++
++		[Test]
++		[ExpectedException (typeof (ArgumentNullException))]
++		public void Inherits_Name_Null ()
++		{
++			GetType (String.Empty).Inherits ("a", null);
+ 		}
+ 
+ 		[Test]
+ 		public void Inherits ()
+ 		{
+-			Assert.IsFalse (GetType ("/NotAttribute").Inherits ("System.Attribute"), "NotAttribute");
+-			Assert.IsTrue (GetType ("/AnAttribute").Inherits ("System.Attribute"), "AnAttribute");
+-			Assert.IsFalse (GetType ("/ClassInheritsNotAttribute").Inherits ("System.Attribute"), "ClassInheritsNotAttribute");
+-			Assert.IsTrue (GetType ("/AttributeInheritsAnAttribute").Inherits ("System.Attribute"), "AttributeInheritsAnAttribute");
++			Assert.IsFalse (GetType ("/NotAttribute").Inherits ("System", "Attribute"), "NotAttribute");
++			Assert.IsTrue (GetType ("/AnAttribute").Inherits ("System", "Attribute"), "AnAttribute");
++			Assert.IsFalse (GetType ("/ClassInheritsNotAttribute").Inherits ("System", "Attribute"), "ClassInheritsNotAttribute");
++			Assert.IsTrue (GetType ("/AttributeInheritsAnAttribute").Inherits ("System", "Attribute"), "AttributeInheritsAnAttribute");
+ 		}
+ 
+ 		[Test]
+ 		public void Inherits_FromAnotherAssembly ()
+ 		{
+ 			// we can't be sure here so to avoid false positives return false
+-			Assert.IsTrue (GetType ("/AttributeInheritsOuterAttribute").Inherits ("System.Attribute"), "AttributeInheritsOuterAttribute");
+-			Assert.IsTrue (GetType ("/AttributeInheritsOuterAttributeDerivingAttribute").Inherits ("System.Attribute"), "AttributeInheritsOuterAttributeDerivingAttribute");
++			Assert.IsTrue (GetType ("/AttributeInheritsOuterAttribute").Inherits ("System", "Attribute"), "AttributeInheritsOuterAttribute");
++			Assert.IsTrue (GetType ("/AttributeInheritsOuterAttributeDerivingAttribute").Inherits ("System", "Attribute"), "AttributeInheritsOuterAttributeDerivingAttribute");
+ 		}
+ 
+ 		[Test]
+ 		public void Inherits_Itself ()
+ 		{
+ 			TypeDefinition type = GetType (String.Empty);
+-			Assert.IsTrue (type.Inherits (type.FullName), "itself");
++			Assert.IsTrue (type.Inherits (type.Namespace, type.Name), "itself");
+ 		}
+ 
+ 		[Test]
+@@ -322,6 +343,50 @@ namespace Test.Framework.Rocks {
+ 		}
+ 
+ 		[Test]
++		public void IsNamed ()
++		{
++			string name = "Test.Framework.Rocks.PublicType";
++			TypeDefinition type = assembly.MainModule.GetType (name);
++
++			Assert.IsTrue (type.IsNamed ( "Test.Framework.Rocks.PublicType"));
++			Assert.IsFalse (type.IsNamed ("Test.Framework.Rocks.P"));//Missing Text
++			Assert.IsFalse (type.IsNamed ("Test.Framework.Rocks.PublicTypeExtraText"));
++
++			Assert.IsTrue (type.IsNamed ("Test.Framework.Rocks", "PublicType"));
++			Assert.IsFalse (type.IsNamed ("Test.Framework.Rocks", "P"));//Missing Text
++			Assert.IsFalse (type.IsNamed ("Test.Framework.Rocks", "PublicTypeExtraText"));
++		}
++
++		[Test]
++		public void IsNamedNestedType ()
++		{
++			string name = "Test.Framework.Rocks.PublicType/NestedPublicType";
++			TypeDefinition type = assembly.MainModule.GetType (name);
++
++			Assert.IsTrue (type.IsNamed ("Test.Framework.Rocks.PublicType/NestedPublicType"));
++			Assert.IsFalse (type.IsNamed ("Test.Framework.Rocks.PublicType/N"));//Missing Text
++			Assert.IsFalse (type.IsNamed ("Test.Framework.Rocks.PublicType/NestedPublicTypeExtaStuff"));
++
++			Assert.IsTrue (type.IsNamed ("Test.Framework.Rocks", "PublicType/NestedPublicType"));
++			Assert.IsFalse (type.IsNamed ("Test.Framework.Rocks", "PublicType/N"));//Missing Text
++			Assert.IsFalse (type.IsNamed ("Test.Framework.Rocks", "PublicType/NestedPublicTypeExtraText"));
++
++			Assert.IsFalse (type.IsNamed ("Test.Framework.Rocks", "NestedPublicType"));
++			Assert.IsFalse (type.IsNamed ("", "NestedPublicType"));
++		}
++
++		[Test]
++		public void IsNamedDoubleNestedType ()
++		{
++			string name = "Test.Framework.Rocks.PublicType/NestedPublicType/NestedNestedPublicType";
++			TypeDefinition type = assembly.MainModule.GetType (name);
++
++			Assert.IsTrue (type.IsNamed ("Test.Framework.Rocks.PublicType/NestedPublicType/NestedNestedPublicType"));
++			
++			Assert.IsTrue (type.IsNamed ("Test.Framework.Rocks", "PublicType/NestedPublicType/NestedNestedPublicType"));
++		}
++
++		[Test]
+ 		public void IsVisible ()
+ 		{
+ 			string name = "Test.Framework.Rocks.PublicType";
+diff --git a/gendarme/man/gendarme.1.in b/gendarme/man/gendarme.1.in
+index 0389780..cc1989f 100644
+--- a/gendarme/man/gendarme.1.in
++++ b/gendarme/man/gendarme.1.in
+@@ -33,8 +33,7 @@ Specify the rule sets and rule settings. Default is 'rules.xml'.
+ Specify a rule set from configfile. Defaults to 'default'.
+ .TP
+ .I "--log file"
+-Save the report to the specified file. If none of --log, --xml, or --html are used
+-then the report is written to stdout.
++Save the report, as a text file, to the specified file.
+ .TP
+ .I "--xml file"
+ Save the report, formatted as XML, to the specified file.
+@@ -42,6 +41,11 @@ Save the report, formatted as XML, to the specified file.
+ .I "--html file"
+ Save the report, formatted as HTML, to the specified file.
+ .TP
++.I "--console"
++Write the defects on stdout. This is the default (implicit) behavior if none of
++--log, --xml, or --html options are specified. If (explicitely) specified then 
++the defects will be shown on both stdout and inside text/xml/html report(s).
++.TP
+ .I "--ignore ignore-file"
+ Do not report defects listed in the specified file.
+ .TP
+diff --git a/gendarme/mono-options.ignore b/gendarme/mono-options.ignore
+index c48ca1a..aa1799a 100644
+--- a/gendarme/mono-options.ignore
++++ b/gendarme/mono-options.ignore
+@@ -67,3 +67,15 @@ T: NDesk.Options.OptionSet
+ R: Gendarme.Rules.Smells.AvoidCodeDuplicatedInSameClassRule
+ T: NDesk.Options.OptionSet
+ 
++R: Gendarme.Rules.Globalization.PreferStringComparisonOverrideRule
++M: System.String NDesk.Options.OptionSet::GetArgumentName(System.Int32,System.Int32,System.String)
++
++R: Gendarme.Rules.Globalization.PreferIFormatProviderOverrideRule
++M: System.Void NDesk.Options.Option::AddSeparators(System.String,System.Int32,System.Collections.Generic.ICollection`1<System.String>)
++M: System.Boolean NDesk.Options.OptionSet::ParseBundledValue(System.String,System.String,NDesk.Options.OptionContext)
++M: System.Void NDesk.Options.OptionValueCollection::AssertValid(System.Int32)
++M: System.Void NDesk.Options.Option::.ctor(System.String,System.String,System.Int32)
++M: NDesk.Options.OptionValueType NDesk.Options.Option::ParsePrototype()
++M: T NDesk.Options.Option::Parse(System.String,NDesk.Options.OptionContext)
++M: System.Void NDesk.Options.OptionSet::ParseValue(System.String,NDesk.Options.OptionContext)
++
+diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/AvoidAssemblyVersionMismatchRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/AvoidAssemblyVersionMismatchRule.cs
+index 3b2ba33..dc43d09 100644
+--- a/gendarme/rules/Gendarme.Rules.BadPractice/AvoidAssemblyVersionMismatchRule.cs
++++ b/gendarme/rules/Gendarme.Rules.BadPractice/AvoidAssemblyVersionMismatchRule.cs
+@@ -25,6 +25,7 @@
+ // THE SOFTWARE.
+ 
+ using System;
++using System.Globalization;
+ 
+ using Mono.Cecil;
+ using Mono.Cecil.Cil;
+@@ -61,26 +62,6 @@ namespace Gendarme.Rules.BadPractice {
+ 	[Solution ("This situation can be confusing once deployed. Make sure both version are identical.")]
+ 	public class AvoidAssemblyVersionMismatchRule : Rule, IAssemblyRule {
+ 
+-		static bool VersionTryParse (string input, out Version result)
+-		{
+-			result = null;
+-			if (String.IsNullOrEmpty (input))
+-				return false;
+-
+-			try {
+-				result = new Version (input);
+-				return true;
+-			}
+-			catch (ArgumentException) {
+-				// also cover ArgumentOutOfRangeException
+-			}
+-			catch (FormatException) {
+-			}
+-			catch (OverflowException) {
+-			}
+-			return false;
+-		}
+-
+ 		public RuleResult CheckAssembly (AssemblyDefinition assembly)
+ 		{
+ 			if (!assembly.HasCustomAttributes)
+@@ -100,11 +81,10 @@ namespace Gendarme.Rules.BadPractice {
+ 				// any attribute without arguments can be skipped
+ 				if (!ca.HasConstructorArguments)
+ 					continue;
+-				if (ca.AttributeType.FullName != "System.Reflection.AssemblyFileVersionAttribute")
++				if (!ca.AttributeType.IsNamed ("System.Reflection", "AssemblyFileVersionAttribute"))
+ 					continue;
+ 
+-				// FIXME: replace with Version.TryParse once we upgrade to FX4.0
+-				VersionTryParse (ca.ConstructorArguments [0].Value as string, out file_version);
++				Version.TryParse (ca.ConstructorArguments [0].Value as string, out file_version);
+ 				break;
+ 			}
+ 
+@@ -127,9 +107,11 @@ namespace Gendarme.Rules.BadPractice {
+ 			else if (assembly_version.Revision == file_version.Revision)
+ 				return RuleResult.Success;
+ 
+-			string msg = String.Format ("Assembly version is '{0}' while file version is '{1}'.", assembly_version, file_version);
++			string msg = String.Format (CultureInfo.InvariantCulture,
++				"Assembly version is '{0}' while file version is '{1}'.", assembly_version, file_version);
+ 			Runner.Report (assembly, s, Confidence.High, msg);
+ 			return RuleResult.Failure;
+ 		}
+ 	}
+ }
++
+diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/AvoidCallingProblematicMethodsRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/AvoidCallingProblematicMethodsRule.cs
+index 777cc02..87d00c2 100644
+--- a/gendarme/rules/Gendarme.Rules.BadPractice/AvoidCallingProblematicMethodsRule.cs
++++ b/gendarme/rules/Gendarme.Rules.BadPractice/AvoidCallingProblematicMethodsRule.cs
+@@ -27,8 +27,9 @@
+ //
+ 
+ using System;
+-using System.Reflection;
++using System.Globalization;
+ using System.Collections.Generic;
++using System.Reflection;
+ 
+ using Mono.Cecil;
+ using Mono.Cecil.Cil;
+@@ -100,22 +101,22 @@ namespace Gendarme.Rules.BadPractice {
+ 		public AvoidCallingProblematicMethodsRule ()
+ 		{
+ 			problematicMethods.Add ("Collect", (m, i) => 
+-				(m.DeclaringType.FullName == "System.GC") ? Severity.Critical : (Severity?) null);
++				m.DeclaringType.IsNamed ("System", "GC") ? Severity.Critical : (Severity?) null);
+ 			problematicMethods.Add ("Suspend", (m, i) => 
+-				(m.DeclaringType.FullName == "System.Threading.Thread") ? Severity.Medium : (Severity?) null);
++				m.DeclaringType.IsNamed ("System.Threading", "Thread") ? Severity.Medium : (Severity?) null);
+ 			problematicMethods.Add ("Resume", (m, i) => 
+-				(m.DeclaringType.FullName == "System.Threading.Thread") ? Severity.Medium : (Severity?) null);
++				m.DeclaringType.IsNamed ("System.Threading", "Thread") ? Severity.Medium : (Severity?) null);
+ 			problematicMethods.Add ("DangerousGetHandle", (m, i) => 
+-				(m.DeclaringType.FullName == "System.Runtime.InteropServices.SafeHandle") ? Severity.Critical : (Severity?) null);
++				m.DeclaringType.IsNamed ("System.Runtime.InteropServices", "SafeHandle") ? Severity.Critical : (Severity?) null);
+ 			problematicMethods.Add ("LoadFrom", (m, i) => 
+-				(m.DeclaringType.FullName == "System.Reflection.Assembly") ? Severity.High : (Severity?) null);
++				m.DeclaringType.IsNamed ("System.Reflection", "Assembly") ? Severity.High : (Severity?) null);
+ 			problematicMethods.Add ("LoadFile", (m, i) => 
+-				(m.DeclaringType.FullName == "System.Reflection.Assembly") ? Severity.High : (Severity?) null);
++				m.DeclaringType.IsNamed ("System.Reflection", "Assembly") ? Severity.High : (Severity?) null);
+ 			problematicMethods.Add ("LoadWithPartialName", (m, i) => 
+-				(m.DeclaringType.FullName == "System.Reflection.Assembly") ? Severity.High : (Severity?) null);
++				m.DeclaringType.IsNamed ("System.Reflection", "Assembly") ? Severity.High : (Severity?) null);
+ 			problematicMethods.Add ("InvokeMember", (m, i) => 
+-				(m.DeclaringType.FullName != "System.Type") ? (Severity?) null :
+-				IsAccessingWithNonPublicModifiers (i) ? Severity.Critical : (Severity?) null);
++				!m.DeclaringType.IsNamed ("System", "Type") ? (Severity?) null :
++					IsAccessingWithNonPublicModifiers (i) ? Severity.Critical : (Severity?) null);
+ 		}
+ 
+ 		private static bool OperandIsNonPublic (BindingFlags operand)
+@@ -166,7 +167,8 @@ namespace Gendarme.Rules.BadPractice {
+ 
+ 				Severity? severity = IsProblematicCall (instruction);
+ 				if (severity.HasValue) {
+-					string msg = String.Format ("You are calling to {0}, which is a potentially problematic method", 
++					string msg = String.Format (CultureInfo.InvariantCulture,
++						"You are calling to {0}, which is a potentially problematic method", 
+ 						instruction.Operand);
+ 					Runner.Report (method, instruction, severity.Value, Confidence.High, msg);
+ 				}
+diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/AvoidNullCheckWithAsOperatorRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/AvoidNullCheckWithAsOperatorRule.cs
+new file mode 100644
+index 0000000..26394d9
+--- /dev/null
++++ b/gendarme/rules/Gendarme.Rules.BadPractice/AvoidNullCheckWithAsOperatorRule.cs
+@@ -0,0 +1,141 @@
++//
++// Gendarme.Rules.BadPractice.AvoidNullCheckWithAsOperatorRule
++//
++// Authors:
++//	Sebastien Pouliot <sebastien at ximian.com>
++//
++// Copyright (C) 2011 Novell, Inc (http://www.novell.com)
++//
++// Permission is hereby granted, free of charge, to any person obtaining
++// a copy of this software and associated documentation files (the
++// "Software"), to deal in the Software without restriction, including
++// without limitation the rights to use, copy, modify, merge, publish,
++// distribute, sublicense, and/or sell copies of the Software, and to
++// permit persons to whom the Software is furnished to do so, subject to
++// the following conditions:
++// 
++// The above copyright notice and this permission notice shall be
++// included in all copies or substantial portions of the Software.
++// 
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++//
++
++using System;
++
++using Mono.Cecil;
++using Mono.Cecil.Cil;
++
++using Gendarme.Framework;
++using Gendarme.Framework.Engines;
++using Gendarme.Framework.Helpers;
++using Gendarme.Framework.Rocks;
++
++namespace Gendarme.Rules.BadPractice {
++
++	/// <summary>
++	/// The rule will detect if a null check is done before using the <c>as</c> operator. 
++	/// This null check is not needed, a <c>null</c> instance will return <c>null</c>,
++	/// and the code will need to deal with <c>as</c> returning a null value anyway.
++	/// </summary>
++	/// <example>
++	/// Bad example:
++	/// <code>
++	/// public string AsString (object obj)
++	/// {
++	///	return (o == null) ? null : o as string;
++	/// }
++	/// </code>
++	/// </example>
++	/// <example>
++	/// Good example:
++	/// <code>
++	/// public string AsString (object obj)
++	/// {
++	///	return (o as string);
++	/// }
++	/// </code>
++	/// </example>
++	// as suggested in https://bugzilla.novell.com/show_bug.cgi?id=651305
++	[Problem ("An unneeded null check is done before using the 'as' operator.")]
++	[Solution ("Remove the extraneous null check")]
++	[EngineDependency (typeof (OpCodeEngine))]
++	public class AvoidNullCheckWithAsOperatorRule : Rule, IMethodRule {
++
++		OpCodeBitmask mask = new OpCodeBitmask (0x100000, 0x10000000000000, 0x0, 0x0);
++
++		static bool CheckFalseBranch (Instruction ins)
++		{
++			Instruction next = ins.Next;
++			if (!next.Is (ins.Previous.OpCode.Code))
++				return false;
++
++			if (!(ins.Operand as Instruction).Is (Code.Ldnull))
++				return false;
++
++			return CheckIsinst (next.Next);
++		}
++
++		static bool CheckTrueBranch (Instruction ins)
++		{
++			if (!ins.Next.Is (Code.Ldnull))
++				return false;
++
++			Instruction br = (ins.Operand as Instruction);
++			if (ins.Previous.OpCode.Code != br.OpCode.Code)
++				return false;
++
++			return CheckIsinst (br.Next);
++		}
++
++		static bool CheckIsinst (Instruction ins)
++		{
++			if (!ins.Is (Code.Isinst))
++				return false;
++			return (ins.Next.OpCode.FlowControl != FlowControl.Cond_Branch);
++		}
++
++		public RuleResult CheckMethod (MethodDefinition method)
++		{
++			// rule only applies to methods with IL...
++			if (!method.HasBody)
++				return RuleResult.DoesNotApply;
++
++			// and when the IL contains both a isinst and ldnull
++			if (!mask.IsSubsetOf (OpCodeEngine.GetBitmask (method)))
++				return RuleResult.DoesNotApply;
++
++			foreach (Instruction ins in method.Body.Instructions) {
++				bool detected = false;
++				switch (ins.OpCode.Code) {
++				case Code.Brfalse_S:
++				case Code.Brfalse:
++					detected = CheckFalseBranch (ins);
++					break;
++				case Code.Brtrue_S:
++				case Code.Brtrue:
++					detected = CheckTrueBranch (ins);
++					break;
++				}
++				if (detected)
++					Runner.Report (method, ins, Severity.Medium, Confidence.Normal);
++			}
++
++			return Runner.CurrentRuleResult;
++		}
++#if false
++		public void Bitmask ()
++		{
++			OpCodeBitmask mask = new OpCodeBitmask ();
++			mask.Set (Code.Isinst);
++			mask.Set (Code.Ldnull);
++			Console.WriteLine (mask);
++		}
++#endif
++	}
++}
+diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/AvoidVisibleConstantFieldRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/AvoidVisibleConstantFieldRule.cs
+index 0831682..c18be47 100644
+--- a/gendarme/rules/Gendarme.Rules.BadPractice/AvoidVisibleConstantFieldRule.cs
++++ b/gendarme/rules/Gendarme.Rules.BadPractice/AvoidVisibleConstantFieldRule.cs
+@@ -24,6 +24,8 @@
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ // THE SOFTWARE.
+ 
++using System.Globalization;
++
+ using Mono.Cecil;
+ using Mono.Cecil.Cil;
+ 
+@@ -80,11 +82,12 @@ namespace Gendarme.Rules.BadPractice {
+ 
+ 				// we let null constant for all reference types (since they can't be changed to anything else)
+ 				// except for strings (which can be modified later)
+-				string type_name = field.FieldType.FullName;
+-				if (!field.FieldType.IsValueType && (type_name != "System.String"))
++				TypeReference ftype = field.FieldType;
++				if (!ftype.IsValueType && !ftype.IsNamed ("System", "String"))
+ 					continue;
+ 
+-				string msg = string.Format ("'{0}' of type {1}.", field.Name, type_name);
++				string msg = string.Format (CultureInfo.InvariantCulture, "'{0}' of type {1}.", 
++					field.Name, ftype.GetFullName ());
+ 				Runner.Report (field, Severity.High, Confidence.High, msg);
+ 
+ 			}
+diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/CheckNewExceptionWithoutThrowingRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/CheckNewExceptionWithoutThrowingRule.cs
+index e40aed6..183a18c 100644
+--- a/gendarme/rules/Gendarme.Rules.BadPractice/CheckNewExceptionWithoutThrowingRule.cs
++++ b/gendarme/rules/Gendarme.Rules.BadPractice/CheckNewExceptionWithoutThrowingRule.cs
+@@ -96,7 +96,7 @@ namespace Gendarme.Rules.BadPractice {
+ 
+ 				MethodReference constructor = (MethodReference) ins.Operand;
+ 
+-				if (!constructor.DeclaringType.Inherits ("System.Exception"))
++				if (!constructor.DeclaringType.Inherits ("System", "Exception"))
+ 					continue;
+ 
+ 				// quick check to save resources
+diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/CheckNewThreadWithoutStartRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/CheckNewThreadWithoutStartRule.cs
+index 3f01bb1..ac0c146 100644
+--- a/gendarme/rules/Gendarme.Rules.BadPractice/CheckNewThreadWithoutStartRule.cs
++++ b/gendarme/rules/Gendarme.Rules.BadPractice/CheckNewThreadWithoutStartRule.cs
+@@ -110,8 +110,6 @@ namespace Gendarme.Rules.BadPractice {
+ 			return false;
+ 		}
+ 
+-		private const string Thread = "System.Threading.Thread";
+-
+ 		public override void Initialize (IRunner runner)
+ 		{
+ 			base.Initialize (runner);
+@@ -119,8 +117,10 @@ namespace Gendarme.Rules.BadPractice {
+ 			// if the module does not reference (sealed) System.Threading.Thread 
+ 			// then no code inside the module will instanciate it
+ 			Runner.AnalyzeModule += delegate (object o, RunnerEventArgs e) {
+-				Active = (e.CurrentAssembly.Name.Name == "mscorlib") ||
+-					e.CurrentModule.HasTypeReference (Thread);
++				Active = (e.CurrentAssembly.Name.Name == "mscorlib" ||
++					e.CurrentModule.AnyTypeReference ((TypeReference tr) => {
++						return tr.IsNamed ("System.Threading", "Thread");
++					}));
+ 			};
+ 		}
+ 
+@@ -141,11 +141,11 @@ namespace Gendarme.Rules.BadPractice {
+ 
+ 				MethodReference constructor = (MethodReference) ins.Operand;
+ 
+-				if (constructor.DeclaringType.FullName != Thread)
++				if (!constructor.DeclaringType.IsNamed ("System.Threading", "Thread"))
+ 					continue;
+ 				if (ins.Next != null && (ins.Next.OpCode.Code == Code.Call || ins.Next.OpCode.Code == Code.Callvirt)) { //quick check to safe resources
+ 					MethodReference calledMethod = (MethodReference) ins.Next.Operand;
+-					if ((calledMethod.DeclaringType.FullName == Thread) && (calledMethod.Name == "Start"))
++					if (calledMethod.IsNamed ("System.Threading", "Thread", "Start"))
+ 						continue;
+ 				}
+ 
+diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/CloneMethodShouldNotReturnNullRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/CloneMethodShouldNotReturnNullRule.cs
+index eff7ae0..e740a02 100644
+--- a/gendarme/rules/Gendarme.Rules.BadPractice/CloneMethodShouldNotReturnNullRule.cs
++++ b/gendarme/rules/Gendarme.Rules.BadPractice/CloneMethodShouldNotReturnNullRule.cs
+@@ -69,8 +69,6 @@ namespace Gendarme.Rules.BadPractice {
+ 	[Solution ("Return an appropriate object instead of returning null.")]
+ 	public class CloneMethodShouldNotReturnNullRule : ReturnNullRule, IMethodRule {
+ 
+-		private const string ICloneable = "System.ICloneable";
+-
+ 		public override void Initialize (IRunner runner)
+ 		{
+ 			base.Initialize (runner);
+@@ -78,8 +76,10 @@ namespace Gendarme.Rules.BadPractice {
+ 			// if the module does not reference System.ICloneable then
+ 			// no type inside will be implementing it
+ 			Runner.AnalyzeModule += delegate (object o, RunnerEventArgs e) {
+-				Active = (e.CurrentAssembly.Name.Name == "mscorlib") ||
+-					e.CurrentModule.HasTypeReference (ICloneable);
++				Active = (e.CurrentAssembly.Name.Name == "mscorlib" ||
++					e.CurrentModule.AnyTypeReference ((TypeReference tr) => {
++						return tr.IsNamed ("System", "ICloneable");
++					}));
+ 			};
+ 		}
+ 
+@@ -90,7 +90,7 @@ namespace Gendarme.Rules.BadPractice {
+ 				return RuleResult.DoesNotApply;
+ 
+ 			// where the type implements ICloneable
+-			if (!method.DeclaringType.Implements (ICloneable))
++			if (!method.DeclaringType.Implements ("System", "ICloneable"))
+ 				return RuleResult.DoesNotApply;
+ 
+ 			// call base class to detect if the method can return null
+diff --git a/gendarme/rules/Gendarme.Rules.BadPractice/ConstructorShouldNotCallVirtualMethodsRule.cs b/gendarme/rules/Gendarme.Rules.BadPractice/ConstructorShouldNotCallVirtualMethodsRule.cs
+index d3758bb..7f47cf5 100644
+--- a/gendarme/rules/Gendarme.Rules.BadPractice/ConstructorShouldNotCallVirtualMethodsRule.cs
<Skipped 25389 lines>
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/mono-tools.git/commitdiff/d2d045d07c22571a40e7f5991cd2e5bc8c37c019



More information about the pld-cvs-commit mailing list