I am compelled to febreeze every bit of code smell I come across. I often rewrite large sections of working code into better structures, more readable/concise syntax, better naming of variables/functions, etc. and In the process I have at times introduced bugs.
But that isn't enough to deter me.
I feel like I've accomplished something but in reality I have done nothing. It's kinda like cleaning behind the refrigerator. You know it's dirty back there, but it's not stopping the fridge from keeping your food cold.
At my current job I was introduced to the notion of 'past you' and 'future you'. I hadn't really thought about actions in those terms exactly, but the act of doing something today so that in the future when you come back to it you'll be in a better position, is the essence of the philosophy.
I have found that taking the time to rewrite the code that finally works into something that I can explain to myself in the future has paid dividends when I came back to it, and when I have not done that, we'll that can be annoying.
One thing I'm also guilty of is fixing code that I'm not currently touching. I like consistency and having a project with code from old me (and old others) mixed in with code from new me (and new others) really bothers my OCDness. The problem is that changing working old code in lieu of fixing bugs or adding features is just another form of procrastination.
There is a time and place for code cleaning. If the code isn't something you are already working in, then leave it. If you are tasked to fix a problem or add something to existing code then cleaning it up is acceptable. Keep mind, I'm assuming there are tests written. Nothing pisses off your co-workers more than cleaning up working code and breaking inadvertently breaking something.
I am compelled to febreeze every bit of code smell I come across. I often rewrite large sections of working code into better structures, more readable/concise syntax, better naming of variables/functions, etc. and In the process I have at times introduced bugs.
That's sort of like throwing a punch so hard that you throw yourself off balance.
I would suggest that you take that energy and first write unit tests or a code coverage tool or an assertion framework that doesn't intrude on production. (I've done all of the above, but I may have been "cheating" by using a language with exceptional access to the meta-level.)
This would allow you to refactor with greatly reduced introduced bugs. That would be more like keeping your balance thus staying in a good position to exploit an opening.
This happens to me too, but I try to take a more optimistic look at it. I've found that code that I've written that turned into a monstrosity is code that I'll rarely want to touch again. If I don't want to touch it, then I'm less likely to add (or remove) features, fix bugs, etc.
But if I find the time to clean that code up---make it simpler and clearer, usually---then I find that I'm no longer fearful of touching that portion of code. I'm reinvigorated to fix bugs, add/remove features, etc.
So yeah, while the intangible effect is, "oh I've made the code simpler that really does feel good," I've also found tangible effects because I'm more motivated to work with that code in the future.
> I am compelled to febreeze every bit of code smell I come across. I often rewrite large sections of working code into better structures, more readable/concise syntax, better naming of variables/functions, etc. and In the process I have at times introduced bugs.
I can absolutely relate to that. It has happened that I find code so terribly written that needed to be modified. As nobody on the team actually understood how it was supposed to be working, I ripped it out, and rewrote it in a cleaner way. I knew this may introduce regressions, but I knew the modification I had to make would very likely do the same thing. But if there were going to be bugs, I'd rather have them come from a maintainable codebase.
> You know it's dirty back there, but it's not stopping the fridge from keeping your food cold.
Unfortunately, the more technical debt you accumulate, the more difficult it is to change anything. So, yes, enough dirt will eventually lead to "we can't do X because it's too risky/too much work". Ideally, we should all do some refactoring every week.
I feel the same way, only I usually end up packing up those nice refactorings and tucking them away. I do not want to introduce a live site bug while trying to make things "nicer."
I've had the same problem at times. It's kind of a mental masturbation; adding more abstract structures and more higher order functions.
Need to strike a balance between Get Shit Done and leaving behind code that isn't a pain to maintain.
In fact, often the kind of abstractions I've created when I'm in that masturbatory mode described above, it turns out that the abstractions aren't worth it in the end because they're only used once, and it doesn't actually make the code cleaner or easier to maintain going forward!
Isn't that what unit tests are for? I seem to recall the original XP practices mandated unit tests mostly as a way to allow the programmer freedom to refactor without fear of breaking code.
Good Article, I have found the hardest part of software to be the team work. It's hard to agreement on what's right, to write code that other people understand, to understand other peoples code, and generally just to get a good productive team working.
In fact a lot of software design is just for making things easier for humans. Otherwise we could have files that are 14,000 lines long.... The hardest part of software is the people.
strong ideas that are held weakly! I try my hardest to cultivate a mindset that allows people to speak freely and express their ideas and also drop said ideas when a clearly better idea arises.
Every idea brought to the table should have a counter argument, we should all carefully discuss the pros and cons of everyone's ideas, and we shouldn't hold so tightly onto a pipe dream because we really want to use xyz tech or because "we're used to doing it x way!"
If something is clearly better, safer, smarter, or mitigates risks that another idea doesn't then you need to accept it. I do not care how comfortable you are with your idea. It is time to switch gears and make the sensible choice based on the facts, not your personal bias.
> Good Article, I have found the hardest part of software to be the team work.
This... I'm trying to work with someone whose only programming experience is with IDEs on Windows that hand-hold every step of the way. Something as simple as creating a file, compiling it and running it in a terminal is something he's never done.
I've spent more time trying to explain incredibly basic concepts than actually getting anything done.
Here's why I think programming will never get much simpler than it is now...as our stacks and applications become more sophisticated and powerful, so do the relations between the systems...Apple has managed to make things simpler on iOS by clamping down on what developers and users can do, which is one possibility for a "simpler" future. But for those who do want to be developers and have flexibility...complexity will just have to be a way of life.
As an example, I recently tried my hand at making a Chrome extension using the Yeoman build tool. It was a simple plugin to allow you, on Reddit IAMA pages, to hide all comments except those from the IAMA subject and their direct questioners, and to also auto-load all comments:
Figuring out how to use the yeoman build tool took about 30 minutes (it's not quite fully developed)...it took about 30 minutes to browse through the Chrome extension documentation and then think of what I wanted to do. About 10 minutes to write the actual jQuery.
...And then about 3 - 4 hours figuring out why the comment auto-loader wasn't working. I thought I could simply just have my jquery activate the "click" event on all "load more comments" links...but a recent Chrome upgrade clamped down on security, effectively sandboxing all extension code and preventing it from executing existing inline JavaScript.
IMHO, this is a good security measure. But it just goes to show you that when things are made "easier" (the scaffolding of the extension, the jQuery to do DOM/AJAX work), there are still intractable tradeoffs and details that have to be dealt with...in this case, security.
I had a similar experience with a very basic Android app I did for a Coursera class. It took me about an hour to finish it, and then 3-4 hours to figure out that the test cases would only run successfully using one particular Android virtual device at a particular API version. It didn't work on any other AVD's or on my phone. This was an exercise designed by a compsci professor at a major university. Who knows how many additional hours would be necessary to determine the exact reason for the error?
I think "bad environment" is the worst of all the problems.
At first we had no environment, so we had to make it ourselves. A few companies did this, and turned into monopolies.
Then we started trying to make free/open-source environments to combat this problem, but they ended up so incredibly scatterbrained that compatibility is a very real and current nightmare.
The monopolies are trying really hard to give us good environments, but first of all they come at a cost, which isn't accessible to many (Apple's hardware, MS's software, etc). And secondly they are not community-driven efforts, so we have little control over them.
So the battle rages on between the plethora of options I have for a programming environment. Meanwhile I'm just trying to write some simple apps that help me pay the bills (we get dangerously close to not being able to each month) and the competition between environments only slows me down.
Free/open source OSes are great programming environments that leave you in control.
As for the compatibility 'problem', install the compiler/interpreter version you need from source, use chroot if you need to, etc... If you're making apps to run on said scatterbrained systems, you can ship statically linked libraries with the app, or use a cross-platform solution (Java, HTML5, something like Haxe, etc...).
To me what is difficult about programming is to deal with huge undocumented and badly written legacy code, and also understanding tons of frameworks and APIs. Algorithms are the easy part.
Yes. My company's CRM uses a single 2500-line Perl script to handle all of its licensing emails. The script was written by our current VP of engineering in 1998 when our CRM was still built on ActiveX. I started porting this code over to Ruby for our now Rails-based CRM and I am beginning to doubt I will ever finish.
Programming is difficult because people are profiting from the difficultability of it. For as long as you can give someone a money-making machine, but say that it will be 'a lot of esoteric work' to make it, grease it, keep it clean .. there will be development work.
By the very nature of the business, if you are not improving something, some human-describable human activity, by using esoteric magic, you're probably not that good. If you're making it indescribable in the process of making improvement, perhaps you've been in the business a long enough time to know, the only difference is whether the customer can be bothered to learn the language, or not. Anyone can 'program computers'; computers are a universal language.
> Programming is difficult because people are profiting from the "difficultability" of it
That's backwards. Not "anyone" can program computers. Anyone can try, but most will fail. Just like "anyone" can "do math" or "do chemistry" or "do anything", but most will fail. The reason programming is lucrative, whether as an employee or entrepeneur exploiting programmers' labor (or supplying their own technical labor), is exactly because not everybody can program well enough to meet a market need.
It's a curious thing, this misplaced, or in some cases faux-humility about programming, or any other academic/intellectual endeavour. It dovetails very well with certain business interests who would love for nothing more than programming to be as commoditized as, say, janitorial work is. These interests are definitely getting their wish in some areas (e.g. web/mobile development).
Anyone can learn plumbing, framing, or drywall too, that doesn't mean we should all learn to do everything we need done. Furthermore it's not feasible or practical for anyone to be a master of everything.
This view point overlooks the fact that people don't have infinite time and resources for learning and/or creating stuff. It also ignores the role of specialization.
Amen. When I think, "I love my job", I'm generally thinking about the "easy" part, where the tools are all under my control and well known, and I just have to build something with them using my knowledge of algorithms and architecture.
However, the reality tends more often to be:
- Frantic Googling trying to figure out the magic code to pass to a black box 3rd party component that will prompt it to spit out exactly what I need
- Banging 3rd party components together to see what happens to be compatible
- Trying to figure out how to work around the limitations of an API without being too inefficient or complex
- Spending 4 times longer on conference calls discussing a problem than actually fixing it
This article only scratches the surface of the "programming is easy, programming is hard" riddle. It's a big question really, linking up with the "mythical man month" and all the paradoxes that commentators have observed since people began thinking about the process of programming.
The way I would put it is that programming gives a person more power to realize their ideas than any other device in existence, in that sense, programming is the easiest thing ever. But since programming put so much power at your finger-tips, it gives you more ways to shoot yourself in the foot than any other activity. So programming while avoiding the pitfalls can suddenly look like the hardest thing in the world.
Arguably humans have a natural facility with language. And I am inclined to believe that our ability to produce programs leverages that facility. But again, the upshot is we wind-up with a really big cannon that, if aimed at all wrong, blows our feet clean away.
I enjoyed this post for one very simple reason: it makes me realize that, no, I am not the only one who dislikes these parts of programming.
Too often when problems like those mentioned by Joe are brought up in discussion, the (seemingly) majority of programmers argue that these are just complexities we have to deal with. Perhaps they're just the vocal ones. I admit, it is a pragmatic attitude, but I constantly daydream about an environment, both technical and social, where these problems mostly disappear.
Thankfully, we're starting to approach some solutions on the technical side with virtual environments, deterministic builds, etc.. The social side I hope will fall out of having better environments for reproducible behaviour. Although I believe a total solution is technically impossible (at least practically, e.g. requiring total system verification, managed behaviour, etc.), I think we can make a lot of improvements to the environments we currently use.
I have always argued that programming is not "intellectually difficult" (for me) but is rather "emotionally difficult" for a lot of the reasons mentioned in the blog post.
I don't know whether I think programming is hard or not. I think it's difficult for the fact that it requires a unique way of thinking and it takes a series of consecutive and uninterrupted thoughts in order to form a piece of logic.
I cannot even imagine learning programming and not having instant access to learning material/answers to my questions.
In short, working with computer is easy, working with people is hard. This is also reflected by salary. It pays to have the skill communicate, influence, or manipulate people.
Most programmer job is simply translate others thought to language that computer can understand. Therefore the difficult is never the programming part, but the understanding human being part.
Comparing to human ability making computer close to understanding human, civilization has developed much more advanced in manipulate human to think like computer, evidenced by all the gadgets surround us today. Comparing to programmers inventing new ways to make computing smarter or say closer to human, majority of corporate line of business IT programmers are merely temporarily filling the gap between human and computer, but for how long? There is no need exaggerate the Corporate experience, that's a translator job can be easily replaced by cheaper labor and eventually by smarter computer.
Programming used to be hard because of the hyper-optimization needed to get things to run.
Now programming is hard because of the giant scale of existing open source codebases.
It's not just the libraries, it's the toolchains, the build systems, the versioning tools, and that's just the things I've touched myself.
Someone once compared classical mathematics with modern mathematics, with the analogy of open pit mining vs deep shaft mining. I think programming has followed a similar trend. Modern programming involves strategically using existing tools, combining them without making major modifications to any of them. Of course, this is just for the individual programmer working on a discrete task. There is still room to participate in or lead large projects.
With the words of my mentor at my first programming job:
Beginners guess programming is hard.
Advanced ones think programming is easy.
Experts know programming is hard.
> When I’d finished this article, I wanted to spell check the content. At this particular time emacs-ispell mode decided to that it could not find aspell, the program that I use for spelling checking.
Does emacs have a grammar sanity check as well as spellchecker?
[+] [-] buckbova|12 years ago|reply
I am compelled to febreeze every bit of code smell I come across. I often rewrite large sections of working code into better structures, more readable/concise syntax, better naming of variables/functions, etc. and In the process I have at times introduced bugs.
But that isn't enough to deter me.
I feel like I've accomplished something but in reality I have done nothing. It's kinda like cleaning behind the refrigerator. You know it's dirty back there, but it's not stopping the fridge from keeping your food cold.
[+] [-] ChuckMcM|12 years ago|reply
I have found that taking the time to rewrite the code that finally works into something that I can explain to myself in the future has paid dividends when I came back to it, and when I have not done that, we'll that can be annoying.
[+] [-] jrs235|12 years ago|reply
However, "You know it's dirty back there, but it's not stopping the fridge from keeping your food cold."
If you don't properly maintain your fridge and allow too much dust to build up you could end up burning out the compressor.
Everything needs to be done thoughtfully, in moderation, and with purpose.
[+] [-] matwood|12 years ago|reply
There is a time and place for code cleaning. If the code isn't something you are already working in, then leave it. If you are tasked to fix a problem or add something to existing code then cleaning it up is acceptable. Keep mind, I'm assuming there are tests written. Nothing pisses off your co-workers more than cleaning up working code and breaking inadvertently breaking something.
[+] [-] stcredzero|12 years ago|reply
That's sort of like throwing a punch so hard that you throw yourself off balance.
I would suggest that you take that energy and first write unit tests or a code coverage tool or an assertion framework that doesn't intrude on production. (I've done all of the above, but I may have been "cheating" by using a language with exceptional access to the meta-level.)
This would allow you to refactor with greatly reduced introduced bugs. That would be more like keeping your balance thus staying in a good position to exploit an opening.
[+] [-] burntsushi|12 years ago|reply
But if I find the time to clean that code up---make it simpler and clearer, usually---then I find that I'm no longer fearful of touching that portion of code. I'm reinvigorated to fix bugs, add/remove features, etc.
So yeah, while the intangible effect is, "oh I've made the code simpler that really does feel good," I've also found tangible effects because I'm more motivated to work with that code in the future.
[+] [-] mercurial|12 years ago|reply
I can absolutely relate to that. It has happened that I find code so terribly written that needed to be modified. As nobody on the team actually understood how it was supposed to be working, I ripped it out, and rewrote it in a cleaner way. I knew this may introduce regressions, but I knew the modification I had to make would very likely do the same thing. But if there were going to be bugs, I'd rather have them come from a maintainable codebase.
> You know it's dirty back there, but it's not stopping the fridge from keeping your food cold.
Unfortunately, the more technical debt you accumulate, the more difficult it is to change anything. So, yes, enough dirt will eventually lead to "we can't do X because it's too risky/too much work". Ideally, we should all do some refactoring every week.
[+] [-] steve-howard|12 years ago|reply
[+] [-] mnemonik|12 years ago|reply
Need to strike a balance between Get Shit Done and leaving behind code that isn't a pain to maintain.
In fact, often the kind of abstractions I've created when I'm in that masturbatory mode described above, it turns out that the abstractions aren't worth it in the end because they're only used once, and it doesn't actually make the code cleaner or easier to maintain going forward!
[+] [-] billyjobob|12 years ago|reply
[+] [-] swayvil|12 years ago|reply
For example, I presently dance around about 6 projects. Only one really matters.
[+] [-] pattisapu|12 years ago|reply
[+] [-] agumonkey|12 years ago|reply
[+] [-] tenpoundhammer|12 years ago|reply
In fact a lot of software design is just for making things easier for humans. Otherwise we could have files that are 14,000 lines long.... The hardest part of software is the people.
[+] [-] killertypo|12 years ago|reply
Every idea brought to the table should have a counter argument, we should all carefully discuss the pros and cons of everyone's ideas, and we shouldn't hold so tightly onto a pipe dream because we really want to use xyz tech or because "we're used to doing it x way!"
If something is clearly better, safer, smarter, or mitigates risks that another idea doesn't then you need to accept it. I do not care how comfortable you are with your idea. It is time to switch gears and make the sensible choice based on the facts, not your personal bias.
[+] [-] Mikeb85|12 years ago|reply
This... I'm trying to work with someone whose only programming experience is with IDEs on Windows that hand-hold every step of the way. Something as simple as creating a file, compiling it and running it in a terminal is something he's never done.
I've spent more time trying to explain incredibly basic concepts than actually getting anything done.
[+] [-] danso|12 years ago|reply
As an example, I recently tried my hand at making a Chrome extension using the Yeoman build tool. It was a simple plugin to allow you, on Reddit IAMA pages, to hide all comments except those from the IAMA subject and their direct questioners, and to also auto-load all comments:
https://github.com/dannguyen/iama-highlights-chrome-extensio...
Figuring out how to use the yeoman build tool took about 30 minutes (it's not quite fully developed)...it took about 30 minutes to browse through the Chrome extension documentation and then think of what I wanted to do. About 10 minutes to write the actual jQuery.
...And then about 3 - 4 hours figuring out why the comment auto-loader wasn't working. I thought I could simply just have my jquery activate the "click" event on all "load more comments" links...but a recent Chrome upgrade clamped down on security, effectively sandboxing all extension code and preventing it from executing existing inline JavaScript.
IMHO, this is a good security measure. But it just goes to show you that when things are made "easier" (the scaffolding of the extension, the jQuery to do DOM/AJAX work), there are still intractable tradeoffs and details that have to be dealt with...in this case, security.
[+] [-] philosophus|12 years ago|reply
[+] [-] sdegutis|12 years ago|reply
At first we had no environment, so we had to make it ourselves. A few companies did this, and turned into monopolies.
Then we started trying to make free/open-source environments to combat this problem, but they ended up so incredibly scatterbrained that compatibility is a very real and current nightmare.
The monopolies are trying really hard to give us good environments, but first of all they come at a cost, which isn't accessible to many (Apple's hardware, MS's software, etc). And secondly they are not community-driven efforts, so we have little control over them.
So the battle rages on between the plethora of options I have for a programming environment. Meanwhile I'm just trying to write some simple apps that help me pay the bills (we get dangerously close to not being able to each month) and the competition between environments only slows me down.
[+] [-] Mikeb85|12 years ago|reply
As for the compatibility 'problem', install the compiler/interpreter version you need from source, use chroot if you need to, etc... If you're making apps to run on said scatterbrained systems, you can ship statically linked libraries with the app, or use a cross-platform solution (Java, HTML5, something like Haxe, etc...).
[+] [-] yodsanklai|12 years ago|reply
[+] [-] abvdasker|12 years ago|reply
[+] [-] 3minus1|12 years ago|reply
[+] [-] fit2rule|12 years ago|reply
By the very nature of the business, if you are not improving something, some human-describable human activity, by using esoteric magic, you're probably not that good. If you're making it indescribable in the process of making improvement, perhaps you've been in the business a long enough time to know, the only difference is whether the customer can be bothered to learn the language, or not. Anyone can 'program computers'; computers are a universal language.
[+] [-] Iftheshoefits|12 years ago|reply
That's backwards. Not "anyone" can program computers. Anyone can try, but most will fail. Just like "anyone" can "do math" or "do chemistry" or "do anything", but most will fail. The reason programming is lucrative, whether as an employee or entrepeneur exploiting programmers' labor (or supplying their own technical labor), is exactly because not everybody can program well enough to meet a market need.
It's a curious thing, this misplaced, or in some cases faux-humility about programming, or any other academic/intellectual endeavour. It dovetails very well with certain business interests who would love for nothing more than programming to be as commoditized as, say, janitorial work is. These interests are definitely getting their wish in some areas (e.g. web/mobile development).
[+] [-] tenpoundhammer|12 years ago|reply
This view point overlooks the fact that people don't have infinite time and resources for learning and/or creating stuff. It also ignores the role of specialization.
[+] [-] lutusp|12 years ago|reply
If that were true, programmers would be making minimum wage and would be ranked alongside people who wash cars.
[+] [-] rom16384|12 years ago|reply
[+] [-] gnaritas|12 years ago|reply
No they can't. Anyone can try, most will fail, because few are suited for it.
[+] [-] rbanffy|12 years ago|reply
Often with the most hilarious results.
[+] [-] duwease|12 years ago|reply
However, the reality tends more often to be: - Frantic Googling trying to figure out the magic code to pass to a black box 3rd party component that will prompt it to spit out exactly what I need - Banging 3rd party components together to see what happens to be compatible - Trying to figure out how to work around the limitations of an API without being too inefficient or complex - Spending 4 times longer on conference calls discussing a problem than actually fixing it
[+] [-] walshemj|12 years ago|reply
[+] [-] moistgorilla|12 years ago|reply
[+] [-] tantalor|12 years ago|reply
[+] [-] joe_the_user|12 years ago|reply
The way I would put it is that programming gives a person more power to realize their ideas than any other device in existence, in that sense, programming is the easiest thing ever. But since programming put so much power at your finger-tips, it gives you more ways to shoot yourself in the foot than any other activity. So programming while avoiding the pitfalls can suddenly look like the hardest thing in the world.
Arguably humans have a natural facility with language. And I am inclined to believe that our ability to produce programs leverages that facility. But again, the upshot is we wind-up with a really big cannon that, if aimed at all wrong, blows our feet clean away.
[+] [-] dmunoz|12 years ago|reply
Too often when problems like those mentioned by Joe are brought up in discussion, the (seemingly) majority of programmers argue that these are just complexities we have to deal with. Perhaps they're just the vocal ones. I admit, it is a pragmatic attitude, but I constantly daydream about an environment, both technical and social, where these problems mostly disappear.
Thankfully, we're starting to approach some solutions on the technical side with virtual environments, deterministic builds, etc.. The social side I hope will fall out of having better environments for reproducible behaviour. Although I believe a total solution is technically impossible (at least practically, e.g. requiring total system verification, managed behaviour, etc.), I think we can make a lot of improvements to the environments we currently use.
[+] [-] Consultant32452|12 years ago|reply
[+] [-] w4f7z|12 years ago|reply
[+] [-] Ryel|12 years ago|reply
I cannot even imagine learning programming and not having instant access to learning material/answers to my questions.
[+] [-] bitcuration|12 years ago|reply
Most programmer job is simply translate others thought to language that computer can understand. Therefore the difficult is never the programming part, but the understanding human being part.
Comparing to human ability making computer close to understanding human, civilization has developed much more advanced in manipulate human to think like computer, evidenced by all the gadgets surround us today. Comparing to programmers inventing new ways to make computing smarter or say closer to human, majority of corporate line of business IT programmers are merely temporarily filling the gap between human and computer, but for how long? There is no need exaggerate the Corporate experience, that's a translator job can be easily replaced by cheaper labor and eventually by smarter computer.
[+] [-] yetanotherphd|12 years ago|reply
Now programming is hard because of the giant scale of existing open source codebases.
It's not just the libraries, it's the toolchains, the build systems, the versioning tools, and that's just the things I've touched myself.
Someone once compared classical mathematics with modern mathematics, with the analogy of open pit mining vs deep shaft mining. I think programming has followed a similar trend. Modern programming involves strategically using existing tools, combining them without making major modifications to any of them. Of course, this is just for the individual programmer working on a discrete task. There is still room to participate in or lead large projects.
[+] [-] thiloberlin|12 years ago|reply
[+] [-] Kluny|12 years ago|reply
[+] [-] sh4na|12 years ago|reply
[+] [-] buckbova|12 years ago|reply
> When I’d finished this article, I wanted to spell check the content. At this particular time emacs-ispell mode decided to that it could not find aspell, the program that I use for spelling checking.
Does emacs have a grammar sanity check as well as spellchecker?
[+] [-] philosophus|12 years ago|reply
[+] [-] bryan_rasmussen|12 years ago|reply
[+] [-] elwell|12 years ago|reply