<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://agile.codebetter.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Patrick Smacchia [MVP C#]</title><link>http://agile.codebetter.com/blogs/patricksmacchia/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2007 (Build: 20416.853)</generator><item><title>Manage states in a multi-threaded environment without the synchronization pain</title><link>http://agile.codebetter.com/blogs/patricksmacchia/archive/2008/05/05/manage-states-in-a-multi-threaded-environment-without-the-synchronization-pain.aspx</link><pubDate>Mon, 05 May 2008 05:10:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:177650</guid><dc:creator>Patrick Smacchia</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://agile.codebetter.com/blogs/patricksmacchia/rsscomments.aspx?PostID=177650</wfw:commentRss><comments>http://agile.codebetter.com/blogs/patricksmacchia/archive/2008/05/05/manage-states-in-a-multi-threaded-environment-without-the-synchronization-pain.aspx#comments</comments><description>&lt;p class="MsoNormal"&gt;&lt;span&gt;I see 4 common
ways to deal with states in a multi-threaded environment:&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;span&gt;Immutable objects&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: The idea is simple and efficient: make sure
that the states of objects cannot be changed. This way, the object can be
accessed concurrently by multiple threads without any risk of state corruption
or thread race. I wrote a blog post&lt;/span&gt;&lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2008/01/13/immutable-types-understand-them-and-use-them.aspx"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; on &lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2008/01/13/immutable-types-understand-them-and-use-them.aspx" target="_blank"&gt;how to implement immutability
with C#&lt;/a&gt; and how you can use &lt;a href="http://www.NDepend.com" target="_blank"&gt;NDepend&lt;/a&gt;
facilities to enforce object immutability and method purity.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;





&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;



&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;span&gt;Thread / Resource affinity&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: The idea is as simple as it is
efficient here also: making sure that an object is always accessed by the same
thread. The .NET Framework offers several ways to implement this paradigm: the
&lt;a href="http://msdn.microsoft.com/en-us/library/system.threadstaticattribute.aspx" target="_blank"&gt;System.ThreadStatic&lt;/a&gt;&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.threadstaticattribute.aspx" target="_blank"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; attribute on fields, &lt;i&gt;Thread Local
Storage API&lt;/i&gt; and the interface &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.isynchronizeinvoke.aspx" target="_blank"&gt;ISynchronizeInvoke&lt;/a&gt;.
These are described in &lt;a href="http://www.codeproject.com/KB/books/thread_resource_affinity.aspx" target="_blank"&gt;this article&lt;/a&gt; &lt;/span&gt;&lt;span&gt;I published
on CodeProject.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;span&gt;Synchronized objects / Thread-Safe class&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: Since v1.0, the .NET Framework comes
natively with a way to implement synchronized objects through the lock
C#/VB.NET keyword, alias the &lt;i&gt;Monitor &lt;/i&gt;class. I found it convenient to implement
this pattern &lt;a href="http://www.practicaldot.net/Chapter_5/Listing_5_10.htm" target="_blank"&gt;this way&lt;/a&gt;&lt;/span&gt;&lt;a href="http://www.practicaldot.net/Chapter_5/Listing_5_10.htm"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;span&gt;Synchronization objects&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: The .NET Framework comes with
several synchronization API. Some of them are based on &lt;i&gt;Windows &lt;/i&gt;synchronization
primitives (events, mutex, semaphore) and some of them are implemented by the
CLR (&lt;i&gt;ReaderWriterLock&lt;/i&gt;). These API have been proven to be not optimal and even
buggy, &lt;a href="http://wesnerm.blogs.com/net_undocumented/2005/04/the_art_of_thre.html" target="_blank"&gt;with possible starvation phenomenon in some particular cases&lt;/a&gt;.&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:16pt;"&gt;The cost of synchronizing&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;The goal of
this post is to praise immutability and affinity over synchronization. There
are 2 killer arguments against synchronization:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;First,
immutability and affinity are so efficient &lt;i&gt;by-design&lt;/i&gt;
that once you go with them you won’t get anymore any concurrent access bug. Every experienced programmer knows that synchronizing accesses
to states is a real pain and generally ends-up in all sorts of
non-deterministic bugs very hard to pinpoint and correct.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;Second
immutability and affinity won’t hurt performance. Synchronizing thread accesses to states leads to thread-context-switches that
are extremely costly. Also, threads are very expensive resources that are
wasted each time a thread is put in a wait state. I agree that immutability
sometime provokes extra object creation but frankly, this is neglectable compare to
threading cost.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:16pt;"&gt;Why most of developers still
opt for synchronization? &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;First it is
a matter of education. Every programmer academic background comes with a course
on how to program in a multi-threaded environment with synchronization primitives.
This is an entertaining course illustrated with pleasent concurrent patterns and as
far as I know, tricks such as immutability and affinity are not presented.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Second, at
first glance immutability and affinity doesn’t seem to solve any problem. In both
case there are no shared and mutable states. And this is what programmers want:
being able to read and write a state from several threads. Just have a look at
this comment on &lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2008/01/13/immutable-types-understand-them-and-use-them.aspx" target="_blank"&gt;my blog post on immutability&lt;/a&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;



&lt;p class="MsoNormal"&gt;&lt;i&gt;&lt;span&gt;I&amp;#39;m doing concurrency because I want to
calculate lots of things in parallel. &amp;nbsp;I want them to change.
&amp;nbsp;Immutable types don&amp;#39;t help concurrency much. &amp;nbsp;Sure you can prevent
accidental changes to things that shouldn&amp;#39;t change. &amp;nbsp;Of course that&amp;#39;s just
as valuable when coding single threaded. &amp;nbsp;I really don&amp;#39;t think you can have
done much concurrent programming.&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:16pt;"&gt;Immutable object / Changing state&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Immutability
is more subtle than this. The string class is immutable for example. Did you
hear any programmer complain that he cannot code multi-threaded access to its
strings? No, and the non-obvious reason actually lies in how we consider the state’s
identity. A state is typically identified by an object and we write things
like:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;Person person = new Person(“Julien”);&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;person.FirstName = “Mathieu”;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;We also
write things like:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;string personFirstName = “Julien”;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;personFirstName = “Mathieu”;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;The
difference is that in the first case we have non-thread safe code because the
object &lt;i&gt;person &lt;/i&gt;can be read/write accessed by several threads. In the second case
the state &lt;i&gt;personFirstName &lt;/i&gt;had also been modified but now we won’t get
multi-threading issue because the string class is immutable and the same state
is handled by 2 different strings. We are losing the common one-to-one relation
between a state and the underlying object. In other words, the identity of the
state is not the object anymore but the value itself. But still, the state has
been changed! The programmer is now free to expose the new &lt;i&gt;“Mathieu”&lt;/i&gt; state to
other threads without any kind of synchronization infrastructure.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:16pt;"&gt;The beauty of thread /
resource affinity&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Thread /
Resource affinity is also a concept that deserves more attention. It promotes
task-oriented programming. A task is thoroughly executed by the same thread,
from A to Z, and its states are not visible from other tasks. One famous application of affinity is the way &lt;i&gt;win32/Windows Form&lt;/i&gt; works. For a given
form, all tasks are executed by the same thread, essentially
painting/refreshing/timer operations and input/mouse/keyboard event handlers.
The immense benefit that &lt;i&gt;Windows Form&lt;/i&gt; users get is that we can be sure that the
mouse click event handler won’t be triggered while the windows is re-painted.
Thus all the states maintained behind our form don’t need to be synchronized.
As we know, the down-side effect is that doing computation from the UI
thread leads to unresponsive UI, and this is why there are tricks such as the
&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx" target="_blank"&gt;BackgroundWorker&lt;/a&gt;
class to make it easy to trigger task on tier threads.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;To
implement affinity, personally I am not a fan of &lt;i&gt;ThreadStatic &lt;/i&gt;or &lt;i&gt;Thread Local
Storage&lt;/i&gt; because they both rely on costly &lt;i&gt;Windows &lt;/i&gt;and CLR internals. Also, I
remember &lt;a href="http://docs.msdnaa.net/ark_new3.0/cd3/content/Tech_System%20Programming.htm#title2_13" target="_blank"&gt;this article from Juval Lowy&lt;/a&gt; that explains how to implement
&lt;i&gt;ISynchronizeInvoke
&lt;/i&gt;but I especially remember how complicated and error-prone it is. I prefer to
implement affinity by myself by:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Preferring
to maintain states with thread affinity from method local variables instead of
object fields. Local variables are &lt;i&gt;by-design&lt;/i&gt;
bound to the current thread.&lt;/span&gt;&lt;/p&gt;



&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Writing
contracts about affinity. Concretely, all methods of a class begin with
something like:&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;Debug.Assert( MyHelperPlumbing.CurrentThreadIsInitialThread()
);&lt;/span&gt;&lt;/p&gt;









&lt;p class="MsoNormal"&gt;&lt;span&gt;The code is
less readable but as long as the language teams don’t provide DbC facilities we
don’t have the choice.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;We are
currently removing most of synchronized accesses from the code of &lt;i&gt;NDepend&lt;/i&gt;. This
is a needed refactoring that will greatly simplify the development of features we want to do next. I admit that managing changing states through
immutable objects sometime require some intellectual gymnastic. For example, if
the object tagged by a &lt;i&gt;DataGridViewRow &lt;/i&gt;is immutable, the tag property needs to
be updated when the state is changing. But clearly, this is a minor programming
exercise compare to synchronization nightmare.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=177650" width="1" height="1"&gt;</description></item><item><title>UI Matter: Make the simple things simple and hard things possible</title><link>http://agile.codebetter.com/blogs/patricksmacchia/archive/2008/04/28/ui-matter-make-the-simple-things-simple-and-hard-things-possible.aspx</link><pubDate>Mon, 28 Apr 2008 15:09:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:177254</guid><dc:creator>Patrick Smacchia</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://agile.codebetter.com/blogs/patricksmacchia/rsscomments.aspx?PostID=177254</wfw:commentRss><comments>http://agile.codebetter.com/blogs/patricksmacchia/archive/2008/04/28/ui-matter-make-the-simple-things-simple-and-hard-things-possible.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;i&gt;&lt;span&gt;Make the simple things simple and hard things
possible&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;IMHO, this tenet
applies perfectly in how UI should be designed. Typically, the most direct way
to use a UI control should result in the most awaited feature from a user
perspective (&lt;i&gt;make the simple things
simple&lt;/i&gt;). Then, some extra/hidden UI control facilities can be added to the
control to support more in-depth scenario (&lt;i&gt;make
hard things possible&lt;/i&gt;). &lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:16pt;"&gt;Case 1: NDepend Start Page&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;We tried to
apply this tenet in the&amp;nbsp;&lt;img src="http://www.NDepend.com" alt="" /&gt;&lt;a href="http://www.NDepend.com" target="_blank"&gt;NDepend&lt;/a&gt;
UI. For example, on the start page there is a DataGridView that lists the most
recent NDepend projects. We estimated that left-clicking a project should
result in loading the results of the most recent analysis done on this project.
This is clearly what the user wants most of the time. But sometime the user
might wish to do something else from a project: maybe she just wants to open
the project in order to view or tweak it, without being bothered with any
analysis result. Maybe she wants to open the result of an analysis done 3
months ago. This is why the DataGridView lets the user right click a project
and access to such options:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;img src="http://codebetter.com/blogs/patricksmacchia/UITenet1/UITenet_StartPage.png" alt="" /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:16pt;"&gt;Case 2: NDepend Project
Properties Page: Code to Analyze Panel&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;This tenet
also drove the way the Project Properties window has been designed. Basically,
a NDepend project is just a list of .NET assemblies to analyze. Even thought an
NDepend project can be made of dozens of options the Project Properties window
must reflect this simplicity at first glance. This is why the first things a
user see when editing a project is a DataGridView that can be populated with a
list of assemblies (eventually drag and dropped from Windows Explorer):&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;img src="http://codebetter.com/blogs/patricksmacchia/UITenet1/UITenet_ProjectPropertiesFolders.png" alt="" /&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Besides
assemblies of the application that must be analyzed, there is a list of tiers
assemblies, i.e assemblies referenced by the application assemblies, such as &lt;i&gt;mscorlib&lt;/i&gt; for example. The list of tier
assemblies is automatically populated and real-time refreshed from the list of
application assemblies. Thus, we hope that the user doesn’t perceive this
second list as a burden but more as interesting extra information.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Actually
listing some assemblies can sometime be a little trickier:&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;•&lt;span&gt; &lt;/span&gt;&lt;span&gt;Assemblies
of a same NDepend project can be located in different folders&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;

&lt;/p&gt;

&lt;p class="MsoNormal"&gt;•&lt;span&gt; When
working as a team, bin folders are usually rooted differently on the various
developers machines and build server machines. But only one NDepend project file
must be shared by all machines.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;•&lt;span&gt; &lt;/span&gt;&lt;span&gt;Microsoft
.NET Framework assemblies, such as &lt;i&gt;mscorlib &lt;/i&gt;or &lt;i&gt;System.Core&lt;/i&gt;, can be located in
some tricky folders such as &lt;i&gt;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727&lt;/i&gt; or &lt;i&gt;C:\Program
Files\Reference Assemblies\Microsoft\Framework\v3.5&lt;/i&gt;. And these folders can
slightly vary depending on your installation drive or if you are on a 32 or 64 bits
machine.&lt;/span&gt;&lt;/p&gt;







&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;To handle
this extra-complexity, there is a single button &lt;i&gt;View Folders&lt;/i&gt;. When clicking this button, a folder panel expands.
This folder panel let’s tweaks the list of folders that contains application
and tiers assemblies.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;•&lt;span&gt; &lt;/span&gt;&lt;span&gt;There is
an option &lt;i&gt;Relative Path Mode&lt;/i&gt; that
makes all folder referenced by the NDepend project relative to the folder where
the NDepend project file is located.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;•&lt;span&gt; &lt;/span&gt;&lt;span&gt;The .NET
Framework assemblies tricky folders are automatically referenced. These folders
are not impacted by the &lt;i&gt;Relative Path
Mode&lt;/i&gt; option because they depend on the .NET framework installation on the
current machine and not on the development working environment.&lt;/span&gt;&lt;/p&gt;







&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;img src="http://codebetter.com/blogs/patricksmacchia/UITenet1/UITenet_ProjectPropertiesFolders2.png" alt="" /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;The great consequence is that users that don’t need to cope with folders will never see this
panel since the list of folders is automatically filled up when application
assemblies get browsed. &lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;The problem
with this approach is that it is a bit scary: Do users that wish to tweak
folders will figured out that there is a whole deep folders panel? Or will she
skip the &lt;i&gt;View Folders&lt;/i&gt; button and
think that the tool is not well designed for real-world use?&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;So far, we
got only one user’s mail about how to handle folders so it seems that it is
worth trusting users when it comes to dig a bit into the UI to achieve what they
want to do.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:16pt;"&gt;Case 3: Red-Gate Ants Profiler
Filter Builder&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;An UI that
positively surprised me by abiding by the tenet is the &lt;img src="http://www.red-gate.com/Products/ants_profiler/index.htm" alt="" /&gt;&lt;a href="http://www.red-gate.com/Products/ants_profiler/index.htm" target="_blank"&gt;Red Gate Ants Profiler&lt;/a&gt;.
Typically, you end up with a DataGridView that lists thousands of methods
profiled. &lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;img src="http://codebetter.com/blogs/patricksmacchia/UITenet1/UITenet_Ants1.png" alt="" /&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;While you
can sort these methods by name or time spent in it by clicking the
corresponding columns, after a few minutes tinkering with this, you certainly
want to focus your attention on the performance of a small subset of methods. In
other words as a user I need to filter my methods according to certain
criterias. And the good news is that Ants is very good at this thanks to a
powerful filter builder that you get by right clicking any of the columns:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;img src="http://codebetter.com/blogs/patricksmacchia/UITenet1/UITenet_Ants2.png" alt="" /&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;img src="http://codebetter.com/blogs/patricksmacchia/UITenet1/UITenet_Ants3.png" alt="" /&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;And you,
do you obtain (or not) some success stories by applying the &lt;i&gt;Make the simple things simple and hard
things possible &lt;/i&gt;tenet?&lt;i&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=177254" width="1" height="1"&gt;</description></item><item><title>Diff tools to see source files changes</title><link>http://agile.codebetter.com/blogs/patricksmacchia/archive/2008/04/28/diff-tools-to-see-source-files-changes.aspx</link><pubDate>Mon, 28 Apr 2008 10:02:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:177243</guid><dc:creator>Patrick Smacchia</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://agile.codebetter.com/blogs/patricksmacchia/rsscomments.aspx?PostID=177243</wfw:commentRss><comments>http://agile.codebetter.com/blogs/patricksmacchia/archive/2008/04/28/diff-tools-to-see-source-files-changes.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;

&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;Making easy
to compare 2 versions of a code base is something that I consider super
important and that is why it became a major feature of &lt;a href="http://www.NDepend.com" target="_blank"&gt;NDepend&lt;/a&gt;&lt;/span&gt;&lt;a href="http://www.NDepend.com" target="_blank"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;. While source file repository tools
(a la VSS or CVS…) also provide this feature, the great thing with NDepend is
that changes are not considered just as text file modifications. For example
you can dissociate code change from comment change and from structural change
with these 3 CQL queries:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;SELECT&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;METHODS&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WHERE&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;CodeWasChanged&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;SELECT&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;METHODS&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WHERE&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;CommentsWereChanged&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;SELECT&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;METHODS&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WHERE&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;VisibilityWasChanged&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;…and there
are plenty of others trick supported, to see what is not used in a tiers
assembly or to see how the coupling has been impacted by code changes. These
are summarized in this &lt;a href="http://s3.amazonaws.com/NDependOnlineDemos/BuildComparison_viewlet_swf.html" target="_blank"&gt;3mn screencast&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;&lt;a href="http://s3.amazonaws.com/NDependOnlineDemos/BuildComparison_viewlet_swf.html"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; &lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Often
knowing where the code was changed is not enough, you want to see what was
changed by comparing older and newer versions of source files. This is useful
to focus code reviews on code that has been changed. &lt;b&gt;Doing so is a killer practice to rationalize code reviews and make the
most of it by often pinpointing subtle last-minutes bugs.&lt;/b&gt; Empirically, I
came to the conclusion that the bulk of bugs are luring inside the code that is
not yet in production, in other words, the code that has been refactored or added since the last release. I wrote an article on this topic: &lt;a href="http://searchwindevelopment.techtarget.com/tip/0,289483,sid8_gci1285059,00.html" target="_blank"&gt;How to avoid
regression bugs while adding new features&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://searchwindevelopment.techtarget.com/tip/0,289483,sid8_gci1285059,00.html"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; &lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;NDepend
used to rely on the good old &lt;a href="http://en.wikipedia.org/wiki/WinDiff" target="_blank"&gt;WinDiff&lt;/a&gt; &lt;/span&gt;&lt;span&gt;tool to compare 2 versions of a file:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="color:red;"&gt;&lt;img src="http://codebetter.com/blogs/patricksmacchia/SourceFileCompare/SourceFileCompare_CompareWithWinDiff.PNG" alt="" /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;One of the most
common feature request we got was to support any source files diff tools. Thus
we added this as an option, with a list of the most popular text diff tools
available:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="color:red;"&gt;&lt;img src="http://codebetter.com/blogs/patricksmacchia/SourceFileCompare/SourceFileCompare_ListOfTools.png" alt="" /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Notice that we want to make sure to provide a flexible support for any diff tool with the command line arguments tags $OldSrcFilePath$ and &lt;/span&gt;&lt;span&gt;$NewSrcFilePath$&lt;/span&gt;&lt;span&gt;. Thus, the list of tools is here to make it more convenient to bind NDepend with your prefered tool but you can still choose any tool outside the list. We also provided the tags &lt;/span&gt;&lt;span&gt;$OldSrcFileLine$ and &lt;/span&gt;&lt;span&gt;$NewSrcFileLine$ but surprisingly, none of the diff tool we tried support these command line arguments.&lt;/span&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;It was quite
interesting to churn the web for the most popular diff tools. It seems that
some free tools, especially &lt;a href="http://winmerge.org/" target="_blank"&gt;WinMerge&lt;/a&gt;&lt;/span&gt;&lt;span&gt;, sustain the comparison with
non-free tools. There are some passionate debates around which diff tools to
use, such as on the Jeff Atwood’s blog that praises for &lt;a href="http://www.codinghorror.com/blog/archives/000454.html" target="_blank"&gt;Beyond Compare&lt;/a&gt;&lt;/span&gt;&lt;span&gt;. There is also a feature I was not
aware: You can compare 3 versions of a file. This seems to be supported only by
&lt;a href="http://www.araxis.com/merge/topic_threeway_file_comparisons.html" target="_blank"&gt;KDiff3&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.araxis.com/merge/topic_threeway_file_comparisons.html"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;and &lt;a href="http://www.araxis.com/merge/topic_threeway_file_comparisons.html" target="_blank"&gt;Araxis Merge&lt;/a&gt;&lt;/span&gt;&lt;a href="http://www.araxis.com/merge/topic_threeway_file_comparisons.html"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;. One of the must-have feature that
most of tool supports is the ability to compare recursively 2 folders to see
which files have been deleted/added/changed.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Frankly, I haven’t tested thoroughly all tools. At first sight, &lt;a href="http://www.araxis.com/merge/index.html" target="_blank"&gt;Araxis Merge&lt;/a&gt;
seems to be the most featured one with &lt;a href="http://www.araxis.com/merge/topic_features.html" target="_blank"&gt;an impressive list of features&lt;/a&gt;&lt;/span&gt;&lt;span&gt; and I found it quite easy to grasp.
However this is also the most expensive one.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;The main
difference that I have found between free and commercial tools is on how the
tool got polished. By polish I mean things like: Is it localized, How smartly the
command are organized, Startup time, On-Line and Embedded Documentation, No UI
Freeze or user wait, No pesky crash, How cleverly the UI real-estate is used,
Options persistence and sharing.... However, let’s mention that the freeware &lt;a href="http://winmerge.org/" target="_blank"&gt;WinMerge&lt;/a&gt;&lt;/span&gt;&lt;a href="http://winmerge.org/"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; &lt;span&gt;is really polished.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;As the team
lead of a commercial tool for .NET developers, I found that indeed
polishing a software is the best (and only) way to extend the set of users from the enthusiast/early ones to the (much bigger) set of potentially interested users. For the development team
this is also a great satisfaction to be allowed to spend time on all minor but
important details. This is usually a burden list that tends to grow. There are
always numerous features in the pipe to add but &lt;/span&gt;&lt;span&gt;when the minor-TODO list gets shortened, you&amp;#39;ll notice &lt;/span&gt;&lt;span&gt;a lot of positive
energy and feedbacks.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;After this
digression, it is maybe worth providing the list of tools we found:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.araxis.com/merge/index.html" target="_blank"&gt;Araxis Merge&lt;/a&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;(commercial)
&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;&lt;a href="http://www.scootersoftware.com/" target="_blank"&gt;Beyond
Compare&lt;/a&gt; (commercial)&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.scootersoftware.com/"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; &lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;&lt;a href="http://www.grigsoft.com/wincmp3.htm" target="_blank"&gt;Compare It!&lt;/a&gt;
&lt;/span&gt;(commercial)&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.sourcegear.com/diffmerge/" target="_blank"&gt;DiffMerge&lt;/a&gt; (free)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;&lt;a href="http://www.prestosoft.com/edp_examdiff.asp" target="_blank"&gt;ExamDiff&lt;/a&gt;&lt;span&gt;&lt;a href="http://www.prestosoft.com/edp_examdiff.asp" target="_blank"&gt;&amp;nbsp;&lt;/a&gt; &lt;/span&gt;(commercial)&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.prestosoft.com/edp_examdiff.asp"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; &lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;&lt;a href="http://kdiff3.sourceforge.net/" target="_blank"&gt;KDiff3&lt;/a&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;(free)&amp;nbsp;&lt;/span&gt;&lt;a href="http://kdiff3.sourceforge.net/"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; &lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;&lt;a href="http://www.angusj.com/delphi/textdiff.html" target="_blank"&gt;TextDiff&lt;/a&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;(free)&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.angusj.com/delphi/textdiff.html"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; &lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=49ae8576-9bb9-4126-9761-ba8011fabf38&amp;amp;displaylang=en" target="_blank"&gt;WinDiff&lt;/a&gt;&lt;span&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=49ae8576-9bb9-4126-9761-ba8011fabf38&amp;amp;displaylang=en" target="_blank"&gt;&amp;nbsp;&lt;/a&gt; &lt;/span&gt;(free)&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=49ae8576-9bb9-4126-9761-ba8011fabf38&amp;amp;displaylang=en"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; &lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;&lt;a href="http://winmerge.org/" target="_blank"&gt;WinMerge&lt;/a&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;(free)&amp;nbsp;&lt;/span&gt;&lt;a href="http://winmerge.org/"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; &lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Finally, I
noticed a free diff tool that comes with an intuitive presentation of changes
but unfortunately it is only available on Unix. &lt;a href="http://www.caffeinated.me.uk/kompare/" target="_blank"&gt;Kompare&lt;/a&gt;: &lt;/span&gt;&lt;a href="http://www.caffeinated.me.uk/kompare/"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;img src="http://codebetter.com/blogs/patricksmacchia/SourceFileCompare/SourceFileCompare_Kompare.png" alt="" /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;a href="http://www.donationcoder.com/Reviews/Archive/CompareTools/index.html" target="_blank"&gt;Here&lt;/a&gt;
is a list of dream feature sets for diff tools (in praise of Beyond Compare) but
personally, such a simple and intuitive way to browse changes could make me prefer one diff
tool over the super-polished ones.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=177243" width="1" height="1"&gt;</description></item><item><title>NDepend presentation at MVP Summit</title><link>http://agile.codebetter.com/blogs/patricksmacchia/archive/2008/04/09/ndepend-presentation-at-mvp-summit.aspx</link><pubDate>Wed, 09 Apr 2008 10:28:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:176485</guid><dc:creator>Patrick Smacchia</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://agile.codebetter.com/blogs/patricksmacchia/rsscomments.aspx?PostID=176485</wfw:commentRss><comments>http://agile.codebetter.com/blogs/patricksmacchia/archive/2008/04/09/ndepend-presentation-at-mvp-summit.aspx#comments</comments><description>

&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&lt;span&gt;I will
present &lt;a href="http://www.NDepend.com"&gt;NDepend&lt;/a&gt; during the MVP summit. The schedule is one hour &lt;b&gt;Wednesday 16th at 5pm in MSCC/ Hood&lt;/b&gt;. It has
been well thought out since this doesn’t overlap with others MVP summit
presentations.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:10pt;"&gt;This
presentation is dedicated to MVP and RD.&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-bottom:0.0001pt;line-height:normal;"&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="font-size:10pt;"&gt;Another one is forecasted for MSFT on &lt;b&gt;April 14, 2008 4:00 PM-5:00 PM&amp;nbsp; Conf Room 41/5731 (18) AV&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;



&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;This
presentation will be a great occasion to talk about the future and to recap
NDepend main features: quality and metrics, dependencies management, visual
facilities, code snapshot comparison, custom CQL queries and rules, and the
&lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2008/04/09/make-the-most-of-your-test-coverage-data.aspx" target="_blank"&gt;brand new facilities to churn test coverage data&lt;/a&gt;.&lt;span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;I would
like to thank &lt;a href="http://blogs.msdn.com/kcwalina/" target="_blank"&gt;&lt;span class="hccdpe"&gt;Krzysztof Cwalina&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;a href="http://blogs.msdn.com/kcwalina/"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="hccdpe"&gt;&lt;span&gt;, Kit George and Kathy Carper for
their kind help in setting up this meeting.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=176485" width="1" height="1"&gt;</description></item><item><title>Make the most of your test coverage data</title><link>http://agile.codebetter.com/blogs/patricksmacchia/archive/2008/04/09/make-the-most-of-your-test-coverage-data.aspx</link><pubDate>Wed, 09 Apr 2008 08:28:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:176483</guid><dc:creator>Patrick Smacchia</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://agile.codebetter.com/blogs/patricksmacchia/rsscomments.aspx?PostID=176483</wfw:commentRss><comments>http://agile.codebetter.com/blogs/patricksmacchia/archive/2008/04/09/make-the-most-of-your-test-coverage-data.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;

&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;I am really
glad to announce that now &lt;a href="http://www.ndepend.com/" target="_blank"&gt;NDepend&lt;/a&gt;&lt;/span&gt;&lt;a href="http://www.ndepend.com/" target="_blank"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; &lt;span&gt;supports test coverage
metrics:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;a href="http://www.ndepend.com/Metrics.aspx#PercentageCoverage" target="_blank"&gt;&lt;span&gt;PercentageCoverage&lt;/span&gt;&lt;/a&gt;&lt;a href="http://www.ndepend.com/Metrics.aspx#PercentageCoverage"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;, &lt;a href="http://www.ndepend.com/Metrics.aspx#NbLinesOfCodeCovered" target="_blank"&gt;NbLinesOfCodeCovered&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.ndepend.com/Metrics.aspx#NbLinesOfCodeCovered"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;and &lt;a href="http://www.ndepend.com/Metrics.aspx#NbLinesOfCodeNotCovered" target="_blank"&gt;NbLinesOfCodeNotCovered&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;, defined on methods, types,
namespaces and assemblies. &lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;There is
also the metric &lt;a href="http://www.ndepend.com/Metrics.aspx#PercentageBranchCoverage" target="_blank"&gt;PercentageBranchCoverage&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.ndepend.com/Metrics.aspx#PercentageBranchCoverage"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;defined on methods.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Coverage
data are gathered from coverage files emitted by &lt;a href="http://www.ncover.com/" target="_blank"&gt;NCover 2.x&lt;/a&gt; &lt;/span&gt;&lt;span&gt;and &lt;a href="http://msdn.microsoft.com/teamsystem/" target="_blank"&gt;Visual Studio Team System 2005
or 2008&lt;/a&gt;&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/teamsystem/" target="_blank"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;So why is
it so great that NDepend now supports these metrics? After all both
&lt;i&gt;VisualStudio &lt;/i&gt;and &lt;i&gt;NCoverExplorer&lt;/i&gt;&lt;/span&gt;&lt;span&gt; present facilities to churn
coverage data. The cool thing is that integrating coverage metrics inside
NDepend and the CQL language opens up a wide range of brand new possibilities.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:18pt;"&gt;Continuously check for
coverage&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Typically,
you spend time making sure that your class &lt;b&gt;YourNamespace.YourClass&lt;/b&gt;
is 100% covered. But how can you make sure that in the future your class will
remain 100% covered across versions and evolutions? With NDepend and CQL 1.7
you just have to define the CQL rule:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WARN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IF&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;Count&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;gt; &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;0&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;SELECT&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;TYPES&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WHERE&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;FullNameIs&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;&amp;quot;YourNamespace.YourClass&amp;quot;&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;AND&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;PercentageCoverage&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;lt; &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;100&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;As we are
heavily using this facility on the code of NDepend itself, we found convenient
to define an attribute &lt;b&gt;NDepend.CQL.FullCoveredAttribute&lt;/b&gt;
in the assembly &lt;b&gt;NDepend.CQL.dll&lt;/b&gt;, Then we defined the rule: make sure that all types tagged with this attribute are 100%
covered. With CQL this results in:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WARN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IF&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;Count&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;gt; &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;0&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;SELECT&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;TYPES&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WHERE&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;HasAttribute&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;&amp;quot;NDepend.CQL.FullCoveredAttribute&amp;quot;&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;AND&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;PercentageCoverage&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;lt; &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;100&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;This is a
great way to scale on hundreds of classes fully covered. But also it helps
documenting the source code: when a developer is about to tweak such a class,
she can’t even forget covering all her modifications.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Alternatively,
if you think in terms of namespaces or assemblies thoroughly covered, you can
write such a rule:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WARN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IF&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;Count&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;gt; &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;0&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;SELECT&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;NAMESPACES&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WHERE&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;NameIs&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;&amp;quot;YourNamespace&amp;quot;&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;AND&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;PercentageCoverage&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;lt; &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;100&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Or:&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WARN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IF&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;Count&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;gt; &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;0&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;SELECT&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;ASSEMBLIES&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WHERE&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;HasAttribute&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;&amp;quot;NDepend.CQL.FullCoveredAttribute&amp;quot;&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;AND&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;PercentageCoverage&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;lt; &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;100&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Because
assembly has support for attribute while namespace don’t.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:18pt;"&gt;Focus coverage on sensitive
code &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;What is sensitive
code? In my last blog entry on &lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2008/03/30/towards-bug-free-code.aspx" target="_blank"&gt;practices to tend toward bug-free code&lt;/a&gt;&lt;/span&gt;&lt;span&gt; I explained that sensitive code
that will likely contains most of bugs you’ll get within the next release is:&lt;/span&gt;&lt;/p&gt;



&lt;ul&gt;&lt;li&gt;&lt;span&gt;Methods
that have been added since the last release.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;Methods
that have been refactored since the last release.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;Complex
methods.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;With CQL,
you can write rules to be warned when such sensitive code is not 100% covered.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:green;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;//&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:green;"&gt; Methods that have been added must be fully covered&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WARN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IF&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;Count&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;gt;
&lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;0&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;SELECT&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;METHODS&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WHERE&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WasAdded &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;AND&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;PercentageCoverage&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;lt; &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;100&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:green;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;//&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:green;"&gt; Methods that have been refactored must be fully covered&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WARN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IF&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;Count&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;gt;
&lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;0&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;SELECT&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;METHODS&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WHERE&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;CodeWasChanged &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;AND&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;PercentageCoverage&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;lt; &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;100&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:green;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;//&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:green;"&gt; Complex Methods must be fully covered&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WARN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IF&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;Count&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;gt;
&lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;0&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;SELECT&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;METHODS&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WHERE&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;(&lt;span&gt;CyclomaticComplexity &lt;/span&gt;&lt;span style="color:black;"&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;15&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;OR&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;NestingDepth&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;gt; &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;5&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;)&lt;span style="color:blue;"&gt; AND&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;PercentageCoverage&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;lt; &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;100&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;You can
also use the metric &lt;a href="http://www.ndepend.com/Metrics.aspx#MethodRank" target="_blank"&gt;MethodRank&lt;/a&gt;&lt;/span&gt;&lt;span&gt; to know which method is sensitive,
in the sense that if it contains a bug, this will likely be a catastrophic bug.
The trick is that methods with high &lt;i&gt;MethodRank &lt;/i&gt;are those that are the most
used.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:green;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;//&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:green;"&gt; The 100 most important methods must be fully covered&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WARN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IF&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;Count&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;gt;
&lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;0&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;IN&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;SELECT
TOP &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;100&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; METHODS&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;WHERE&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;PercentageCoverage&lt;/span&gt;&lt;span style="background:white none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt; &amp;lt; &lt;/span&gt;&lt;span style="background:yellow none repeat scroll 0% 50%;font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;100&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:black;"&gt; &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;ORDER BY &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;"&gt;MethodRank
&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;color:blue;"&gt;DESC&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:18pt;"&gt;Get an intuitive feeling of
how your code base is covered&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;The visual
facility supported by NDepend to display a set of code element that matches
some condition is especially useful when it comes to evaluate what is well or poorly
covered. For example, the following picture shows the methods fully covered in
NDepend. They represent 22.726 lines of code on 58.955.&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;a href="http://codebetter.com/blogs/patricksmacchia/Coverage/Coverage_2Big.png" target="_blank"&gt;&lt;img src="http://codebetter.com/blogs/patricksmacchia/Coverage/Coverage_2Small.png" alt="" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt; &lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;It is
interesting to compare this with the set of methods at least a bit covered (i.e
%coverage &amp;gt; 0). They represent 32.790 lines of code on 58.955.&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;a href="http://codebetter.com/blogs/patricksmacchia/Coverage/Coverage_1Big.png" target="_blank"&gt;&lt;img src="http://codebetter.com/blogs/patricksmacchia/Coverage/Coverage_1Small.png" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;span&gt;&lt;a href="http://codebetter.com/blogs/patricksmacchia/Coverage/Coverage_1Small.png"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/span&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:18pt;"&gt;Deal with ‘uncoverable code’&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;We all know
that 100% coverage of an entire code base is not feasable. Even if you are
really enthusiast about testing, some case just cannot be tested automatically.
Typically, a method that call &lt;b&gt;MessageBox.Show(…)&lt;/b&gt;
cannot be covered by unit tests because it requires a user action. This is why
NDepend has support for what we call &lt;i&gt;uncoverable
code&lt;/i&gt;. Project properties accept an attribute
that will tag uncoverable methods, &lt;/span&gt;&lt;span&gt;uncoverable &lt;/span&gt;&lt;span&gt;classes or &lt;/span&gt;&lt;span&gt;uncoverable &lt;/span&gt;&lt;span&gt;assemblies. Such tagged code
element won’t be taken account when computing coverage statistics. This will
let you write full coverage rule without being bothered by &lt;i&gt;uncoverable code&lt;/i&gt;.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;img src="http://codebetter.com/blogs/patricksmacchia/Coverage/Coverage_3.png" alt="" /&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:18pt;"&gt;Smart merge of coverage files &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Code coverage data is often spread across numerous coverage files. Thus NDepend
accepts a list of coverage files as input. A coverage file has a merge option
OR XOR AND or NONE. &lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Most of the
time you’ll use the option OR to merge your coverage files. But if you want to
know what is only covered by a particular file, you’ll need the option XOR. And
if you want to know what is the intersection of what is covered by all coverage
files, you’ll use the option AND. And finally the option NONE will be used to
temporarily disable some coverage files.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;img src="http://codebetter.com/blogs/patricksmacchia/Coverage/Coverage_4.png" alt="" /&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;You won’t
have to re-analyze your project to play with these options because they can
be computed on the fly on an analysis currently loaded.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;If you wish
to see all these facilities live, have a look at this &lt;a href="http://s3.amazonaws.com/NDependOnlineDemos/Coverage_viewlet_swf.html" target="_blank"&gt;3 minutes screencast&lt;/a&gt;.&lt;/span&gt;&lt;a href="http://s3.amazonaws.com/NDependOnlineDemos/Coverage_viewlet_swf.html"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; &lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Also,
details on how to import coverage data from coverage files are available &lt;a href="http://www.ndepend.com/Coverage.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;a href="http://www.ndepend.com/Coverage.aspx"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=176483" width="1" height="1"&gt;</description></item><item><title>Towards Bug-Free Code</title><link>http://agile.codebetter.com/blogs/patricksmacchia/archive/2008/03/30/towards-bug-free-code.aspx</link><pubDate>Sun, 30 Mar 2008 19:02:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:176071</guid><dc:creator>Patrick Smacchia</dc:creator><slash:comments>21</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://agile.codebetter.com/blogs/patricksmacchia/rsscomments.aspx?PostID=176071</wfw:commentRss><comments>http://agile.codebetter.com/blogs/patricksmacchia/archive/2008/03/30/towards-bug-free-code.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;

&lt;/p&gt;&lt;span&gt;The only
way to have bug-free code is to mathematically prove the code. Very few
programs in the world are mathematically proved. Some industry can afford the
price of a mathematical proof, especially when bugs would turn into human death,
such as embedded software in planes, trains or cars. Most of us are working on
projects that cannot afford the cost of a mathematical proof. We then rely on
some tricks to maintain our bug rate as low as possible. I classify these
tricks into 6 categories.&lt;/span&gt;



&lt;ul&gt;&lt;li&gt;&lt;span&gt;Contract&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;Automatic
test&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;Empirical approach&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;Code
review&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;Prioritizing
bugs fix over new features development&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;Programming
style and code quality&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;Static
Analysis Tools&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:18pt;"&gt;Contract&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;The idea of
contracts is to insert correctness information inside the code. When contract
is violated it means that your code contains a bug somewhere. Typically, the
.NET world is very poor in terms of contracts. Our only way to express contract
is to use the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.diagnostics.debug.assert.aspx" target="_blank"&gt;&lt;b&gt;System.Diagnostics.Debug.Assert(…)&lt;/b&gt;&lt;/a&gt;
method&lt;/span&gt;&lt;span&gt;. This is very unfortunate because
not only our code is blurred with numerous &lt;b&gt;Debug.Assert(…)&lt;/b&gt;
calls, but also the compilers cannot check contracts at compile-time. For
example the &lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2007/07/25/i-want-non-nullable-types-in-c-4.aspx" target="_blank"&gt;Spec#&lt;/a&gt;&lt;/span&gt;&lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2007/07/25/i-want-non-nullable-types-in-c-4.aspx" target="_blank"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2007/07/25/i-want-non-nullable-types-in-c-4.aspx" target="_blank"&gt;&lt;span&gt; non-nullable types&lt;/span&gt;&lt;/a&gt;&lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2007/07/25/i-want-non-nullable-types-in-c-4.aspx"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; is an excellent form of contract at
language level that help a lot avoiding pesky &lt;b&gt;NullReferenceException&lt;/b&gt;. And &lt;i&gt;Spec&lt;/i&gt;#
is far from being the only language that propose contract facilities, think
about what &lt;a href="http://en.wikipedia.org/wiki/Eiffel_%28programming_language%29" target="_blank"&gt;&lt;i&gt;Eiffel&lt;/i&gt;&lt;/a&gt;&lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Eiffel_%28programming_language%29" target="_blank"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt; &lt;span&gt;proposed more than twenty
years ago in terms of contract!&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;As I
believe in contract, I personally use a lot &lt;b&gt;Debug.Assert(…)&lt;/b&gt;. This represents around 15% of my code. I will
likely blog more on this because with all the buzz actually made around automatic
tests, I feel that contracts should deserve more attention.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:18pt;"&gt;Automatic test&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;I won’t
enumerate the numerous benefits of automatic tests and high code coverage ratio
here. The important thing to remember is that having a solid battery of
automatic tests is an excellent way to decrease significantly the bug rate on tested
code, but also to avoid new bugs when code gets refactored. As many, my
opinion is that the cost of writing automatic tests is worth the price compared
to the cost of maintaining not automatically tested code.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:18pt;"&gt;Empirical approach&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;What I call
empirical approachis a simple tenet that every seasoned programmer know: &lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;Most of bugs in a new version are
coming from modified code and brand new code&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;ul&gt;&lt;li&gt;&lt;span&gt;Unchanged code that works well for
a long time in production won&amp;#39;t likely crash within the next release (what we
call &lt;i&gt;stable code&lt;/i&gt;). We don&amp;#39;t say that stable code don&amp;#39;t contain bug, but
discovering a bug in stable code is rare.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;How do you know that some code works
well for a long time in production? Simply by listening to users. If they
didn’t report problems on some features for a long time then you can be
confident that underlying code is &lt;i&gt;stable&lt;/i&gt;.
Some might say that I consider here users as testers but don’t take me wrong, we
don’t have the choice. If you have real users, they will complain when they
will find a bug and they will remain silent when they consider that the product
is working fine. You are responsible to deliver correct code that will satisfy
users but why wouldn’t you infer statistics from their feedbacks to asses where
is your &lt;i&gt;stable/unstable&lt;/i&gt; code? &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;I wrote an
article about how we (the &lt;a href="http://www.NDepend.com" target="_blank"&gt;NDepend&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.ndepend.com/"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;team) use this simple but effective
idea and our own dog-food to &lt;a href="http://searchwindevelopment.techtarget.com/tip/0,289483,sid8_gci1285059,00.html#" target="_blank"&gt;avoid regression bugs while adding new features&lt;/a&gt;&lt;/span&gt;&lt;span&gt;. Basically we focus our code
reviews mainly on code that have been added or code that have been changed
since the last release and of course.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;

&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:18pt;"&gt;Code review&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Code
reviews are good to enhance quality and to educate programmers but I don’t
believe in the efficiency of code reviews to anticipate bugs. Even though some
portions of code can be fascinating to read, the bulk of a code base is tedious
and will make you lose your focus in less than an hour. The problem of code
review comes from the mass of code to read. This is why I advise to only
focus your review on not &lt;i&gt;stable code&lt;/i&gt;,
i.e added code and modified code. If you release new versions often, the mass
of code to review before each release will quickly become an &lt;i&gt;epsilon&lt;/i&gt; of the size of your entire code
base. Doing so can also be seen as a way to capitalize on code reviews made during previous iterations.&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:18pt;"&gt;&lt;b&gt;Prioritizing bugs fix over new features development&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;





&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;This popular methodology directly results from the concept of &lt;i&gt;stable &lt;/i&gt;code. &lt;/span&gt;&lt;span&gt;Prioritizing
bugs fix over new features development can be seen as a way to constantly struggle to maximize the surface of &lt;i&gt;stable &lt;/i&gt;code in our code base.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:18pt;"&gt;Programming style and code
quality&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;The recent
buzz around &lt;i&gt;LINQ&lt;/i&gt; or &lt;a href="http://research.microsoft.com/fsharp/fsharp.aspx" target="_blank"&gt;&lt;i&gt;F#&lt;/i&gt;&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://research.microsoft.com/fsharp/fsharp.aspx"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;comes from the fact that object
style programming is more bug-prone than functional style programming. This
fact results from the expressiveness of functional style. In other words,
functional code is easier to read and understand. A major aspect of the
expressiveness of functional programming style is IMHO the concept of
immutability that I described in a previous blog post &lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2008/01/13/immutable-types-understand-them-and-use-them.aspx" target="_blank"&gt;Immutable types:
understand their benefits and use them&lt;/a&gt;&lt;/span&gt;&lt;span&gt;. That’s a fact, it is hard to
write, understand and maintain code that mutates states at runtime (for example
this is why global variables are so harmful). And this becomes much harder in
concurrent environment.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;Obviously, code
quality has also a direct impact on code correctness. Anti pattern such as methods
with high &lt;a href="http://www.ndepend.com/Metrics.aspx#NbLinesOfCode" target="_blank"&gt;LOC&lt;/a&gt;,
high &lt;a href="http://www.ndepend.com/Metrics.aspx#CC" target="_blank"&gt;Cyclomatic Complexity&lt;/a&gt; or
high &lt;a href="http://www.ndepend.com/Metrics.aspx#ILNestingDepth" target="_blank"&gt;Nesting Depth&lt;/a&gt;, entangled components, methods with multiple concerns, classes with multiple responsibilities…
leads to code harder to debug and to test.&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:18pt;"&gt;Static Analysis Tools&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;We all
dream of a static analyzer that could pinpoint automatically bugs in our code
by just pushing an &lt;i&gt;Analyze&lt;/i&gt; button. Some
tools are already able to detect naïve mistakes, such as calling a method with
a null reference as parameters where there are no tests of parameter nullity
(i.e interprocedural analysis).&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;But most
bugs are not that easy to pinpoint. By just analyzing the code a tool cannot distinguish
between a feature and a bug because it doesn’t know how the application should
behave. Some heuristic exists but still, to be efficient, a &lt;i&gt;bug finder&lt;/i&gt; static analyzer needs to be
feed with more information than just the code. Typically, this extra
information can be found in contracts and unit-tests code. As far as I know,
in the .NET area there are 2 projects revolving around this idea &lt;a href="http://wesnerm.blogs.com/net_undocumented/" target="_blank"&gt;NStatic&lt;/a&gt;
and &lt;a href="http://research.microsoft.com/Pex/" target="_blank"&gt;Pex&lt;/a&gt;,
and I am really looking forward to use them on my own code. &lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:18pt;"&gt;Conclusion&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;From what I
understand from the agile trend, having a bug-free product to release shouldn’t
be the goal. Anyway, every program not mathematically proved has bugs. The goal
should then be to tend toward a bug-free product by applying as many correctness
tricks as possible.&lt;/span&gt;&lt;/p&gt;

&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=176071" width="1" height="1"&gt;</description><category domain="http://agile.codebetter.com/blogs/patricksmacchia/archive/tags/Featured/default.aspx">Featured</category></item><item><title>Number of Types in the .NET Framework (2)</title><link>http://agile.codebetter.com/blogs/patricksmacchia/archive/2008/03/19/number-of-types-in-the-net-framework-2.aspx</link><pubDate>Wed, 19 Mar 2008 12:05:00 GMT</pubDate><guid isPermaLink="false">d21fbbc9-c112-4f32-ad14-95939a2c53d4:175573</guid><dc:creator>Patrick Smacchia</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://agi