Random Thoughts of a Scatterbrain.
 Monday, April 07, 2008

On The Shortcomings of WF

4/7/2008 11:09:47 AM (Eastern Daylight Time, UTC-04:00)

An article in the April issue of MSDN magazine features an interview with Bjarne Stroustrup, the man that invented C++.  There's an interesting quote that quite eloquently and succintly sums up my distaste for Windows Workflow Foundation and BizTalk (at least the versions that I've worked with).

When asked about his feelings on IDEs and how they should (or should not) support languages and the role of the IDE in software development, Stroustrup responsed:

I'm not a heavy IDE user.  I appreciate a responsive IDE editor with understanding of my language, but I also want to be able to work without an IDE.  My desire for portability of code plays a role here.  With C++, I want to be able to understand my system from just the source code in the source files.  I actively dislike IDE mechanisms that involve trasformations or generation that cannot be represented as code fit for human consumption.

While WF does certainly generate code in the background, it's not what I would consider "code fit for human consumption".  It's messy and aesthetically unpleasing (so far as code goes).  I always inevitably end up spending quite a bit of time cleaning up the mess left by the code generation engine; there's an odd disconnect between the cleanly delineated visual design of the workflow and the mess of code that gets generated just for a dependency property.

 Wednesday, April 02, 2008

I Think It's Time For An Upgrade

4/2/2008 1:33:26 PM (Eastern Daylight Time, UTC-04:00)

Massive droolage:

4-2-08-nehalem.jpg

Courtesy of engadget.

SharePoint As A Development Platform

4/2/2008 9:19:53 AM (Eastern Daylight Time, UTC-04:00)

I got an email today regarding a blog post by Jeffrey Palermo on the shortcomings of SharePoint as a development platform.

Now I have to say, SharePoint is not without fault (particularly in the area of feature packaging and deployment), but Jeffrey's perceived issues with SharePoint really show either the lack of personal development experience with SharePoint or a lack of creativity on the part of the team he's working with.

Let's get one thing clear first, okay?  SharePoint is meant as an enterprise collaboration and document storage platform, first and foremost.  One must always bear this in mind with regards to any discussion on SharePoint.  Why is it so big?  Why is it clunky in some places?  Why does it have to be installed on a server OS (okay, I admit, this one is probably more about licensing and $$ than anything technical)?

It seems that Jeffrey's major beef, that it must be installed on a server OS, kills any benefits of SharePoint as a development platform immediately.  So let's tackle this one first. 

First, a disclaimer: I'm not a SharePoint guru.  I don't have 5 years of experience with SharePoint.  I'm only going on what I've learned in working with SharePoint, day in and day out, for the last year.

In our development group of 5 or so people, we've managed to develop against SharePoint quite well, despite the fact that we all run XP as our primary development environment.  How?  Virtual machines.  Of course, some would view this as a hassle, as another stumbling block or quite clumsy.  I view it otherwise as there are numerous benefits in developing against a VM server environment:

  1. Every deployment is exactly the same.  This means that server names, file structures, databases, and so on are exactly the same for every developer.  This aids -- not hinders -- the development of automated scripts and deployment utilities.  On our team, we usually synchronize images once every month or so.  What this means is that we'll take turns updating a common image and then everyone will grab a copy of said image.
  2. Virtual Machines are easy to deploy.  It's called: copy-paste!  Nothing easier when adding a new developer to your team.  Instead of configuring a whole new SharePoint environment, just have the developer copy the latest development image.  So easy, a caveman could do it.
  3. Virtual Machines can be rolled back.  Try doing that with your development environment!  If every developer had SharePoint deployed on his or her machine, a mistake (deleting/altering some core database tables or records, for example) would be devastating...it would mean at least a day of lost work time trying to rebuild the development environment.  Using virtual machines to host the server environment protects it from inadvertant dismantling.  And even if it is somehow altered for the worse, no matter, get another copy from someone else!  And of course, being able to rollback the image (provided that you created a snapshot) makes updates (for example, adding a SQL Server service pack) painless.
  4. Virtual Machines are portable.  Why does this matter?  Demos!  There's nothing more convenient than having a sales guy pack up a copy of the VM with all of the software installed and tweaked for demos.  This is a huge bonus.

Look, the suggestion of developing with SharePoint in a "native" environment in a team is just plain stupid; it's a matter of working harder, not smarter and it shows a lack of creativity in terms of development management.  (One disclaimer: some Visual Studio tools from Microsoft for SharePoint cannot be installed on XP...this is a shortcoming, for sure, but it hasn't really affected our development.  If absolutely necessary, you can install a stripped down copy of Visual Studio on the VM).

Now let's address each of the other 7 points that Jeffrey brings up:

  1. SharePoint isn't easy to install.  I'm going to skip that one because clearly, this man has never installed SharePoint.  It's nothing more than point and click...my gosh, I don't understand how it could possibly be easier.  Aside from this, using a VM approach, it only has to be installed once.
  2. SharePoint isn't easy to configure.  See above.
  3. SharePoint does not integrate well with simple tools.  I'm not sure what he means here.  Many administrative tasks can be handled by stsadm.exe which in turn, means that many of the administrative tasks can be handled by batch scripts.  Aside from this, SharePoint is just an average ASP.NET application.  Stopping and starting IIS, xcopy, and so on...these are all still applicable to a SharePoint deployment.
  4. SharePoint isn't easily extended to make simple tools.  What?  Nothing could be further from the truth.  The only beef that I would hold is that Microsoft doesn't package the SharePoint DLLs separately so you have to extract the DLLs from the GAC of your server environment.  But once you do that, it's easy to reference and use the API by copying the DLLs to your development environment.
  5. SharePoint isn't easy to debug.  Again, I'm not sure what the issue here is.  The process of debugging SharePoint applications (web parts, layout pages, etc.) is no harder than debugging any standard, run of the mill ASP.NET web applications.  Okay, sure, you can't just hit F5 (oooh, the horror!), but seriously, I hate F5 developers - sometimes, F5 just isn't the way to go, dude.  I'm also pretty sure chimps (or macros) can be trained to hook up the debugger and hit F10 and F11.  As for debugging core SharePoint, well, I guess he has a point since the source and debugging files aren't available (not that I know of), but I don't see that as an issue.  I mean, how many platforms ship with debugging symbols included?
  6. It's not easy to create test automation for SharePoint.  There is some truth to this since it requires the developer to learn about the platform first (API, database tables, web services, and so on).  But I don't think it's any more difficult or challenging than setting up automated tests against any other third party platform.
  7. SharePoint configuration does not store easily in source control.  See above regarding VMs.  Aside from this, he's got it all wrong again.  We can look at this from a few different angles.  First, SharePoint is just an ASP.NET application.  Repeat that to yourself about 100 times.  With regards to application configuration (in terms of the web.config), it's as simple as copying the web.config to your source control system and using a script to deploy it on build.  Secondly, if we look at the configuration in terms of web parts and layout pages, it's possible to include these in source control as well using solution packages deployed either on build or manually as features.  Certainly requires a bit of research to get it working the first time, but it's not a task that takes more than 1-2 days of experimentation.

From personal experience, I've found SharePoint a very compelling application development platform (again, that's not to say that it doesn't have shortcomings) because it's nothing more than ASP.NET but with the added bonus of a document management/storage API, profiling, permissions, and it acts as an integration platform for a variety of applications. 

You can make it as hard or as easy as you want it to be with regards to developing applications for SharePoint.  It's only a matter of how much time you are willing to put into flipping through the API and understanding the fundamentals of working with SharePoint.  A big part of successfully and painlessly developing against SharePoint is creativity in terms of setting up your development environment and automation (batch scripts, pre/post-build scripts).

The points that Jeffrey, didn't bring up -- the true pain points -- are really "fringe" features so far as I'm concerned.  Namely, this centers around SharePoint hosted and integrated workflows and InfoPath (because no one likes and no one actually uses the otherwise useless and purposeless InfoPath).  You're not required to use InfoPath or SharePoint hosted workflow; in FirstPoint, absent the early documentation and tools required to be productive on this front, we made an early decision to host workflow in our own environment. Sure, we miss out on some of the native features of SharePoint like workflow state visibility and integrated forms via Forms Services, but I don't see it as something we can't overcome as documentation and tool support becomes better on this front.

 Friday, March 28, 2008

SharePoint: The Second Coming Of Lotus Notes?

3/28/2008 8:51:33 AM (Eastern Daylight Time, UTC-04:00)
As I was pondering the suckage of Lotus Notes, I came across an interesting little piece on a CMS Watch Report titled: "SharePoint Has Become the New Lotus Notes":

Microsoft Office SharePoint Server 2007 is repeating history as it mimics the allure and pitfalls of Lotus Notes, according to research released by CMS Watch, an independent analyst firm that evaluates content technologies.

SharePoint exploits traditionally underserved collaboration needs for information workers laboring within Office tools, and fulfills a common desire to easily create disposable workspaces, CMS Watch found.

Like Notes in a previous decade, IT often embraces SharePoint as a simple answer to myriad business information problems.  But the platform can morph into a technical and operational morass, as repositories proliferate, and IT comes to recognize that various custom applications require highly specialized expertise to keep running properly.

...

The SharePoint Report 2008 concludes by advising customers to establish clear boundaries on SharePoint services, to keep it from becoming their new Notes – the platform that everyone loved, but then loved to avoid.

While SharePoint does indeed have it's weaknesses (total lack of any integration with ASP.NET AJAX in the SharePoint implementation itself -- guess we'll just have to wait for 4.0, web services support is still kind of weak) and oddities (CAML?), it's nowhere near the steaming pile that is Lotus Notes.

On a serious note, I do kind of see the point in that last paragraph there.  SharePoint often gets evangelized as some silver bullet for collaboration ("Oh look, workspaces! Workflows! Tasks lists!") but I've never been in an organization that's used SharePoint in a way that was actually of any aid to productivity or collaboration; people just don't seem to want to log onto a corporate SharePoint portal unless they have to. 

That's not to say that the platform doesn't have its useful bits, but the real gem in SharePoint is its integration with Office applications as a platform for "seamless" sharing of documents and I think the idea of offering that to a much larger audience (via Office Live Workspaces) is long overdue from Microsoft.  Until recently, there were few integrated solutions for small businesses, students, and other non-business groups for the very simple act of sharing Office documents aside from using e-mail. 

Even when I joined Zorch Software, I would do a facepalm regularly when I got an email with a document attached with a "v15" suffix.  I'd save it in the same folder as the previous 14 "versions" that I received.  The irony.  The problem is that most of SharePoint just isn't that useful.  Even in a tech minded organization like Zorch Software, you just can't break some people out of old habits; to many, collaboration is synonymous with e-mail.  There is a whole generation that doesn't get wikis and doesn't want to learn wiki markup. 

Well, in any case, I'm still not over the fact that I'm being forced to use Lotus against my will and I'm still bitter over the fact that it's been so hard to get people to embrace our Trac wiki and embrace the ticket system for tracking issues.

 Thursday, March 27, 2008

Lotus Notes: It Sucks...Hard

3/27/2008 3:30:39 PM (Eastern Daylight Time, UTC-04:00)

As part of the transition from FCG to CSC (Computer Sciences Corporation), we are also switching our mail system from Outlook/Exchange to Lotus Notes/Domino/Whatever.

There can only be one immediate reaction up on switching from Outlook 2007 to Notes 6.5:

WTF?? AHHHHH!!11 MY EYES!! GIVE ME BACK MY OUTLOOK!

Surely, this application which looks like it crawled out of the late 90's cannot be the primary enterprise messaging system for a large, publicly traded company, can it?  Maybe it's a clever ruse to get people to stop using email and actually interact with one another by ecouraging calls instead of email...maybe.  I can't believe IBM actually sells this product and I can only imagine the painful life endured by the Notes sales team and all of the mockery they must live with.  If my parents worked on the Notes team in development or sales, I'd ask to be disavowed for their crime of bringing such a shitty piece of software into existence.

I think I'm going to start my own trail of why Lotus sucks posts, but Lotus Notes Hater already has a headstart on me.

The truly absurd thing that I've learned is that there are actually standalone programs that have been written to clean up crashed instances of Notes!  No kidding, I got the following email from a company wide distribution list:

If Lotus Notes crashes, you don't have to restart your PC anymore! Just run ZapNotes and allow it to clean up what Notes left behind so you can restart Lotus Notes. ZapNotes works on Windows 9x/NT/2000/XP

Lotus Notes Hater comments:

Cassetica charges US$1,500 for NotesMedic Pro and US$2,500 for the enterprise level of NotesMedic. The fact that a company makes money from a product that shouldn't even exist makes us ask, "Why haven't the owners of Lotus Notes put Cassetica out of business by incorporating the feature of NotesMedic directly into Lotus Notes?"

NotesMedic is not the only product out there. There is also ZapNotes. And KillNotes. There are at least three products that have no reason to exist.

Awesome!  Now I'm really gonna look forward to using Notes!

I also got to chat with some of my teammates in Vietnam just to see how they felt about it.  Who knows, maybe their Asian sensibilities would lead them to be more polite and less judgemental.  Maybe their allegiance to their employer would cause them to accept Lotus as their fate and use it dutifully.

Mumble mumble says:
  Did you guys install Lotus yet?
Vietnamese Guy says:
  Yes
Mumble mumble says:
  What do you think?
Vietnamese Guy says:
  Slow
Vietnamese Guy says:
  very slow
Vietnamese Guy says:
  urgly

So there you have it, even the Vietnamese hate it.

 Tuesday, March 25, 2008

Photos And Notes From NYIAS 2008

3/25/2008 1:20:27 PM (Eastern Daylight Time, UTC-04:00)

The highlight of this year's show, for me, was definitely the Nissan GT-R. It's quite possibly one of the most anticipated mass produced vehicles to be released in recent years.

I was also looking forward to the new Maxima. Admittedly, it looks way better in person than it does in photographs; you can't really capture how low slung and aggressive it looks.

It was also an opportunity for my wife and I to explore the 2009 Murano. We haven't made it a priority to stop by the dealership to check one out, but it is definitely a nice upgrade from the outgoing model with a price upgrade to match. The Murano is much more luxurious now and looks surprisingly good in person. I didn't think I'd like the new shape -- particularly the grill -- but I have to say that it looks great in person.

I was hoping to see the Mazda 2, but unfortunately, it wasn't at the show.

As far as the American manufacturers go, I have to say, I like where GM is headed. On a recent trip, I was upgraded to a new Malibu and I'm thoroughly impressed. It may have been the first time I've driven a product from the Big Three and actually could imagine myself purchasing the vehicle. I also really like what they've done with the CTS and the CTS Coupe concept...fantastic work.

Click here to go to the gallery.

DRM = Doesn't Really Matter

3/25/2008 10:52:05 AM (Eastern Daylight Time, UTC-04:00)
It's true, DRM just doesn't really matter.  The music industry has pretty much seen the light at this point with Amazon now offering tracks from all four major labels DRM free.  How much longer will it take for the movie industry to realize the same truth?

Blu-Ray's vaunted BD+ encryption scheme was supposed to give it the upper edge over HD-DVD's ill-fated AACS encryption scheme.  The news on this front the last couple of days has been software maker SlySoft's crack of BD+.

My favorite little tidbit is this statement by the Blu-Ray camp:

Richard Doherty of the Envisioneering Group will have to revise his statement from July, 2007 regarding BD+: "BD+, unlike AACS which suffered a partial hack last year, won't likely be breached for 10 years". It is worth mentioning that since he made that statement only eight months have gone by.
We'll see how this shakes up.  DRM, once again, proves that it is barely a deterrent to pirates while a genuine hassle for legitimate consumers who wish to back up their physical media.

Disabling Office 2003 Browser Inline Behavior

3/25/2008 10:21:43 AM (Eastern Daylight Time, UTC-04:00)

There's a unique problem in an Office 2003 environment that may be encountered by add-in developers.  Namely, by default, Office 2003 documents, when opened from a URL (for example, clicking on a link in an email or typing a URL into a browser address bar) will cause the document to open "inline" with the browser.

open-office2003-from-ie7-s.png

The problem with this, for add-in developers, is that while the WINWORD.EXE process is indeed launched, the add-in is not loaded (I'm still not sure why, but I'm guessing it's due to the different security restrictions of being "hosted" in Internet Explorer).  Aside from this, it's generally problematic because the default menu bars and toolbars are not displayed by default...not the ideal behavior.

As it turns out, in Office 2007, the behavior is entirely different: the document always open in a standalone WINWORD.EXE process.  So how can we get Office 2003 to behave the same way?  A series of articles lead the way to an answer:

First, Microsoft actually has a KB (927009) which advises how to enabled Office 2003 behavior in an Office 2007 environment.  This is the first clue that the core of the issue is a series of registry keys.  Knowing which keys to look for, I simply checked the keys in an Office 2007 environment to get the values which would cause an application like Word to launch in standalone mode instead of inline mode (decimal 44 in the case of Word).

The next step was figuring out how to adjust these values in existing deployments.  One option would have been to use a similar registry script as porposed in the KB but I decided to use a programmatic approach instead.  I came across some hints on how to approach this task from a forum posting and MSDN articles.

The outcome was this script:

/*=============================================================================
   This file contains the scripts which are executed after installation of the 
   Office 2003 client update registry keys which would otherwise force Office 
   documents to open in Internet Explorer (inline behavior)
=============================================================================*/
// Key paths
var commonRootPath = "HKLM\\SOFTWARE\\Classes\\";
var commonPath = "SOFTWARE\\Classes\\";
var commonKey = "BrowserFlags";
var HKLM = 0x80000002;

// Instantiate the shell.
var shell = WScript.CreateObject("WScript.Shell");

// Holds the values for the key types
var keyTypes = {
    String:"REG_SZ", 
    Number:"REG_DWORD", 
    Binary:"REG_BINARY", 
    ExpandableString:"REG_EXPAND_SZ"
};

// Holds the array of all key paths (not including the shared "BrowserFlags" 
// DWORD key name) and the value to assign to the key (different for each
// runtime).
var keys = [
    {Class:"Word.Document", Value:44},
    {Class:"Word.Document.6", Value:44},
    {Class:"Word.Document.8", Value:44},
    {Class:"Word.Document.12", Value:44},
    {Class:"Word.RTF.8", Value:44},
    {Class:"Word.DocumentMacroEnabled.12", Value:44}
];

/*-----------------------------------------------------------------------------
    Main method.
-----------------------------------------------------------------------------*/    
function Run() {
    try {
        for(var i = 0; i < keys.length; i++) {  
            var key = keys[i];
            
            if(RegistryKeyExists(key.Class)) {            
                var keyPath = commonRootPath + key.Class + "\\" + commonKey;                              
            
                shell.RegWrite(keyPath, key.Value, keyTypes.Number);
            }
        }   

	    shell.Popup("Updated registry keys.", 0, "Completed", 0 + 64);
    }
    catch(all) {
        // Failures are considered non-fatal.
        var errorMessage = "A non-fatal error occurred while configuring Word 2003\r\n";
        errorMessage += "document handling in IE.\r\n\r\n";
        errorMessage += "You can re-run this script at a later time from:\r\n\r\n";
        errorMessage += "[Program Files]\\[Common Files]\\FirstPoint\";
		errorMessage += "UpdateOffice2003RegistrySettings.js\r\n\r\n";
        errorMessage += "Press OK to continue.";

        shell.Popup(errorMessage, 0, "Error", 0 + 48);
    }
}

/*-----------------------------------------------------------------------------
    Checks to see if a registry key exists.
-----------------------------------------------------------------------------*/
function RegistryKeyExists(className) {
    var registry = GetObject("winmgmts:\\\\.\\root\\default:StdRegProv");   
    
    var path = commonPath + className;       
    
    var value = registry.GetStringValue(HKLM, path, "");
    
    return value == 0;
}

/*-----------------------------------------------------------------------------
    Abstracts Popup()
-----------------------------------------------------------------------------*/
function Alert(string) {
    shell.Popup(string, 0, "Message", 0);
}

Run();

Perhaps the most useful little tidbit in all of this is the RegistryKeyExists method which checks to see a registry path exists.  A return value of 0 from any of the Get[KeyType]Value() method calls indicates that the path was found; it's a very neat little trick to have up your sleeve.

 Wednesday, March 19, 2008

Bees

3/19/2008 12:17:21 PM (Eastern Daylight Time, UTC-04:00)
Caught this little gem in the comments section of a Slashdot posting:



Windows Made Me This Way

How Software Companies Die

Windows Sources, March 1995, p. 208

By: Orson Scott Card

You can domesticate programmers the way beekeepers tame bees.

The environment that nutures creative programmers kills management and marketing types - and vice versa. Programming is the Great Game. It consumes you, body and soul. When you're caught up in it, nothing else matters. When you emerge into daylight, you might well discover that you're a hundred pounds overweight, your underwear is older than the average first grader, and judging from the number of pizza boxes lying around, it must be spring already. But you don't care, because your program runs, and the code is fast and clever and tight. You won. You're aware that some people think you're a nerd. So what? They're not players. They've never jousted with Windows or gone hand to hand with DOS. To them C++ is a decent grade, almost a B - not a language. They barely exist. Like soldiers or artists, you don't care about the opinions of civilians. You're building something intricate and fine. They'll never understand it.

Beekeeping

Here's the secret that every successful software company is based on: You can domesticate programmers the way beekeepers tame bees. You can't exactly communicate with them, but you can get them to swarm in one place and when they're not looking, you can carry off the honey. You keep these bees from stinging by paying them money. More money than they know what to do with. But that's less than you might think. You see, all these programmers keep hearing their fathers' voices in their heads saying "When are you going to join the real world?" All you have to pay them is enough money that they can answer (also in their heads) "Geez, Dad, I'm making more than you." On average, this is cheap. And you get them to stay in the hive by giving them other coders to swarm with. The only person whose praise matters is another programmer. Less-talented programmers will idolize them; evenly matched ones will challenge and goad one another; and if you want to get a good swarm, you make sure that you have at least one certified genius coder that they can all look up to, even if he glances at other people's code only long enough to sneer at it. He's a Player, thinks the junior programmer. He looked at my code. That is enough. If a software company provides such a hive, the coders will give up sleep, love, health, and clean laundry, while the company keeps the bulk of the money.

Out Of Control

Here's the problem that ends up killing company after company. All successful software companies had, as their dominant personality, a leader who nurtured programmers. But no company can keep such a leader forever. Either he cashes out, or he brings in management types who end up driving him out, or he changes and becomes a management type himself. One way or another, marketers get control. But...control of what? Instead of finding assembly lines of productive workers, they quickly discover that their product is produced by utterly unpredictable, uncooperative, disobedient, and worst of all, unattractive people who resist all attempts at management. Put them on a time clock, dress them in suits, and they become sullen and start sabotaging the product. Worst of all, you can sense that they are making fun of you with every word they say.

Smoked Out

The shock is greater for the coder, though. He suddenly finds that alien creatures control his life. Meetings, Schedules, Reports. And now someone demands that he PLAN all his programming and then stick to the plan, never improving, never tweaking, and never, never touching some other team's code. The lousy young programmer who once worshiped him is now his tyrannical boss, a position he got because he played golf with some sphincter in a suit. The hive has been ruined. The best coders leave. And the marketers, comfortable now because they're surrounded by power neckties and they have things under control, are baffled that each new iteration of their software loses market share as the code bloats and the bugs proliferate. Got to get some better packaging. Yeah, that's it.



Programming is the Great Game. It consumes you, body and soul. When you're caught up in it, nothing else matters. When you emerge into daylight, you might well discover that you're a hundred pounds overweight, your underwear is older than the average first grader, and judging from the number of pizza boxes lying around, it must be spring already.
I know this feeling...well, minus the fat, smelly part.  And I have to admit, I haven't felt it in a while :(

 Thursday, March 13, 2008

The Joe Louis Story

3/13/2008 12:17:20 AM (Eastern Daylight Time, UTC-04:00)

I'm in awe of Joe Louis at this moment and a little bit ashamed that prior to this evening, I'd known almost next to nothing about the man.  Joe Louis: America's Hero...Betrayed is an amazing documentary, telling the story of a man that every American should know and a story that is especially moving to minorities who can look to him as a selfless pioneer.

Selfless in the sense that no person should have to carry the burden of the hopes and dreams of millions of people that individuals like Louis, Jackie Robinson, Rosa Parks, and Martin Luther King Jr. did in their lifetimes.  Against the tidal waves of hatred, the threats against their lives and safety, and in times much different than the one that we live in today, people like Louis gave a nation of minorities hope and pride.  He was a man who didn't shy from his responsiblities and the responsibility of being the ambassador for the black community in a time when they needed him the most.  Perhaps the most inspiring aspect is that he shouldered all of that responsibility in a humble, soft spoken, and professional manner.

It is a must watch not only for minorities, but also for all of America.  Louis isn't merely a hero to the black community, but his story is one of a true American hero and a patriot.  Jimmy Cannon is quoted on the title page of the documentary's website, "He was a credit to his race -- the Human Race."

He is a hero, a role model, a champion, a patriot, and a pioneer.  I hope that he'll be remembered as such in American history for generations to come.

RSS 2.0 Atom 1.0 CDF