[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