<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Laputa</title>
    <link>http://laputa.sharpdevelop.net/</link>
    <description>The Web log of the #develop team</description>
    <language>en-us</language>
    <copyright>SharpDevelop Core Team</copyright>
    <lastBuildDate>Tue, 01 Apr 2008 07:13:48 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>team@icsharpcode.net</managingEditor>
    <webMaster>team@icsharpcode.net</webMaster>
    <item>
      <trackback:ping>http://laputa.sharpdevelop.net/Trackback.aspx?guid=f1145c1c-3278-4d96-8cf3-539ed0cdc2a5</trackback:ping>
      <pingback:server>http://laputa.sharpdevelop.net/pingback.aspx</pingback:server>
      <pingback:target>http://laputa.sharpdevelop.net/PermaLink,guid,f1145c1c-3278-4d96-8cf3-539ed0cdc2a5.aspx</pingback:target>
      <dc:creator>Daniel Grunwald</dc:creator>
      <wfw:comment>http://laputa.sharpdevelop.net/CommentView,guid,f1145c1c-3278-4d96-8cf3-539ed0cdc2a5.aspx</wfw:comment>
      <wfw:commentRss>http://laputa.sharpdevelop.net/SyndicationService.asmx/GetEntryCommentsRss?guid=f1145c1c-3278-4d96-8cf3-539ed0cdc2a5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Starting with version 3.0.0.3010, the C# code completion in SharpDevelop has support
for implicitly typed lambda expressions.
</p>
        <p>
Given a variable "IEnumerable&lt;MyClass&gt; items" and the "Select" extension method
from LINQ, typing "items.Select(i =&gt; i." now shows the members of MyClass. And
if the result of the Select call is assigned to an implicitly typed variable, SharpDevelop
is now able to infer that the variable has the type IEnumerable&lt;return type of
the lambda expression&gt;.
</p>
        <p>
Unlike all other expressions in C#, the type of a lambda expression cannot be inferred
just from by at the expression itself (and the variables used by the expression).
To resolve lambda type parameters, we also need to look at the <strong>context</strong> where
the lambda is used. Currently, not all contexts are supported by code-completion,
you can find the <a href="http://bugtracker.sharpdevelop.net/Issues.aspx?m=1&amp;c=1&amp;v=53">list
of known problems</a> in our bugtracker (Component: DOM / Resolver). Should you find
anything where code-completion does not work correctly which is not in that list,
please file a bug report in our forum.
</p>
        <p>
The most commonly used context for lambda expressions is method calls, and this is
also the most difficult thing to support. It's easy when the method has a clear
signature like "void M(Func&lt;int, string&gt; f)", since then SharpDevelop can <strong>infer
the lambda parameter types</strong> directly from the delegate type. But most of the
time, things aren't that easy. For example, the signature of the Select method is
"IEnumerable&lt;R&gt; Select&lt;T, R&gt;(this IEnumerable&lt;T&gt; input, Func&lt;T,
R&gt; f)". Here, SharpDevelop needs to first infer what T is, then it can know what
the lambda parameter types are, and only after that it can resolve the lambda expression
to infer what R is.
</p>
        <p>
But when the method has multiple overloads, things can get even more messy:<br />
When a method has to overloads "<font face="Courier New">void M(Func&lt;string, int&gt;
f)</font>" and "<font face="Courier New">void M(Func&lt;int, int&gt; f)</font>", it
is valid to call them like this: "<font face="Courier New">F(i=&gt;i.Length)</font>",
"<font face="Courier New">F(i=&gt;i+i)</font>". In the first call, <font face="Courier New">i</font> is
a string; in the second, it is int. What SharpDevelop needs to do here is to infer
the lambda parameter types for each overload separately, infer the lambda's return
type; and then check that against the delegate's signature to see which overload was
the correct one.
</p>
        <p>
          <font face="Courier New">i=&gt;i.Length</font> is a resolve error if <font face="Courier New">i</font> would
be int, but returns the expected int if <font face="Courier New">i</font> is
string; so <font face="Courier New">i</font> must resolve to string.<br /><font face="Courier New">i=&gt;i+i</font> returns a string if <font face="Courier New">i</font> would
be string, but returns the expected int if <font face="Courier New">i</font> is
int; so <font face="Courier New">i</font> must resolve to int.
</p>
        <p>
Note that because there's no way to tell the type of <font face="Courier New">i</font> before
the lambda expression is completed, you cannot expect that SharpDevelop gives you
correct code completion for it. "Length" will not be included in the code-completion
list for <font face="Courier New">i</font> when you type ".", because at that
point, the method call is "F(i=&gt;i)", and <font face="Courier New">i</font> is
thus an int. But after the expression is written, SharpDevelop will show a tooltip
for "Length", and features like "Go to definiton" and "Find references" will work.
</p>
        <img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=f1145c1c-3278-4d96-8cf3-539ed0cdc2a5" />
      </body>
      <title>Implicit lambda parameter type inference</title>
      <guid isPermaLink="false">http://laputa.sharpdevelop.net/PermaLink,guid,f1145c1c-3278-4d96-8cf3-539ed0cdc2a5.aspx</guid>
      <link>http://laputa.sharpdevelop.net/ImplicitLambdaParameterTypeInference.aspx</link>
      <pubDate>Tue, 01 Apr 2008 07:13:48 GMT</pubDate>
      <description>&lt;p&gt;
Starting with version 3.0.0.3010, the C# code completion in SharpDevelop has support
for implicitly typed lambda expressions.
&lt;/p&gt;
&lt;p&gt;
Given a variable "IEnumerable&amp;lt;MyClass&amp;gt; items" and the "Select" extension method
from LINQ, typing "items.Select(i =&amp;gt; i." now shows the members of MyClass. And
if the result of the Select call is assigned to an implicitly typed variable, SharpDevelop
is now able to infer that the variable has the type IEnumerable&amp;lt;return type of
the lambda expression&amp;gt;.
&lt;/p&gt;
&lt;p&gt;
Unlike all other expressions in C#, the type of a lambda expression cannot be inferred
just from by at the expression itself (and the variables used by the expression).
To resolve lambda type parameters, we also need to look at the &lt;strong&gt;context&lt;/strong&gt; where
the lambda is used. Currently, not all contexts are supported by code-completion,
you can find the &lt;a href="http://bugtracker.sharpdevelop.net/Issues.aspx?m=1&amp;amp;c=1&amp;amp;v=53"&gt;list
of known problems&lt;/a&gt; in our bugtracker (Component: DOM / Resolver). Should you find
anything&amp;nbsp;where code-completion does not work correctly which is not in that list,
please file a bug report in our forum.
&lt;/p&gt;
&lt;p&gt;
The most commonly used context for lambda expressions is method calls, and this is
also the most difficult thing to support. It's easy when the&amp;nbsp;method has a clear
signature like "void M(Func&amp;lt;int, string&amp;gt; f)", since then SharpDevelop can &lt;strong&gt;infer
the lambda parameter types&lt;/strong&gt; directly from the delegate type. But most of the
time, things aren't that easy. For example, the signature of the Select method is
"IEnumerable&amp;lt;R&amp;gt; Select&amp;lt;T, R&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; input, Func&amp;lt;T,
R&amp;gt; f)". Here, SharpDevelop needs to first infer what T is, then it can know what
the lambda parameter types are, and only after that it can resolve the lambda expression
to infer what R is.
&lt;/p&gt;
&lt;p&gt;
But when the method has multiple overloads, things can get even more messy:&lt;br&gt;
When a method has to overloads "&lt;font face="Courier New"&gt;void M(Func&amp;lt;string, int&amp;gt;
f)&lt;/font&gt;" and "&lt;font face="Courier New"&gt;void M(Func&amp;lt;int, int&amp;gt; f)&lt;/font&gt;", it
is valid to call them like this: "&lt;font face="Courier New"&gt;F(i=&amp;gt;i.Length)&lt;/font&gt;",
"&lt;font face="Courier New"&gt;F(i=&amp;gt;i+i)&lt;/font&gt;". In the first call, &lt;font face="Courier New"&gt;i&lt;/font&gt; is
a string; in the second, it is int. What SharpDevelop needs to do here is to infer
the lambda parameter types for each overload separately, infer the lambda's return
type; and then check that against the delegate's signature to see which overload was
the correct one.
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;i=&amp;gt;i.Length&lt;/font&gt; is a&amp;nbsp;resolve&amp;nbsp;error if &lt;font face="Courier New"&gt;i&lt;/font&gt;&amp;nbsp;would
be int,&amp;nbsp;but&amp;nbsp;returns the expected int if &lt;font face="Courier New"&gt;i&lt;/font&gt; is
string; so &lt;font face="Courier New"&gt;i&lt;/font&gt; must resolve to string.&lt;br&gt;
&lt;font face="Courier New"&gt;i=&amp;gt;i+i&lt;/font&gt; returns a string if &lt;font face="Courier New"&gt;i&lt;/font&gt; would
be string, but&amp;nbsp;returns the expected int if &lt;font face="Courier New"&gt;i&lt;/font&gt; is
int; so &lt;font face="Courier New"&gt;i&lt;/font&gt; must resolve to int.
&lt;/p&gt;
&lt;p&gt;
Note that because there's no way to tell the type of&amp;nbsp;&lt;font face="Courier New"&gt;i&lt;/font&gt; before
the lambda expression is completed, you cannot expect that SharpDevelop gives you
correct code completion for it.&amp;nbsp;"Length" will not be included in the code-completion
list for&amp;nbsp;&lt;font face="Courier New"&gt;i&lt;/font&gt; when you type ".", because at that
point, the method call is "F(i=&amp;gt;i)", and&amp;nbsp;&lt;font face="Courier New"&gt;i&lt;/font&gt; is
thus an int. But after the expression is written, SharpDevelop will show a tooltip
for "Length", and features like "Go to definiton" and "Find references" will work.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=f1145c1c-3278-4d96-8cf3-539ed0cdc2a5" /&gt;</description>
      <comments>http://laputa.sharpdevelop.net/CommentView,guid,f1145c1c-3278-4d96-8cf3-539ed0cdc2a5.aspx</comments>
      <category>Daniel</category>
    </item>
    <item>
      <trackback:ping>http://laputa.sharpdevelop.net/Trackback.aspx?guid=87aadbb6-561f-4a0a-a7f2-27bcaf6e17ef</trackback:ping>
      <pingback:server>http://laputa.sharpdevelop.net/pingback.aspx</pingback:server>
      <pingback:target>http://laputa.sharpdevelop.net/PermaLink,guid,87aadbb6-561f-4a0a-a7f2-27bcaf6e17ef.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://laputa.sharpdevelop.net/CommentView,guid,87aadbb6-561f-4a0a-a7f2-27bcaf6e17ef.aspx</wfw:comment>
      <wfw:commentRss>http://laputa.sharpdevelop.net/SyndicationService.asmx/GetEntryCommentsRss?guid=87aadbb6-561f-4a0a-a7f2-27bcaf6e17ef</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In addition to our presence on SourceForge (<a href="http://sourceforge.net/projects/sharpdevelop">project
page</a>) we now also set up shop at CodePlex (<a href="http://www.codeplex.com/SharpDevelop">project
page</a>). The motivation for this step is to increase awareness about SharpDevelop,
and how parts of SharpDevelop can be reused in other applications / scenarios.
</p>
        <img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=87aadbb6-561f-4a0a-a7f2-27bcaf6e17ef" />
      </body>
      <title>SharpDevelop Now on CodePlex Too</title>
      <guid isPermaLink="false">http://laputa.sharpdevelop.net/PermaLink,guid,87aadbb6-561f-4a0a-a7f2-27bcaf6e17ef.aspx</guid>
      <link>http://laputa.sharpdevelop.net/SharpDevelopNowOnCodePlexToo.aspx</link>
      <pubDate>Tue, 04 Mar 2008 11:42:29 GMT</pubDate>
      <description>&lt;p&gt;
In addition to our presence on SourceForge (&lt;a href="http://sourceforge.net/projects/sharpdevelop"&gt;project
page&lt;/a&gt;) we now also set up shop at CodePlex (&lt;a href="http://www.codeplex.com/SharpDevelop"&gt;project
page&lt;/a&gt;). The motivation for this step is to increase awareness about SharpDevelop,
and how parts of SharpDevelop can be reused in other applications / scenarios.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=87aadbb6-561f-4a0a-a7f2-27bcaf6e17ef" /&gt;</description>
      <comments>http://laputa.sharpdevelop.net/CommentView,guid,87aadbb6-561f-4a0a-a7f2-27bcaf6e17ef.aspx</comments>
      <category>Chris</category>
    </item>
    <item>
      <trackback:ping>http://laputa.sharpdevelop.net/Trackback.aspx?guid=fd64e057-133f-4b64-89ce-8f26d8cc8633</trackback:ping>
      <pingback:server>http://laputa.sharpdevelop.net/pingback.aspx</pingback:server>
      <pingback:target>http://laputa.sharpdevelop.net/PermaLink,guid,fd64e057-133f-4b64-89ce-8f26d8cc8633.aspx</pingback:target>
      <dc:creator>Daniel Grunwald</dc:creator>
      <wfw:comment>http://laputa.sharpdevelop.net/CommentView,guid,fd64e057-133f-4b64-89ce-8f26d8cc8633.aspx</wfw:comment>
      <wfw:commentRss>http://laputa.sharpdevelop.net/SyndicationService.asmx/GetEntryCommentsRss?guid=fd64e057-133f-4b64-89ce-8f26d8cc8633</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In SharpDevelop 1.1, the IClass interface had a property that was used in several
places in the code:<br />
Once added to a project content, it was <strong>immutable</strong>. This was not enforced,
not even documented. It just happened that no one changed IClass objects except for
the code constructing them. After being added to a project content, a class could
be removed or replaced by a new version, but if some code still held a reference to
an old instance, it could safely access the members without worrying that an update
to the class on another thread changed something.
</p>
        <p>
IClass objects are accessed without locks all over the place on the main thread during
code completion, and updates on the parser thread should not interfere with that.
</p>
        <p>
However, because I didn't understand this, I broke it in SharpDevelop 2.0. My implementation
of <strong>partial classes</strong> works as following: each file (compilation unit)
contributes a part of the class as IClass object representing that part of the class.<br />
Once multiple files register a part of the class in the project content, the project
content creates a <strong>compound class</strong>. This compound class combines the
members of all the parts. When updating a part, only the IClass for that part was
recreated, and the existing CompoundClass was updated.
</p>
        <img src="http://laputa.sharpdevelop.net/content/binary/mutation.jpg" align="right" border="0" />
        <p>
The CompoundClass, which could be in use by multiple threads, changed values. To quote <a href="http://blogs.msdn.com/wesdyer/archive/2007/03/01/immutability-purity-and-referential-transparency.aspx">Wes
Dyer</a>: "Mutation often seems to just cause problems."
</p>
        <p>
Now, that happened to work correctly for quite some time. Most code iterating through
a class' members did this with<br /><font face="Courier New">foreach (IMethod method in c.Methods) {<br />
}</font><br />
where c is an IClass (possibly a CompoundClass). An update of the compound class happened
to recreate the List&lt;IMethod&gt; behind the c.Methods property, so this code continued
to work as expected.
</p>
        <p>
However, in the quick class browser (the two combo boxes above the code window), there
was code similar to this:<br /><font face="Courier New">list.AddRange(c.Methods);<br />
list.Sort();<br />
list.AddRange(c.Properties);<br />
list.Sort(c.Methods.Count, c.Properties.Count); // sort the properties without mixing
them up with the methods</font></p>
        <p>
Suddenly, due to the addition of partial classes, this became a <strong>race condition</strong> waiting
to happen. But it was found in time for the SharpDevelop 2.0 release, and I fixed
the crash.<br />
But I didn't know much about immutability back then, so what I did was the worst fix
possible:<br /><font face="Courier New">lock (c) { ... }</font><br />
And in CompoundClass, during update of the parts: <font face="Courier New">lock (this)
{ ... }</font></p>
        <p>
Now, this is not only bad because it's fixing the symptom instead of the problem and
it leaves the possibility for similar problems elsewhere in the code - though it might
have been the only instance of the problem, since no other crashes due to this have
been found while SharpDevelop was using the fix (all 2.x releases use it, including
the current stable release, SharpDevelop 2.2.1).
</p>
        <p>
But multi-threading (without immutability) is not hard, it's <strong>really, really
hard</strong>. So it's not really surprising that some day, I found this code to <strong>deadlock</strong>.
</p>
        <p>
So where's the deadlock?<br />
First I must tell you the other lock we're colliding with: every project content has
a lock that it uses to ensure that GetClass() calls are not happening concurrently
when the list of classes is updated. So the parser thread acquires the project content
lock and then the CompoundClass lock to update the CompoundClass.
</p>
        <p>
But why would the AddRange / Sort code deadlock with this? The comparer used for list.Sort()
sorts the members alphabetically using their language-specific conversion to string.
In the case of methods, this includes the parameter list, including the parameter
types.
</p>
        <p>
What you need to know here is that type references (IReturnType objects) are not immutable
- they need to always reference the newest version of the class, as we cannot afford
rebuilding all IReturnType objects from all classes in the solution whenever any class
changes. Now remember that C# allows code like "<font face="Courier New">using
Alias = System.String; class Test { void Method(Alias parameter) {} }</font>".
</p>
        <p>
In this case, the quick class browser correctly resolves the alias and reports "Method(string
parameter)". This means that our Sort() call actually sometimes needs to resolve types!
And resolving types works using IProjectContent.SearchType, which locks on the project
contents' class list lock. And that's our deadlock.
</p>
        <p>
I think it's near impossible to find this kind of deadlock until it occurs and you
can see the call stacks of the two blocked threads.<br />
Remember that the actual Method-&gt;string conversion and the type resolving is language-specific;
it may or may not happen to take a lock for other language binding AddIns.
</p>
        <p>
I fixed the deadlock on trunk (SharpDevelop 3.0) a few months ago by removing the
lock on CompoundClass and instead doing this: 
<br /><font face="Courier New">list.AddRange(c.Methods);<br />
list.Sort();<br />
int count = list.Count;<br />
list.AddRange(c.Properties);<br />
list.Sort(count, list.Count - count);</font></p>
        <p>
It's still a hack, but this doesn't have any side effects (like taking a lock). And
it works correctly under our (new) rule (undocumented rule, aka. <em>assumption</em>)
that multiple c.get_Methods calls may return different collections, but the collection's
contents don't change.
</p>
        <p>
"<font face="Courier New">foreach (IMethod method in c.Methods) { ... }</font>" is
safe, but "<font face="Courier New">for (int i = 0; i &lt; c.Methods.Count; i++) {
IMethod method = c.Methods[i]; ... }</font>" can crash.
</p>
        <p>
But that's quite a difficult rule compared to "IClass never changes". So after reading
Erip Lippert's <a href="http://blogs.msdn.com/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx">series
on immutability</a>, I finally decided to <strong>make IClass immutable again</strong>.
</p>
        <p>
It's "popsicle immutability", that means IClass instances are mutable, but when the
Freeze() method is called, they become immutable. And this time, immutability is <strong>enforced</strong>,
trying to change a property of a frozen IClass will cause an exception. Adding
an IClass to a project content will cause it to freeze if it isn’t already frozen,
so it's guaranteed that IClass objects returned by GetClass or by some type reference
are immutable.
</p>
        <img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=fd64e057-133f-4b64-89ce-8f26d8cc8633" />
      </body>
      <title>IClass Immutability</title>
      <guid isPermaLink="false">http://laputa.sharpdevelop.net/PermaLink,guid,fd64e057-133f-4b64-89ce-8f26d8cc8633.aspx</guid>
      <link>http://laputa.sharpdevelop.net/IClassImmutability.aspx</link>
      <pubDate>Sat, 26 Jan 2008 23:30:59 GMT</pubDate>
      <description>&lt;p&gt;
In SharpDevelop 1.1, the IClass interface had a property that was used in several
places in the code:&lt;br&gt;
Once added to a project content, it was &lt;strong&gt;immutable&lt;/strong&gt;. This was not enforced,
not even documented. It just happened that no one changed IClass objects except for
the code constructing them. After being added to a project content, a class could
be removed or replaced by a new version, but if some code still held a reference to
an old instance, it could safely access the members without worrying that an update
to the class on another thread changed something.
&lt;/p&gt;
&lt;p&gt;
IClass objects are accessed without locks all over the place on the main thread during
code completion, and updates on the parser thread should not interfere with that.
&lt;/p&gt;
&lt;p&gt;
However, because I didn't understand this, I broke it in SharpDevelop 2.0. My implementation
of &lt;strong&gt;partial classes&lt;/strong&gt; works as following: each file (compilation unit)
contributes a part of the class as IClass object representing that part of the class.&lt;br&gt;
Once multiple files register a part of the class in the project content, the project
content creates a &lt;strong&gt;compound class&lt;/strong&gt;. This compound class combines the
members of all the parts. When updating a part, only the IClass for that part was
recreated, and the existing CompoundClass was updated.
&lt;/p&gt;
&lt;img src="http://laputa.sharpdevelop.net/content/binary/mutation.jpg" align=right border=0&gt; 
&lt;p&gt;
The CompoundClass, which could be in use by multiple threads, changed values. To quote &lt;a href="http://blogs.msdn.com/wesdyer/archive/2007/03/01/immutability-purity-and-referential-transparency.aspx"&gt;Wes
Dyer&lt;/a&gt;: "Mutation often seems to just cause problems."
&lt;/p&gt;
&lt;p&gt;
Now, that happened to work correctly for quite some time. Most code iterating through
a class' members did this with&lt;br&gt;
&lt;font face="Courier New"&gt;foreach (IMethod method in c.Methods) {&lt;br&gt;
}&lt;/font&gt;
&lt;br&gt;
where c is an IClass (possibly a CompoundClass). An update of the compound class happened
to recreate the List&amp;lt;IMethod&amp;gt; behind the c.Methods property, so this code continued
to work as expected.
&lt;/p&gt;
&lt;p&gt;
However, in the quick class browser (the two combo boxes above the code window), there
was code similar to this:&lt;br&gt;
&lt;font face="Courier New"&gt;list.AddRange(c.Methods);&lt;br&gt;
list.Sort();&lt;br&gt;
list.AddRange(c.Properties);&lt;br&gt;
list.Sort(c.Methods.Count, c.Properties.Count); // sort the properties without mixing
them up with the methods&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Suddenly, due to the addition of partial classes, this became a &lt;strong&gt;race condition&lt;/strong&gt; waiting
to happen. But it was found in time for the SharpDevelop 2.0 release, and I fixed
the crash.&lt;br&gt;
But I didn't know much about immutability back then, so what I did was the worst fix
possible:&lt;br&gt;
&lt;font face="Courier New"&gt;lock (c) { ... }&lt;/font&gt;
&lt;br&gt;
And in CompoundClass, during update of the parts: &lt;font face="Courier New"&gt;lock (this)
{ ... }&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Now, this is not only bad because it's fixing the symptom instead of the problem and
it leaves the possibility for similar problems elsewhere in the code - though it might
have been the only instance of the problem, since no other crashes due to this have
been found while SharpDevelop was using the fix (all 2.x releases use it, including
the current stable release, SharpDevelop 2.2.1).
&lt;/p&gt;
&lt;p&gt;
But multi-threading (without immutability) is not hard, it's &lt;strong&gt;really, really
hard&lt;/strong&gt;. So it's not really surprising that some day, I found this code to &lt;strong&gt;deadlock&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
So where's the deadlock?&lt;br&gt;
First I must tell you the other lock we're colliding with: every project content has
a lock that it uses to ensure that GetClass() calls are not happening concurrently
when the list of classes is updated. So the parser thread acquires the project content
lock and then the CompoundClass lock to update the CompoundClass.
&lt;/p&gt;
&lt;p&gt;
But why would the AddRange / Sort code deadlock with this? The comparer used for list.Sort()
sorts the members alphabetically using their language-specific conversion to string.
In the case of methods, this includes the parameter list, including the parameter
types.
&lt;/p&gt;
&lt;p&gt;
What you need to know here is that type references (IReturnType objects) are not immutable
- they need to always reference the newest version of the class, as we cannot afford
rebuilding all IReturnType objects from all classes in the solution whenever any class
changes. Now remember that C# allows code&amp;nbsp;like "&lt;font face="Courier New"&gt;using
Alias = System.String; class Test { void Method(Alias parameter) {} }&lt;/font&gt;".
&lt;/p&gt;
&lt;p&gt;
In this case, the quick class browser correctly resolves the alias and reports "Method(string
parameter)". This means that our Sort() call actually sometimes needs to resolve types!
And resolving types works using IProjectContent.SearchType, which locks on the project
contents' class list lock. And that's our deadlock.
&lt;/p&gt;
&lt;p&gt;
I think it's near impossible to find this kind of deadlock until it occurs and you
can see the call stacks of the two blocked threads.&lt;br&gt;
Remember that the actual Method-&amp;gt;string conversion and the type resolving is language-specific;
it may or may not happen to take a lock for other language binding AddIns.
&lt;/p&gt;
&lt;p&gt;
I fixed the deadlock on trunk (SharpDevelop 3.0) a few months ago by removing the
lock on CompoundClass and instead doing this: 
&lt;br&gt;
&lt;font face="Courier New"&gt;list.AddRange(c.Methods);&lt;br&gt;
list.Sort();&lt;br&gt;
int count = list.Count;&lt;br&gt;
list.AddRange(c.Properties);&lt;br&gt;
list.Sort(count, list.Count - count);&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
It's still a hack, but this doesn't have any side effects (like taking a lock). And
it works correctly under our (new) rule (undocumented rule, aka. &lt;em&gt;assumption&lt;/em&gt;)
that multiple c.get_Methods calls may return different collections, but the collection's
contents don't change.
&lt;/p&gt;
&lt;p&gt;
"&lt;font face="Courier New"&gt;foreach (IMethod method in c.Methods) { ... }&lt;/font&gt;" is
safe, but "&lt;font face="Courier New"&gt;for (int i = 0; i &amp;lt; c.Methods.Count; i++) {
IMethod method = c.Methods[i]; ... }&lt;/font&gt;" can crash.
&lt;/p&gt;
&lt;p&gt;
But that's quite a difficult rule compared to "IClass never changes". So after reading
Erip Lippert's &lt;a href="http://blogs.msdn.com/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx"&gt;series
on immutability&lt;/a&gt;, I finally decided to &lt;strong&gt;make IClass immutable again&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
It's "popsicle immutability", that means IClass instances are mutable, but when the
Freeze() method is called, they become immutable. And this time, immutability is &lt;strong&gt;enforced&lt;/strong&gt;,
trying to change&amp;nbsp;a property&amp;nbsp;of a&amp;nbsp;frozen IClass will cause an exception.&amp;nbsp;Adding
an IClass to a project content will cause it to freeze if it isn’t already frozen,
so it's guaranteed that IClass objects returned by GetClass or by some type reference
are immutable.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=fd64e057-133f-4b64-89ce-8f26d8cc8633" /&gt;</description>
      <comments>http://laputa.sharpdevelop.net/CommentView,guid,fd64e057-133f-4b64-89ce-8f26d8cc8633.aspx</comments>
      <category>Daniel</category>
    </item>
    <item>
      <trackback:ping>http://laputa.sharpdevelop.net/Trackback.aspx?guid=945bfd56-ebde-44f4-ab83-e25ffe104a6e</trackback:ping>
      <pingback:server>http://laputa.sharpdevelop.net/pingback.aspx</pingback:server>
      <pingback:target>http://laputa.sharpdevelop.net/PermaLink,guid,945bfd56-ebde-44f4-ab83-e25ffe104a6e.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://laputa.sharpdevelop.net/CommentView,guid,945bfd56-ebde-44f4-ab83-e25ffe104a6e.aspx</wfw:comment>
      <wfw:commentRss>http://laputa.sharpdevelop.net/SyndicationService.asmx/GetEntryCommentsRss?guid=945bfd56-ebde-44f4-ab83-e25ffe104a6e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A change that happened rather early in the development process of SharpDevelop 3.0
(revision 2658, 8/13/2007) was that we replaced NDoc (a stalled open source project)
with <a href="http://www.codeplex.com/SHFB/">Sandcastle Help File Builder (SHFB)</a>.
SHFB looks and feels similar to NDoc, however, it builds on top of <a href="http://www.codeplex.com/Sandcastle">Sandcastle</a>,
a documentation generation tool by Microsoft.
</p>
        <p>
Our <a href="http://build.sharpdevelop.net/buildartefacts/">build server</a> (revision
2913 and higher) contains <a href="http://www.codeplex.com/SHFB/Release/ProjectReleases.aspx?ReleaseId=9848">SHFB
1.6.0.4</a>, which itself builds on top of the <a href="http://www.codeplex.com/Sandcastle/Release/ProjectReleases.aspx?ReleaseId=9921">January
2008 release of Sandcastle</a> (both are at the moment the latest releases of their
respective projects). SharpDevelop 3.0 setup ships with SHFB, however, <strong>Sandcastle
itself does not and must be installed separately</strong>! (this might change in the
future once the final license of Sandcastle is known)
</p>
        <p>
Because of the regular releases of Sandcastle and SHFB, the distribution of SharpDevelop
3.0 might ship with older versions of SHFB than currently available for download.
Thanks to Eric Woodruff, the maintainer of SHFB, this is not a big deal - he is offering
a download specific for SharpDevelop:
</p>
        <p>
          <img src="http://laputa.sharpdevelop.net/content/binary/shfb_distribution.png" border="0" />
        </p>
        <p>
All you have to do is first delete the contents of the following installation directory
(including subdirectories):
</p>
        <p>
          <img src="http://laputa.sharpdevelop.net/content/binary/shfb_directory.png" border="0" />
        </p>
        <p>
Then simply unzip the SHFB distribution archive into this folder and presto - you
are now using the latest version of SHFB from inside SharpDevelop!
</p>
        <img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=945bfd56-ebde-44f4-ab83-e25ffe104a6e" />
      </body>
      <title>NDoc Replaced With Sandcastle Help File Builder (SHFB)</title>
      <guid isPermaLink="false">http://laputa.sharpdevelop.net/PermaLink,guid,945bfd56-ebde-44f4-ab83-e25ffe104a6e.aspx</guid>
      <link>http://laputa.sharpdevelop.net/NDocReplacedWithSandcastleHelpFileBuilderSHFB.aspx</link>
      <pubDate>Wed, 23 Jan 2008 08:40:44 GMT</pubDate>
      <description>&lt;p&gt;
A change that happened rather early in the development process of SharpDevelop 3.0
(revision 2658, 8/13/2007)&amp;nbsp;was that we replaced NDoc (a stalled open source project)
with &lt;a href="http://www.codeplex.com/SHFB/"&gt;Sandcastle Help File Builder (SHFB)&lt;/a&gt;.
SHFB looks and feels similar to NDoc, however, it builds on top of &lt;a href="http://www.codeplex.com/Sandcastle"&gt;Sandcastle&lt;/a&gt;,
a documentation generation tool by Microsoft.
&lt;/p&gt;
&lt;p&gt;
Our &lt;a href="http://build.sharpdevelop.net/buildartefacts/"&gt;build server&lt;/a&gt; (revision
2913 and higher) contains &lt;a href="http://www.codeplex.com/SHFB/Release/ProjectReleases.aspx?ReleaseId=9848"&gt;SHFB
1.6.0.4&lt;/a&gt;, which itself builds on top of the &lt;a href="http://www.codeplex.com/Sandcastle/Release/ProjectReleases.aspx?ReleaseId=9921"&gt;January
2008 release of Sandcastle&lt;/a&gt; (both are at the moment the latest releases of their
respective projects). SharpDevelop 3.0 setup ships with SHFB, however, &lt;strong&gt;Sandcastle
itself does not and must be installed separately&lt;/strong&gt;! (this might change in the
future once the final license of Sandcastle is known)
&lt;/p&gt;
&lt;p&gt;
Because of the regular releases of Sandcastle and SHFB, the distribution of SharpDevelop
3.0 might ship with older versions of SHFB than currently available for download.
Thanks to Eric Woodruff, the maintainer of SHFB, this is not a big deal - he is offering
a download specific for SharpDevelop:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://laputa.sharpdevelop.net/content/binary/shfb_distribution.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
All you have to do is first delete the contents of the following installation directory
(including subdirectories):
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://laputa.sharpdevelop.net/content/binary/shfb_directory.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Then simply unzip the SHFB distribution archive into this folder and presto - you
are now using the latest version of SHFB from inside SharpDevelop!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=945bfd56-ebde-44f4-ab83-e25ffe104a6e" /&gt;</description>
      <comments>http://laputa.sharpdevelop.net/CommentView,guid,945bfd56-ebde-44f4-ab83-e25ffe104a6e.aspx</comments>
      <category>Chris</category>
    </item>
    <item>
      <trackback:ping>http://laputa.sharpdevelop.net/Trackback.aspx?guid=68f2f173-d918-4525-ac35-09570b71e50e</trackback:ping>
      <pingback:server>http://laputa.sharpdevelop.net/pingback.aspx</pingback:server>
      <pingback:target>http://laputa.sharpdevelop.net/PermaLink,guid,68f2f173-d918-4525-ac35-09570b71e50e.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://laputa.sharpdevelop.net/CommentView,guid,68f2f173-d918-4525-ac35-09570b71e50e.aspx</wfw:comment>
      <wfw:commentRss>http://laputa.sharpdevelop.net/SyndicationService.asmx/GetEntryCommentsRss?guid=68f2f173-d918-4525-ac35-09570b71e50e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This question came up for example in the thread <a href="http://community.sharpdevelop.net/forums/t/7213.aspx">SharpDev
2.2.x on BuilderServer</a> (this thread was started because we ceased to automatically
build v2.2 on 1/11/2008).
</p>
        <p>
The answer is <strong>Yes</strong>. Development of SharpDevelop 2.2 stopped with revision
2675 (8/28/2007), which is three revisions higher than the officially shipping version
of SharpDevelop 2.2 (<a href="http://www.icsharpcode.net/OpenSource/SD/Download/#SharpDevelop22">Download</a>,
8/8/2007). The three non-shipping commits are:
</p>
        <ul>
          <li>
2673: Improved CSharpCodeCompletion sample: add tool tip support, show only one entry
for overloaded methods</li>
          <li>
2674: Fixed some off-by-one bugs in the CSharpCodeCompletion example (caused by the
different line counting in the parser and the text editor).</li>
          <li>
2675: CSharpCodeCompletionSample: show xml documentation</li>
        </ul>
        <p>
All three were (of course) merged into Montferrer (SharpDevelop 3.0), this merge happened
in revision 2679. However, those commits did not merit a release of a new setup because
those were all changes to a sample shipping only in the source download.
</p>
        <p>
Since releasing v2.2.1 all work stopped on the 2.x series of SharpDevelop. Our efforts
went (and still go) into SharpDevelop 3.
</p>
        <img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=68f2f173-d918-4525-ac35-09570b71e50e" />
      </body>
      <title>Did Development of SharpDevelop 2.2 Stop?</title>
      <guid isPermaLink="false">http://laputa.sharpdevelop.net/PermaLink,guid,68f2f173-d918-4525-ac35-09570b71e50e.aspx</guid>
      <link>http://laputa.sharpdevelop.net/DidDevelopmentOfSharpDevelop22Stop.aspx</link>
      <pubDate>Tue, 15 Jan 2008 10:37:39 GMT</pubDate>
      <description>&lt;p&gt;
This question came up for example in the thread &lt;a href="http://community.sharpdevelop.net/forums/t/7213.aspx"&gt;SharpDev
2.2.x on BuilderServer&lt;/a&gt;&amp;nbsp;(this thread was started because we ceased to automatically
build v2.2 on 1/11/2008).
&lt;/p&gt;
&lt;p&gt;
The answer is &lt;strong&gt;Yes&lt;/strong&gt;. Development of SharpDevelop 2.2 stopped with revision
2675 (8/28/2007), which is three revisions higher than the officially shipping version
of SharpDevelop 2.2 (&lt;a href="http://www.icsharpcode.net/OpenSource/SD/Download/#SharpDevelop22"&gt;Download&lt;/a&gt;,
8/8/2007). The three non-shipping commits are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
2673: Improved CSharpCodeCompletion sample: add tool tip support, show only one entry
for overloaded methods&lt;/li&gt;
&lt;li&gt;
2674: Fixed some off-by-one bugs in the CSharpCodeCompletion example (caused by the
different line counting in the parser and the text editor).&lt;/li&gt;
&lt;li&gt;
2675: CSharpCodeCompletionSample: show xml documentation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
All three were (of course) merged into Montferrer (SharpDevelop 3.0), this merge happened
in revision 2679. However, those commits did not merit a release of a new setup because
those were all changes to a sample shipping only in the source download.
&lt;/p&gt;
&lt;p&gt;
Since releasing v2.2.1 all work stopped on the 2.x series of SharpDevelop. Our efforts
went (and still go) into SharpDevelop 3.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=68f2f173-d918-4525-ac35-09570b71e50e" /&gt;</description>
      <comments>http://laputa.sharpdevelop.net/CommentView,guid,68f2f173-d918-4525-ac35-09570b71e50e.aspx</comments>
      <category>Chris</category>
    </item>
    <item>
      <trackback:ping>http://laputa.sharpdevelop.net/Trackback.aspx?guid=0c2cf439-97f5-4eed-86d0-88208efca697</trackback:ping>
      <pingback:server>http://laputa.sharpdevelop.net/pingback.aspx</pingback:server>
      <pingback:target>http://laputa.sharpdevelop.net/PermaLink,guid,0c2cf439-97f5-4eed-86d0-88208efca697.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://laputa.sharpdevelop.net/CommentView,guid,0c2cf439-97f5-4eed-86d0-88208efca697.aspx</wfw:comment>
      <wfw:commentRss>http://laputa.sharpdevelop.net/SyndicationService.asmx/GetEntryCommentsRss?guid=0c2cf439-97f5-4eed-86d0-88208efca697</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In continuing to list changes to SharpDevelop 3, we are going to talk about the code
coverage addin in SharpDevelop 3 "Montferrer" in this blog post. 
</p>
        <p>
Previously, the addin used NCover for calculating code coverage (this is
a metric you gain by writing unit tests). However, recently NCover was turned into
a commercial product. Because we only include / support tools that are free to use
for anyone (commercial or open source / hobby development), we switched to a different
tool - <a href="http://sourceforge.net/projects/partcover">PartCover</a>.
</p>
        <p>
This change happened in rev 2744 on 19th of November last year. The addin has retained
its original functionality, however, for end users there is an important change: you
no longer need to download and install a separate package (as it was the case with
NCover), PartCover is part of the SharpDevelop setup. You are good to go right after
installation!
</p>
        <img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=0c2cf439-97f5-4eed-86d0-88208efca697" />
      </body>
      <title>Code Coverage Addin Uses PartCover 2.2 Instead of NCover in SharpDevelop 3</title>
      <guid isPermaLink="false">http://laputa.sharpdevelop.net/PermaLink,guid,0c2cf439-97f5-4eed-86d0-88208efca697.aspx</guid>
      <link>http://laputa.sharpdevelop.net/CodeCoverageAddinUsesPartCover22InsteadOfNCoverInSharpDevelop3.aspx</link>
      <pubDate>Fri, 11 Jan 2008 11:02:23 GMT</pubDate>
      <description>&lt;p&gt;
In continuing to list changes to SharpDevelop 3, we are going to talk about the code
coverage addin in SharpDevelop 3 "Montferrer" in this blog post. 
&lt;/p&gt;
&lt;p&gt;
Previously,&amp;nbsp;the addin&amp;nbsp;used NCover for calculating code coverage (this is
a metric you gain by writing unit tests). However, recently NCover was turned into
a commercial product. Because we only include / support tools that are free to use
for anyone (commercial or open source / hobby development), we switched to a different
tool - &lt;a href="http://sourceforge.net/projects/partcover"&gt;PartCover&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
This change happened in rev 2744 on 19th of November last year. The addin has retained
its original functionality, however, for end users there is an important change: you
no longer need to download and install a separate package (as it was the case with
NCover), PartCover is part of the SharpDevelop setup. You are good to go right after
installation!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=0c2cf439-97f5-4eed-86d0-88208efca697" /&gt;</description>
      <comments>http://laputa.sharpdevelop.net/CommentView,guid,0c2cf439-97f5-4eed-86d0-88208efca697.aspx</comments>
      <category>Chris</category>
    </item>
    <item>
      <trackback:ping>http://laputa.sharpdevelop.net/Trackback.aspx?guid=795b79b1-f798-4f94-89df-48f4789dc666</trackback:ping>
      <pingback:server>http://laputa.sharpdevelop.net/pingback.aspx</pingback:server>
      <pingback:target>http://laputa.sharpdevelop.net/PermaLink,guid,795b79b1-f798-4f94-89df-48f4789dc666.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://laputa.sharpdevelop.net/CommentView,guid,795b79b1-f798-4f94-89df-48f4789dc666.aspx</wfw:comment>
      <wfw:commentRss>http://laputa.sharpdevelop.net/SyndicationService.asmx/GetEntryCommentsRss?guid=795b79b1-f798-4f94-89df-48f4789dc666</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
An issue that initially came up in 2006 (<a href="http://community.sharpdevelop.net/forums/t/1649.aspx">Unable
to compile #develop: access denied</a>) "resurfaced" on our contributors mailing list
because one of our developers ran into this very problem that McAfee blocks access
to our Main\StartUp folder:
</p>
        <p>
          <img src="http://laputa.sharpdevelop.net/content/binary/StartupFolder.png" border="0" />
        </p>
        <p>
The problem and a workaround is described in <a href="http://www.sturmnet.org/blog/archives/2005/02/21/mcafee-startup-folder/">McAfee
VirusScan and the Startup folder</a>. However, this developer doesn't have the administrative
rights to change this setting of McAfee, so he asked whether we are going to rename
the folder.
</p>
        <p>
My take on this issue is that this is a bug in McAfee's software, because willy-nilly
disabling anything that resides in a random folder called StartUp isn't a security
feature. 
</p>
        <img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=795b79b1-f798-4f94-89df-48f4789dc666" />
      </body>
      <title>McAfee and \Src\Main\StartUp</title>
      <guid isPermaLink="false">http://laputa.sharpdevelop.net/PermaLink,guid,795b79b1-f798-4f94-89df-48f4789dc666.aspx</guid>
      <link>http://laputa.sharpdevelop.net/McAfeeAndSrcMainStartUp.aspx</link>
      <pubDate>Thu, 10 Jan 2008 17:43:52 GMT</pubDate>
      <description>&lt;p&gt;
An issue that initially came up in 2006 (&lt;a href="http://community.sharpdevelop.net/forums/t/1649.aspx"&gt;Unable
to compile #develop: access denied&lt;/a&gt;) "resurfaced" on our contributors mailing list
because one of our developers ran into this very problem that McAfee blocks access
to our Main\StartUp folder:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://laputa.sharpdevelop.net/content/binary/StartupFolder.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
The problem and a workaround is described in &lt;a href="http://www.sturmnet.org/blog/archives/2005/02/21/mcafee-startup-folder/"&gt;McAfee
VirusScan and the Startup folder&lt;/a&gt;. However, this developer doesn't have the administrative
rights to change this setting of McAfee, so he asked whether we are going to rename
the folder.
&lt;/p&gt;
&lt;p&gt;
My take on this issue is that this is a bug in McAfee's software, because willy-nilly
disabling anything that resides in a random folder called StartUp isn't a security
feature. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=795b79b1-f798-4f94-89df-48f4789dc666" /&gt;</description>
      <comments>http://laputa.sharpdevelop.net/CommentView,guid,795b79b1-f798-4f94-89df-48f4789dc666.aspx</comments>
      <category>Chris</category>
    </item>
    <item>
      <trackback:ping>http://laputa.sharpdevelop.net/Trackback.aspx?guid=7b36854f-673a-495a-bcb7-4d5e05cc4e9f</trackback:ping>
      <pingback:server>http://laputa.sharpdevelop.net/pingback.aspx</pingback:server>
      <pingback:target>http://laputa.sharpdevelop.net/PermaLink,guid,7b36854f-673a-495a-bcb7-4d5e05cc4e9f.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://laputa.sharpdevelop.net/CommentView,guid,7b36854f-673a-495a-bcb7-4d5e05cc4e9f.aspx</wfw:comment>
      <wfw:commentRss>http://laputa.sharpdevelop.net/SyndicationService.asmx/GetEntryCommentsRss?guid=7b36854f-673a-495a-bcb7-4d5e05cc4e9f</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Over the past months we made a couple of feature changes in SharpDevelop 3 (currently
alpha status). One major change is that we moved <a href="http://nant.sourceforge.net/">NAnt</a> and <a href="http://www.mono-project.com/Main_Page">Mono</a> support
from the binary distribution (aka "setup") to the source code distribution. You can
find the addins ready to build in the \samples directory:
</p>
        <p>
          <img src="http://laputa.sharpdevelop.net/content/binary/sd3_samples_directory.png" border="0" />
        </p>
        <p>
What was the reasoning behind this decision? For NAnt, we had taken this decision
a long time ago because SharpDevelop itself no longer uses NAnt as the primary build
solution, and as such, the addin wasn't actively enhanced and tested. But it still
is a great tool as well as a good sample for building addins with SharpDevelop.
</p>
        <p>
The decision to "relegate" Mono from production to sample status has been based on
multiple factors. For one, we only support basic compilation for Mono, no debugger
nor any kind of visual designers (like GTK#). We got lots of support questions regarding
these, and the honest answer had to be "we won't support that, sorry". Then in December <a href="http://tirania.org/blog/archive/2007/Dec-02-2.html">Miguel
announced that MonoDevelop will come to Windows</a> (MonoDevelop is a fork of SharpDevelop),
which meant that an IDE would come to Windows that fully supports all the things in
Mono we don't have. 
</p>
        <p>
That's why we decided to make Mono an addin for people who know how to deal with source
code, all the features are still there. And now that it is separate, it also makes
a great sample addin because of the deepness of integration with low-level features
of SharpDevelop.
</p>
        <p>
To sum it up - we didn't remove anything, we just trimmed the setup to include features
that are targeted at the Microsoft .NET platform.
</p>
        <img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=7b36854f-673a-495a-bcb7-4d5e05cc4e9f" />
      </body>
      <title>SharpDevelop 3: Where Did Mono and NAnt Support Go?</title>
      <guid isPermaLink="false">http://laputa.sharpdevelop.net/PermaLink,guid,7b36854f-673a-495a-bcb7-4d5e05cc4e9f.aspx</guid>
      <link>http://laputa.sharpdevelop.net/SharpDevelop3WhereDidMonoAndNAntSupportGo.aspx</link>
      <pubDate>Wed, 02 Jan 2008 08:15:59 GMT</pubDate>
      <description>&lt;p&gt;
Over the past months we made a couple of feature changes in SharpDevelop 3 (currently
alpha status). One major change is that we moved &lt;a href="http://nant.sourceforge.net/"&gt;NAnt&lt;/a&gt; and &lt;a href="http://www.mono-project.com/Main_Page"&gt;Mono&lt;/a&gt; support
from the binary distribution (aka "setup") to the source code distribution. You can
find the addins ready to build in the \samples directory:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://laputa.sharpdevelop.net/content/binary/sd3_samples_directory.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
What was the reasoning behind this decision? For NAnt, we had taken this decision
a long time ago because SharpDevelop itself no longer uses NAnt as the primary build
solution, and as such, the addin wasn't actively enhanced and tested. But it still
is a great tool as well as a good sample for building addins with SharpDevelop.
&lt;/p&gt;
&lt;p&gt;
The decision to "relegate" Mono from production to sample status has been based on
multiple factors. For one, we only support basic compilation for Mono, no debugger
nor any kind of visual designers (like GTK#). We got lots of support questions regarding
these, and the honest answer had to be "we won't support that, sorry". Then in December &lt;a href="http://tirania.org/blog/archive/2007/Dec-02-2.html"&gt;Miguel
announced that MonoDevelop will come to Windows&lt;/a&gt; (MonoDevelop is a fork of SharpDevelop),
which meant that an IDE would come to Windows that fully supports all the things in
Mono we don't have. 
&lt;/p&gt;
&lt;p&gt;
That's why we decided to make Mono an addin for people who know how to deal with source
code, all the features are still there. And now that it is separate, it also makes
a great sample addin because of the deepness of integration with low-level features
of SharpDevelop.
&lt;/p&gt;
&lt;p&gt;
To sum it up - we didn't remove anything, we just trimmed the setup to include features
that are targeted at the Microsoft .NET platform.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=7b36854f-673a-495a-bcb7-4d5e05cc4e9f" /&gt;</description>
      <comments>http://laputa.sharpdevelop.net/CommentView,guid,7b36854f-673a-495a-bcb7-4d5e05cc4e9f.aspx</comments>
      <category>Chris</category>
    </item>
    <item>
      <trackback:ping>http://laputa.sharpdevelop.net/Trackback.aspx?guid=1c4a3a6b-1a1a-4e3f-9cdf-f4909748c138</trackback:ping>
      <pingback:server>http://laputa.sharpdevelop.net/pingback.aspx</pingback:server>
      <pingback:target>http://laputa.sharpdevelop.net/PermaLink,guid,1c4a3a6b-1a1a-4e3f-9cdf-f4909748c138.aspx</pingback:target>
      <dc:creator>Daniel Grunwald</dc:creator>
      <wfw:comment>http://laputa.sharpdevelop.net/CommentView,guid,1c4a3a6b-1a1a-4e3f-9cdf-f4909748c138.aspx</wfw:comment>
      <wfw:commentRss>http://laputa.sharpdevelop.net/SyndicationService.asmx/GetEntryCommentsRss?guid=1c4a3a6b-1a1a-4e3f-9cdf-f4909748c138</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Microsoft just <a href="http://weblogs.asp.net/scottgu/archive/2007/11/19/visual-studio-2008-and-net-3-5-released.aspx">released
Visual Studio 2008</a> and the .NET Framework 3.5.
</p>
        <p>
          <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=333325FD-AE52-4E35-B531-508D977D32A6&amp;displaylang=en">Download
.NET Framework 3.5</a>
        </p>
        <p>
To develop applications for the .NET Framework 3.5, <a href="http://build.sharpdevelop.net/BuildArtefacts/">download
SharpDevelop 3.0 from the build server</a>.
</p>
        <p>
Note that SharpDevelop 3.0 are not release quality builds, especially the integrated
debugger is very unstable. As currently no one is working on the debugger (hint: you
can help!), I disabled it in SharpDevelop 3.0.0.2745 so that people trying SharpDevelop
3.0 do not immediately get exceptions when they try run their programs. To re-enable
the debugger, open C:\Program Files\SharpDevelop\3.0\AddIns\AddIns\Misc\Debugger\Debugger.AddIn.addin
in a text editor and remove the &lt;DisableAddIn .../&gt; node.
</p>
        <img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=1c4a3a6b-1a1a-4e3f-9cdf-f4909748c138" />
      </body>
      <title>.NET Framework 3.5 release</title>
      <guid isPermaLink="false">http://laputa.sharpdevelop.net/PermaLink,guid,1c4a3a6b-1a1a-4e3f-9cdf-f4909748c138.aspx</guid>
      <link>http://laputa.sharpdevelop.net/NETFramework35Release.aspx</link>
      <pubDate>Mon, 19 Nov 2007 21:35:48 GMT</pubDate>
      <description>&lt;p&gt;
Microsoft just &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/11/19/visual-studio-2008-and-net-3-5-released.aspx"&gt;released
Visual Studio 2008&lt;/a&gt; and the .NET Framework 3.5.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=333325FD-AE52-4E35-B531-508D977D32A6&amp;amp;displaylang=en"&gt;Download
.NET Framework 3.5&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
To develop applications for the .NET Framework 3.5, &lt;a href="http://build.sharpdevelop.net/BuildArtefacts/"&gt;download
SharpDevelop 3.0 from the build server&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Note that SharpDevelop 3.0 are not release quality builds, especially the integrated
debugger is very unstable. As currently no one is working on the debugger (hint: you
can help!), I disabled it in SharpDevelop 3.0.0.2745 so that people trying SharpDevelop
3.0 do not immediately get exceptions when they try run their programs. To re-enable
the debugger, open C:\Program Files\SharpDevelop\3.0\AddIns\AddIns\Misc\Debugger\Debugger.AddIn.addin
in a text editor and remove the &amp;lt;DisableAddIn .../&amp;gt; node.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=1c4a3a6b-1a1a-4e3f-9cdf-f4909748c138" /&gt;</description>
      <comments>http://laputa.sharpdevelop.net/CommentView,guid,1c4a3a6b-1a1a-4e3f-9cdf-f4909748c138.aspx</comments>
      <category>Daniel</category>
    </item>
    <item>
      <trackback:ping>http://laputa.sharpdevelop.net/Trackback.aspx?guid=d6dec112-4165-4281-819e-571704f55926</trackback:ping>
      <pingback:server>http://laputa.sharpdevelop.net/pingback.aspx</pingback:server>
      <pingback:target>http://laputa.sharpdevelop.net/PermaLink,guid,d6dec112-4165-4281-819e-571704f55926.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://laputa.sharpdevelop.net/CommentView,guid,d6dec112-4165-4281-819e-571704f55926.aspx</wfw:comment>
      <wfw:commentRss>http://laputa.sharpdevelop.net/SyndicationService.asmx/GetEntryCommentsRss?guid=d6dec112-4165-4281-819e-571704f55926</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Daniel is currently working on areas such as project subsystem or code completion
(aside from fixing bugs). Therefore, work on the WPF designer is stalled. But Daniel
put together a list of tasks (hard, medium &amp; easy) that you could be helping us
with. So if you are interested in helping, and want to be part of writing an open
source WPF designer, please do get in touch with me at <strong><em>christophw at icsharcode.net</em></strong>!
</p>
        <h1>WPF Designer mini tasks
</h1>
        <p>
Here are some jobs to do on the WPF Designer broken into small parts.
</p>
        <p>
Apart from this list, there are also big jobs to do: Data Binding support, support
using Styles, support defining resources.
</p>
        <h2>Components to be used by multiple designer parts
</h2>
        <h3>Create “Choose Class” dialog
</h3>
        <p>
The data binding UI will need a dialog that allows choosing a class from the referenced
assemblies. This will be implemented in WpfDesigner.AddIn and made available to WpfDesign.Designer
through a service. The referenced assemblies should be inspected using ICSharpCode.SharpDevelop.Dom
</p>
        <p>
This will be used by the “Content” property editor and by the data binding UI.
</p>
        <h3>Support ‘Virtual Design Root Element’
</h3>
        <p>
This means that instead of displaying the designed component, the designer is able
to display another component as if it was the root component. The designer should
provide a “Back” button on the design surface to allow the user to go back to the
real root component.
</p>
        <p>
This feature is required for designing elements that cannot be designed directly on
the main design surface, e.g. Tooltips 
</p>
        <h3>Write menu designer
</h3>
        <p>
Priority: High
</p>
        <p>
The menu designer might be a dialog box that allows editing the menu in a tree view;
or it might be an in-place menu designer like the Windows.Forms designer.
</p>
        <h2>Property editing support
</h2>
        <p>
Here I’m listing properties that could need improved editing support.
</p>
        <p>
When implementing property editors, take care that the editor should also work when
multiple components with different property values are selected, so you always need
a way to represent the ‘ambiguous’ value.
</p>
        <h3>Properties of type Brush (e.g. Control.Background / Control.BorderBrush)
</h3>
        <p>
Priority: High
</p>
        <p>
Change ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor to include
a little drop down button, the drop down should allow to choose the brush type (SolidColorBrush,
etc., we don't need to support all of them at the beginning) and allow the user to
edit the brush according to the chosen type.
</p>
        <h3>Properties of type BitmapEffect / BitmapEffectInput (e.g. UIElement.BitmapEffect
/ UIElement.BitmapEffectInput)
</h3>
        <p>
Priority: Low
</p>
        <p>
Implement a TypeEditor (similar to BrushEditor) for the types BitmapEffect and BitmapEffectInput.
Could be as simple as a combo box with the most commonly used effects.
</p>
        <h3>Properties of type ICommand (e.g. ButtonBase.Command)
</h3>
        <p>
Priority: Medium
</p>
        <p>
There should be a way to choose the command to use from some kind of list.
</p>
        <h3>ContentControl.Content
</h3>
        <p>
Priority: High
</p>
        <p>
ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.ContentEditor<br />
The “C” button should be made a drop down button (like the one used for the Brush
editor), it should present “null”, “string”, and menu items for creating commonly
used child configurations (e.g. StackPanel with Image and Text when the parent is
a button), and “choose class” to create arbitrary objects. This depends on “Create
Choose Class Dialog”.
</p>
        <h3>Properties of type ContextMenu (e.g. FrameworkElement.ContextMenu)
</h3>
        <p>
Priority: Medium
</p>
        <p>
Provide a way to create and edit a context menu inside the designer. 
</p>
        <h3>Properties of type InputScope
</h3>
        <p>
Priority: Low
</p>
        <p>
Research what an InputScope is and if/how we should allow the user to edit it.
</p>
        <h3>Properties of type Transform
</h3>
        <p>
Priority: Low
</p>
        <p>
Similar to the BrushEditor, provide a drop down to choose from the different available
transforms and allow editing the transform properties.
</p>
        <h3>FrameworkElement.ToolTip
</h3>
        <p>
Priority: Medium (setting string tool tips), Low (designing complex tool tips)
</p>
        <p>
Should be editable similar to ContentControl.Content, but has to allow the user to
design complex tooltips. Depends on “Support ‘Virtual Design Root Element’”
</p>
        <h3>Properties of type FontStretch / FontStyle / FontWeight
</h3>
        <p>
Priority: Low
</p>
        <p>
Provide a drop down with the available settings
</p>
        <h3>Properties of type FontFamily
</h3>
        <p>
Priority: Low
</p>
        <p>
Use a dialog to allow the user to choose the font to use.
</p>
        <h3>Properties of type Nullable&lt;bool&gt; (e.g. ToggleButton.IsChecked)
</h3>
        <p>
Priority: Low
</p>
        <h3>ItemsControl.ItemsSource
</h3>
        <p>
Priority: Low
</p>
        <p>
There are two main usage scenarios: this property is specified using data binding
(this doesn’t need to be handled by the type editor), or there are some hard coded
values.
</p>
        <p>
Write a type editor to support entering <b>string</b> values.
</p>
        <h3>Label.Target
</h3>
        <p>
Priority: Low
</p>
        <p>
Label.Target is set to the control described by the label (the control getting focus
when Alt+Access Key is pressed). This is done using data binding, but choosing the
target from the data binding dialog is too tedious – drag’n’drop of a crosshair on
the target control would be much easier. Depends on data binding support.
</p>
        <h3>Properties of type ImageSource (e.g. Image.Source)
</h3>
        <p>
Priority: High
</p>
        <p>
Allow choosing a “Resource” element already part of the project, or choose a file
and it will get added to the project. This TypeEditor would be implemented in WpfDesign.AddIn
and not WpfDesign.Designer because it needs access to the project in SharpDevelop
</p>
        <h3>Properties of type ViewBase (e.g. ListView.View)
</h3>
        <p>
Priority: Low
</p>
        <p>
Provide a drop down with the most commonly used views. 
</p>
        <img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=d6dec112-4165-4281-819e-571704f55926" />
      </body>
      <title>Help Wanted: WPF Designer Tasks</title>
      <guid isPermaLink="false">http://laputa.sharpdevelop.net/PermaLink,guid,d6dec112-4165-4281-819e-571704f55926.aspx</guid>
      <link>http://laputa.sharpdevelop.net/HelpWantedWPFDesignerTasks.aspx</link>
      <pubDate>Wed, 24 Oct 2007 18:01:35 GMT</pubDate>
      <description>&lt;p&gt;
Daniel is currently working on areas such as project subsystem or code completion
(aside from fixing bugs). Therefore, work on the WPF designer is stalled. But Daniel
put together a list of tasks (hard, medium &amp;amp; easy) that you could be helping us
with. So if you are interested in helping, and want to be part of writing an open
source WPF designer, please do get in touch with me at &lt;strong&gt;&lt;em&gt;christophw at icsharcode.net&lt;/em&gt;&lt;/strong&gt;!
&lt;/p&gt;
&lt;h1&gt;WPF Designer mini tasks
&lt;/h1&gt;
&lt;p&gt;
Here are some jobs to do on the WPF Designer broken into small parts.
&lt;/p&gt;
&lt;p&gt;
Apart from this list, there are also big jobs to do: Data Binding support, support
using Styles, support defining resources.
&lt;/p&gt;
&lt;h2&gt;Components to be used by multiple designer parts
&lt;/h2&gt;
&lt;h3&gt;Create “Choose Class” dialog
&lt;/h3&gt;
&lt;p&gt;
The data binding UI will need a dialog that allows choosing a class from the referenced
assemblies. This will be implemented in WpfDesigner.AddIn and made available to WpfDesign.Designer
through a service. The referenced assemblies should be inspected using ICSharpCode.SharpDevelop.Dom
&lt;/p&gt;
&lt;p&gt;
This will be used by the “Content” property editor and by the data binding UI.
&lt;/p&gt;
&lt;h3&gt;Support ‘Virtual Design Root Element’
&lt;/h3&gt;
&lt;p&gt;
This means that instead of displaying the designed component, the designer is able
to display another component as if it was the root component. The designer should
provide a “Back” button on the design surface to allow the user to go back to the
real root component.
&lt;/p&gt;
&lt;p&gt;
This feature is required for designing elements that cannot be designed directly on
the main design surface, e.g. Tooltips 
&lt;/p&gt;
&lt;h3&gt;Write menu designer
&lt;/h3&gt;
&lt;p&gt;
Priority: High
&lt;/p&gt;
&lt;p&gt;
The menu designer might be a dialog box that allows editing the menu in a tree view;
or it might be an in-place menu designer like the Windows.Forms designer.
&lt;/p&gt;
&lt;h2&gt;Property editing support
&lt;/h2&gt;
&lt;p&gt;
Here I’m listing properties that could need improved editing support.
&lt;/p&gt;
&lt;p&gt;
When implementing property editors, take care that the editor should also work when
multiple components with different property values are selected, so you always need
a way to represent the ‘ambiguous’ value.
&lt;/p&gt;
&lt;h3&gt;Properties of type Brush (e.g. Control.Background / Control.BorderBrush)
&lt;/h3&gt;
&lt;p&gt;
Priority: High
&lt;/p&gt;
&lt;p&gt;
Change ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.BrushEditor to include
a little drop down button, the drop down should allow to choose the brush type (SolidColorBrush,
etc., we don't need to support all of them at the beginning) and allow the user to
edit the brush according to the chosen type.
&lt;/p&gt;
&lt;h3&gt;Properties of type BitmapEffect / BitmapEffectInput (e.g. UIElement.BitmapEffect
/ UIElement.BitmapEffectInput)
&lt;/h3&gt;
&lt;p&gt;
Priority: Low
&lt;/p&gt;
&lt;p&gt;
Implement a TypeEditor (similar to BrushEditor) for the types BitmapEffect and BitmapEffectInput.
Could be as simple as a combo box with the most commonly used effects.
&lt;/p&gt;
&lt;h3&gt;Properties of type ICommand (e.g. ButtonBase.Command)
&lt;/h3&gt;
&lt;p&gt;
Priority: Medium
&lt;/p&gt;
&lt;p&gt;
There should be a way to choose the command to use from some kind of list.
&lt;/p&gt;
&lt;h3&gt;ContentControl.Content
&lt;/h3&gt;
&lt;p&gt;
Priority: High
&lt;/p&gt;
&lt;p&gt;
ICSharpCode.WpfDesign.Designer.Controls.TypeEditors.ContentEditor&lt;br&gt;
The “C” button should be made a drop down button (like the one used for the Brush
editor), it should present “null”, “string”, and menu items for creating commonly
used child configurations (e.g. StackPanel with Image and Text when the parent is
a button), and “choose class” to create arbitrary objects. This depends on “Create
Choose Class Dialog”.
&lt;/p&gt;
&lt;h3&gt;Properties of type ContextMenu (e.g. FrameworkElement.ContextMenu)
&lt;/h3&gt;
&lt;p&gt;
Priority: Medium
&lt;/p&gt;
&lt;p&gt;
Provide a way to create and edit a context menu inside the designer. 
&lt;/p&gt;
&lt;h3&gt;Properties of type InputScope
&lt;/h3&gt;
&lt;p&gt;
Priority: Low
&lt;/p&gt;
&lt;p&gt;
Research what an InputScope is and if/how we should allow the user to edit it.
&lt;/p&gt;
&lt;h3&gt;Properties of type Transform
&lt;/h3&gt;
&lt;p&gt;
Priority: Low
&lt;/p&gt;
&lt;p&gt;
Similar to the BrushEditor, provide a drop down to choose from the different available
transforms and allow editing the transform properties.
&lt;/p&gt;
&lt;h3&gt;FrameworkElement.ToolTip
&lt;/h3&gt;
&lt;p&gt;
Priority: Medium (setting string tool tips), Low (designing complex tool tips)
&lt;/p&gt;
&lt;p&gt;
Should be editable similar to ContentControl.Content, but has to allow the user to
design complex tooltips. Depends on “Support ‘Virtual Design Root Element’”
&lt;/p&gt;
&lt;h3&gt;Properties of type FontStretch / FontStyle / FontWeight
&lt;/h3&gt;
&lt;p&gt;
Priority: Low
&lt;/p&gt;
&lt;p&gt;
Provide a drop down with the available settings
&lt;/p&gt;
&lt;h3&gt;Properties of type FontFamily
&lt;/h3&gt;
&lt;p&gt;
Priority: Low
&lt;/p&gt;
&lt;p&gt;
Use a dialog to allow the user to choose the font to use.
&lt;/p&gt;
&lt;h3&gt;Properties of type Nullable&amp;lt;bool&amp;gt; (e.g. ToggleButton.IsChecked)
&lt;/h3&gt;
&lt;p&gt;
Priority: Low
&lt;/p&gt;
&lt;h3&gt;ItemsControl.ItemsSource
&lt;/h3&gt;
&lt;p&gt;
Priority: Low
&lt;/p&gt;
&lt;p&gt;
There are two main usage scenarios: this property is specified using data binding
(this doesn’t need to be handled by the type editor), or there are some hard coded
values.
&lt;/p&gt;
&lt;p&gt;
Write a type editor to support entering &lt;b&gt;string&lt;/b&gt; values.
&lt;/p&gt;
&lt;h3&gt;Label.Target
&lt;/h3&gt;
&lt;p&gt;
Priority: Low
&lt;/p&gt;
&lt;p&gt;
Label.Target is set to the control described by the label (the control getting focus
when Alt+Access Key is pressed). This is done using data binding, but choosing the
target from the data binding dialog is too tedious – drag’n’drop of a crosshair on
the target control would be much easier. Depends on data binding support.
&lt;/p&gt;
&lt;h3&gt;Properties of type ImageSource (e.g. Image.Source)
&lt;/h3&gt;
&lt;p&gt;
Priority: High
&lt;/p&gt;
&lt;p&gt;
Allow choosing a “Resource” element already part of the project, or choose a file
and it will get added to the project. This TypeEditor would be implemented in WpfDesign.AddIn
and not WpfDesign.Designer because it needs access to the project in SharpDevelop
&lt;/p&gt;
&lt;h3&gt;Properties of type ViewBase (e.g. ListView.View)
&lt;/h3&gt;
&lt;p&gt;
Priority: Low
&lt;/p&gt;
&lt;p&gt;
Provide a drop down with the most commonly used views. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://laputa.sharpdevelop.net/aggbug.ashx?id=d6dec112-4165-4281-819e-571704f55926" /&gt;</description>
      <comments>http://laputa.sharpdevelop.net/CommentView,guid,d6dec112-4165-4281-819e-571704f55926.aspx</comments>
      <category>Chris</category>
    </item>
  </channel>
</rss>