<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
   <channel>
      <title>arc90 blog</title>
      <link>http://blog.arc90.com/</link>
      <description>Arc90 is a Web 2.0 design consultancy that delivers next-generation technology solutions for our clients. With technologies like Ajax, Flash and RSS we deliver richer, more powerful strategies and end-user experiences. The arc90 blog is a place where we share our philosophy, ideas, experiences and thoughts on technology and business.</description>
      <language>en</language>
      <copyright>Copyright 2008</copyright>
      <lastBuildDate>Wed, 23 Jul 2008 14:35:00 -0500</lastBuildDate>
      <generator>http://www.sixapart.com/movabletype/?v=4.1</generator>
      <docs>http://blogs.law.harvard.edu/tech/rss</docs> 

      
      <item>
         <title>Flying Virgin America</title>
         <description>&lt;p&gt;I recently flew to L.A. We all know ticket prices are at an all time high and the standards for service in general are very low, so with this in mind, I was extremely delighted to find a reasonably priced ticket on Virgin America Airlines, which is considered a &amp;#8220;premiere airline.&amp;#8221; I'd never flown Virgin before so I was very excited. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Online Experience&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;My first discovery was the great interactive experience on their Website.  This informative site outlines all the cool perks that Virgin provides--like mood lighting and plug-in ports for all your little gadgets including a laptop. I&amp;#8217;d been scrambling to find a way to charge my computer on the plane and had even considered buying an extra battery until I found this out. Problem solved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check-In&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Checking myself in was a breeze--a true sign of a good user experience. Unlike the large kiosks you usually find for self check-in, Virgin has a table with four sleek &lt;a href="http://www.flickr.com/photos/jesseddy/2695788642/in/set-72157606328156148/"&gt;touch screen monitors&lt;/a&gt;. The interface for this process is great&amp;#8212;it&amp;#8217;s nice to look, easy to use, and very quick. Checking in is a five-step process and there's a nice little indicator of this on the screen so you know where you are in the process at all times. As my ticket is being processed, the interface communicates the current time and indicates that I have 40 minutes left until boarding. Thank you interface! My &lt;a href="http://www.flickr.com/photos/jesseddy/2695788370/in/set-72157606328156148/"&gt;boarding pass &lt;/a&gt;then prints and is spit out through a tiny slit that is integrated into the table itself, which is very cool. Additionally, it&amp;#8217;s the smallest pass I've ever seen and yet it still contains all the necessary information. No folding required&amp;#8212;it&amp;#8217;s no larger than my wallet, so I just slip it into my back pocket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Plane&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now the fun really begins. As I walk into the plane, I can see the mood lighting and it's a little like walking into a nightclub. There's jazzy-techno music playing, which in a restaurant wouldn&amp;#8217;t be cool, but in this case, on this plane, it is very much cool. The seats look like expensive, converted executive office chairs from the front and iMacs from the back. They are very comfortable! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Flight Experience&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I find my seat and sit down. In front of me is my very own touch screen monitor, which is actually a media center, called "Red." Red is Virgin's interactive environment and it's in Beta. Like the self check-in interface, Red's interface is also a great experience and has a ton of options. I can watch TV, multi-lingual TV, music videos, premium television (episodes of 30 Rock, Dexter, etc.) and movies (which you have to pay for), and even a section just for kids. Between boarding and taking off, I made an entire playlist and didn't take out my iPod even once during the flight. You can also play games and chat with other people on the plane through an instant messaging system! The remotes accommodate for this perfectly with their three main facets: one side for &lt;a href="http://www.flickr.com/photos/jesseddy/2694969977/in/set-72157606328156148/"&gt;traditional controls&lt;/a&gt; like volume adjustments and channel changing, and the other for &lt;a href="http://www.flickr.com/photos/jesseddy/2694969831/in/set-72157606328156148/"&gt;gaming and texting&lt;/a&gt;, along with an  integrated &lt;a href="http://www.flickr.com/photos/jesseddy/2694969709/in/set-72157606328156148/"&gt;credit card reader w&lt;/a&gt;hich I used to pay (Virgin is a cashless airline) for my yogurt parfait.  Meals are not served on the plane, but you can order food, snacks and beverages from your seat using Red, along with all the free items like coffee, juice and soda, etc. Ordering anything with Red is like building an order on Amazon: you shop, compile, checkout, and pay (or not pay, if ordering free items).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/jesseddy/2694969537/in/set-72157606328156148/"&gt;Google Maps &lt;/a&gt;is also integrated into Red so you can always see your location (Missouri), as well as air speed (514 mph), distance to go until you reach your location (1,415 miles), altitude (36,163), and outside temperature (-51 degrees Fahrenheit). Communication on the plane is great and the in-flight introduction is done through the interface by a very entertaining, illustrated video. There were no awkward live demonstrations of how to apply an oxygen mask and I actually paid attention.&lt;/p&gt;

&lt;p&gt;Virgin is definitely doing something right and it's hard to believe other airlines haven't caught on yet. The utilization and emphasis Virgin puts on design and technology is awesome. Granted, the novelty might wear off if you're a frequent customer, but it sure makes downgrading to another airline an ugly thought!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/343802040" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/343802040/flying_virgin_america.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/07/flying_virgin_america.php</guid>
         <category>Design</category>
         <author>jesse@arc90.com (Jess Eddy)</author>
         <pubDate>Wed, 23 Jul 2008 14:35:00 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/07/flying_virgin_america.php</feedburner:origLink></item>
      
      <item>
         <title>Charles, SSL, and you</title>
         <description>Is &lt;a href="http://www.charlesproxy.com/"&gt;Charles&lt;/a&gt; messing with your SSL traffic? You can fix it by telling
Firefox (or, &lt;i&gt;shudder&lt;/i&gt;, IE) that the Charles SSL proxy is a valid certificate provider.
Here are the instructions:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;&lt;a href="http://www.charlesproxy.com/wiki/ssl_certificates" target="_blank"&gt;http://www.charlesproxy.com/&lt;wbr&gt;wiki/ssl_certificates&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/342702283" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/342702283/charles_ssl_and_you.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/07/charles_ssl_and_you.php</guid>
         <category>Quick Tips</category>
         <author>chrisl@arc90.com (Chris LoSacco)</author>
         <pubDate>Tue, 22 Jul 2008 12:37:17 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/07/charles_ssl_and_you.php</feedburner:origLink></item>
      
      <item>
         <title>We're Looking For The Lone Wolf McQuade Of PHP Development</title>
         <description>&lt;p&gt;&lt;a href="http://blog.arc90.com/WindowsLiveWriter/WereLookingForTheLoneWolfMcQuadeOfPHPDev_98C3/Lone_Wolf_McQuade_TER1071_2.jpg"&gt;&lt;img style="border: 0px none ;" alt="Lone_Wolf_McQuade_TER1071" src="http://blog.arc90.com/WindowsLiveWriter/WereLookingForTheLoneWolfMcQuadeOfPHPDev_98C3/Lone_Wolf_McQuade_TER1071_thumb.jpg" border="0" width="240" height="240" /&gt;&lt;/a&gt; Yeh, this is partly an excuse to throw down this kick-ass image but so what: we're looking for someone who can slay large swaths of software requirements with the sawed-off shotgun that is PHP/MySQL. &lt;/p&gt;  &lt;p&gt;Ok, I'm gonna stop the analogy here. Seriously, if you're well-versed in PHP, MySQL, frameworks (like Zend) and possess front-end/Ajax/JQuery/JSON/XML skills, don't hesitate to hit us up with your resume/portfolio/friendly cover letter.&lt;/p&gt;  &lt;p&gt;Arc90 is a product and consulting firm based in New York City and we're looking for someone to help us build great software experiences. It's a loose, creative and intellectually challenging environment. If you think you've got the goods ("goods" being coding skills and copious amounts of chest hair), &lt;a href="mailto:jobs@arc90.com" target="_blank"&gt;don't hesitate to contact us&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/339058681" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/339058681/were_looking_for_the_lone_wolf.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/07/were_looking_for_the_lone_wolf.php</guid>
         <category>Arc90</category>
         <author>rich@arc90.com (Richard Ziade)</author>
         <pubDate>Fri, 18 Jul 2008 10:51:59 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/07/were_looking_for_the_lone_wolf.php</feedburner:origLink></item>
      
      <item>
         <title>Use grep? Try ack!</title>
         <description>&lt;p&gt;For you command line addicts like myself.&lt;/p&gt;

&lt;p&gt;I find myself using grep constantly to search within files. Most
often in the format 'grep -r "phrase" * | grep -v .svn' To search
subdirectories, and then filter out any subversion files. Which sucks.&lt;/p&gt;

&lt;p&gt;I recently stumbled upon 'ack', which is a similar search function,
but with a whole lot more features, and way faster by default.&lt;/p&gt;

&lt;p&gt;With it, I only need to type 'ack "phrase" *' to get the same result. Neat!&lt;/p&gt;

Some reasons to use ack:
&lt;ul&gt;
&lt;li&gt;Ignores subversion directories by default.&lt;/li&gt;
&lt;li&gt;Color highlighting of matches.&lt;/li&gt;
&lt;li&gt;Full perl regular expression search capable&lt;/li&gt;
&lt;li&gt;type specific filtering with --php, --perl, etc&lt;/li&gt;
&lt;li&gt;Regular expression based file matching&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's neat. Check it out: &lt;a href="http://petdance.com/ack/"&gt;http://petdance.com/ack/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/338185759" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/338185759/use_grep_try_ack.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/07/use_grep_try_ack.php</guid>
         <category>Quick Tips</category>
         <author>chrisd@arc90.com (Chris Dary)</author>
         <pubDate>Thu, 17 Jul 2008 12:23:39 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/07/use_grep_try_ack.php</feedburner:origLink></item>
      
      <item>
         <title>Extending Column Background Color--without Images!</title>
         <description>Lets go straight to the HTML:

&lt;pre name="code" class="xml"&gt;
&lt;div id="canvas"&gt;
	&lt;div id="right"&gt;
		&lt;ul&gt;
			&lt;li&gt;&lt;a href="#"&gt;item 1&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href="#"&gt;item 2&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href="#"&gt;item 3&lt;/a&gt;&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/div&gt;
	&lt;div id="left"&gt;
		&lt;h2&gt;My title&lt;/h2&gt;
		&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;/p&gt;
		&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;/p&gt;

		&lt;h3&gt;My title&lt;/h3&gt;
		&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;/p&gt;

		&lt;h4&gt;My title&lt;/h4&gt;
		&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;/p&gt;
	&lt;/div&gt;
&lt;/div&gt;
&lt;/pre&gt;
and its corresponding style:

&lt;pre name="code" class="xml"&gt;
* { margin: 0; padding: 0; }
body { text-align: center; /*Hello IE*/ }
p { padding-bottom: 1em; line-height: 1.4; }
#canvas { width: 49em; margin: 0 auto; text-align: left; background-color: #F0F0F0; }
#right { float: right; width: 25%; }
#right ul { margin-left: 2em; }
#left { margin-right: 25%;background-color: #FFF; }
&lt;/pre&gt;

Explanation:
Use the id "canvas" to assign the right column color. Then give id "left" a background color of white.

&lt;a href="http://blog.arc90.com/ext_bg/"&gt;Click here to view an example.&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/331916481" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/331916481/http2colalexgarc90dev02.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/07/http2colalexgarc90dev02.php</guid>
         <category>Quick Tips</category>
         <author>alexg@arc90.com (Alex Gutierrez)</author>
         <pubDate>Thu, 10 Jul 2008 13:30:00 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/07/http2colalexgarc90dev02.php</feedburner:origLink></item>
      
      <item>
         <title>From Faceless to Family</title>
         <description>&lt;p&gt;
We released our first product--the lovely &lt;a href="http://www.kindlingapp.com/"target=_"blank"&gt;Kindling&lt;/a&gt;--to public Beta early last week.  Preparing Kindling for public consumption (even the Beta phase) was a test of our imaginations.  We were constantly evaluating who would use the application, what they would want answers to in the FAQ section, how they would react to a video explaining the app itself.&lt;/p&gt;
&lt;p&gt;
Once Kindling was ready to be released, my most immediate responsibility was to extend a few exclusive invitations and then take control of the tidal wave of invite requests that came pouring in.  One by one, they crowded into my inbox, and on that first day, one by one, I responded back. &lt;/p&gt;
&lt;p&gt;I'm not entirely sure what people think happens once they submit their name for a Beta invite. I suppose they assume their information is sent to an almighty database, which then electronically generates an invite code and sends them a confirmation email. Lest you believe otherwise, here at Arc90, all Kindling requests are processed by human hands--and lovingly cared for by yours truly.&lt;/p&gt;
&lt;p&gt;And truth be told, I think of this huge document of names and group descriptions as a funny sort of family. For the past week, I have paid more attention to this group of people than I would a newborn baby, because--in effect--Kindling &lt;em&gt;is &lt;/em&gt;a newborn.  And for all the time and energy my colleagues and I have invested into its conception, it feels a little scary (and oh so exciting!) to watch a large group of users interact with it for the first time.&lt;/p&gt;
&lt;p&gt;In releasing Kindling to public Beta, you--our customers--have become a real, tangible presence in our lives (mine especially). You're Dan with 25 members in your group of lawyers or Lisa who runs a Yoga studio.  Even by only having your names and group descriptions, I now consider you part of the family and don't think I'm not wondering how you're getting along with your Kindling instance.  I get a real kick out of imagining you in your office implementing new ideas, all because of this cool little app we released last week.  Because to me, that's one of the most compelling reasons to work in this industry--the ability to put useful work into the world.&lt;/p&gt;
&lt;p&gt;I suspect that this feeling will wear off as the number of requests grows higher (and certainly as my experience with releasing products increases) but for the moment, the fact remains that I'm thinking about our Beta users, cheering them on when their usage stats go up, and worrying about them when their stats take a dip.  I have a secret dream of sitting down and having coffee with all those people who've requested an invitation.  
Or inviting them to Thanksgiving.  You know, either way.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/325876738" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/325876738/from_faceless_to_family.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/07/from_faceless_to_family.php</guid>
         <category>Thoughts</category>
         <author>jennifere@arc90.com (Jennifer Epting)</author>
         <pubDate>Thu, 03 Jul 2008 10:13:06 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/07/from_faceless_to_family.php</feedburner:origLink></item>
      
      <item>
         <title>Fixing the Can't move '.svn/tmp/entries' to '.svn/entries' error</title>
         <description>&lt;p&gt;I'd been having trouble deploying the latest version of a Flex Module due to an SVN error I had never come across before. I was trying to update the &lt;i&gt;svn:externals&lt;/i&gt; property with a new URL but once I saved my change I would get the following error in Terminal:&lt;/p&gt;

&lt;p&gt;Can't move '.svn/tmp/entries' to '.svn/entries': Operation not permitted&lt;/p&gt;

&lt;p&gt;I tried running an &lt;i&gt;svn cleanup&lt;/i&gt; command but no luck. After digging through Google I came &lt;a href="http://kanads.blogspot.com/2007/03/problemas-compartiendo-repositorio.html#links"&gt;across an excellent post&lt;/a&gt; (it's in Spanish) with a command to run that prevents the above error. Basically on the directory I was trying to run the &lt;i&gt;svn propedit svn:externals .&lt;/i&gt; command, all I had to was run the following command first: &lt;b&gt;&lt;i&gt;chflags -R nouchg ./&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;After that I could update the &lt;i&gt;svn:externals&lt;/i&gt; property without any errors. The blog post suggests that the issue could be with how Windows changes
certain file attributes with later on updating on Mac OSX. Makes sense
for me since I develop on Mac while the developer who originally made
changes to the working copy is on Windows.&lt;/p&gt;
&lt;p&gt;Also I want to note that I've noticed others were getting the same
error but instead of it saying "Operation not permitted" it would say
"Permission denied" which I myself have not come across. I'm not sure
if the same command will solve that problem.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/325308048" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/325308048/fixing_the_cant_move_svntmpent.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/07/fixing_the_cant_move_svntmpent.php</guid>
         <category>Development</category>
         <author>javierj@arc90.com (Javier Julio)</author>
         <pubDate>Wed, 02 Jul 2008 20:07:09 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/07/fixing_the_cant_move_svntmpent.php</feedburner:origLink></item>
      
      <item>
         <title>Netflix Demonstrates Customer Relationship Mastery</title>
         <description>&lt;p&gt;Everyone makes mistakes. It's what you learn from them, and how you deal with them, that matters.&lt;/p&gt;

&lt;p&gt;Two weeks ago, Netflix decided to discontinue one of their features: Profiles. I was annoyed by this, but not enough to make any noise about it, or even tell Netflix. Truth is, I assumed that the decision was final, and that nothing I could say would matter. Well, Netflix proved me wrong, and has once again demonstrated their dedication to customer satisfaction, by reversing their decision in response to &lt;a href="http://pogue.blogs.nytimes.com/2008/06/23/monday-2/"&gt;customer feedback&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;I just found this message in my inbox:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.arc90.com/images/Netflix Profiles Apology Email Screenshot.png" alt="Netflix Profiles Apology Email Screenshot.png" border="0" width="619" height="609" alt="screenshot of Netflix profiles apology email" style="border: 1px solid silver; padding: 1em; -moz-border-radius: 10px; -webkit-border-radius: 10px;"/&gt;&lt;/p&gt;

&lt;p&gt;The tone of the message is perfect, just perfect. I'm very impressed, and I sincerely hope that we at Arc90 can do half as well in our customer interactions - particularly if we're ever as big as Netflix.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/323613351" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/323613351/netflix_demonstrates_customer.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/06/netflix_demonstrates_customer.php</guid>
         <category>Business</category>
         <author>avif@arc90.com (Avi Flax)</author>
         <pubDate>Mon, 30 Jun 2008 19:34:31 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/06/netflix_demonstrates_customer.php</feedburner:origLink></item>
      
      <item>
         <title> Enabling A Drop Shadow On A Flex Container</title>
         <description>&lt;p&gt;To set a drop shadow on say a VBox or HBox component you simply set the boolean property dropShadowEnabled to "true" -- but this is not enough to make the drop shadow appear. An example:&lt;/p&gt;

&lt;textarea name="code" class="php"&gt;
&lt;mx:HBox dropShadowEnabled="true" width="100" height="100" /&gt;
&lt;/textarea&gt;&lt;p&gt;To have the drop shadow appear (with its default shadow color) you need to specify a value for borderStyle since the default is none. Setting the borderStyle property doesn't necessarily mean you have to display a border, but it is needed for the drop shadow to appear. So if the border is not desired, simply set the style property borderThickness to 0.  An example:&lt;/p&gt;

&lt;textarea name="code" class="php"&gt;
&lt;mx:HBox dropShadowEnabled="true" borderStyle="solid" borderThickness="0" width="100" height="100" /&gt;
&lt;/textarea&gt;

&lt;p&gt;The above sample will display a drop shadow for the HBox component without a visible border.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/320579233" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/320579233/enabling_a_drop_shadow_on_a_fl.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/06/enabling_a_drop_shadow_on_a_fl.php</guid>
         <category>Quick Tips</category>
         <author>javierj@arc90.com (Javier Julio)</author>
         <pubDate>Thu, 26 Jun 2008 10:30:00 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/06/enabling_a_drop_shadow_on_a_fl.php</feedburner:origLink></item>
      
      <item>
         <title>In praise of System.Object</title>
         <description>&lt;p&gt;In this Quick Tip, I show you how to make a method that deals with System.Object parameters more type-safe by converting it to use generics. Last year I had written a wrapper class to talk to the ASP.NET caching system for me. It returned cached objects as System.Object for maximum flexibility. The client would cast to the desired type, but it always bugged me, because it wasn't very type-safe. Consider the following chunk of code:&lt;/p&gt;
&lt;textarea name="code" class="C#"&gt;Cache.Set("WhenDidIDoThis", DateTime.Now);
...
int numberOfTicks = (int) Cache.Get("WhenDidIDoThis");
&lt;/textarea&gt;

&lt;p&gt;It will compile just fine, but it will blow up when I run it, because silly me, WhenDidIDoThis contains a DateTime, not an integer. It's far safer to rewrite my code to use generics:&lt;/p&gt;

&lt;textarea name="code" class="C#"&gt;Cache.Set&amp;lt;datetime&amp;gt;("WhenDidIDoThis", DateTime.Now);
...
int numberOfTicks = Cache.Get&amp;lt;int&amp;gt;("WhenDidIDoThis");&lt;/textarea&gt;

&lt;p&gt;Hmm. Actually, that same logic error still compiles just fine, but hey, at least my code now signals its intent more clearly. The bigger problem is now I'm getting a compiler error elsewhere. Let's see why.&lt;/p&gt;&lt;textarea name="code" class="C#"&gt;public static T Get&lt;t&gt;(string key)
{
     T cachedObject = (T) context.Cache.Get(key);

     if(cachedObject != default(T))
          logCacheHit(key);

     return cachedObject;
}
&lt;/textarea&gt;

&lt;p&gt;Ah, that comparison with default(T) fails with the compiler error &lt;strong&gt;Operator '==' cannot be applied to operands of type 'T' and 'T'&lt;/strong&gt; because T can be literally any type, including one that doesn't implement IComparable. Sure I could restrict my class to only accept IComparable types (&lt;em&gt;public static T Get&amp;lt;T&gt;(string key) where T : IComparable&lt;/em&gt;), but then my caching code is less universal. Or I could figure out a type-agnostic way of seeing if I got a cache hit without relying on IComparable. Yeah, that sounds like time well-spent.&lt;/p&gt;

&lt;p&gt;So after a fair bit of work, my code is really no more type-safe than before, and I've either added complexity or limited its reusability, or more likely, both. And all because I wanted to replace my embarrassing System.Object parameters with sexier generic equivalents.&lt;/p&gt;

&lt;p&gt;This class worked perfectly for every single use-case in every single project I've added it to over the past year (at least 10 so far). It doesn't matter that it ignores every single advance in the .NET languages and framework since 1.0. It doesn't matter that the other classes tease it for its positively Luddite reliance on System.Object. What does matter is realizing that a lot of the time in development, "good enough" isn't just good enough, it's actually pretty great. In hindsight, that's a much more valuable Quick Tip.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/319828748" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/319828748/in_praise_of_systemobject.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/06/in_praise_of_systemobject.php</guid>
         <category>Quick Tips</category>
         <author>joelp@arc90.com (Joel Potischman)</author>
         <pubDate>Wed, 25 Jun 2008 12:15:00 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/06/in_praise_of_systemobject.php</feedburner:origLink></item>
      
      <item>
         <title>Introducing Kindling, the first product from Arc90</title>
         <description>&lt;p&gt;&lt;b&gt;&lt;em&gt;Ideas are everywhere, but how do I find them?&lt;/em&gt;&lt;/b&gt; &lt;/p&gt;  &lt;p&gt;It&amp;#8217;s been often said that the best ideas come from within an organization, as the people closest to the action are best positioned to see untapped value.&amp;nbsp; However, in practice some businesses seek new ideas, whether they be process changes or the next product line, from the outside - from hired consultants or strategic management firms.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;For those that do seek this out from within, often the problem is actually tapping into this potential wealth of ideas.&amp;nbsp; If there was only a tool that allowed all members of an organization or community to submit, discuss, refine and vote on ideas?&amp;nbsp; The net effect of all of this activity would be a well-vetted list of ideas, those that by the nature of being exposed and vetted have the support of the group.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.kindlingapp.com/"&gt;Kindling&lt;/a&gt;, a new product by Arc90, is just such a tool.&amp;nbsp; The product has been within our company for over a year, as well as by a handful of organizations during our private beta, and is available today, as we widen our scope to a public beta.&amp;nbsp; More on that below, but first, since when is Arc90 a product company?&amp;nbsp; As &lt;a href="http://www.arc90.com/"&gt;cryptic as our web presence might be&lt;/a&gt;, it is pretty clear that Arc is a services company, so how did we get here?&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;   &lt;p&gt;&lt;b&gt;&lt;em&gt;An evolution into product&lt;/em&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;A year or so ago, the management at Arc90 made a strategic decision to diversify our business by pursuing product development.&amp;nbsp; As a services company we had been functioning as if we were building product, because we were building product - product used exclusively by our clients!&amp;nbsp; Very rarely could our work be considered custom software.&amp;nbsp; There&amp;#8217;s both cause and effect in play here, as we tend to think in a way where we look at the problem at hand, abstract it one or two levels up, and then create software that speaks to the larger issue.&amp;nbsp; We also only hire people that think that way, perpetuating the trend.&amp;nbsp; This is how we keep ourselves interested in, and passionate about, our clients&amp;#8217; business.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Besides our inherent product disposition, we also seek control over our future.&amp;nbsp; A simple truth exists about the services business:&amp;nbsp; no matter how good the work is that you deliver to clients, you can never fully control your own destiny.&amp;nbsp; A client, very pleased with our work, could fail, or get sued, or experience a change in management, or undergo a strategic change in direction.&amp;nbsp;&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Services companies attempt to get around this inherent challenge through diversification - &amp;#8216;let&amp;#8217;s get additional services clients!&amp;#8217;&amp;nbsp; But that&amp;#8217;s the rub for a company like Arc90 - we do our best work, and frankly usually only take on work, when we&amp;#8217;re operating at a strategic level within an external organization.&amp;nbsp; And those relationships are hard to find.&amp;nbsp; We could take less desirable (as we define it) project work, but then not only would we not be controlling our destiny, but we&amp;#8217;d be doing work that doesn&amp;#8217;t suit us.&amp;nbsp; And since this is our company, we&amp;#8217;re just not going to choose to do that.&lt;/p&gt;  &lt;p&gt;For those reasons, we made the decision which we are now executing on - diversify into product.&amp;nbsp; Teams within Arc have been working on a few product efforts which are at various states of readiness.&amp;nbsp; And so, as I mentioned above, I&amp;#8217;m very pleased to announce that our first product is ready.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;em&gt;Kindling, an idea management and collaboration tool&lt;/em&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Kindling is a web-delivered application which allows the members of an organization or community to create, discuss, refine, and vote on ideas.&amp;nbsp; All of this activity naturally results in a listing of refined, quality, popular ideas.&amp;nbsp; &amp;#8220;Bad&amp;#8221; or &amp;#8220;unpopular&amp;#8221; ideas will filter out of view, and &amp;#8220;good&amp;#8221; and &amp;#8220;popular&amp;#8221; ideas bubble up to the top.&amp;nbsp; From there, decision-makers can approve or reject ideas and the cycle continues.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;A key aspect of Kindling&amp;#8217;s value is the scarcity of votes available to everyone using your group&amp;#8217;s Kindling.&amp;nbsp; Fewer votes means more value for each one, so people will use them to support the ideas they feel strongest about.&amp;nbsp; That decision-making process, as played out over the group, will result in the best ideas gaining the most support.&lt;/p&gt;  &lt;p&gt;Why would the people in my community or organization participate in Kindling?&amp;nbsp; People participate in Kindling to see their ideas get acted upon, and to help support and refine other good ideas.&amp;nbsp; Group or community decision-makers participate in Kindling for the same reason, as well as to identify and implement the group&amp;#8217;s ideas.&amp;nbsp; There&amp;#8217;s a strong incentive here for decision-makers to participate in Kindling, as who besides members of the organization or community would have or recognize good ideas?&lt;/p&gt;  &lt;p&gt;Kindling&amp;#8217;s thoughtfully designed interface and experience make this process fun and engaging.&amp;nbsp; I see this play out in Arc90&amp;#8217;s Kindling, where there are usually a few new ideas and lots of new commentary around existing ideas every day.&amp;nbsp; To illustrate, here&amp;#8217;s an idea from our Kindling (note the date):&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.arc90.com/images/KindlingIdea.jpg" height="281" width="575" /&gt;&lt;/p&gt;  &lt;br /&gt;  &lt;p&gt;Kindling works for us, and we think it&amp;#8217;ll be useful for others.&amp;nbsp; If you find this interesting, head over to &lt;a href="http://www.kindlingapp.com/"&gt;kindlingapp.com&lt;/a&gt; and request an invitation to join the public beta.&amp;nbsp; The beta program is free with no obligation to subscribe once we launch the paid version (but you'll receive reduced pricing if you're in the beta program), and you&amp;#8217;ll have the chance to provide feedback and participate in the refinement of the product as we prepare it for public availability. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Stay tuned to this blog for updates on Kindling, as well as our quest into product.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/318931057" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/318931057/introducing_kindling_the_first.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/06/introducing_kindling_the_first.php</guid>
         <category>Arc90</category>
         <author>tim@arc90.com (Tim Meaney)</author>
         <pubDate>Tue, 24 Jun 2008 10:10:10 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/06/introducing_kindling_the_first.php</feedburner:origLink></item>
      
      <item>
         <title>Building RESTful Web Apps with Groovy and Restlet, Part 2: Resources</title>
         <description>&lt;p&gt;In &lt;a href="http://blog.arc90.com/2008/06/building_restful_web_apps_groovy_restlet_part_1.php"&gt;Part 1&lt;/a&gt; of this series, we set up a development environment for our apps, and created and tested a simple &amp;#8220;Hello, world&amp;#8221; example. In this installment, we'll make our app more realistic and useful.&lt;/p&gt;

&lt;p&gt;If we revisit the current makeup of &lt;tt&gt;restfulapp.groovy&lt;/tt&gt;, we see that there are two elements: the class &lt;tt&gt;RequestHandler&lt;/tt&gt;, and the line which creates and starts an HTTP server. &lt;tt&gt;RequestHandler&lt;/tt&gt; has only one method: &lt;tt&gt;handle()&lt;/tt&gt;, which is called for every request. &lt;tt&gt;handle()&lt;/tt&gt; checks whether the request method is &lt;tt&gt;GET&lt;/tt&gt;, which is the only method supported by the app at this stage, and responds with &amp;#8220;Hello, world!&amp;#8221; if it is, and with an error response if it isn't.&lt;/p&gt;

&lt;p&gt;It works, but there's definitely some key elements missing from the picture at this point &amp;#8211; namely resources and representations. While our &lt;tt&gt;RequestHandler&lt;/tt&gt; is indeed responding to requests and is therefore doing actual work, it's not particularly RESTful. There's no clear resource specified, and no representations of the state of that resource transferred back and forth. So that's what we'll add to the app now.&lt;/p&gt;&lt;style type="text/css"&gt;
  #left-content {
    font-family: "Lucida Grande", "Verdana", "Sans Serif";
    font-size: 120%;
    color: black;
  }

  #left-content a {
    color: blue;
    text-decoration: underline;
  }

  #left-content h1,  #left-content h2,  #left-content h3 {
    margin: 0.5em 0;
  }

  #blog-entry #left-content h3 {
    font-size: 140%;
  }

  #left-content ul, #left-content ol {
    margin: 1em 0;
  }

  #blog-entry #left-content .comment {
    border: none;
    padding: 0;
    margin: 0;
  }
&lt;/style&gt;

&lt;p&gt;Let's update &lt;tt&gt;RequestHandler&lt;/tt&gt; so it's no longer a generic &amp;#8220;request handler&amp;#8221; class, but instead models a resource. I'm not going to go into REST theory here to discuss what a resource is; if you could use a primer see your favorite REST tutorial or reference, or refer to &lt;a href="http://roy.gbiv.com/pubs/dissertation/rest_arch_style.htm#sec_5_2_1_1"&gt;the relevant section of The Dissertation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So what resource should our class model? For the purposes of this article, we could choose almost anything. But we'll want something that'll allow us to demonstrate some important RESTful concepts, and to build something that resembles real-world resources in transactional software systems.&lt;/p&gt;

&lt;p&gt;How about a mailbox? It's a good candidate because it has state of its own, which would be retrieved with &lt;tt&gt;GET&lt;/tt&gt;, might support both &lt;tt&gt;PUT&lt;/tt&gt; to update its own state, and &lt;tt&gt;POST&lt;/tt&gt; to accept entities for processing, and maybe even &lt;tt&gt;DELETE&lt;/tt&gt;. It also might have &amp;#8220;child resources&amp;#8220;: messages.&lt;/p&gt;

&lt;p&gt;Let's try changing the name of &lt;tt&gt;RequestHandler&lt;/tt&gt; to &lt;tt&gt;MailboxResource&lt;/tt&gt; and see what it looks like:&lt;/p&gt;

&lt;pre name="code" class="java"&gt;
class MailboxResource extends Restlet
{
    void handle(Request request, Response response)
    {
    	if (request.method == Method.GET)
		{
			response.setEntity("Hello, world!", MediaType.TEXT_PLAIN)
		}
		else
    	{
    		// The request method is not GET, so set an error response status
			response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED)
			response.setAllowedMethods([Method.GET] as Set)
    	}
    }
}
&lt;/pre&gt;

&lt;p&gt;Next, let's change the handling of &lt;tt&gt;GET&lt;/tt&gt; to return a meaningful representation of the current state of the mailbox:&lt;/p&gt;

&lt;pre name="code" class="java"&gt;
	if (request.method == Method.GET)
	{
		response.setEntity("access: closed; messages: 0;", MediaType.TEXT_PLAIN)
	}
&lt;/pre&gt;

&lt;p&gt;OK, it's primitive. But it's a plausible representation of the current state of the mailbox &amp;#8211; and that's all we need at this point.&lt;/p&gt;

&lt;p&gt;Next, let's add support for &lt;tt&gt;PUT&lt;/tt&gt;, which a client might use to update the open/closed state of the Mailbox, and &lt;tt&gt;POST&lt;/tt&gt; which a client might use to put a message into the Mailbox.&lt;/p&gt;

&lt;p&gt;A first attempt to do so might look like this:&lt;/p&gt;

&lt;pre name="code" class="java"&gt;
		switch (request.method)
		{
			case Method.GET:
				response.setEntity("access: closed; messages: 0;", MediaType.TEXT_PLAIN)
				break
			
			case Method.PUT:
				if (request.attributes.access)
				{
					this.access = request.attributes.access
				}
				else
				{
					response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "The request representation must include the parameter 'access'.")
				}
				break
			
			case Method.POST:
				if (request.attributes.messageContent)
				{
					createMessage(request.attributes.messageContent)
				}
				else
				{
					response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "The request representation must include the parameter 'messageContent'.")
				}
				break
							
			default:
				// The request method is not allowed; set an error status
				response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED)
				response.setAllowedMethods([Method.GET, Method.PUT, Method.POST] as Set)
		}
&lt;/pre&gt;

&lt;p&gt;This code would work, as long as we implemented the field &lt;tt&gt;this.access&lt;/tt&gt; set on line 10, and the method &lt;tt&gt;createMessage()&lt;/tt&gt;, called from line 21. But as you can see, our once-svelte method is getting fairly unwieldy, and at this point we're still only doing very basic processing for our requests. You can imagine that once we need some more complex processing, our method could become impossible to work with.&lt;/p&gt;

&lt;p&gt;OK, no problem, we all know what to do in situations like this: create class methods to handle each of our allowed HTTP methods. After which, &lt;tt&gt;MailboxResource&lt;/tt&gt; might look something like this:&lt;/p&gt;

&lt;pre name="code" class="java"&gt;
class MailboxResource extends Restlet
{
    void handle(Request request, Response response)
    {
		switch (request.method)
		{
			case Method.GET:
				handleGet(request, response)
				break
			
			case Method.PUT:
				handlePut(request, response)
				break
			
			case Method.POST:
				handlePost(request, response)
				break
							
			default:
				// The request method is not allowed; set an error status
				response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED)
				response.setAllowedMethods([Method.GET, Method.PUT, Method.POST] as Set)
		}
    }

    void handleGet(request, response)
    {
	    response.setEntity("access: closed; messages: 0;", MediaType.TEXT_PLAIN)	
    }

    void handlePut(request, response)
    {
		if (request.attributes.access)
		{
			this.access = request.attributes.access
		}
		else
		{
			response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "The request representation must include the parameter 'access'.")
		}    	
    }

    void handlePost(request, response)
    {
		if (request.attributes.messageContent)
		{
			createMessage(request.attributes.messageContent)
		}
		else
		{
			response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "The request representation must include the parameter 'messageContent'.")
		}    	
    }
}
&lt;/pre&gt;

&lt;p&gt;Definitely easier to read, but still fairly verbose. That switch statement is looking kinda dumb at this point; it's not doing much.&lt;/p&gt;

&lt;p&gt;So let's use some dynamic Groovy magic to get rid of it:&lt;/p&gt;

&lt;pre name="code" class="java"&gt;
    void handle(Request request, Response response)
    {
    	def allowedMethods = [Method.GET, Method.PUT, Method.POST] as Set
    	
    	if (request.method in allowedMethods)
    	{
			def handleMethodName = "handle" + request.method.name.substring(0, 1).toUpperCase() + request.method.name.substring(1).toLowerCase()
			this."$handleMethodName"(request, response)
		}
		else
		{
			// The request method is not allowed; set an error status
			response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED)
			response.setAllowedMethods(allowedMethods)			
		}
	}
&lt;/pre&gt;

&lt;p&gt;OK, now we're getting somewhere! Easy dynamic method invocation &amp;#8211; pretty cool.&lt;/p&gt;

&lt;p&gt;Thing is, our &lt;tt&gt;handle()&lt;/tt&gt; method is at this point barely doing anything &amp;#8211; just figuring out whether the requested HTTP method is allowed, and calling the appropriate class method if it is, or returning an error if it isn't. We shouldn't have to implement this standard logic in every single one of our resources, that'd be pretty redundant.&lt;/p&gt;

&lt;p&gt;Thankfully, the developers of Restlet realized this, and they created a very useful class which takes care of much of this sort of overheard for you. It's named, simply, &lt;a href="http://www.restlet.org/documentation/1.1/api/org/restlet/resource/Resource.html"&gt;&lt;tt&gt;Resource&lt;/tt&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's convert &lt;tt&gt;MailboxResource&lt;/tt&gt; to extend &lt;tt&gt;Resource&lt;/tt&gt;. We'll do this in a few steps, to illustrate some of the work that &lt;tt&gt;Resource&lt;/tt&gt; does for us.&lt;/p&gt;

&lt;p&gt;Let's start &lt;tt&gt;MailboxResource&lt;/tt&gt; from scratch:&lt;/p&gt;

&lt;pre name="code" class="java"&gt;
#!/usr/bin/env groovy -classpath org.restlet.jar:com.noelios.restlet.jar

import org.restlet.*
import org.restlet.data.*
import org.restlet.resource.*

class MailboxResource extends Resource
{
	static String access = 'closed'
	static int messageCount = 0

	def MailboxResource(Context context, Request request, Response response)
	{
		super(context, request, response)
		variants.add(new Variant(MediaType.APPLICATION_WWW_FORM))
		modifiable = true
	}

}

// Create a Finder which will create new instances of MailboxResource as needed
finder = new Finder(new Context(), MailboxResource.class)

/* Create a new HTTP Server on port 3000, pass it the Finder,
 to which it will pass all incoming Requests, and start it. */
new Server(Protocol.HTTP, 3000, finder).start()
&lt;/pre&gt;

&lt;p&gt;As you can see, there's a new import on line 5, because &lt;tt&gt;Resource&lt;/tt&gt; is in a Restlet sub-package. Now's also a good time to add some static fields to store the state of the resource, on lines 9 and 10. Normally we wouldn't store state this way; this is just more convenient for now than using a real persistent data store.&lt;/p&gt;

&lt;p&gt;Next, you'll see that &lt;tt&gt;MailboxResource&lt;/tt&gt; now has a constructor. This may seem like annoying overhead, but trust me, it'll be worth it. For example: the framework will pass the request and response to the constructor, which passes them to the super constructor, which stores them in class fields. This means there's no more need to pass the &lt;tt&gt;request&lt;/tt&gt; and &lt;tt&gt;response&lt;/tt&gt; around to every method &amp;#8211; we can just refer to &lt;tt&gt;this.request&lt;/tt&gt; and &lt;tt&gt;this.response&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;There's some other good things going on in the constructor. On line 15 we add a &lt;a href="http://www.restlet.org/documentation/1.1/api/org/restlet/resource/Variant.html"&gt;&lt;tt&gt;Variant&lt;/tt&gt;&lt;/a&gt; to the &lt;tt&gt;variants&lt;/tt&gt; collection; this is used for &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html"&gt;HTTP content negotiation&lt;/a&gt; &amp;#8211; which &lt;tt&gt;Resource&lt;/tt&gt; &lt;em&gt;does for you.&lt;/em&gt; That's right &amp;#8211; one of the trickiest aspects of implementing a sophisticated RESTful web app, and you get it &lt;em&gt;for free&lt;/em&gt; just by using &lt;tt&gt;Resource&lt;/tt&gt;. Good deal! I'll demonstrate content negotiation in a later article in this series.&lt;/p&gt;

&lt;p&gt;The last line of the constructor sets the resource as modifiable; by default instances of &lt;tt&gt;Resource&lt;/tt&gt; only allow &lt;tt&gt;GET&lt;/tt&gt;; setting &lt;tt&gt;modifiable&lt;/tt&gt; to &lt;tt&gt;true&lt;/tt&gt; allows &lt;tt&gt;PUT&lt;/tt&gt;, &lt;tt&gt;POST&lt;/tt&gt;, and &lt;tt&gt;DELETE&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;We don't want to allow &lt;tt&gt;DELETE&lt;/tt&gt; for now, so let's add this method:&lt;/p&gt;
&lt;pre name="code" class="java"&gt;
	def boolean allowDelete()
	{
		return false
	}
&lt;/pre&gt;

&lt;p&gt;It's time to add our request handling logic back into the application. Let's add this method:&lt;/p&gt;

&lt;pre name="code" class="java"&gt;
	def Representation represent(Variant variant)
	{
		def form = new Form()
		
		form.add("access", access)
		form.add("messages", messageCount as String)
		
		return form.webRepresentation
	}
&lt;/pre&gt;

&lt;p&gt;Notice that the new method isn't named &amp;#8220;handle&amp;#8221; or &amp;#8220;handleGet&amp;#8221;; instead it's &lt;tt&gt;represent()&lt;/tt&gt;. There are many good and useful reasons for this, but I'm not going to go into all of them at the moment. I'll just point out one for now: after processing a &lt;tt&gt;PUT&lt;/tt&gt; or &lt;tt&gt;POST&lt;/tt&gt; request, a common behaviour is to return a representation of the new, altered, state of the resource. So it's not only when responding to &lt;tt&gt;GET&lt;/tt&gt; that we need to construct a representation of the resource; it's also frequently needed for other methods. Therefore, a specific method for this need makes a lot of sense.&lt;/p&gt;

&lt;p&gt;All we need to do now is implement &lt;tt&gt;PUT&lt;/tt&gt; and &lt;tt&gt;POST&lt;/tt&gt;. Here's &lt;tt&gt;PUT&lt;/tt&gt;:&lt;/p&gt;

&lt;pre name="code" class="java"&gt;
	def void storeRepresentation(Representation representation)
	{
		def form = new Form(representation)

		if (form.getFirst("access"))
		{
			access = form.getFirstValue("access")
			response.entity = represent()
		}
		else
		{
			response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "The request representation must include the parameter 'access'.")
		}
	}
&lt;/pre&gt;

&lt;p&gt;And as you can see, the HTTP method &lt;tt&gt;PUT&lt;/tt&gt; is handled by a method named &lt;tt&gt;storeRepresentation()&lt;/tt&gt;. This is because Restlet attempts to model REST semantics in its API. The framework passes the request representation into the method, because it is the main input of the operation.&lt;/p&gt;

&lt;p&gt;On line 3 we see another useful Restlet class: &lt;a href="http://www.restlet.org/documentation/1.1/api/org/restlet/data/Form.html"&gt;&lt;tt&gt;Form&lt;/tt&gt;&lt;/a&gt;. As you might guess, this is convenient for working with web forms.&lt;/p&gt;

&lt;p&gt;Finally, let's add support for &lt;tt&gt;POST&lt;/tt&gt;:&lt;/p&gt;

&lt;pre name="code" class="java"&gt;
	def void acceptRepresentation(Representation representation)
	{
		if (access != 'open')
		{
			response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "A message can only be put into the mailbox if it is open.")
			return
		}

		def form = new Form(representation)

		if (form.getFirst("message_content"))
		{
			messageCount++
			response.entity = represent()
		}
		else
		{
			response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "The request representation must include the parameter 'message_content'.")
		}
	}
&lt;/pre&gt;

&lt;p&gt;Normally, an operation like this would create a sub-resource, and the URL of that resource would be returned as a response header, along with the response status &lt;tt&gt;201 Created&lt;/tt&gt;. This will be illustrated in a later article in this series.&lt;/p&gt;

&lt;p&gt;And that's it, we're done with our first &lt;tt&gt;Resource&lt;/tt&gt;! We just need to make one last change to our script to make it all work; we need to change the last line to:&lt;/p&gt;

&lt;pre name="code" class="java"&gt;
// Create a Finder which will create new instances of MailboxResource as needed
finder = new Finder(new Context(), MailboxResource.class)

/* Create a new HTTP Server on port 3000, pass it the Finder,
 to which it will pass all incoming Requests, and start it. */
new Server(Protocol.HTTP, 3000, finder).start()
&lt;/pre&gt;

&lt;p&gt;I'll explain the &lt;tt&gt;Finder&lt;/tt&gt; class in a later article.&lt;/p&gt; 

&lt;p&gt;As the comments indicate, a new instance of MailboxResource will be created for every single HTTP request. At first this might seem inefficient, but it means that every &lt;tt&gt;Resource&lt;/tt&gt; class is inherently threadsafe &amp;#8211; no small value there. And it's still plenty fast: my &lt;tt&gt;ab&lt;/tt&gt; script from Part 1 now yields 688 requests per second.&lt;/p&gt;

&lt;h2&gt;Tests!&lt;/h2&gt;

&lt;p&gt;Let's update &lt;tt&gt;testfulapp.groovy&lt;/tt&gt; to test our new resource:&lt;/p&gt;

&lt;pre name="code" class="java"&gt;
#!/usr/bin/env groovy -classpath org.restlet.jar:com.noelios.restlet.jar

import org.restlet.*
import org.restlet.data.*

client = new Client(Protocol.HTTP)
mailboxResourceUrl = "http://localhost:3000/mailbox"


/*** Test 1: at first, access to the mailbox should be closed ***/
response = client.get(mailboxResourceUrl)

assert response.status.code == 200
assert response.entity.mediaType.equals(MediaType.APPLICATION_WWW_FORM, true)
assert response.entityAsForm instanceof Form
assert response.entityAsForm.getFirstValue("access") == "closed"


/*** Test 2: we shouldn't be able to post messages when the mailbox is closed ***/
form = new Form()
form.add("message_content", "whatever")
response = client.post(mailboxResourceUrl, form.webRepresentation)

assert response.status.code == 400
assert response.isEntityAvailable() == false


/*** Test 3: change the mailbox access to "open" ***/
form = new Form()
form.add("access", "open")
response = client.put(mailboxResourceUrl, form.webRepresentation)

assert response.status.code == 200
assert response.isEntityAvailable() == true
assert response.entityAsForm instanceof Form
assert response.entityAsForm.getFirstValue("access") == "open"

messageCount = response.entityAsForm.getFirstValue("messages") as Integer


/*** Test 4: we should be able to post a message now that the mailbox is open ***/
form = new Form()
form.add("message_content", "whatever")
response = client.post(mailboxResourceUrl, form.webRepresentation)

assert response.status.code == 200
assert response.isEntityAvailable() == true
assert response.entityAsForm instanceof Form
assert response.entityAsForm.getFirstValue("access") == "open"
assert response.entityAsForm.getFirstValue("messages") as Integer == messageCount + 1


/*** Test 5: change the mailbox access to "closed" ***/
form = new Form()
form.add("access", "closed")
response = client.put(mailboxResourceUrl, form.webRepresentation)

assert response.status.code == 200
assert response.isEntityAvailable() == true
assert response.entityAsForm instanceof Form
assert response.entityAsForm.getFirstValue("access") == "closed"


println "\nAll tests passed successfully!\n"
&lt;/pre&gt;

&lt;h2&gt;That's all, folks!&lt;/h2&gt;

&lt;p&gt;And that's it! We've now used Restlet to implement a truly RESTful resource. And we used some Groovy goodness as well: &lt;tt&gt;switch&lt;/tt&gt;, &lt;a href="http://groovy.codehaus.org/Groovy+Truth"&gt;Groovy Truth&lt;/a&gt;, dynamic method invocation, casting, and more.&lt;/p&gt;

&lt;p&gt;I hope this second installment in the series has been interesting and valuable for you, and I look forward to your feedback, comments, critiques, and constructive criticism.&lt;/p&gt;

&lt;p&gt;Coming up in Part 3: Routing. And it'll be shorter than this monstrosity, I promise.&lt;/p&gt;

&lt;h3&gt;Full source of &lt;tt&gt;restfulapp.groovy&lt;/tt&gt;&lt;/h3&gt;

&lt;pre name="code" class="java"&gt;
#!/usr/bin/env groovy -classpath org.restlet.jar:com.noelios.restlet.jar

import org.restlet.*
import org.restlet.data.*
import org.restlet.resource.*

class MailboxResource extends Resource
{
	static def access = 'closed'
	static def messageCount = 0

	def MailboxResource(Context context, Request request, Response response)
	{
		super(context, request, response)
		variants.add(new Variant(MediaType.APPLICATION_WWW_FORM))
		modifiable = true
	}
	
	def boolean allowDelete()
	{
		return false
	}

	def Representation represent(Variant variant)
	{
		def form = new Form()
		
		form.add("access", access)
		form.add("messages", messageCount as String)
		
		return form.webRepresentation
	}
	
	def void storeRepresentation(Representation representation)
	{
		def form = new Form(representation)

		if (form.getFirst("access"))
		{
			access = form.getFirstValue("access")
			response.entity = represent()
		}
		else
		{
			response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "The request representation must include the parameter 'access'.")
		}
	}
	
	def void acceptRepresentation(Representation representation)
	{
		if (access != 'open')
		{
			response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "A message can only be put into the mailbox if it is open.")
			return
		}
	
		def form = new Form(representation)

		if (form.getFirst("message_content"))
		{
			messageCount++
			response.entity = represent()
		}
		else
		{
			response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "The request representation must include the parameter 'message_content'.")
		}
	}
}

// Create a Finder which will create new instances of MailboxResource as needed
finder = new Finder(new Context(), MailboxResource.class)

/* Create a new HTTP Server on port 3000, pass it the Finder,
 to which it will pass all incoming Requests, and start it. */
new Server(Protocol.HTTP, 3000, finder).start()
&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/311347589" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/311347589/building_restful_web_apps_groovy_restlet_part_2.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/06/building_restful_web_apps_groovy_restlet_part_2.php</guid>
         <category>Development</category>
         <author>avif@arc90.com (Avi Flax)</author>
         <pubDate>Fri, 13 Jun 2008 15:02:00 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/06/building_restful_web_apps_groovy_restlet_part_2.php</feedburner:origLink></item>
      
      <item>
         <title>Using ColdFusion and LCDS in AIR-powered Flex Applications</title>
         <description>&lt;p&gt;Previously, I've discussed &lt;a href="http://blog.arc90.com/2008/04/using_coldfusion_components_cf.php" target="_blank"&gt;how to use ColdFusion Components (CFCs) in AIR-powered Flex applications&lt;/a&gt; but I never got a chance to follow up on how to use CF8's integrated LiveCycle Data Services ES in AIR.&lt;/p&gt;&lt;p&gt;I've figured out that all I need to do is specify a ChannelSet component that is reused in both the Consumer and Producer. Since I was developing locally, I set up my AMFChannel to use my local server. You can see in the following example:&lt;/p&gt;

&lt;textarea name="code" class="php"&gt;
&lt;!-- when developing a Flex web app, this is not required but we need this now that we are on AIR --&gt;
&lt;mx:ChannelSet id="channelSet"&gt;
	&lt;mx:channels&gt;
		&lt;mx:AMFChannel uri="http://localhost:8500/flex2gateway/cfamfpolling" pollingEnabled="true" pollingInterval="3000"&gt;
			&lt;mx:id&gt;cf-polling-amf&lt;/mx:id&gt;
		&lt;/mx:AMFChannel&gt;
	&lt;/mx:channels&gt;
&lt;/mx:ChannelSet&gt;

&lt;!--- consumer handles any broadcasted messages from either a client or the server ---&gt;
&lt;mx:Consumer id="consumer" destination="ColdFusionGateway" channelSet="{channelSet}" /&gt;

&lt;!--- producer handles creating a message to broadcast from a client to all subscribed clients ---&gt;
&lt;mx:Producer id="producer" destination="ColdFusionGateway" channelSet="{channelSet}" /&gt;
&lt;/textarea&gt;

&lt;p&gt;
I know there are other channels, such as RTMP, but I have not used them yet. Since I was learning how to use CF/LCDS in AIR, I used it in an AIR version of a simple Chat application. I was quite impressed how easy this was to do. By simply setting up the ChannelSet, I had a working LCDS powered AIR application.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/310443947" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/310443947/_using_coldfusion_and_lcds.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/06/_using_coldfusion_and_lcds.php</guid>
         <category>Quick Tips</category>
         <author>javierj@arc90.com (Javier Julio)</author>
         <pubDate>Thu, 12 Jun 2008 10:30:00 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/06/_using_coldfusion_and_lcds.php</feedburner:origLink></item>
      
      <item>
         <title>Layers of Java Logging</title>
         <description>&lt;p&gt;
&lt;img src="http://img176.imageshack.us/img176/3065/logginglayerstm5.gif" style="float: right; margin-left: 6px; margin-bottom: 6px;" width="151" height="198"/&gt; 
The Java Logging API is great for tracking the internal workings of your application, both during development and after it goes to production. The API is based on a highly flexible configuration model that gives you complete control over what gets logged and where it gets logged.
&lt;/p&gt;

&lt;p&gt;
I recently started using the API after some time away, and it took a bit to get reacquainted with some of its concepts. In my first few attempts, I ended up with either all logging statements output or none, when what I really wanted was output from only a few specific classes.
&lt;/p&gt;

&lt;p&gt;
I think my problem stemmed from confusion between the various ways to filter output. In the end, I found it easiest to think of the API as two separate layers - a &lt;em&gt;filtering layer&lt;/em&gt; that answers the question "What should be output?" and a &lt;em&gt;handler layer&lt;/em&gt; that answers the question "How should it be output?"
&lt;/p&gt;
&lt;p&gt;
Below is an example configuration divided into two sections. Although they both end up in a single logging.properties file, I've broken them up to demonstrate the concept of separate &lt;em&gt;layers&lt;/em&gt;. In the first, I define a default filter level for the entire application, as well as custom filter levels for select packages and classes.
&lt;/p&gt;

&lt;h3&gt;&lt;em&gt;Filter Layer&lt;/em&gt;&lt;/h3&gt;
&lt;pre name="code" class="php"&gt;
# Set the global filtering level to INFO. By default all statements below the
# INFO level will not be logged.

.level = INFO

# Set the filtering level for a few packages to ALL. This overrides the
# global level, so all statements in these packages will be output.
# This is good for limiting output to a section of code you're currently
# working with.

com.arc90.package1.level = ALL
com.arc90.package2.level = ALL

# Set the filtering level for a few individual classes. Again, this overrides
# less specific settings. In this case, all statements of level FINE and 
# higher in ClassA will be output, and all statements of level FINER and 
# higher in ClassB will be ouput.

com.arc90.package3.ClassA.level = FINE
com.arc90.package3.ClassB.level = FINER
&lt;/pre&gt;

&lt;p&gt;
Next, I'll define the handlers that will be used. In addition, I'll specify filters for the handlers themselves. This performs high level filtering on the final output from the &lt;em&gt;filtering layer&lt;/em&gt;. Here, I say that I want only INFO level and higher statements sent to the console, and all statements sent to the log file. &lt;strong&gt;The important thing to remember is that these levels apply to the output from the &lt;em&gt;filter layer&lt;/em&gt; only - if statements were already filtered out in that layer, they will never make it this far.&lt;/strong&gt;
&lt;/p&gt;

&lt;h3&gt;&lt;em&gt;Handler Layer&lt;/em&gt;&lt;/h3&gt;
&lt;pre name="code" class="php"&gt;
# Specify the handlers to be used. Multiple handlers can be specified
# in a comma separated list.

handlers = java.util.logging.ConsoleHandler,java.util.logging.FileHandler

# Specify the formatters that will be used for each handler

java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter

# Specify the log file location for the FileHandler. In this case the log will
# be written to my home directory, in a file named example.log.

java.util.logging.FileHandler.pattern = "%h/example.log"

# Finally, specify the filtering level for each handler

java.util.logging.ConsoleHandler.level = INFO
java.util.logging.FileHandler.level = ALL
&lt;/pre&gt;

&lt;p&gt;
Thinking of the Java Logging API this way has helped to clear things up for me, and I hope it will for others as well. If you haven't used the API, you can try it out for yourself by dropping the above text into a logging.properties file (make sure there aren't spaces at the end of the lines or it won't work), which must be palced into your JVM's lib directory or a path specified as a -Djava.util.logging.config.file VM argument. Finally, just add some logging statements to your Java code and you should start seeing output to the console and the log file.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/309805466" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/309805466/the_layers_of_java_logging.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/06/the_layers_of_java_logging.php</guid>
         <category>Quick Tips</category>
         <author>dougb@arc90.com (Doug Burns)</author>
         <pubDate>Wed, 11 Jun 2008 10:30:00 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/06/the_layers_of_java_logging.php</feedburner:origLink></item>
      
      <item>
         <title>Deposit-friendly Development</title>
         <description>&lt;p&gt;Yesterday I had to deposit a check. My bank, Chase, has begun rolling out new "deposit-friendly" ATMs that require neither envelope nor deposit slip for check-only deposits. The process is shockingly simple. Here's what I had to do:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Select Deposit from the on-screen menu&lt;/li&gt;&lt;li&gt;Insert the endorsed check into a slot, just as I would insert a dollar bill into a vending machine&lt;/li&gt;&lt;li&gt;When I saw an image of the check on-screen, enter its amount &lt;em&gt;[2008/07/02 UPDATE - It gets even better. I discovered today that it actually OCRs the check amount! After I inserted a handwritten check this morning it magically asked me to confirm whether the amount it read on it was correct. It was! I deposited two other checks and it asked me to enter the check amount, indicating that it couldn't read the amounts or it didn't have a high degree of confidence in its scan, so it didn't waste my time asking me to confirm them. I assume OCR would work nearly 100% of the time on machine-generated checks.]&lt;/em&gt;&lt;/li&gt;&lt;li&gt;Repeat for any additional checks&lt;/li&gt;&lt;li&gt;Press Done&lt;/li&gt;&lt;li&gt;Get receipt showing an image of my check(s)&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Here's what I DIDN'T have to do:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fill out a deposit slip, which means I didn't need to...&lt;/li&gt;&lt;li&gt;Find a working pen, which I would need if I could...&lt;/li&gt;&lt;li&gt;Remember my checking account number, which I never do, so I used to have to...&lt;/li&gt;&lt;li&gt;Wait in line for a teller to give me my checking account number, before I could...&lt;/li&gt;&lt;li&gt;Check the under-copies of the deposit slip to make sure nobody leaned hard and smushed their deposit info down into my slip or surreptitiously wrote in their account number to scam me into depositing my check into their account. (And to think some people trust paper.)&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Chase saw a process where a machine that is already operating in a high-security and high-knowledge context asked me to write down the account number it already knows on a piece of paper it can't read and seal it into an envelope it can't open. What a wonderfully archaic set of steps to get rid of!&lt;/p&gt;&lt;p&gt;For me the customer, life is now clearly simpler, but what about the poor machine? Like all banks, Chase is very comfortable with ATM software and hardware, but surely the addition of machine-reading and imaging each check makes the ATM vastly more complicated and error-prone, yes? Well, no. Every check in the U.S. banking system has the issuing bank's routing number, account number, and check number printed along the bottom in a standard Magnetic Ink Character Recognition (MICR) format designed for accurate high-speed scanning. Banks have been whipping checks around and reading those numbers all day every day for decades. And the check image I saw onscreen and printed on my receipt? They've been doing that for years as well. When's the last time you got actual cancelled checks back in your statement? What might seem like an incredibly complex and high-risk project for you or me was to Chase essentially sticking together a few very familiar Lego pieces they'd used a million times.&lt;/p&gt;
&lt;p&gt;Any time you see a business process that asks for information it either already knows, already should know, or can easily find out for itself, there is an opportunity for vastly improving the user experience. When you further see that you can do so with technologies you already live and breathe, to me it reads like the story of the perfect development project. Let's review:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First, there was a clear customer benefit: Customers will spend a lot less time doing tedious and error-prone steps that do not benefit them.&lt;/li&gt;&lt;li&gt;Second, there was a clear client benefit: Bank staff will spend a lot less time looking up account numbers, opening envelopes and deciphering handwriting on incorrectly filled out deposit slips, and making sure the ATM kiosk is stocked with envelopes and deposit slips. Chase will also spend a lot less money buying and almost immediately disposing of &lt;a href="http://freep.com/apps/pbcs.dll/article?AID=/20080608/BUSINESS06/806080574" target="_blank" style="text-decoration: underline; "&gt;NINETEEN MILLION&lt;/a&gt; deposit envelopes a year.&lt;/li&gt;&lt;li&gt;Lastly, from an IT standpoint, the requirements are clear and the risk is low: Get rid of all that paper by gluing together all these things we already know very well.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Dare I say it, this project sounds fun! Unfortunately, not all IT projects are such no-brainers. It's not uncommon for a project to be approved with only two of those three stars, or sometimes even one. Maybe it benefits the client and the customer, but it's going to be a huge and risky endeavor to implement. Maybe it will be a huge pain to implement and actually infuriate the customers, but the cost savings make it worthwhile (&lt;span class="Apple-style-span" style="font-style: italic;"&gt;"Your call is important to us. Please listen carefully as our menu items have changed"&lt;/span&gt;).&lt;/p&gt;
&lt;p&gt;In my experience, the one-star and two-star projects tend to come from an incomplete understanding of the business problem, either by IT or frequently from the business itself. Sometimes clients don't really know what they want. Sometimes they're too close to the action to think long-term. Sometimes they don't understand technology at all. And sometimes we in IT just don't ask, because we're too busy trying to keep production up and running while watching Twitter feeds of the iPhone 3G announcement. I'm just saying.&lt;/p&gt;
&lt;p&gt;No matter how it happens, if you simply treat isolated problems as isolated technology projects, you'll get paid for your work, and life will go on. However, a deeper relationship with your client lets you do so much more. Understanding your client's business plans and long-term goals lets you and your client both see the big picture. You'll be surprised to see how this wider worldview leads to a more holistic approach to these seemingly tactical technical problems ("the ATMs fill up with deposit envelopes by 11:30. Make it hold more.") When you do that, you'll see that those one and two star problems can often be rearranged into three star solutions that make everybody happy. Sometimes so happy that they're inspired to stay up late writing paeans to something as mundane as a deposit-friendly ATM.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Arc90Blog/~4/309659074" height="1" width="1"/&gt;</description>
         <link>http://feeds.feedburner.com/~r/Arc90Blog/~3/309659074/depositfriendly_development.php</link>
         <guid isPermaLink="false">http://blog.arc90.com/2008/06/depositfriendly_development.php</guid>
         <category>Business</category>
         <author>joelp@arc90.com (Joel Potischman)</author>
         <pubDate>Wed, 11 Jun 2008 10:05:33 -0500</pubDate>
      <feedburner:origLink>http://blog.arc90.com/2008/06/depositfriendly_development.php</feedburner:origLink></item>
      
   </channel>
</rss>
