EViL Decorating in the Igloo
Update #2: JP called to tell me that this really isn't a decorator pattern. It's actually the adapter pattern. Like he said in his training course, identifying patterns in the wild is hard to do and takes a lot of practice. Looks like I need a lot more practice. He also asked about a factory class to create these items, and I figured that it would be nice if I put the one I had created up here too.
I'm working on some stuff for the EViL project again. After my training last week, I've been looking at the work I do a little differently and this project is no different. For me, the great thing about working on EViL is that it allows me to explore the depths of the System.Reflection namespace. In the last couple of days I've found some interesting things.
I was working on some additions to allow for validation against private fields in classes and I noticed that the PropertyInfo and FieldInfo classes didn't implement a common interface or base class that had the GetValue method on it. In the end, I needed to be able to get all of the PropertyInfo and FieldInfo classes into one collection so that I could iterate through the values in search of matches to perform validation on. Here's how I went about it. Now, it may not be the best way. I may not have named this right. Regardless, this solved the problem for me and I figured I'd share it.
In the end what I did was wrap the PropertyInfo and FieldInfo classes in a SmartPropertyInfo and SmartFieldInfo Decorator Adapter classes. By creating the wrapper, and it's correlating interface, I was able to make both PropertyInfo and FieldInfo data look and behave the same. EViL is now completely agnostic to the classes that are provided by reflection.
Update: After an email from David Woods I decided to implement one more level of refactoring to clean this up even more.
public class SmartPropertyInfo : ISmartMethodInfo { private readonly PropertyInfo propertyInfo; public SmartPropertyInfo(PropertyInfo info) { this.propertyInfo = info; } public string Name { get { return propertyInfo.Name; } }public Type PropertyType { get { return propertyInfo.PropertyType; } }public object GetValue(object entity, object[] index) { return propertyInfo.GetValue(entity, index); } }public class SmartFieldInfo : ISmartMethodInfo { private readonly FieldInfo fieldInfo; public SmartFieldInfo(FieldInfo info) { this.fieldInfo = info; }public string Name { get { return fieldInfo.Name; } } public Type PropertyType { get { return fieldInfo.FieldType; } } public object GetValue(object entity, object[] index) { return fieldInfo.GetValue(entity); } }public static class PropertyFactory { public static IList<ISmartMethodInfo> GetProperties(object entity) { IList<ISmartMethodInfo> results = new List<ISmartMethodInfo>(); GetReflectedProperties(entity, results); GetReflectedFields(entity, results); return results; } private static void GetReflectedProperties(object entity, IList<ISmartMethodInfo> values) { PropertyInfo[] properties = entity.GetType().GetProperties(); foreach (PropertyInfo info in properties) { ISmartMethodInfo smartMethodInfo = new SmartPropertyInfo(info); values.Add(smartMethodInfo); } } private static void GetReflectedFields(object entity, IList<ISmartMethodInfo> values) { FieldInfo[] fields = entity.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); foreach (FieldInfo info in fields) { ISmartMethodInfo smartMethodInfo = new SmartFieldInfo(info); values.Add(smartMethodInfo); } } }
My latest continuous integration experience
Last week I spent a lot of time working with people that I'd never worked with before. Surprisingly, of the eleven people in the class, only about half had worked with any kind of continuous integration before. Top off the situation with the fact that the group was not at all proficient with the style of development (TDD and DDD for example) and you end up with an interest first week for a team.
We really only worked with a full CI environment for a couple of those days, but I noticed one really interesting thing. We never broke the build in over 30 source control check-ins. I had even gone so far to bring in a build hat for the lucky bugger that I thought would inevitably break it. The disappointment was unbelievable for me.
What this did do, was get me thinking about the reasons that this could happen with such a green team in such a green environment while my team at work can't string together more than 4 or 5 successful builds before we fail. I spent some time talking with JP about it and we came to the consensus that there was only one reason for the training team's success. Consistency.
Every time someone wanted to perform a check-in they first (U)pdated, (A)dded, (T)est and then (C)ommitted. As a result of always following UATC, all code integration issues were identified well before the build server kicked off it's process. On top of that, the fact that the build server had a very short delay (5 seconds) between check-in and build kickoff, a very fast build and CCTray it meant that we had immediate knowledge of changes coming down the pipe.
Compared to my CI experience at work (which is beyond the end of the bad end of the spectrum), this was a great experience. By the end of the first day I could feel the group getting some serious rhythm. Keyboards clicked, conversation buzzed and sweet code was made. This week I'm going to be working to see if I can get the same to happen at work.
A week with JP Boodhoo
Last week I spent five full days under the tutelage of Jean-Paul Boodhoo. He was offering a course he's calling Nothin' But .NET and I was lucky enough to weasel my way into it as one of the 11 attendees.
The first thing that needs to be said about this course is definitely for well seasoned developers. You can not expect to go into this course and learn .NET. There is no way that a developer at that skill level can expect to keep up to the concepts and pace that they will be faced with.
We covered a lot of ground in five days. We started with a brief refresher on IEnumerable, IEnumerator and the use of the yield statement. Like many of the concepts that we covered, they appeared in an order that allowed us to apply them at many points as we moved forward.
After the quick refresher, we dove into some serious software development and OO concepts. Us students were hit with everything from the Single Responsibility Principle (SRP) to the Monostate Pattern. Although keeping up with these teachings was a stretch at one point or another for pretty much everyone in the room, we got to apply them in a group code project. Because we had some weaker students in the class I did find that the application of the lessons onto our class project left some people sitting around with nothing to work on while they waited for others to complete their tasks.
One of the most difficult concepts that we covered was Domain Driven Design. The domain that we were working in wasn't that difficult, but the change to a completely different way of analyzing problems required us to unlearn a lot of what we normally do. In the end JP worked really hard at getting us through this mental barrier and I think it hit home for almost everyone in the room.
Of all the things that that were good about the course, there was one thing that really didn't seem to fit for me. We spent an afternoon working on setting up nAnt scripts and configuring Cruise Control .NET servers. Even though these are important project and development basics in my mind, I think that they didn't work with the rest of the course topics. Many times I heard JP saying that he'd take care of some code for us because he considered it to be "infrastructure" and that we shouldn't waste time on it when we could be working on the concepts of the day. With hindsight, I think that the nAnt and CCNet work could have been approached from this standpoint and it would have freed up a half a day for more OO goodness.
Overall this was a fantastic course. You will be very hard pressed to find another that can offer the topics that JP did all in one week. The value for dollar is significant. If you're lucky enough to get into JPs course make sure you do two thing...cancel all plans and send the family on holidays. You will not have an ounce of energy when the days are over. Top that with the fact that JP will give you all that he can, even if it means running the course from 830am to 1030pm.
ReverseDOS and Community Server error
I got hit by some spammers today and I figured that I'd alter my ReverseDOS.config file so that they wouldn't get through again. One of the common things that was in each post was the value [/url] so I added the following to the config.
<filter isRegex="true" matchCount="1">[/url]</filter>
Unfortunately that addition caused the following error when I tried to open any page on my site.
XML Parsing Error: no element found
Not a very pretty error. I'm not sure why that error is being generated, but it is. I'm guessing that the [/url] value appears somewhere in the page that I'm receiving. I removed the filter enter that I show above and modified some of the other RegEx entries which should pick up the spammers the next time.
There's more to Velocity than speed
Tonight I was sitting here thinking about some of the current issues I'm fighting with at work. One of the most obvious to me is the fact that we have no project velocity. After thinking about velocity for some time, I decided that I should put those wandering thoughts to paper...so here we go.
To truly understand the problems I think that my team is having with velocity, I figured that I should first fully understand the definition of the term as it pertains to software development. My searching around found that velocity can be defined as follows.
Velocity: The amount of business value that is delivered in each development cycle.
So if you're in an agile-ish development system, velocity is the number of stories that you deliver each iteration. It sounds simple enough, but it really isn't. Because some stories require greater effort to complete, a simple count of stories delivered within an iteration may be misleading. In one iteration a team may be able to deliver 10 smaller stories, but the following iteration they may only deliver 3 larger stories. If we were to simply count the stories delivered, we would have to report that our velocity fell by 70% between the two iterations.
Instead of using a story count, we should use an abstract estimation value. The unit of the estimation value doesn't have to represent anything concrete. For the purposes of this post I'm going to call my estimation units "peanuts". Arguably, I would suggest against using a measure of hours because of some of the negative planning and estimation connotations that it carries around. So now the people doing estimations are using peanuts to determine how much work each story entails. When it comes time to measure velocity, you will count the number of peanuts that each delivered story was estimated at and use that as the final tally. Because this is based more on effort rather than quantity you should get better analysis about the fluctuations that your project will encounter.
So with the definition and method of measurement roughly determined, I'm now thinking that velocity is more than just a math calculation resulting in a cold number. Velocity is the heartbeat of your project. The more I think about this, the more I'm believing that I can tell the health of my software development team by listening to the velocity. If I see that the team's velocity has been at what I think is an inflated value for an extended period of time, it might be a good sign that I need to let the team step back and take a breather. Like a heart, teams can flex their muscle and produce at high levels when required, but in the end both the heart and the team need to recuperate.
Even with the frenzy of development happening around the team, there is always an feeling of the velocity that is being achieved. The social nature of teams dictates that there will be cross conversation between members about the progress that each is making. This may happen informally around the water cooler or in a more formal setting like daily standups. Regardless, every team member knows the feeling when the team is getting bogged down. Those people that have intimate daily contact with the development effort will not need to see the velocity graphs or numbers to know when things aren't moving along. This is good because hard velocity metrics are for the people above you. The people who have to justify the team's existence or it's timeline. Self motivation at the team or individual level is much better served by the gut feelings and 'vibe' that is surrounding the group on a daily basis. Those feelings are much more real time and thus should allow for a faster diagnosis and response.
One of the things that goes unnoticed with velocity is it's impact on moral. Development teams that have attained and maintained an acceptable velocity will thump along like the heart of an athlete. If the velocity wanes, the extremities will not be nourished adequately and the core of the team will lose the ability to feel and manipulate them. You will see people loosing interest in keeping the build successful or writing adequate tests. When you have adequate or high velocity all things need to work together which doesn't allow for members of the team to forget about the little things that so many rely on.
In the end, velocity brings more to a project than just delivering functionality in a timely fashion. It's not just a metric that we can use to judge the iteration to iteration successes and failures of a development team. Velocity is about the overall health of the project. It's more like the EKG of the project than anything else. You can tell a lot from those blips.
So, what should I test?
I was talking with Dave Woods today and we slid into this topic. We've all been in a situation where we release a new version of our software to a client's testing environment and they immediately ask "So, what should I test?" For most of us developers this is a tough question to answer. We're not experts in the black art of system test design and writing. Heck, most of us are only a couple of years into full blown unit testing. So how do you answer this?
I figure I've answered the question three different ways.
- I tell the client specifically what areas I changed. I suggest that they can be confident testing only those specific things. Usually these changes have few, if any tentacles through the rest of my codebase. Sometimes I will suggest this method if the change is simple to test and part of a common utility. Testing JavaScript that is used on every webpage and only changes the image of a control common to all those pages is not worthy of one or more tests per page. Instead I would suggest testing it on one or two randomly selected pages.
- I tell the client which modules, pages or processes have been, or could be affected by the modifications that I made. Usually this answer would be given if I have a moderate confidence that the testers will not see side effects in places that they may not be expecting them.
- I tell the client to retest the entire application. What I think rather than say is "If you guys only knew how ridiculously scared of breaking all kinds of things in the app when I made this change, you'd run for the hills." If I were a client and I was told by a dev team that I should retest the entire application, I would take it as a sign of some serious code and development process smells.
Underlying all three answers is the common question I have to ask myself of my code. "How much faith do I have in the isolation of the changes that I just made?" More confidence should mean a smaller swath of testing. Occasionally you will get bit by this. You'll say "Just test that one thing there" and, sure enough, 10 minutes after it gets released to production your phone will be buzzing with bugs that the isolated testing didn't find.
The other thing to remember is that your automated tests (assuming that you have them) can give you enormous confidence in the fact your changes didn't ripple through the system like a mini tsunami. The only thing is that you see them....not the client. The boost in your confidence is not easily transmitted or felt by the people who haven't worked with your automated tests, so they will be wary. No matter how much you say "None of our automated tests failed after we made the changes", clients will be justifiably skeptical.
Looping Code Smell?
I read somewhere in the last few days that someone considered that looping over enumerable lists using a for loop should be considered a code smell. They went on to say that the preferred way to loop should be using the foreach syntax.
The reasoning behind the the preference was that the for loop syntax opens the possibility for boundary errors. Everyone has written a loop over an array where we start at 0 and end at array.Length instead of array.Length - 1.
In the past I would not have cared if a developer had used either method of looping. Today I opened up some code and the first thing that I noticed was that the it used the for syntax and my immediate reaction was to verify the boundary values in the syntax. So why should I have to do that? If we're going to write a loop that navigates over an entire collection of data, should we really have to worry about coding the boundaries? We have the foreach syntax which automatically takes care of the boundaries. Why not use that?
In the modern development world we go to great lengths to abstract away complexity. I've come around to believing that the for syntax doesn't achieve this. Sometimes it may be needed, but for looping over entire collections I think it should be avoided.
Inbred in IT
I was thinking about the reasons that I'm continually getting a feeling of conceptual and practical stagnation when I go in to work. One can easily say that it's because people are stuck in their ways, but I think that there's more to it than that.
Every so often I have conversations with people who are so proud when they state "I've been here for over 20 years". There always are people who stay at one company for a long time, but I've been shocked at how large that person count can be. To top this off, the new blood that is injected into the company's genetic makeup is scared away by dire practices, incredibly ridiculous deadlines and continual management meddling.
Here's my theory on the stagnation. When you spend a lot of time with the same people (let's say coworkers for 20 years), and you don't get regular and strong injections of new people, the idea pool doesn't grow. In our industry, ideas are the genes in a family tree. If you keep working with the same ones, your family starts to get weaker an weaker genetically. If you only circulate and implement the same ideas over and over, the IT portion of your company will begin to wither, tire and cripple.
I'm finding the that people who have been around in these situations now are blind to alternative solutions. This is a group of people who are not late adopters, but non-adopters because they've never had to before. Their world has revolved around the few ideas that have been repeatedly shared amongst themselves. Their experience has never included comprehending, assimilating and using new ideas on any mass scale. No matter how hard you work at describing a proposed solution, the situation and it's validity, the blind can not be brought to see it. Instead the only way to convince them by putting into their hands so they can feel it. The only thing that seems to work is to circumvent the inbreeding.
Usually this isn't well received by the inbred clique. They'll label you as a renegade...a loose canon. All they're trying to do is get you to fall back in line with their incestuous way of thinking. They fear the things they don't know...your ideas being the foremost on their mind. Once you have something tangible, take the time to show the inbred masses that it works and explain it to them. There will be naysayers. Whether to your face or not, you and your ideas will be berated, belittled and torn apart. Don't worry about it. Let the working solution stand as your testament.
So on Valentines Day I leave you with one last thought: Inbreeding runs deep and trying to stop it is impossible, but at least there's only a few people to screw you.
Walking the Property Tree with Reflection for the EViL project
This past week I started to work on the EViL project over at Codeplex. I figured that if I commented about all of its weaknesses, I should get involved and offer some solutions to the problems that I pointed out.
Today I finished up the first bit of code that I was working on. What I was looking to do was extend the capabilities of the attributes in the EViL framework so that comparisons could be made to properties that were attached to embedded objects. For example, I want to be able to ensure that date of an invoice is not before the opening date of the customer associated with that invoice.
public class Invoice : EvilBaseEntity { private Customer _customer; public Customer Customer { get { return _customer; } set { _customer = value; } } private DateTime _saleDate; [ValidateDateOccursOnOrAfter("Customer.OpenAccountDate","Invoices can not be dated before the opening of a customer's account.")] public DateTime SaleDate { get { return _saleDate; } set { _saleDate = value; } } } public class Customer { private DateTime _openAccountDate; public DateTime OpenAccountDate { get { return _openAccountDate; } set { _openAccountDate = value; } } }
In the end the solution was quite slick. Because you can't get the source from Codeplex, I've included it here. What I managed to do was write a recursive function that would parse through the "." delimited property name and navigate the tree of properties until it either couldn't find the requested property or it reached the end of the passed in property name. I ran into two interesting situations while working on this.
First, I had to figure out how to handle lists of objects. I couldn't figure out a reason that I'd want to compare one property value to one property from multiple different objects. Until I hear of or run into a situation with the need for this, I decided to leave it as a gap in the functionality. To do this I had to treat all IEnumerable objects that were the value in the property string as if they weren't found. This allows the code to navigate over an IEnumerable to make comparisons to properties such as Count and Length. Here's how you can compare the Count property of the Items IList<> type.
public class Invoice : EvilBaseEntity { private Customer _customer; public Customer Customer { get { return _customer; } set { _customer = value; } } private DateTime _saleDate; [ValidateDateOccursOnOrAfter("Customer.OpenAccountDate","Invoices can not be dated before the opening of a customer's account.")] public DateTime SaleDate { get { return _saleDate; } set { _saleDate = value; } } private int _saleItems; [ValidateLessThanOrEqualTo("Items.Count","There can not be more sale items than there are items.")] public int SaleItems { get { return _saleItems; } set { _saleItems = value; } } private IList<Item> _items = new List<Item>(); public IList<Item> Items { get { return _items; } set { _items = value; } } } public class Customer { private DateTime _openAccountDate; public DateTime OpenAccountDate { get { return _openAccountDate; } set { _openAccountDate = value; } } } public class Item { private string _name; public string Name { get { return _name; } set { _name = value; } } private double _cost; public double Cost { get { return _cost; } set { _cost = value; } } }
The second thing I had to deal with was as a result of limiting the comparisons to IEnumerable types. As many developers forget (this one included...thank goodness for unit tests), strings are IEnumerable. As soon as I implemented the code to treat IEnumerable types as not existing, all comparisons to strings would fail. All I had to do was add a quick check for string types and everything was peachy again.
Here's the function that I created to do all of this work. As you can see, it's nothing special and it could probably do with a little refactoring to get the logic depth under control.
/// <summary> /// Gets the value of property that is being compared to. This recursively searches /// through the object tree based on the propertyName passed in. If the name is /// in a Class.Class.Class.Property format it will traverse all the way to the Property /// and use it for comparison. /// </summary> /// <param name="propertyName">String representation of the property that is being compared to. /// Should be in a Class.Class.Class.Property format if the property is in embedded objects.</param> /// <param name="entity">The class that the property is being searched for in.</param> /// <returns>The property value if it is found. If the property is not found, null will be returned.</returns> protected object GetPropertyValue(string propertyName, object entity) { string[] propertyNames = propertyName.Split('.'); if (propertyNames.Length == 0 || entity == null) { return null; } string firstPropertyName = propertyNames[0]; PropertyInfo[] properties = entity.GetType().GetProperties(); // Loop thru to find the one we want foreach (PropertyInfo pi in properties) { if (pi.Name == firstPropertyName) { //this is to prevent comparisons against lists of objects, but allows comparison against properties of those lists if (pi.PropertyType.GetInterface("IEnumerable") != null && propertyNames.Length == 1) { //this is needed because strings are IEnumerable and without this we can't compare string to string easily if (typeof(string) == pi.PropertyType) { return pi.GetValue(entity, null); } else { return null; } } else if (propertyNames.Length > 1) { return GetPropertyValue(MakeTrimmedPropertyName(propertyNames), pi.GetValue(entity, null)); } else { return pi.GetValue(entity, null); } } } return null; }
Hi my name is Jack and I'm a...Canadian?
Recently I went through the exercise (quite unsuccessfully I might add) of trying to determine what is my technical expertise. I'm sure you're thinking "Well that's easy, he's a .NET developer". Well, you're right, but I was looking to determine if I could convince myself that I had an expertise that was more granular than that. I was looking to be able to feel justified in saying I'm the <insert .NET technology of choice here> guy.
Frankly, I couldn't do it. I'm a Jack of all trades and master of none. I've worked with all sorts of different technologies, but I can't think of one that I've worked with throughout my career. Instead of becoming the "UI guy" or the "Data Access guy" on a project, I usually just grab whatever work needs to be done and get att'er. Truthfully, I rarely think about what I need from the project and instead concentrate on what the project needs to succeed.
After realizing this, I began to think about the possibility that my lack of focus may have put me into a bit of a professional sales pitch pickle. I asked myself if I thought I could sell my random cross section of skills to a client better, worse or the same as the person down the block who can credibly claim to be "Mr/Mrs Technology-X". It was an interesting conversation that I had with myself about this topic. I think it did a lot more for me than it did for the people that were sitting in the next table over at the coffee shop.
I heard or read a great story that semi-pertains to this subject. When the Red Cross begins to staff up teams to assist in disasters, the call goes out, from management to the different countries around the world. When the managers put together their skillset shopping list they ask may ask for "Logisticians, Drivers, Mechanics, Construction Workers and Canadians" (this story probably gets told all over the world so replace Canadians with your country of choice). Now, a list of specific skills followed by a nationality is a little bit odd. The rationale behind it is that the Canadians (or whatever country you inserted into the story) can, and will, do anything that is asked or needed of them.
The thing is, software development project managers and team leads, like Red Cross managers, love this type of person. I have a guy like this on my team right now. I couldn't survive without him. I firmly believe that utilitarian programmers are the glue that binds a decent team together. They're the ones that can switch and cover for a person on a moments notice. They're the ones that will be asked to put a second set of eyes on some code. Invariably they're the ones that have the most wide spread respect from their peers on the team.
Being an expert may get your names up in lights, but there's something great about knowing that you can be put into any situation and you will not be a detriment. As tempting as the marquee billing is, I don't think that I'd like it any better than being the person featured on page four of the program.
Dictating to the User for Technical Reasons
I have been fighting with a technical situation at one of my clients for the last couple of months. Because of decisions made, well before my time, about the architecture of the application I'm working on, we have no ability to provide full transactional protection to the data that we're saving to the database. After numerous meetings with architects from different areas of the company, I've been told that this is the way it is and there is no remedy in sight.
I was called a meeting again this past week to discuss issues around one set of specific transactions where we were seeing orphaned data being created in our testing environments. After looking through the business transactions and their fractional technical transactions, one of the solutions that was presented to me was that we should split the screens in the application so that they match the individual transactions instead of rolling all that functionality together into one screen.
I'm certainly not a professional Business Analyst, but I can't see how we, as technical people, can have the gall to dictate the screen flow and functionality to the end user. We are, after all, building this application for them. Even worse, how can we tell the users that their we can't accommodate their business needs when they see the same types of functionality in other applications? Not to stereotype the people that made these comments to me, but they were old school main frame folks and all admit readily that they don't have the first bit of knowledge about "...that new fangled Windows .NET development..." Again, running the risk of stereotyping, I think that dictating to the users is an approach that was used in the past. I also think that this is why we've historically seen a huge amount of animosity between clients and the technical teams. In the past few years the friction between the two has started to wear away, and, in my experiences, the two groups are working together with great results.
I have no problems with telling a client that their request is not doable with the time and financial constraints that they're placing on me. I can not, however, tell them that their requests have to be shelved due to what I know are surmountable technical issues.
Remember that your users primary goals usually are to get a product that works in a way that makes the most sense to their business flow and needs. Unless you worked in their department or industry for a number of years and have now moved over to the technical world, you have no business dictating to them what they should and shouldn't be able to do. We are, after all, problem solvers. It's the nature of our jobs. Embrace that fact instead of working within, and imposing, perceived restrictions.
ReSharper...crack for developers
I've been using ReSharper for about two years now. As much as I would rather be drawn and quartered than work with the guy who suggested we make it a requirement on that project, I will give him credit for introducing me to crack cocaine for .NET developers. I realize all to well that I don't get enough IDE time at work anymore. With that said, I do find that every week I'm finding great little things within the tool.
For the last week or so, I've been working on recovering as many of the over two hundred ignored tests in our project as possible. To run the tests I have three tools at my disposal. nAnt/nUnit scripts, TestDriven.NET and JetBrains' UnitRun. I hadn't really played with UnitRun before starting this exercise, but I will never leave it again. Probably the greatest thing for my current situation is that I can click the little yellow and green ball that appears to the left of the test definition and run it even if it is ignored.
I also noticed today, on the JetBrains .NET Tools Blog, that there is a suite of six ReSharper PowerToys available for download. I took the time to try a couple today. The new find tool presents the results of a search in the same structured result list that the Find Usages feature does. The unfortunate thing with it is the cumbersome Ctrl-Alt-Shift-F keystroke required to launch it. I also tried the Cyclomatic Complexity tool, but when it was enabled and I navigated to the ReSharper | Options screen and selected the appropriate menu item for this tool, the Options window would immediately close and I wouldn't be able to open it again unless I removed Cyclomatic Complexity from the ReSharper | Plugins... screen. Frustrating.
I also heard the guys on my team talking today about how to perform a refactoring that we had agreed to do. Said by one guy "It'll be easy if we use ReSharper"....and he was right.