<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Developer<br/>Advocate</title>
    <link>http://developeradvocate.appspot.com:80</link>
    <description>Developer<br/>Advocate</description>
    <pubDate>Thu, 7 Oct 2010 21:46:23 +1700</pubDate>
    
    <item>
      <title>Javascript Performance Between Popular Browsers</title>
      <link>http://developeradvocate.appspot.com:80/id/16001/Javascript-Performance-Between-Popular-Browsers</link>
      <guid>http://developeradvocate.appspot.com:80/id/16001/Javascript-Performance-Between-Popular-Browsers</guid>
      <pubDate>Thu, 7 Oct 2010 21:46:23 +1700</pubDate>
      <description>
        &lt;p&gt;
	Using the recently updated V8 Benchmark Suite Version 6 (&amp;nbsp;&lt;a href=&quot;http://v8.googlecode.com/svn/data/benchmarks/v6/run.html&quot;&gt;http://v8.googlecode.com/svn/data/benchmarks/v6/run.html&lt;/a&gt;&amp;nbsp;) javascript test suite, here is the breakdown for scoring by browser version. &amp;nbsp;Higher is better:&lt;/p&gt;
&lt;p&gt;
	Chrome 7.0:&amp;nbsp;3077&lt;/p&gt;
&lt;p&gt;
	Safari 5.0.1:&amp;nbsp;1493&lt;/p&gt;
&lt;p&gt;
	Internet Explorer 9.0 Beta: 877&lt;/p&gt;
&lt;p&gt;
	Firefox 4.0 Beta 6: 683&lt;/p&gt;
&lt;p&gt;
	Firefox 3.6.10: 346&lt;/p&gt;
&lt;p&gt;
	Conclusion: Chrome blows away the competition. &amp;nbsp;Not surprising, as Chrome has almost seemed leaps and bounds faster than anything else to me.&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>Google Web Toolkit (GWT) Wrapper For Twitter @Anywhere Javascript API</title>
      <link>http://developeradvocate.appspot.com:80/id/15001/Google-Web-Toolkit-%28GWT%29-Wrapper-For-Twitter-%40Anywhere-Javascript-API</link>
      <guid>http://developeradvocate.appspot.com:80/id/15001/Google-Web-Toolkit-%28GWT%29-Wrapper-For-Twitter-%40Anywhere-Javascript-API</guid>
      <pubDate>Mon, 30 Aug 2010 22:52:16 +1700</pubDate>
      <description>
        &lt;p&gt;
	&lt;strong&gt;I recently created a wrapper using google web toolkit (gwt) for the twitter @anywhere api. &amp;nbsp;I decided to release it as open source under the bsd license.&lt;/strong&gt;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&lt;b&gt;&lt;br /&gt;
	&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	package org.gwtanywhere.client;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	import com.google.gwt.json.client.JSONParser;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	import com.google.gwt.json.client.JSONValue;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	import com.google.gwt.user.client.rpc.AsyncCallback;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	import com.google.gwt.user.client.ui.HTMLPanel;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	import com.google.gwt.user.client.ui.Widget;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	public class TwitterAnywhere&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	private static AsyncCallback&amp;lt;UserInfo&amp;gt; getUserInfoCallback = null;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	public TwitterAnywhere()&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	public void LoginWithTwitter()&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	LoginWithTwitterNative();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	public void Hovercards(Widget widget, boolean linkify, boolean expandedByDefault)&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	HovercardsNative(addUniqueIdToWidgetAndReturnId(widget), linkify, expandedByDefault);&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	public void beginGetCurrentUserInfoObject(AsyncCallback&amp;lt;UserInfo&amp;gt; callback)&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	getUserInfoCallback = callback;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	try&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	// kick off the async processing&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	getUserInfoNative();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	catch(Exception ex)&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	callback.onFailure(ex);&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	public static native void registerParseUserInfo()&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	/*-{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;$wnd.parseUserInfo = $entry(@org.gwtanywhere.client.TwitterAnywhere::parseUserInfo(Ljava/lang/String;));&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;}-*/;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	public static void parseUserInfo(String json)&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	JSONValue jsonValue = JSONParser.parse(json);&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	// screen_name, name, profile_image_url, friends_count, followers_count, description, url, id, statuses_count, following&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	getUserInfoCallback.onSuccess(new UserInfo(getJsonValue(jsonValue, &amp;quot;screen_name&amp;quot;), getJsonValue(jsonValue, &amp;quot;name&amp;quot;), getJsonValue(jsonValue, &amp;quot;profile_image_url&amp;quot;),&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	getJsonValue(jsonValue, &amp;quot;friends_count&amp;quot;), getJsonValue(jsonValue, &amp;quot;followers_count&amp;quot;), getJsonValue(jsonValue, &amp;quot;description&amp;quot;),&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	getJsonValue(jsonValue, &amp;quot;url&amp;quot;), getJsonValue(jsonValue, &amp;quot;id&amp;quot;), getJsonValue(jsonValue, &amp;quot;statuses_count&amp;quot;)));&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	private static String getJsonValue(JSONValue jsonValue, String propertyName)&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	return jsonValue.isObject().get(propertyName).isString().stringValue();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	private static native void HovercardsNative(String domElementId, boolean linkify, boolean expandedByDefault)&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	/*-{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	$wnd.twttr.anywhere(function (T)&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;T(&amp;quot;#&amp;quot; + domElementId).hovercards({ linkify: linkify, expanded: expandedByDefault });&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;});&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}-*/;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	private static native void LoginWithTwitterNative()&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	/*-{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	$wnd.twttr.anywhere(function (T)&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;T.signIn();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;});&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}-*/;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	private static native String getUserInfoNative()&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	/*-{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;$wnd.twttr.anywhere(function(T)&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{ &amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;$wnd.parseUserInfo(&amp;quot;{ &amp;quot; +&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;&amp;quot;&amp;#39;screen_name&amp;#39;: &amp;#39;&amp;quot; + T.currentUser.data(&amp;#39;screen_name&amp;#39;) + &amp;quot;&amp;#39;, &amp;quot; +&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;&amp;quot;&amp;#39;name&amp;#39;: &amp;#39;&amp;quot; + T.currentUser.data(&amp;#39;name&amp;#39;) + &amp;quot;&amp;#39;, &amp;quot; +&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;&amp;quot;&amp;#39;profile_image_url&amp;#39;: &amp;#39;&amp;quot; + T.currentUser.data(&amp;#39;profile_image_url&amp;#39;) + &amp;quot;&amp;#39;, &amp;quot; +&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;&amp;quot;&amp;#39;friends_count&amp;#39;: &amp;#39;&amp;quot; + T.currentUser.data(&amp;#39;friends_count&amp;#39;) + &amp;quot;&amp;#39;, &amp;quot; +&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;&amp;quot;&amp;#39;followers_count&amp;#39;: &amp;#39;&amp;quot; + T.currentUser.data(&amp;#39;followers_count&amp;#39;) + &amp;quot;&amp;#39;, &amp;quot; +&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;&amp;quot;&amp;#39;description&amp;#39;: &amp;#39;&amp;quot; + T.currentUser.data(&amp;#39;description&amp;#39;) + &amp;quot;&amp;#39;, &amp;quot; +&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;&amp;quot;&amp;#39;url&amp;#39;: &amp;#39;&amp;quot; + T.currentUser.data(&amp;#39;url&amp;#39;) + &amp;quot;&amp;#39;, &amp;quot; +&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;&amp;quot;&amp;#39;id&amp;#39;: &amp;#39;&amp;quot; + T.currentUser.data(&amp;#39;id&amp;#39;) + &amp;quot;&amp;#39;, &amp;quot; +&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;&amp;quot;&amp;#39;statuses_count&amp;#39;: &amp;#39;&amp;quot; + T.currentUser.data(&amp;#39;statuses_count&amp;#39;) + &amp;quot;&amp;#39;, &amp;quot; +&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;&amp;quot;&amp;#39;following&amp;#39;: &amp;#39;&amp;quot; + T.currentUser.data(&amp;#39;following&amp;#39;) + &amp;quot;&amp;#39; &amp;quot; +&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space:pre&quot;&gt; &lt;/span&gt;&amp;quot;}&amp;quot;);&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;});&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}-*/;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	private String addUniqueIdToWidgetAndReturnId(Widget widget)&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	widget.getElement().setId(HTMLPanel.createUniqueId());&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	return widget.getElement().getId();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;div&gt;
	&amp;nbsp;&lt;/div&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: rgb(34, 34, 34); font-family: Arial, Verdana, sans-serif; line-height: normal; &quot;&gt;
	&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
		&lt;strong&gt;This work is licensed under the apache license, listed below:&lt;/strong&gt;&lt;/p&gt;
	&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
		&amp;nbsp;&lt;/p&gt;
	&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(73, 73, 73); font-family: Verdana; line-height: 20px; &quot;&gt;
		Copyright (c) 2010, David Nelson&lt;/p&gt;
	&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(73, 73, 73); font-family: Verdana; line-height: 20px; &quot;&gt;
		All rights reserved.&lt;/p&gt;
	&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(73, 73, 73); font-family: Verdana; line-height: 20px; &quot;&gt;
		Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:&lt;/p&gt;
	&lt;ul style=&quot;margin-top: 0.5em; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(73, 73, 73); font-family: Verdana; line-height: 20px; &quot;&gt;
		&lt;li style=&quot;margin-top: 0.15em; margin-right: 0px; margin-bottom: 0.15em; margin-left: 0.5em; padding-top: 0px; padding-right: 0px; padding-bottom: 0.2em; padding-left: 1.5em; list-style-type: none; list-style-image: none; background-image: url(http://www.opensource.org/files/color/garland-4208c934/menu-leaf.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; background-position: 1px 0.35em; background-repeat: no-repeat no-repeat; &quot;&gt;
			Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.&lt;/li&gt;
		&lt;li style=&quot;margin-top: 0.15em; margin-right: 0px; margin-bottom: 0.15em; margin-left: 0.5em; padding-top: 0px; padding-right: 0px; padding-bottom: 0.2em; padding-left: 1.5em; list-style-type: none; list-style-image: none; background-image: url(http://www.opensource.org/files/color/garland-4208c934/menu-leaf.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; background-position: 1px 0.35em; background-repeat: no-repeat no-repeat; &quot;&gt;
			Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.&lt;/li&gt;
		&lt;li style=&quot;margin-top: 0.15em; margin-right: 0px; margin-bottom: 0.15em; margin-left: 0.5em; padding-top: 0px; padding-right: 0px; padding-bottom: 0.2em; padding-left: 1.5em; list-style-type: none; list-style-image: none; background-image: url(http://www.opensource.org/files/color/garland-4208c934/menu-leaf.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; background-position: 1px 0.35em; background-repeat: no-repeat no-repeat; &quot;&gt;
			Neither the name of the Infinite Power Publishing nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(73, 73, 73); font-family: Verdana; line-height: 20px; &quot;&gt;
		THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &amp;quot;AS IS&amp;quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.&lt;/p&gt;
	&lt;p&gt;
		&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>gwt scrollable suggestbox</title>
      <link>http://developeradvocate.appspot.com:80/id/14001/gwt-scrollable-suggestbox</link>
      <guid>http://developeradvocate.appspot.com:80/id/14001/gwt-scrollable-suggestbox</guid>
      <pubDate>Mon, 2 Aug 2010 13:55:52 +1700</pubDate>
      <description>
        &lt;p&gt;
	I modified the gwt suggestbox class a bit to support scrolling up and down using the arrow keys as well as the mouse. &amp;nbsp;Enjoy!&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	/*&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* Copyright 2009 Google Inc.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;*&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* Licensed under the Apache License, Version 2.0 (the &amp;quot;License&amp;quot;); you may not&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* use this file except in compliance with the License. You may obtain a copy of&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* the License at&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;*&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* http://www.apache.org/licenses/LICENSE-2.0&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;*&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* Unless required by applicable law or agreed to in writing, software&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* distributed under the License is distributed on an &amp;quot;AS IS&amp;quot; BASIS, WITHOUT&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* License for the specific language governing permissions and limitations under&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* the License.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;*/&lt;/p&gt;
&lt;p&gt;
	package com.google.gwt.user.client.ui;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.dom.client.Document;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.dom.client.Element;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.dom.client.HandlesAllKeyEvents;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.dom.client.HasAllKeyHandlers;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.dom.client.KeyCodes;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.dom.client.KeyDownEvent;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.dom.client.KeyDownHandler;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.dom.client.KeyPressEvent;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.dom.client.KeyPressHandler;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.dom.client.KeyUpEvent;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.dom.client.KeyUpHandler;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.logical.shared.HasSelectionHandlers;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.logical.shared.SelectionEvent;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.logical.shared.SelectionHandler;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.logical.shared.ValueChangeEvent;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.logical.shared.ValueChangeHandler;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.event.shared.HandlerRegistration;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.user.client.Command;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.user.client.DOM;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.user.client.ui.PopupPanel.AnimationType;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.user.client.ui.SuggestOracle.Callback;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.user.client.ui.SuggestOracle.Request;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.user.client.ui.SuggestOracle.Response;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	import java.util.Collection;&lt;/p&gt;
&lt;p&gt;
	import java.util.List;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* A {@link SuggestBox} is a text box or text area which displays a&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* pre-configured set of selections that match the user&amp;#39;s input.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;*&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* Each {@link SuggestBox} is associated with a single {@link SuggestOracle}.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* The {@link SuggestOracle} is used to provide a set of selections given a&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* specific query string.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;*&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;p&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* By default, the {@link SuggestBox} uses a {@link MultiWordSuggestOracle} as&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* its oracle. Below we show how a {@link MultiWordSuggestOracle} can be&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* configured:&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;/p&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;*&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;pre&amp;gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;nbsp; MultiWordSuggestOracle oracle = new MultiWordSuggestOracle(); &amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;nbsp; oracle.add(&amp;quot;Cat&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;nbsp; oracle.add(&amp;quot;Dog&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;nbsp; oracle.add(&amp;quot;Horse&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;nbsp; oracle.add(&amp;quot;Canary&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;nbsp; SuggestBox box = new SuggestBox(oracle);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;/pre&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;*&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* Using the example above, if the user types &amp;quot;C&amp;quot; into the text widget, the&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* oracle will configure the suggestions with the &amp;quot;Cat&amp;quot; and &amp;quot;Canary&amp;quot;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* suggestions. Specifically, whenever the user types a key into the text&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* widget, the value is submitted to the &amp;lt;code&amp;gt;MultiWordSuggestOracle&amp;lt;/code&amp;gt;.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;*&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;p&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* Note that there is no method to retrieve the &amp;quot;currently selected suggestion&amp;quot;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* in a SuggestBox, because there are points in time where the currently&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* selected suggestion is not defined. For example, if the user types in some&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* text that does not match any of the SuggestBox&amp;#39;s suggestions, then the&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* SuggestBox will not have a currently selected suggestion. It is more useful&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* to know when a suggestion has been chosen from the SuggestBox&amp;#39;s list of&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* suggestions. A SuggestBox fires {@link SuggestionEvent SuggestionEvents}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* whenever a suggestion is chosen, and handlers for these events can be added&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* using the {@link #addValueChangeHandler(ValueChangeHandler)} method.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;/p&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;*&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;p&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;img class=&amp;#39;gallery&amp;#39; src=&amp;#39;doc-files/SuggestBox.png&amp;#39;/&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;/p&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;*&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;h3&amp;gt;CSS Style Rules&amp;lt;/h3&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dl&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBox&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the suggest box itself&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the suggestion popup&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .item&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;an unselected suggestion&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .item-selected&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;a selected suggestion&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupTopLeft&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the top left cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupTopLeftInner&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the inner element of the cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupTopCenter&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the top center cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupTopCenterInner&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the inner element of the cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupTopRight&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the top right cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupTopRightInner&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the inner element of the cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupMiddleLeft&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the middle left cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupMiddleLeftInner&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the inner element of the cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupMiddleCenter&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the middle center cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupMiddleCenterInner&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the inner element of the cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupMiddleRight&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the middle right cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupMiddleRightInner&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the inner element of the cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupBottomLeft&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the bottom left cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupBottomLeftInner&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the inner element of the cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupBottomCenter&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the bottom center cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupBottomCenterInner&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the inner element of the cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupBottomRight&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the bottom right cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dt&amp;gt;.gwt-SuggestBoxPopup .suggestPopupBottomRightInner&amp;lt;/dt&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;dd&amp;gt;the inner element of the cell&amp;lt;/dd&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* &amp;lt;/dl&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;*&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* @see SuggestOracle&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* @see MultiWordSuggestOracle&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;* @see TextBoxBase&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;*/&lt;/p&gt;
&lt;p&gt;
	@SuppressWarnings(&amp;quot;deprecation&amp;quot;)&lt;/p&gt;
&lt;p&gt;
	public class SuggestBox extends Composite implements HasText, HasFocus,&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;HasAnimation, SourcesClickEvents, SourcesFocusEvents, SourcesChangeEvents,&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;SourcesKeyboardEvents, FiresSuggestionEvents, HasAllKeyHandlers,&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;HasValue&amp;lt;String&amp;gt;, HasSelectionHandlers&amp;lt;Suggestion&amp;gt; {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * The SuggestionMenu class is used for the display and selection of&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * suggestions in the SuggestBox widget. SuggestionMenu differs from MenuBar&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * in that it always has a vertical orientation, and it has no submenus. It&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * also allows for programmatic selection of items in the menu, and&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * programmatically performing the action associated with the selected item.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * In the MenuBar class, items cannot be selected programatically - they can&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * only be selected when the user places the mouse over a particlar item.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Additional methods in SuggestionMenu provide information about the number&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * of items in the menu, and the index of the currently selected item.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private static class SuggestionMenu extends MenuBar {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;public SuggestionMenu(boolean vertical) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;super(vertical);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// Make sure that CSS styles specified for the default Menu classes&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// do not affect this menu&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;setStyleName(&amp;quot;&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;setFocusOnHoverEnabled(false);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;public void doSelectedItemAction() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// In order to perform the action of the item that is currently&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// selected, the menu must be showing.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;MenuItem selectedItem = getSelectedItem();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (selectedItem != null) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;doItemAction(selectedItem, true, false);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;public int getNumItems() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;return getItems().size();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; * Returns the index of the menu item that is currently selected.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; * @return returns the selected item&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;public int getSelectedItemIndex() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// The index of the currently selected item can only be&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// obtained if the menu is showing.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;MenuItem selectedItem = getSelectedItem();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (selectedItem != null) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return getItems().indexOf(selectedItem);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;return -1;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; * Selects the item at the specified index in the menu. Selecting the item&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; * does not perform the item&amp;#39;s associated action; it only changes the style&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; * of the item and updates the value of SuggestionMenu.selectedItem.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; * @param index index&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;public void selectItem(int index) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;List&amp;lt;MenuItem&amp;gt; items = getItems();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (index &amp;gt; -1 &amp;amp;&amp;amp; index &amp;lt; items.size()) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;itemOver(items.get(index), false);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Class for menu items in a SuggestionMenu. A SuggestionMenuItem differs from&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * a MenuItem in that each item is backed by a Suggestion object. The text of&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * each menu item is derived from the display string of a Suggestion object,&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * and each item stores a reference to its Suggestion object.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private static class SuggestionMenuItem extends MenuItem {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;private static final String STYLENAME_DEFAULT = &amp;quot;item&amp;quot;;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;private Suggestion suggestion;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;public SuggestionMenuItem(Suggestion suggestion, boolean asHTML) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;super(suggestion.getDisplayString(), asHTML);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// Each suggestion should be placed in a single row in the suggestion&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// menu. If the window is resized and the suggestion cannot fit on a&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// single row, it should be clipped (instead of wrapping around and&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// taking up a second row).&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;DOM.setStyleAttribute(getElement(), &amp;quot;whiteSpace&amp;quot;, &amp;quot;nowrap&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;setStyleName(STYLENAME_DEFAULT);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;setSuggestion(suggestion);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;public Suggestion getSuggestion() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;return suggestion;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;public void setSuggestion(Suggestion suggestion) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;this.suggestion = suggestion;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private static final String STYLENAME_DEFAULT = &amp;quot;gwt-SuggestBox&amp;quot;;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Creates a {@link SuggestBox} widget that wraps an existing &amp;amp;lt;input&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * type=&amp;#39;text&amp;#39;&amp;amp;gt; element.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * This element must already be attached to the document. If the element is&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * removed from the document, you must call&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * {@link RootPanel#detachNow(Widget)}.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param oracle the suggest box oracle to use&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param element the element to be wrapped&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public static SuggestBox wrap(SuggestOracle oracle, Element element) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;// Assert that the element is attached.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;assert Document.get().getBody().isOrHasChild(element);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;TextBox textBox = new TextBox(element);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;SuggestBox suggestBox = new SuggestBox(oracle, textBox);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;// Mark it attached and remember it for cleanup.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;suggestBox.onAttach();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;RootPanel.detachOnWindowClose(suggestBox);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return suggestBox;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private int limit = 20;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private boolean selectsFirstItem = true;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private SuggestOracle oracle;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private String currentText;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private final SuggestionMenu suggestionMenu;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private final PopupPanel suggestionPopup;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private final TextBoxBase box;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private final ScrollPanel scrollPanel;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private final Callback callback = new Callback() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;public void onSuggestionsReady(Request request, Response response) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;showSuggestions(response.getSuggestions());&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;};&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Constructor for {@link SuggestBox}. Creates a&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * {@link MultiWordSuggestOracle} and {@link TextBox} to use with this&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * {@link SuggestBox}.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public SuggestBox() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;this(new MultiWordSuggestOracle());&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Constructor for {@link SuggestBox}. Creates a {@link TextBox} to use with&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * this {@link SuggestBox}.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param oracle the oracle for this &amp;lt;code&amp;gt;SuggestBox&amp;lt;/code&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public SuggestBox(SuggestOracle oracle) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;this(oracle, new TextBox());&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Constructor for {@link SuggestBox}. The text box will be removed from it&amp;#39;s&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * current location and wrapped by the {@link SuggestBox}.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param oracle supplies suggestions based upon the current contents of the&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;text widget&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param box the text widget&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public SuggestBox(SuggestOracle oracle, TextBoxBase box) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;this.box = box;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;initWidget(box);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;// suggestionMenu must be created before suggestionPopup, because&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;// suggestionMenu is suggestionPopup&amp;#39;s widget&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;suggestionMenu = new SuggestionMenu(true);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;PopupPanel p = new DecoratedPopupPanel(true, false, &amp;quot;suggestPopup&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;scrollPanel = new ScrollPanel(suggestionMenu);&lt;/p&gt;
&lt;p&gt;
	scrollPanel.setHeight(&amp;quot;200px&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	scrollPanel.setWidget(suggestionMenu);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;p.setWidget(scrollPanel);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;p.setStyleName(&amp;quot;gwt-SuggestBoxPopup&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;p.setPreviewingAllNativeEvents(true);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;p.addAutoHidePartner(getTextBox().getElement());&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;suggestionPopup = p;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;suggestionPopup.setAnimationType(AnimationType.ROLL_DOWN);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;addEventsToTextBox();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;setOracle(oracle);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;setStyleName(STYLENAME_DEFAULT);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Adds a listener to receive change events on the SuggestBox&amp;#39;s text box. The&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * source Widget for these events will be the SuggestBox.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param listener the listener interface to add&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @deprecated use {@link #getTextBox}().addChangeHandler instead&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;@Deprecated&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void addChangeListener(final ChangeListener listener) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;ListenerWrapper.WrappedLogicalChangeListener.add(box, listener).setSource(this);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Adds a listener to receive click events on the SuggestBox&amp;#39;s text box. The&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * source Widget for these events will be the SuggestBox.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param listener the listener interface to add&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @deprecated use {@link #getTextBox}().addClickHandler instead&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;@Deprecated&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void addClickListener(final ClickListener listener) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;ListenerWrapper.WrappedClickListener legacy = ListenerWrapper.WrappedClickListener.add(box,&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;listener);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;legacy.setSource(this);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Adds an event to this handler.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @deprecated use {@link #addSelectionHandler} instead.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;@Deprecated&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void addEventHandler(final SuggestionHandler handler) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;ListenerWrapper.WrappedOldSuggestionHandler.add(this, handler);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Adds a listener to receive focus events on the SuggestBox&amp;#39;s text box. The&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * source Widget for these events will be the SuggestBox.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param listener the listener interface to add&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @deprecated use {@link #getTextBox}().addFocusHandler/addBlurHandler() instead&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;@Deprecated&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void addFocusListener(final FocusListener listener) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;ListenerWrapper.WrappedFocusListener focus = ListenerWrapper.WrappedFocusListener.add(box,&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;listener);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;focus.setSource(this);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @deprecated Use {@link #addKeyDownHandler}, {@link&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * #addKeyUpHandler} and {@link #addKeyPressHandler} instead&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;@Deprecated&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void addKeyboardListener(KeyboardListener listener) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;ListenerWrapper.WrappedKeyboardListener.add(this, listener);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return addDomHandler(handler, KeyDownEvent.getType());&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return addDomHandler(handler, KeyPressEvent.getType());&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public HandlerRegistration addKeyUpHandler(KeyUpHandler handler) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return addDomHandler(handler, KeyUpEvent.getType());&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public HandlerRegistration addSelectionHandler(&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;SelectionHandler&amp;lt;Suggestion&amp;gt; handler) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return addHandler(handler, SelectionEvent.getType());&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public HandlerRegistration addValueChangeHandler(&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;ValueChangeHandler&amp;lt;String&amp;gt; handler) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return addHandler(handler, ValueChangeEvent.getType());&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Gets the limit for the number of suggestions that should be displayed for&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * this box. It is up to the current {@link SuggestOracle} to enforce this&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * limit.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @return the limit for the number of suggestions&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public int getLimit() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return limit;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Gets the suggest box&amp;#39;s {@link com.google.gwt.user.client.ui.SuggestOracle}.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @return the {@link SuggestOracle}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public SuggestOracle getSuggestOracle() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return oracle;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public int getTabIndex() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return box.getTabIndex();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public String getText() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return box.getText();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Get the text box associated with this suggest box.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @return this suggest box&amp;#39;s text box&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public TextBoxBase getTextBox() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return box;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public String getValue() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return box.getValue();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Hide current suggestions.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void hideSuggestionList() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;this.suggestionPopup.hide();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public boolean isAnimationEnabled() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return suggestionPopup.isAnimationEnabled();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Returns whether or not the first suggestion will be automatically selected.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * This behavior is on by default.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @return true if the first suggestion will be automatically selected&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public boolean isAutoSelectEnabled() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return selectsFirstItem;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @return true if the list of suggestions is currently showing, false if not&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public boolean isSuggestionListShowing() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return suggestionPopup.isShowing();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @deprecated Use the {@link HandlerRegistration#removeHandler}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * method on the object returned by {@link #getTextBox}().addChangeHandler instead&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;@Deprecated&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void removeChangeListener(ChangeListener listener) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;ListenerWrapper.WrappedChangeListener.remove(box, listener);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @deprecated Use the {@link HandlerRegistration#removeHandler}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * method on the object returned by {@link #getTextBox}().addClickHandler instead&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;@Deprecated&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void removeClickListener(ClickListener listener) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;ListenerWrapper.WrappedClickListener.remove(box, listener);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @deprecated Use the {@link HandlerRegistration#removeHandler}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * method no the object returned by {@link #addSelectionHandler} instead&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;@Deprecated&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void removeEventHandler(SuggestionHandler handler) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;ListenerWrapper.WrappedOldSuggestionHandler.remove(this, handler);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @deprecated Use the {@link HandlerRegistration#removeHandler}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * method on the object returned by {@link #getTextBox}().addFocusListener instead&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;@Deprecated&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void removeFocusListener(FocusListener listener) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;ListenerWrapper.WrappedFocusListener.remove(this, listener);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @deprecated Use the {@link HandlerRegistration#removeHandler}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * method on the object returned by {@link #getTextBox}().add*Handler instead&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;@Deprecated&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void removeKeyboardListener(KeyboardListener listener) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;ListenerWrapper.WrappedKeyboardListener.remove(this, listener);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void setAccessKey(char key) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;box.setAccessKey(key);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void setAnimationEnabled(boolean enable) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;suggestionPopup.setAnimationEnabled(enable);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Turns on or off the behavior that automatically selects the first suggested&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * item. This behavior is on by default.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param selectsFirstItem Whether or not to automatically select the first&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;suggestion&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void setAutoSelectEnabled(boolean selectsFirstItem) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;this.selectsFirstItem = selectsFirstItem;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void setFocus(boolean focused) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;box.setFocus(focused);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Sets the limit to the number of suggestions the oracle should provide. It&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * is up to the oracle to enforce this limit.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param limit the limit to the number of suggestions provided&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void setLimit(int limit) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;this.limit = limit;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Sets the style name of the suggestion popup.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param style the new primary style name&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @see UIObject#setStyleName(String)&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void setPopupStyleName(String style) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;suggestionPopup.setStyleName(style);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void setTabIndex(int index) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;box.setTabIndex(index);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void setText(String text) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;box.setText(text);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void setValue(String newValue) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;box.setValue(newValue);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void setValue(String value, boolean fireEvents) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;box.setValue(value, fireEvents);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Show the current list of suggestions.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;public void showSuggestionList() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;if (isAttached()) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;currentText = null;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;refreshSuggestions();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * &amp;lt;b&amp;gt;Affected Elements:&amp;lt;/b&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * &amp;lt;ul&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * &amp;lt;li&amp;gt;-popup = The popup that appears with suggestions.&amp;lt;/li&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * &amp;lt;li&amp;gt;-items-item# = The suggested item at the specified index.&amp;lt;/li&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * &amp;lt;/ul&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @see UIObject#onEnsureDebugId(String)&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;@Override&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;protected void onEnsureDebugId(String baseID) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;super.onEnsureDebugId(baseID);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;suggestionPopup.ensureDebugId(baseID + &amp;quot;-popup&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;suggestionMenu.setMenuItemDebugIds(baseID);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Gets the specified suggestion from the suggestions currently showing.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param index the index at which the suggestion lives&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @throws IndexOutOfBoundsException if the index is greater then the number&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; of suggestions currently showing&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @return the given suggestion&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;Suggestion getSuggestion(int index) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;if (!isSuggestionListShowing()) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;throw new IndexOutOfBoundsException(&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;No suggestions showing, so cannot show &amp;quot; + index);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return ((SuggestionMenuItem) suggestionMenu.getItems().get(index)).suggestion;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Get the number of suggestions that are currently showing.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @return the number of suggestions currently showing, 0 if there are none&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;int getSuggestionCount() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;return isSuggestionListShowing() ? suggestionMenu.getNumItems() : 0;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;void showSuggestions(String query) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;if (query.length() == 0) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;oracle.requestDefaultSuggestions(new Request(null, limit), callback);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;} else {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;oracle.requestSuggestions(new Request(query, limit), callback);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private void addEventsToTextBox() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;class TextBoxEvents extends HandlesAllKeyEvents implements&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ValueChangeHandler&amp;lt;String&amp;gt; {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;public void onKeyDown(KeyDownEvent event) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// Make sure that the menu is actually showing. These keystrokes&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// are only relevant when choosing a suggestion.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (suggestionPopup.isAttached()) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;switch (event.getNativeKeyCode()) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;case KeyCodes.KEY_DOWN:&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;suggestionMenu.selectItem(suggestionMenu.getSelectedItemIndex() + 1);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;scrollPanel.ensureVisible(suggestionMenu.getSelectedItem());&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;break;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;case KeyCodes.KEY_UP:&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;suggestionMenu.selectItem(suggestionMenu.getSelectedItemIndex() - 1);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;scrollPanel.ensureVisible(suggestionMenu.getSelectedItem());&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;break;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;case KeyCodes.KEY_ENTER:&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;case KeyCodes.KEY_TAB:&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (suggestionMenu.getSelectedItemIndex() &amp;lt; 0) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;suggestionPopup.hide();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;} else {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;suggestionMenu.doSelectedItemAction();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;break;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;delegateEvent(SuggestBox.this, event);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;public void onKeyPress(KeyPressEvent event) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;delegateEvent(SuggestBox.this, event);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;public void onKeyUp(KeyUpEvent event) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// After every user key input, refresh the popup&amp;#39;s suggestions.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;refreshSuggestions();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;delegateEvent(SuggestBox.this, event);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;public void onValueChange(ValueChangeEvent&amp;lt;String&amp;gt; event) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;delegateEvent(SuggestBox.this, event);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;TextBoxEvents events = new TextBoxEvents();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;events.addKeyHandlersTo(box);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;box.addValueChangeHandler(events);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private void fireSuggestionEvent(Suggestion selectedSuggestion) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;SelectionEvent.fire(this, selectedSuggestion);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private void refreshSuggestions() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;// Get the raw text.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;String text = box.getText();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;if (text.equals(currentText)) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;return;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;} else {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;currentText = text;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;showSuggestions(text);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private void setNewSelection(SuggestionMenuItem menuItem) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;Suggestion curSuggestion = menuItem.getSuggestion();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;currentText = curSuggestion.getReplacementString();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;setText(currentText);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;suggestionPopup.hide();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;fireSuggestionEvent(curSuggestion);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Sets the suggestion oracle used to create suggestions.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param oracle the oracle&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private void setOracle(SuggestOracle oracle) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;this.oracle = oracle;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;/**&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * Show the given collection of suggestions.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; *&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; * @param suggestions suggestions to show&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; */&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;private void showSuggestions(Collection&amp;lt;? extends Suggestion&amp;gt; suggestions) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;if (suggestions.size() &amp;gt; 0) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// Hide the popup before we manipulate the menu within it. If we do not&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// do this, some browsers will redraw the popup as items are removed&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// and added to the menu.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;boolean isAnimationEnabled = suggestionPopup.isAnimationEnabled();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (suggestionPopup.isAttached()) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;suggestionPopup.hide();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;suggestionMenu.clearItems();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;for (Suggestion curSuggestion : suggestions) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;final SuggestionMenuItem menuItem = new SuggestionMenuItem(&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;curSuggestion, oracle.isDisplayStringHTML());&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;menuItem.setCommand(new Command() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;public void execute() {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;SuggestBox.this.setNewSelection(menuItem);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;});&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;suggestionMenu.addItem(menuItem);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (selectsFirstItem) {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// Select the first item in the suggestion menu.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;suggestionMenu.selectItem(0);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;suggestionPopup.showRelativeTo(getTextBox());&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;suggestionPopup.setAnimationEnabled(isAnimationEnabled);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;} else {&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;suggestionPopup.hide();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;}&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
      </description>
      <author></author>
    </item>
    
    <item>
      <title>Does Amazon have a strange security issue?</title>
      <link>http://developeradvocate.appspot.com:80/id/13001/Does-Amazon-have-a-strange-security-issue%3F</link>
      <guid>http://developeradvocate.appspot.com:80/id/13001/Does-Amazon-have-a-strange-security-issue%3F</guid>
      <pubDate>Mon, 2 Aug 2010 01:31:54 +1700</pubDate>
      <description>
        &lt;p&gt;
	I was curious to try amazon&amp;#39;s new facebook based recommendation system. &amp;nbsp;I went to amazon, and didn&amp;#39;t really remember which email I used to login. &amp;nbsp;So I put my current email and the password I thought was right for my amazon account. &amp;nbsp;It logged me in (sort of), but said: &amp;nbsp;&amp;quot;Welcome . &amp;nbsp;( Not ? )&amp;quot; - indicating it logged me in as ... nobody. &amp;nbsp;Weird.&lt;/p&gt;
&lt;p&gt;
	So I logged out and tried a fake account and password: &amp;nbsp;bob@bob.com for the email and &amp;quot;fake&amp;quot; for the password. &amp;nbsp;This logged me in as some account with a nickname of: &amp;nbsp;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(228, 121, 17); font-family: verdana, arial, helvetica, sans-serif; font-size: medium; font-weight: bold; &quot;&gt;uhiuhy`&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	Very strange.&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>Useful architecture for working with app engine datastore</title>
      <link>http://developeradvocate.appspot.com:80/id/12001/Useful-architecture-for-working-with-app-engine-datastore</link>
      <guid>http://developeradvocate.appspot.com:80/id/12001/Useful-architecture-for-working-with-app-engine-datastore</guid>
      <pubDate>Mon, 12 Jul 2010 15:44:30 +1700</pubDate>
      <description>
        &lt;p&gt;
	I&amp;#39;ve come up with a way to use the app engine datastore without joins that makes a lot of sense to me.&lt;/p&gt;
&lt;p&gt;
	Design your jpo class with all the fields you need to query on, then store a serialized version of your domain object graph in a blob.&lt;/p&gt;
&lt;p&gt;
	Works like a champ!&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>App Engine Blog Version 1.0.2 Released</title>
      <link>http://developeradvocate.appspot.com:80/id/11001/App-Engine-Blog-Version-1.0.2-Released</link>
      <guid>http://developeradvocate.appspot.com:80/id/11001/App-Engine-Blog-Version-1.0.2-Released</guid>
      <pubDate>Wed, 28 Apr 2010 17:34:04 +1700</pubDate>
      <description>
        &lt;p&gt;
	Version 1.0.2 of App Engine Blog was released today. &amp;nbsp;It is a small bugfix release yet fixes a really important issue. &amp;nbsp;I found out that the tag cloud at the bottom of the blog was appending the urls incorrectly, resulting in /tag/some-topic/tag/another-topic instead of /tag/another-topic. &amp;nbsp;This bug caused not found pages to show up when navigating via the tag cloud.&lt;/p&gt;
&lt;p&gt;
	You can download the new code here:&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;http://appengineblogsoftware.googlecode.com/files/app_engine_blog_1_0_2.zip&quot;&gt;http://appengineblogsoftware.googlecode.com/files/app_engine_blog_1_0_2.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
	Or, you can simply change this line in defs.py&lt;/p&gt;
&lt;p&gt;
	from:&lt;/p&gt;
&lt;p&gt;
	TAG_URL_PATH = &amp;#39;tag&amp;#39;&lt;/p&gt;
&lt;p&gt;
	to:&lt;/p&gt;
&lt;p&gt;
	TAG_URL_PATH = &amp;#39;/tag&amp;#39;&lt;/p&gt;
&lt;p&gt;
	Feel free to comment on this post if you have questions about installation or usage.&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>Simple, Complete, Tested Example Of Fetching 10 HTTP Requests In Parallel Asynchronously Using Google App Engine For Java</title>
      <link>http://developeradvocate.appspot.com:80/id/10001/Simple%2C-Complete%2C-Tested-Example-Of-Fetching-10-HTTP-Requests-In-Parallel-Asynchronously-Using-Google-App-Engine-For-Java</link>
      <guid>http://developeradvocate.appspot.com:80/id/10001/Simple%2C-Complete%2C-Tested-Example-Of-Fetching-10-HTTP-Requests-In-Parallel-Asynchronously-Using-Google-App-Engine-For-Java</guid>
      <pubDate>Sun, 7 Mar 2010 18:58:44 +1600</pubDate>
      <description>
        &lt;p&gt;
	I realize my last example was hard to put into use. &amp;nbsp;The reason is that I took my working code and stripped out a lot of proprietary code from it to use in the example. &amp;nbsp;As such I didn&amp;#39;t present it as a &amp;quot;copy and paste&amp;quot; friendly guide. &amp;nbsp;It required quite a bit of modification to get it to work. &amp;nbsp;So I created a simple youtube search algorithm which let&amp;#39;s you search for a youtube category, such as &amp;quot;soccer&amp;quot;, then fetch 100 results, 10 pages at a time in parrallel.&lt;/p&gt;
&lt;p&gt;
	I also created a GWT Application To Invoke the server side request. &amp;nbsp;I want to keep this as simple as possible though, so I&amp;#39;m only going to show the code for the app engine servlet:&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	package org.appEngineAsync.server;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	import java.io.ByteArrayInputStream;&lt;/p&gt;
&lt;p&gt;
	import java.io.ByteArrayOutputStream;&lt;/p&gt;
&lt;p&gt;
	import java.net.URL;&lt;/p&gt;
&lt;p&gt;
	import java.util.ArrayList;&lt;/p&gt;
&lt;p&gt;
	import java.util.List;&lt;/p&gt;
&lt;p&gt;
	import java.util.concurrent.CopyOnWriteArrayList;&lt;/p&gt;
&lt;p&gt;
	import java.util.concurrent.Future;&lt;/p&gt;
&lt;p&gt;
	import org.appEngineAsync.client.GreetingService;&lt;/p&gt;
&lt;p&gt;
	import com.google.appengine.api.urlfetch.HTTPHeader;&lt;/p&gt;
&lt;p&gt;
	import com.google.appengine.api.urlfetch.HTTPRequest;&lt;/p&gt;
&lt;p&gt;
	import com.google.appengine.api.urlfetch.HTTPResponse;&lt;/p&gt;
&lt;p&gt;
	import com.google.appengine.api.urlfetch.URLFetchServiceFactory;&lt;/p&gt;
&lt;p&gt;
	import com.google.gwt.user.server.rpc.RemoteServiceServlet;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	@SuppressWarnings(&amp;quot;serial&amp;quot;)&lt;/p&gt;
&lt;p&gt;
	public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	private HTTPRequest request = null;&lt;/p&gt;
&lt;p&gt;
	HTTPHeader acceptCharsetHeader = new HTTPHeader(&amp;quot;Accept-Charset&amp;quot;, &amp;quot;utf-8&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	// All three of these data types are synchronized for thread safety&lt;/p&gt;
&lt;p&gt;
	List&amp;lt;Future&amp;lt;HTTPResponse&amp;gt;&amp;gt; responses = new CopyOnWriteArrayList&amp;lt;Future&amp;lt;HTTPResponse&amp;gt;&amp;gt;();&lt;/p&gt;
&lt;p&gt;
	protected List&amp;lt;String&amp;gt; tempSingleUrl = new CopyOnWriteArrayList&amp;lt;String&amp;gt;();&lt;/p&gt;
&lt;p&gt;
	StringBuffer sb = new StringBuffer();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	public String greetServer(String input) throws Exception&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	List&amp;lt;String&amp;gt; urlsToFetchInParrallel = new ArrayList&amp;lt;String&amp;gt;();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	urlsToFetchInParrallel.add(&amp;quot;http://gdata.youtube.com/feeds/api/channels?q=&amp;quot; + input + &amp;quot;&amp;amp;start-index=1&amp;amp;max-results=10&amp;amp;v=2&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	urlsToFetchInParrallel.add(&amp;quot;http://gdata.youtube.com/feeds/api/channels?q=&amp;quot; + input + &amp;quot;&amp;amp;start-index=11&amp;amp;max-results=10&amp;amp;v=2&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	urlsToFetchInParrallel.add(&amp;quot;http://gdata.youtube.com/feeds/api/channels?q=&amp;quot; + input + &amp;quot;&amp;amp;start-index=21&amp;amp;max-results=10&amp;amp;v=2&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	urlsToFetchInParrallel.add(&amp;quot;http://gdata.youtube.com/feeds/api/channels?q=&amp;quot; + input + &amp;quot;&amp;amp;start-index=31&amp;amp;max-results=10&amp;amp;v=2&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	urlsToFetchInParrallel.add(&amp;quot;http://gdata.youtube.com/feeds/api/channels?q=&amp;quot; + input + &amp;quot;&amp;amp;start-index=41&amp;amp;max-results=10&amp;amp;v=2&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	urlsToFetchInParrallel.add(&amp;quot;http://gdata.youtube.com/feeds/api/channels?q=&amp;quot; + input + &amp;quot;&amp;amp;start-index=51&amp;amp;max-results=10&amp;amp;v=2&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	urlsToFetchInParrallel.add(&amp;quot;http://gdata.youtube.com/feeds/api/channels?q=&amp;quot; + input + &amp;quot;&amp;amp;start-index=61&amp;amp;max-results=10&amp;amp;v=2&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	urlsToFetchInParrallel.add(&amp;quot;http://gdata.youtube.com/feeds/api/channels?q=&amp;quot; + input + &amp;quot;&amp;amp;start-index=71&amp;amp;max-results=10&amp;amp;v=2&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	urlsToFetchInParrallel.add(&amp;quot;http://gdata.youtube.com/feeds/api/channels?q=&amp;quot; + input + &amp;quot;&amp;amp;start-index=81&amp;amp;max-results=10&amp;amp;v=2&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	urlsToFetchInParrallel.add(&amp;quot;http://gdata.youtube.com/feeds/api/channels?q=&amp;quot; + input + &amp;quot;&amp;amp;start-index=91&amp;amp;max-results=10&amp;amp;v=2&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	return performHttpRequest(urlsToFetchInParrallel);&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	// pass in 10 urls at a time&lt;/p&gt;
&lt;p&gt;
	private final String performHttpRequest(List&amp;lt;String&amp;gt; urls) throws NumberFormatException, Exception&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	URL url = null;&lt;/p&gt;
&lt;p&gt;
	request = null;&lt;/p&gt;
&lt;p&gt;
	byte[] tempBuffer = null;&lt;/p&gt;
&lt;p&gt;
	byte[] buffer = null;&lt;/p&gt;
&lt;p&gt;
	ByteArrayInputStream memoryStream = null;&lt;/p&gt;
&lt;p&gt;
	ByteArrayOutputStream baos = null;&lt;/p&gt;
&lt;p&gt;
	final int buffSize = 8192;&lt;/p&gt;
&lt;p&gt;
	int size = 0;&lt;/p&gt;
&lt;p&gt;
	sb.setLength(0);&lt;/p&gt;
&lt;p&gt;
	responses.clear();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	try&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	for (String urlString : urls)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	url = new URL(urlString);&lt;/p&gt;
&lt;p&gt;
	request = new HTTPRequest(url);&lt;/p&gt;
&lt;p&gt;
	request.addHeader(acceptCharsetHeader);&lt;/p&gt;
&lt;p&gt;
	responses.add(URLFetchServiceFactory.getURLFetchService().fetchAsync(request));&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	for (Future&amp;lt;HTTPResponse&amp;gt; futureResponse : responses)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	try&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	memoryStream = new ByteArrayInputStream(futureResponse.get().getContent());&lt;/p&gt;
&lt;p&gt;
	tempBuffer = new byte[buffSize];&lt;/p&gt;
&lt;p&gt;
	baos = new ByteArrayOutputStream();&lt;/p&gt;
&lt;p&gt;
	while ((size = memoryStream.read(tempBuffer, 0, buffSize)) != -1)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	baos.write(tempBuffer, 0, size);&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	buffer = baos.toByteArray();&lt;/p&gt;
&lt;p&gt;
	} catch (Exception ex)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	// TODO: log or take other action&lt;/p&gt;
&lt;p&gt;
	return null;&lt;/p&gt;
&lt;p&gt;
	} finally&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	try&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	baos.close();&lt;/p&gt;
&lt;p&gt;
	} catch (Exception ex)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	// TODO: log&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	// TODO: put this on one line when done debugging&lt;/p&gt;
&lt;p&gt;
	String responseString = new String(buffer, &amp;quot;UTF-8&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	sb.append(responseString);&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	// TODO: put this on one line when done debugging&lt;/p&gt;
&lt;p&gt;
	String allResponsesString = sb.toString();&lt;/p&gt;
&lt;p&gt;
	return allResponsesString;&lt;/p&gt;
&lt;p&gt;
	} catch (Exception ex)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	// TODO: log&lt;/p&gt;
&lt;p&gt;
	return null;&lt;/p&gt;
&lt;p&gt;
	} finally&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	try&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	request = null;&lt;/p&gt;
&lt;p&gt;
	url = null;&lt;/p&gt;
&lt;p&gt;
	memoryStream = null;&lt;/p&gt;
&lt;p&gt;
	tempBuffer = null;&lt;/p&gt;
&lt;p&gt;
	baos = null;&lt;/p&gt;
&lt;p&gt;
	} catch (Exception ex)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	// TODO: log&lt;/p&gt;
&lt;p&gt;
	return null;&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
      </description>
      <author></author>
    </item>
    
    <item>
      <title>Implementing Asynchronous Http Io In Google App Engine For Java</title>
      <link>http://developeradvocate.appspot.com:80/id/9001/Implementing-Asynchronous-Http-Io-In-Google-App-Engine-For-Java</link>
      <guid>http://developeradvocate.appspot.com:80/id/9001/Implementing-Asynchronous-Http-Io-In-Google-App-Engine-For-Java</guid>
      <pubDate>Sun, 28 Feb 2010 23:16:22 +1600</pubDate>
      <description>
        &lt;p&gt;
	&lt;span style=&quot;font-size:28px;&quot;&gt;So if you create a BaseRequest class like this:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	package &lt;yournamespace&gt;.server;&lt;/yournamespace&gt;&lt;/p&gt;
&lt;p&gt;
	import java.io.ByteArrayInputStream;&lt;/p&gt;
&lt;p&gt;
	import java.io.ByteArrayOutputStream;&lt;/p&gt;
&lt;p&gt;
	import java.net.URL;&lt;/p&gt;
&lt;p&gt;
	import java.util.List;&lt;/p&gt;
&lt;p&gt;
	import java.util.concurrent.CopyOnWriteArrayList;&lt;/p&gt;
&lt;p&gt;
	import java.util.concurrent.Future;&lt;/p&gt;
&lt;p&gt;
	import java.util.zip.GZIPInputStream;&lt;/p&gt;
&lt;p&gt;
	import com.google.appengine.api.urlfetch.HTTPResponse;&lt;/p&gt;
&lt;p&gt;
	import com.google.appengine.api.urlfetch.HTTPRequest;&lt;/p&gt;
&lt;p&gt;
	import com.google.appengine.api.urlfetch.HTTPHeader;&lt;/p&gt;
&lt;p&gt;
	import com.google.appengine.api.urlfetch.URLFetchServiceFactory;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	public abstract class BaseRequest&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	private String encodedAuthorizationCredentials = &amp;quot;YOURBASE64ENCODEDAUTHORIZATIONCREDENTIALS&amp;quot;;&lt;/p&gt;
&lt;p&gt;
	private HTTPRequest request = null;&lt;/p&gt;
&lt;p&gt;
	private int apiCallsMade = 0;&lt;/p&gt;
&lt;p&gt;
	HTTPHeader userAgentHeader = new HTTPHeader(&amp;quot;User-agent&amp;quot;, &amp;quot;YOURUSERAGENT&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	HTTPHeader authorizationHeader = new HTTPHeader(&amp;quot;Authorization&amp;quot;, &amp;quot;Basic &amp;quot; + encodedAuthorizationCredentials);&lt;/p&gt;
&lt;p&gt;
	HTTPHeader acceptEncodingHeader = new HTTPHeader(&amp;quot;Accept-Encoding&amp;quot;, &amp;quot;gzip&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	HTTPHeader acceptCharsetHeader = new HTTPHeader(&amp;quot;Accept-Charset&amp;quot;, &amp;quot;utf-8&amp;quot;);&lt;/p&gt;
&lt;p&gt;
	List&lt;future&gt;&lt;httpresponse&gt;&amp;gt; responses = new CopyOnWriteArrayList&lt;future&gt;&lt;httpresponse&gt;&amp;gt;();&lt;/httpresponse&gt;&lt;/future&gt;&lt;/httpresponse&gt;&lt;/future&gt;&lt;/p&gt;
&lt;p&gt;
	protected List&lt;string&gt; tempSingleUrl = new CopyOnWriteArrayList&lt;string&gt;();&lt;/string&gt;&lt;/string&gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	protected BaseRequest()&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	apiCallsMade = 0;&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	public void Execute()&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	performExecute(-1);&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	public void Execute(int currentIndex)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	performExecute(currentIndex);&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	private void performExecute(int currentIndexOptional)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	try&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	// TODO: I&amp;#39;d like to eventually use SequenceInputStream to&lt;/p&gt;
&lt;p&gt;
	// concatenate streams, then&lt;/p&gt;
&lt;p&gt;
	// parse all at once at the end. may have issues with tokens using json because&lt;/p&gt;
&lt;p&gt;
	// each response has&lt;/p&gt;
&lt;p&gt;
	// [ ] in start and end...&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	if (IsSerial())&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	performHttpRequest(getUrl(currentIndexOptional));&lt;/p&gt;
&lt;p&gt;
	} else&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	performHttpRequest(getTenUrls(currentIndexOptional));&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	} catch (Exception ex)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	// TODO: log me!&lt;/p&gt;
&lt;p&gt;
	String readme = null;&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	protected abstract List&lt;string&gt; getUrl(int currentCursor) throws Exception;&lt;/string&gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	protected abstract boolean IsSerial();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	protected abstract void parseResponse(String response);&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	protected abstract List&lt;string&gt; getTenUrls(int i) throws Exception;&lt;/string&gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	protected abstract int getPageIterationCount();&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	public int getApiCallsMadeCount()&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	return apiCallsMade;&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	// pass in 10 at a time&lt;/p&gt;
&lt;p&gt;
	private final void performHttpRequest(List&lt;string&gt; urls) throws NumberFormatException, Exception&lt;/string&gt;&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	GZIPInputStream gzipInputStream = null;&lt;/p&gt;
&lt;p&gt;
	URL url = null;&lt;/p&gt;
&lt;p&gt;
	request = null;&lt;/p&gt;
&lt;p&gt;
	byte[] responseBytes = null;&lt;/p&gt;
&lt;p&gt;
	byte[] tempBuffer = null;&lt;/p&gt;
&lt;p&gt;
	byte[] buffer = null;&lt;/p&gt;
&lt;p&gt;
	ByteArrayOutputStream baos = null;&lt;/p&gt;
&lt;p&gt;
	final int buffSize = 8192;&lt;/p&gt;
&lt;p&gt;
	int size = 0;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	responses.clear();&lt;/p&gt;
&lt;p&gt;
	try&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	for (String urlString : urls)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	// TODO: try and get rid of these two heap allocations&lt;/p&gt;
&lt;p&gt;
	url = new URL(urlString);&lt;/p&gt;
&lt;p&gt;
	request = new HTTPRequest(url);&lt;/p&gt;
&lt;p&gt;
	request.addHeader(userAgentHeader);&lt;/p&gt;
&lt;p&gt;
	request.addHeader(authorizationHeader);&lt;/p&gt;
&lt;p&gt;
	request.addHeader(acceptEncodingHeader);&lt;/p&gt;
&lt;p&gt;
	request.addHeader(acceptCharsetHeader);&lt;/p&gt;
&lt;p&gt;
	responses.add(URLFetchServiceFactory.getURLFetchService().fetchAsync(request));&lt;/p&gt;
&lt;p&gt;
	apiCallsMade++;&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	for (Future&lt;httpresponse&gt; futureResponse : responses)&lt;/httpresponse&gt;&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	try&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	responseBytes = futureResponse.get().getContent();&lt;/p&gt;
&lt;p&gt;
	ByteArrayInputStream memoryStream = new ByteArrayInputStream(responseBytes);&lt;/p&gt;
&lt;p&gt;
	gzipInputStream = new GZIPInputStream(memoryStream);&lt;/p&gt;
&lt;p&gt;
	tempBuffer = new byte[buffSize];&lt;/p&gt;
&lt;p&gt;
	baos = new ByteArrayOutputStream();&lt;/p&gt;
&lt;p&gt;
	while ((size = gzipInputStream.read(tempBuffer, 0, buffSize)) != -1)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	baos.write(tempBuffer, 0, size);&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	buffer = baos.toByteArray();&lt;/p&gt;
&lt;p&gt;
	}&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	catch(Exception ex)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	// TODO: log or take other action&lt;/p&gt;
&lt;p&gt;
	String readme = null;&lt;/p&gt;
&lt;p&gt;
	} finally&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	try&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	baos.close();&lt;/p&gt;
&lt;p&gt;
	} catch (Exception ex)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	// TODO: log&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	parseResponse(new String(buffer, &amp;quot;UTF-8&amp;quot;));&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	} catch (Exception ex)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	// TODO: log me&lt;/p&gt;
&lt;p&gt;
	String readme = null;&lt;/p&gt;
&lt;p&gt;
	} finally&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	try&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	request = null;&lt;/p&gt;
&lt;p&gt;
	url = null;&lt;/p&gt;
&lt;p&gt;
	responseBytes = null;&lt;/p&gt;
&lt;p&gt;
	tempBuffer = null;&lt;/p&gt;
&lt;p&gt;
	baos = null;&lt;/p&gt;
&lt;p&gt;
	} catch (Exception ex)&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	// TODO: log me&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	public void nullRequestSpecificReferences()&lt;/p&gt;
&lt;p&gt;
	{&lt;/p&gt;
&lt;p&gt;
	userAgentHeader = null;&lt;/p&gt;
&lt;p&gt;
	authorizationHeader = null;&lt;/p&gt;
&lt;p&gt;
	acceptEncodingHeader = null;&lt;/p&gt;
&lt;p&gt;
	acceptCharsetHeader = null;&lt;/p&gt;
&lt;p&gt;
	responses = null;&lt;/p&gt;
&lt;p&gt;
	encodedAuthorizationCredentials = null;&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;p&gt;
	}&lt;/p&gt;
&lt;div&gt;
	&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
	&lt;span style=&quot;font-size:28px;&quot;&gt;You can then subclass it and add the overridden methods like this:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
	&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
	&lt;div&gt;
		package&amp;nbsp;&lt;your here=&quot;&quot; namespace=&quot;&quot;&gt;.server;&lt;/your&gt;&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		public class&amp;nbsp;SubclassedRequest&amp;nbsp;extends BaseRequest&lt;/div&gt;
	&lt;div&gt;
		{&lt;/div&gt;
	&lt;div&gt;
		private String currentCursor = &amp;quot;-1&amp;quot;;&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;private List&lt;string&gt; allParsedData = new List&lt;string&gt;();&lt;/string&gt;&lt;/string&gt;&lt;/div&gt;
	&lt;div&gt;
		public SubclassedRequest()&lt;/div&gt;
	&lt;div&gt;
		{&lt;/div&gt;
	&lt;div&gt;
		}&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; public List&lt;string&gt; getAllParsedData()&lt;/string&gt;&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return allParsedData;&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		@Override&lt;/div&gt;
	&lt;div&gt;
		protected boolean IsSerial()&lt;/div&gt;
	&lt;div&gt;
		{&lt;/div&gt;
	&lt;div&gt;
		return false;&lt;/div&gt;
	&lt;div&gt;
		}&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		protected int getPageIterationCount()&lt;/div&gt;
	&lt;div&gt;
		{&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		return pageIterationCount;&lt;/div&gt;
	&lt;div&gt;
		}&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		@Override&lt;/div&gt;
	&lt;div&gt;
		protected void parseResponse(String response)&lt;/div&gt;
	&lt;div&gt;
		{&lt;/div&gt;
	&lt;div&gt;
		try&lt;/div&gt;
	&lt;div&gt;
		{&lt;/div&gt;
	&lt;div&gt;
		&lt;insert add=&quot;&quot; and=&quot;&quot; any=&quot;&quot; code=&quot;&quot; collections=&quot;&quot; here=&quot;&quot; parse=&quot;&quot; response=&quot;&quot; the=&quot;&quot; to=&quot;&quot;&gt;&lt;/insert&gt;&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// example&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;allParsedData.add(&lt;your data=&quot;&quot; here=&quot;&quot; parsed=&quot;&quot; string=&quot;&quot;&gt;);&lt;/your&gt;&lt;/div&gt;
	&lt;div&gt;
		}&lt;/div&gt;
	&lt;div&gt;
		catch(Exception ex)&lt;/div&gt;
	&lt;div&gt;
		{&lt;/div&gt;
	&lt;div&gt;
		// TODO: log this&lt;/div&gt;
	&lt;div&gt;
		}&lt;/div&gt;
	&lt;div&gt;
		// TODO: set objects to null in finally?&lt;/div&gt;
	&lt;div&gt;
		}&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		// TODO: try to remove this&lt;/div&gt;
	&lt;div&gt;
		@Override&lt;/div&gt;
	&lt;div&gt;
		protected List&lt;string&gt; getTenUrls(int nextCursorInex) throws Exception&lt;/string&gt;&lt;/div&gt;
	&lt;div&gt;
		{&lt;/div&gt;
	&lt;div&gt;
		// TODO: make this not necessary&lt;/div&gt;
	&lt;div&gt;
		throw new Exception(&amp;quot;unimplemented. &amp;nbsp;getting friend ids is a serial process. &amp;nbsp;it can&amp;#39;t be parrallelized.&amp;quot;);&lt;/div&gt;
	&lt;div&gt;
		}&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		@Override&lt;/div&gt;
	&lt;div&gt;
		protected List&lt;string&gt; getUrl(int unused) throws Exception&lt;/string&gt;&lt;/div&gt;
	&lt;div&gt;
		{&lt;/div&gt;
	&lt;div&gt;
		try&lt;/div&gt;
	&lt;div&gt;
		{&lt;/div&gt;
	&lt;div&gt;
		if (tempSingleUrl.size() &amp;gt; 0)&lt;/div&gt;
	&lt;div&gt;
		{&lt;/div&gt;
	&lt;div&gt;
		tempSingleUrl.clear();&lt;/div&gt;
	&lt;div&gt;
		}&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		tempSingleUrl.add(ENTERYOURRESTURLHERE);&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		} catch (Exception ex)&lt;/div&gt;
	&lt;div&gt;
		{&lt;/div&gt;
	&lt;div&gt;
		// TODO: log&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		}&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		return tempSingleUrl;&lt;/div&gt;
	&lt;div&gt;
		}&lt;/div&gt;
	&lt;div&gt;
		}&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		&lt;span style=&quot;font-size:28px;&quot;&gt;Then, once you have it all set up, you can simply use it like this:&lt;/span&gt;&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		SubclassedRequest subclassedRequest = new SubclassedRequest();&lt;/div&gt;
	&lt;div&gt;
		for (i = 0; i &amp;lt; 100; i++)&lt;/div&gt;
	&lt;div&gt;
		&lt;div&gt;
			{&lt;/div&gt;
		&lt;div&gt;
			&amp;nbsp;&amp;nbsp; // pass 10 http requests at a time, totalling 100 requests using the page count from&amp;nbsp;baserequest if needed to build the url&lt;/div&gt;
		&lt;div&gt;
			&amp;nbsp;&lt;/div&gt;
		&lt;div&gt;
			&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;subclassedRequest.Execute(i);&lt;/div&gt;
		&lt;div&gt;
			}&lt;/div&gt;
	&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
	&lt;div&gt;
		List&lt;string&gt; allParsedData = subClassedRequest.getAllParsedData();&lt;/string&gt;&lt;/div&gt;
	&lt;div&gt;
		&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>How To Configure A GWT Google Web Toolkit Module</title>
      <link>http://developeradvocate.appspot.com:80/id/8001/How-To-Configure-A-GWT-Google-Web-Toolkit-Module</link>
      <guid>http://developeradvocate.appspot.com:80/id/8001/How-To-Configure-A-GWT-Google-Web-Toolkit-Module</guid>
      <pubDate>Thu, 11 Feb 2010 21:59:57 +1600</pubDate>
      <description>
        &lt;p&gt;
	It took me a while to figure out how to configure a gwt module. &amp;nbsp;I have yet to figure out how to include external projects, although I am looking into that soon.&lt;/p&gt;
&lt;p&gt;
	Here is the code, replace &amp;lt;APP_NAME&amp;gt; with whatever your app is named. &amp;nbsp;Create a folder/package under the server folder/package called ObjectModel, and store your pojo&amp;#39;s. &amp;nbsp;(plain old java object) or jdo enhanced detached pojo&amp;#39;s. &amp;nbsp;If you use jdo enhanced pojos, make sure to set them to the detached state before trying to deserialize them with gwt-rpc and consuming them inside gwt.&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;lt;module rename-to=&amp;#39;&amp;lt;APP_NAME&amp;gt;.server&amp;#39;&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;&amp;lt;inherits name=&amp;#39;com.google.gwt.user.User&amp;#39;/&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;&amp;lt;!-- Specify the paths for translatable code &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;--&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&amp;nbsp;&amp;lt;source path=&amp;#39;server/ObjectModel&amp;#39;/&amp;gt;&lt;/p&gt;
&lt;p&gt;
	&amp;lt;/module&amp;gt;&lt;/p&gt;
&lt;div&gt;
	&amp;nbsp;&lt;/div&gt;
      </description>
      <author></author>
    </item>
    
    <item>
      <title>Have some fun with geomeme by comparing google tweets to yahoo tweets</title>
      <link>http://developeradvocate.appspot.com:80/id/7001/Have-some-fun-with-geomeme-by-comparing-google-tweets-to-yahoo-tweets</link>
      <guid>http://developeradvocate.appspot.com:80/id/7001/Have-some-fun-with-geomeme-by-comparing-google-tweets-to-yahoo-tweets</guid>
      <pubDate>Tue, 26 Jan 2010 13:40:20 +1600</pubDate>
      <description>
        &lt;p&gt;
	Go to&amp;nbsp;&lt;a href=&quot;http://www.geome.me/&quot;&gt;http://www.geome.me/&lt;/a&gt;&amp;nbsp;and locate the googleplex on the map. &amp;nbsp;Check out the tweets. &amp;nbsp;Move the map over the yahoo campus in sunnyvale. &amp;nbsp;Check out the tweets. &amp;nbsp;Pretty cool!&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>twitter sentiment test showcasing twittersentiment.com</title>
      <link>http://developeradvocate.appspot.com:80/id/6001/twitter-sentiment-test-showcasing-twittersentiment.com</link>
      <guid>http://developeradvocate.appspot.com:80/id/6001/twitter-sentiment-test-showcasing-twittersentiment.com</guid>
      <pubDate>Mon, 25 Jan 2010 23:53:20 +1600</pubDate>
      <description>
        &lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(102, 102, 102); font-family: &#39;Lucida Grande&#39;, sans-serif; font-size: 11px; &quot;&gt;twitter sentiment test.&amp;nbsp;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(34, 34, 34); font-family: Arial, Verdana, sans-serif; font-size: 12px; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(102, 102, 102); font-family: &#39;Lucida Grande&#39;, sans-serif; font-size: 11px; &quot;&gt;&lt;a href=&quot;http://twittersentiment.appspot.com/search?query=foxnews&quot;&gt;foxnews (50/50)&lt;/a&gt;: &lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(34, 34, 34); font-family: Arial, Verdana, sans-serif; font-size: 12px; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(102, 102, 102); font-family: &#39;Lucida Grande&#39;, sans-serif; font-size: 11px; &quot;&gt;&amp;nbsp;vs &lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(34, 34, 34); font-family: Arial, Verdana, sans-serif; font-size: 12px; &quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(102, 102, 102); font-family: &#39;Lucida Grande&#39;, sans-serif; font-size: 11px; &quot;&gt;&lt;a href=&quot;http://twittersentiment.appspot.com/search?query=ycombinator&quot;&gt;ycombinator(85/15&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	the results will improve over time and include thousands of sentiments.&lt;/p&gt;
&lt;p&gt;
	check back tomorrow when the algorithm finishes.&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>Design For An Automatic Google App Engine Datastore Backup System</title>
      <link>http://developeradvocate.appspot.com:80/id/5001/Design-For-An-Automatic-Google-App-Engine-Datastore-Backup-System</link>
      <guid>http://developeradvocate.appspot.com:80/id/5001/Design-For-An-Automatic-Google-App-Engine-Datastore-Backup-System</guid>
      <pubDate>Sat, 23 Jan 2010 04:03:12 +1600</pubDate>
      <description>
        &lt;p&gt;
	This is something I&amp;#39;d like to do in the future.&lt;/p&gt;
&lt;p&gt;
	Build an app that uses Aral Balkan&amp;#39;s google app engine backup and restore (gaebar) code to do automatic backups to box.net via their api. &amp;nbsp;A cron job and java or python app invoked by it would need to call the gaebar code, and send either chunks of, or the whole backup to box.net. &amp;nbsp;If chunks were required due to app engine request limits, the cron job could add a task to the task queue, which would build the chunks into the full backup file prior to sending to box.net.&lt;/p&gt;
&lt;p&gt;
	Box.net api:&amp;nbsp;&lt;a href=&quot;http://developers.box.net/ApiOverview&quot;&gt;http://developers.box.net/ApiOverview&lt;/a&gt;&lt;/p&gt;
      </description>
      <author></author>
    </item>
    
    <item>
      <title>How Twitter Can Become Profitable</title>
      <link>http://developeradvocate.appspot.com:80/id/4001/How-Twitter-Can-Become-Profitable</link>
      <guid>http://developeradvocate.appspot.com:80/id/4001/How-Twitter-Can-Become-Profitable</guid>
      <pubDate>Tue, 19 Jan 2010 19:30:45 +1600</pubDate>
      <description>
        &lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	How Twitter Can Become Profitable&lt;/p&gt;
&lt;p&gt;
	There are currently approximately 50,000 twitter api applications that are actively used. &amp;nbsp;I&amp;#39;m sure a good number of those could extend what they offer by&amp;nbsp;having more api calls. &amp;nbsp;They could do new and amazing things with the data, and software companies would value add applications on top of the reams of data.&lt;/p&gt;
&lt;p&gt;
	This is how Twitter can become profitable. &amp;nbsp;By selling API calls to independent software developers.&lt;/p&gt;
&lt;p&gt;
	The things you can do with Twitter data are amazing! &amp;nbsp;New types of applications can be built on this platform. &amp;nbsp;The power of Twitter is in the platform!&lt;/p&gt;
&lt;p&gt;
	By enabling developers unlimited access to the twitter api, incredible insight can be achieved by those who need that level of insight, and are willing to&amp;nbsp;pay for it.&lt;/p&gt;
&lt;p&gt;
	David Nelson&lt;/p&gt;
&lt;p&gt;
	http://twitter.com/devadvocate&lt;/p&gt;
      </description>
      <author></author>
    </item>
    
    <item>
      <title>An abstract java class you can inherit from and implement a HttpRequest, HttpWebRequest, URLConnection in Java </title>
      <link>http://developeradvocate.appspot.com:80/id/3002/An-abstract-java-class-you-can-inherit-from-and-implement-a-HttpRequest%2C-HttpWebRequest%2C-URLConnection-in-Java-</link>
      <guid>http://developeradvocate.appspot.com:80/id/3002/An-abstract-java-class-you-can-inherit-from-and-implement-a-HttpRequest%2C-HttpWebRequest%2C-URLConnection-in-Java-</guid>
      <pubDate>Sun, 10 Jan 2010 23:07:01 +1600</pubDate>
      <description>
        &lt;p&gt;
	package com.java.net.HttpWebRequest;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	import java.net.HttpURLConnection;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	import java.net.URL;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	import java.net.URLEncoder;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	import java.io.IOException;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	import java.io.InputStreamReader;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	import sun.misc.BASE64Encoder;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	import java.io.BufferedReader;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	public abstract class BaseRequest&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	private BASE64Encoder base64 = new BASE64Encoder();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	private String encodedAuthorizationCredentials;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	private StringBuilder outputBuffer = new StringBuilder(Integer.parseInt(getTotalItemsToPage())&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	* Integer.parseInt(getItemsPerPage()));&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	private int totalItemsToPage = Integer.parseInt(getTotalItemsToPage());&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	protected BaseRequest()&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	encodedAuthorizationCredentials = base64.encode((getUsername() + &amp;quot;:&amp;quot; + getPassword()).getBytes());&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	public String getHttpResponseText() throws IOException&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	for (int i = 1; i &amp;lt; totalItemsToPage; i++)&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	outputBuffer.append(getPage(getUrl());&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	return outputBuffer.toString();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	protected abstract String getUrl();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	protected abstract String getItemsPerPage();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	protected abstract String getTotalItemsToPage();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	protected abstract String getUsername();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	protected abstract String getPassword();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	protected abstract String getUserAgent();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	protected abstract String getPageIndexParamName();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	protected String getPage(String urlString) throws IOException&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	HttpURLConnection connection = null;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	BufferedReader bufferedReader = null;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	InputStreamReader inputReader = null;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	URL url = null;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	try&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	// TODO: try and get rid of this heap allocation&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	url = new URL(urlString);&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	connection = (HttpURLConnection) url.openConnection();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	connection.setDoOutput(true);&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // TODO: implement POST&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	connection.setRequestMethod(&amp;quot;GET&amp;quot;);&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	connection.setRequestProperty(&amp;quot;User-agent&amp;quot;, getUserAgent());&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	// TODO: implement oauth.&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	connection.setRequestProperty(&amp;quot;Authorization&amp;quot;, &amp;quot;Basic &amp;quot; + encodedAuthorizationCredentials);&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	// support gzip compression&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	connection.setRequestProperty(&amp;quot;Accept-Encoding&amp;quot;, &amp;quot;gzip&amp;quot;);&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	connection.connect();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	// TODO: try and get rid of these two heap allocations&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	inputReader = new InputStreamReader(connection.getInputStream());&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	bufferedReader = new BufferedReader(inputReader);&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	// response is stripped of line breaks. &amp;nbsp;if it&amp;#39;s not, loop through the bufferedreader here and use a stringbuilder to concatenate each line..&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	return bufferedReader.readLine();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	} finally&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	{&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	connection.disconnect();&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	bufferedReader = null;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	url = null;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	inputReader = null;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	connection = null;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	}&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	Copyright (c) 2010, &lt;a href=&quot;http://twitter.com/devadvocate&quot;&gt;David Nelson&lt;/a&gt;, &lt;a href=&quot;http://www.expertwebinstalls.com&quot;&gt;Infinite Power Publishing&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&lt;a href=&quot;http://twitter.com/devadvocate&quot;&gt;http://twitter.com/devadvocate&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	All rights reserved.&lt;/p&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:&lt;/p&gt;
&lt;ul style=&quot;margin-top: 0.5em; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	&lt;li style=&quot;margin-top: 0.15em; margin-right: 0px; margin-bottom: 0.15em; margin-left: 0.5em; padding-top: 0px; padding-right: 0px; padding-bottom: 0.2em; padding-left: 1.5em; list-style-type: none; list-style-image: none; background-image: url(http://www.opensource.org/files/color/garland-for-licences-89d62840/menu-leaf.gif); background-repeat: no-repeat; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: transparent; background-position: 1px 0.35em; &quot;&gt;
		&lt;strong&gt;Redistributions of source code must retain the above copyright notice including the html anchor tags and links, this list of conditions and the following disclaimer.&lt;/strong&gt;&lt;/li&gt;
	&lt;li style=&quot;margin-top: 0.15em; margin-right: 0px; margin-bottom: 0.15em; margin-left: 0.5em; padding-top: 0px; padding-right: 0px; padding-bottom: 0.2em; padding-left: 1.5em; list-style-type: none; list-style-image: none; background-image: url(http://www.opensource.org/files/color/garland-for-licences-89d62840/menu-leaf.gif); background-repeat: no-repeat; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: transparent; background-position: 1px 0.35em; &quot;&gt;
		Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.&lt;/li&gt;
	&lt;li style=&quot;margin-top: 0.15em; margin-right: 0px; margin-bottom: 0.15em; margin-left: 0.5em; padding-top: 0px; padding-right: 0px; padding-bottom: 0.2em; padding-left: 1.5em; list-style-type: none; list-style-image: none; background-image: url(http://www.opensource.org/files/color/garland-for-licences-89d62840/menu-leaf.gif); background-repeat: no-repeat; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: transparent; background-position: 1px 0.35em; &quot;&gt;
		Neither the name of the &lt;organization&gt; nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.&lt;/organization&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;margin-top: 0.6em; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; &quot;&gt;
	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &amp;quot;AS IS&amp;quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>Object Oriented PHP Tutorial For Beginners</title>
      <link>http://developeradvocate.appspot.com:80/id/3001/Object-Oriented-PHP-Tutorial-For-Beginners</link>
      <guid>http://developeradvocate.appspot.com:80/id/3001/Object-Oriented-PHP-Tutorial-For-Beginners</guid>
      <pubDate>Sat, 9 Jan 2010 12:48:26 +1600</pubDate>
      <description>
        &lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Verdana, Arial, sans-serif; font-size: 11px; white-space: pre-wrap; &quot;&gt;This article is intended for folks just starting out with php. As your php journey progresses, you&amp;#39;ll want to learn object oriented programming. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Verdana, Arial, sans-serif; font-size: 11px; white-space: pre-wrap; &quot;&gt;Here&amp;#39;s a good tutorial on it: &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Verdana, Arial, sans-serif; font-size: 11px; white-space: pre-wrap; &quot;&gt;&lt;a href=&quot;http://www.killerphp.com/tutorials/object-oriented-php/&quot;&gt;http://www.killerphp.com/tutorials/object-oriented-php/&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Verdana, Arial, sans-serif; font-size: 11px; white-space: pre-wrap; &quot;&gt;Also, design patterns can help you a lot. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Verdana, Arial, sans-serif; font-size: 11px; white-space: pre-wrap; &quot;&gt;Here&amp;#39;s a few I use often: &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Verdana, Arial, sans-serif; font-size: 11px; white-space: pre-wrap; &quot;&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Singleton_pattern#PHP&quot;&gt;http://en.wikipedia.org/wiki/Singleton_pattern#PHP&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Verdana, Arial, sans-serif; font-size: 11px; white-space: pre-wrap; &quot;&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller#PHP&quot;&gt;http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller#PHP&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Verdana, Arial, sans-serif; font-size: 11px; white-space: pre-wrap; &quot;&gt;&lt;a href=&quot;http://www.devshed.com/c/a/PHP/Introducing-the-Facade-Pattern-in-PHP-5/1/&quot;&gt;http://www.devshed.com/c/a/PHP/Introducing-the-Facade-Pattern-in-PHP-5/1/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>Great Twitter API Client For Java - twitter4j</title>
      <link>http://developeradvocate.appspot.com:80/id/2001/Great-Twitter-API-Client-For-Java---twitter4j</link>
      <guid>http://developeradvocate.appspot.com:80/id/2001/Great-Twitter-API-Client-For-Java---twitter4j</guid>
      <pubDate>Fri, 8 Jan 2010 20:41:29 +1600</pubDate>
      <description>
        &lt;p&gt;
	When comparing the twitter api clients that twitter links to from their api docs, I noticed that twitter4j said &amp;#39;app engine safe&amp;#39;. &amp;nbsp;That made me want to download it. &amp;nbsp;So far it has worked fantastically. &amp;nbsp;I recommend it to anyone building a twitter api application.&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;http://github.com/yusuke/twitter4j/archives/master&quot;&gt;You can download the source code for twitter4j here.&lt;/a&gt;&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>AppEngineBlog ("AEB") Version 1.0.1 Released</title>
      <link>http://developeradvocate.appspot.com:80/id/1005/AppEngineBlog-%28%22AEB%22%29-Version-1.0.1-Released</link>
      <guid>http://developeradvocate.appspot.com:80/id/1005/AppEngineBlog-%28%22AEB%22%29-Version-1.0.1-Released</guid>
      <pubDate>Wed, 30 Dec 2009 13:57:20 +1600</pubDate>
      <description>
        &lt;p&gt;
	Today I released version 1.0.1 of AppEngineBlog (&amp;quot;AEB&amp;quot;).&lt;/p&gt;
&lt;p&gt;
	Here is the release notes summary:&lt;/p&gt;
&lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;runs on app engine&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;
		&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;uses python and django&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;
		&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;fully functional password protected admin to add/edit/delete blog posts&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;
		&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;fully functional public blog viewer to view blog posts&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;
		&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;tag cloud support&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;
		&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;WYSIWYG editor for posts&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;
		&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;home page truncated article previews with read more link&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;
		&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;search engine friendly url&amp;#39;s&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;
		&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;working to keep the code barebones and add features via integration with social media &amp;amp; other javascript api&amp;#39;s for promotion/analytics/profit:&lt;/span&gt;
		&lt;ul&gt;
			&lt;li&gt;
				&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;feedburner rss&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;
				&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;feedburner email&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;
				&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;twitter follow&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;
				&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;facebook fan follow&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;
				&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;disqus comments&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;
				&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;google analytics&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;
				&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;google adsense&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;
				&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;google custom search&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;
				&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;wibiya toolbar&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;
				&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;tweetmeme retweet this&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;
				&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;facebook share this.&lt;/span&gt;&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;In addition, I have packaged a &lt;a href=&quot;http://appengineblogsoftware.googlecode.com/files/app_engine_blog_1_0_1.zip&quot;&gt;source code distribution in a .zip file&lt;/a&gt;, and uploaded to the &lt;a href=&quot;http://code.google.com/p/appengineblogsoftware/&quot;&gt;application&amp;#39;s google project hosting page&lt;/a&gt;. &amp;nbsp;I have also checked in the &lt;a href=&quot;http://code.google.com/p/appengineblogsoftware/source/browse/#svn/trunk&quot;&gt;Version 1.1.0 code&lt;/a&gt; to the &lt;a href=&quot;http://code.google.com/p/appengineblogsoftware/&quot;&gt;application&amp;#39;s google project hosting page&lt;/a&gt;. &amp;nbsp;I enabled anyone to code review it.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;I also added it to the &lt;a href=&quot;http://appgallery.appspot.com/about_app?app_id=agphcHBnYWxsZXJ5chQLEgxBcHBsaWNhdGlvbnMYiOgfDA&quot;&gt;google app engine project gallery&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;Please use it liberally and submit all issues you find with it at the &lt;a href=&quot;http://code.google.com/p/appengineblogsoftware/issues/list&quot;&gt;application&amp;#39;s google project issue tracker&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;Thanks, and enjoy! &amp;nbsp;:-)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;David&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(0, 0, 0); font-family: Arial, Verdana, Helvetica, &#39;sans serif&#39;; font-size: 16px; &quot;&gt;p.s. &amp;nbsp;Time permitting, I will be releasing installation instructions as well as adding many new features, listed in a previous blog post. &amp;nbsp;It should be fairly trivial to install. &amp;nbsp;Just edit the &amp;#39;defs.py&amp;#39; file, then upload to app engine like you would any other python app. &amp;nbsp;You&amp;#39;ll have to visit a number of the social media / api sites to get account id&amp;#39;s first if you don&amp;#39;t already have them.&lt;/span&gt;&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>Don't Make Me Click - Sage User Experience Advice From Google</title>
      <link>http://developeradvocate.appspot.com:80/id/1004/Don%27t-Make-Me-Click---Sage-User-Experience-Advice-From-Google</link>
      <guid>http://developeradvocate.appspot.com:80/id/1004/Don%27t-Make-Me-Click---Sage-User-Experience-Advice-From-Google</guid>
      <pubDate>Wed, 30 Dec 2009 11:46:15 +1600</pubDate>
      <description>
        &lt;p&gt;
	&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
	I watched this fantastic tech talk by Aza Raskin at google a while back. &amp;nbsp;It totally changed the way I think about building web application UI&amp;#39;s. &amp;nbsp;I hope it challenges and enlightens you like it did for me:&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;http://bit.ly/17B50&quot;&gt;Don&amp;#39;t Make Me Click (whoops, forced you to click didn&amp;#39;t I? &amp;nbsp;:-)&lt;/a&gt;&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>Created Google Project Hosting Site For App Engine Blog </title>
      <link>http://developeradvocate.appspot.com:80/id/7/Created-Google-Project-Hosting-Site-For-App-Engine-Blog-</link>
      <guid>http://developeradvocate.appspot.com:80/id/7/Created-Google-Project-Hosting-Site-For-App-Engine-Blog-</guid>
      <pubDate>Wed, 30 Dec 2009 10:42:12 +1600</pubDate>
      <description>
        &lt;p&gt;
	App Engine Blog (&amp;quot;AEB&amp;quot;, pronounced &amp;quot;Abe&amp;quot;) seeks to provide a near wordpress quality blog engine that runs on the google app engine.&lt;/p&gt;
&lt;div id=&quot;wikicontent&quot; style=&quot;padding: 0pt 3em 1.2em 0pt;&quot;&gt;
	&lt;p&gt;
		It is a fork of Brian M. Clapper&amp;#39;s excellent Pico Blog for app engine: &lt;a href=&quot;http://www.clapper.org/software/python/picoblog/&quot; rel=&quot;nofollow&quot;&gt;http://www.clapper.org/software/python/picoblog/&lt;/a&gt;&lt;/p&gt;
	&lt;p&gt;
		Some core features / attributes:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;
			runs on app engine&lt;/li&gt;
		&lt;li&gt;
			uses python and django&lt;/li&gt;
		&lt;li&gt;
			fully functional password protected admin to add/edit/delete blog posts&lt;/li&gt;
		&lt;li&gt;
			fully functional public blog viewer to view blog posts&lt;/li&gt;
		&lt;li&gt;
			tag cloud support&lt;/li&gt;
		&lt;li&gt;
			WYSIWYG editor for posts&lt;/li&gt;
		&lt;li&gt;
			home page truncated article previews with read more link&lt;/li&gt;
		&lt;li&gt;
			search engine friendly url&amp;#39;s&lt;/li&gt;
		&lt;li&gt;
			working to keep the code barebones and add features via integration with social media &amp;amp; other javascript api&amp;#39;s for promotion/analytics/profit:
			&lt;ul&gt;
				&lt;li&gt;
					feedburner rss&lt;/li&gt;
				&lt;li&gt;
					feedburner email&lt;/li&gt;
				&lt;li&gt;
					twitter follow&lt;/li&gt;
				&lt;li&gt;
					facebook fan follow&lt;/li&gt;
				&lt;li&gt;
					disqus comments&lt;/li&gt;
				&lt;li&gt;
					google analytics&lt;/li&gt;
				&lt;li&gt;
					google adsense&lt;/li&gt;
				&lt;li&gt;
					google custom search&lt;/li&gt;
				&lt;li&gt;
					wibiya toolbar&lt;/li&gt;
				&lt;li&gt;
					tweetmeme retweet this&lt;/li&gt;
				&lt;li&gt;
					facebook share this.&lt;/li&gt;
			&lt;/ul&gt;
		&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;
		Upgrades / future enhancements being considered / in progress:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;
			considering port to java app engine&lt;/li&gt;
		&lt;li&gt;
			non ajax for now (considering adding ajax features but concerned with search engine optimization issues)&lt;/li&gt;
		&lt;li&gt;
			memcache support&lt;/li&gt;
		&lt;li&gt;
			image upload support&lt;/li&gt;
		&lt;li&gt;
			&amp;quot;themelets&amp;quot;, ie: a minimalist base ui theme that can be extended via editing a css file&lt;/li&gt;
		&lt;li&gt;
			support for plugins ala wordpress&lt;/li&gt;
		&lt;li&gt;
			source code auto-formatter to make it easier to share source code snippets&lt;/li&gt;
		&lt;li&gt;
			there are more ideas which are eluding me at the moment, stay tuned.&amp;nbsp;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;
		Please comment and share your ideas on how to make the project better. &amp;nbsp; Also if you would like to join the project, shoot me your resume. &amp;nbsp;Thanks!&lt;/p&gt;
	&lt;p&gt;
		&lt;a href=&quot;http://code.google.com/p/appengineblogsoftware/&quot;&gt;Here is the link to the newly created project on google code.&lt;/a&gt; &amp;nbsp;&lt;/p&gt;
	&lt;p&gt;
		I have to externalize some config settings, after which I will be doing my first checkin.&lt;/p&gt;
&lt;/div&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>How To Convert Dates To A Timezone In Python / Django / Google App Engine Datastore</title>
      <link>http://developeradvocate.appspot.com:80/id/1003/How-To-Convert-Dates-To-A-Timezone-In-Python-/-Django-/-Google-App-Engine-Datastore</link>
      <guid>http://developeradvocate.appspot.com:80/id/1003/How-To-Convert-Dates-To-A-Timezone-In-Python-/-Django-/-Google-App-Engine-Datastore</guid>
      <pubDate>Tue, 29 Dec 2009 17:23:44 +1600</pubDate>
      <description>
        &lt;p&gt;
	I found it pretty tough to do something I had thought would be simple in python on the google app engine today. I was trying to get my blog posts to show up in pacific standard time. I looked at the app engine docs, and googled for quite a while. I finally figured it out.&lt;/p&gt;
&lt;p&gt;
	The reason it is tricky is that the datetime from the app engine datastore comes back &amp;quot;naive&amp;quot;, which just means that it doesn&amp;#39;t have a time zone set yet. So, even though it comes back in UTC time, you have to replace it&amp;#39;s time zone with UTC anyway before you try and change it&amp;#39;s time zone to pacific time. I&amp;#39;m still not entirely clear why if datetime&amp;#39;s are stored in UTC they don&amp;#39;t automatically have the tzinfo set to UTC.&lt;/p&gt;
&lt;p&gt;
	Here is the python code running in a console app format to convert an app engine datastore datetime into a specific time zone, this one being pacific standard time:&lt;/p&gt;
&lt;pre&gt;import datetime
from datetime import tzinfo

class Article(db.Model):
published_when = db.DateTimeProperty(auto_now_add=True)

class UtcTzinfo(datetime.tzinfo):
    def utcoffset(self, dt): return datetime.timedelta(0)
    def dst(self, dt): return datetime.timedelta(0)
    def tzname(self, dt): return &amp;#39;UTC&amp;#39;
    def olsen_name(self): return &amp;#39;UTC&amp;#39;

class PstTzinfo(datetime.tzinfo):
    def utcoffset(self, dt):
        return datetime.timedelta(hours=-8) + self.dst(dt)
    def _FirstSunday(self, dt):
        return dt + datetime.timedelta(days=(6-dt.weekday()))
    def dst(self, dt):
        dst_start = self._FirstSunday(datetime.datetime(dt.year, 3, 8, 2))
        dst_end = self._FirstSunday(datetime.datetime(dt.year, 11, 1, 1))
        if dst_start &amp;lt;= dt.replace(tzinfo=None) &amp;lt; dst_end:
            return datetime.timedelta(hours=1)
        else:
            return datetime.timedelta(hours=0)
    def tzname(self, dt):
        if self.dst(dt) == datetime.timedelta(hours=0):
            return &amp;quot;PST&amp;quot;
        else:
            return &amp;quot;PDT&amp;quot;

def main():
    article = Article.gql(&amp;quot;limit 1&amp;quot;)
    article.published_when = article.published_when.replace(tzinfo=UtcTzinfo()).astimezone(PstTzinfo())

if __name__ == &amp;#39;__main__&amp;#39;:
    main()

&lt;/pre&gt;
      </description>
      <author></author>
    </item>
    
    <item>
      <title>GPL, Free Web 2.0 Social Icons For Twitter, Facebook, RSS, and Email</title>
      <link>http://developeradvocate.appspot.com:80/id/6/GPL%2C-Free-Web-2.0-Social-Icons-For-Twitter%2C-Facebook%2C-RSS%2C-and-Email</link>
      <guid>http://developeradvocate.appspot.com:80/id/6/GPL%2C-Free-Web-2.0-Social-Icons-For-Twitter%2C-Facebook%2C-RSS%2C-and-Email</guid>
      <pubDate>Tue, 29 Dec 2009 15:19:04 +1600</pubDate>
      <description>
        &lt;p&gt;
	I&amp;#39;m creating an open source blog platform, and needed some free icons for following the blog owner via the most popular social channels; facebook, twitter, rss and email. I searched for an hour, and came close. I found some fantastic icons, which had a super annoying creative commons license which required a link back to their site if you used them. How ridiculous is that!&lt;/p&gt;
&lt;p&gt;
	Then I found some great GPL licensed icons, which did not contain an email icon. Frustrated, I finally decided to create my own GPL icons based on the GPL package I found, adding my own email icon using another GPL&amp;#39;d image for the email image. I also added a little drop shadow and gaussian blur to remove some ugly edges on the buttons.&lt;/p&gt;
&lt;p&gt;
	I honestly haven&amp;#39;t done any graphic design in 12 years, and don&amp;#39;t even have photoshop. I made these in GIMP. I think they turned out alright. Please use and enjoy them!!&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;http://developeradvocate.appspot.com/static/gpl_social_icons.zip&quot;&gt;Here is the link to the images flattened as .png, as well as the master .psd file with layers.&lt;/a&gt;&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>What Are Good Interview Questions For A C# Software Engineer Candidate?</title>
      <link>http://developeradvocate.appspot.com:80/id/5/What-Are-Good-Interview-Questions-For-A-C%23-Software-Engineer-Candidate%3F</link>
      <guid>http://developeradvocate.appspot.com:80/id/5/What-Are-Good-Interview-Questions-For-A-C%23-Software-Engineer-Candidate%3F</guid>
      <pubDate>Mon, 28 Dec 2009 11:33:21 +1600</pubDate>
      <description>
        &lt;ol&gt;
	&lt;li&gt;
		object oriented programming: encapsulation, inheritance, polymorphism&lt;/li&gt;
	&lt;li&gt;
		implement a singleton in c# on the whiteboard&lt;/li&gt;
	&lt;li&gt;
		explain these design patterns: singleton, factory, mvc, inversion of control, activerecord, proxy, facade, observer.&lt;/li&gt;
	&lt;li&gt;
		what is a race condition? how do you prevent it?&lt;/li&gt;
	&lt;li&gt;
		what is a deadlock? how do you prevent it?&lt;/li&gt;
	&lt;li&gt;
		what is your preferred object relational modeling tool for .NET and why?&lt;/li&gt;
	&lt;li&gt;
		what are 20 ways to speed up a web application?&lt;/li&gt;
	&lt;li&gt;
		what is the difference between a left join and right join in sql?&lt;/li&gt;
	&lt;li&gt;
		approximately how many classes are there in the .NET framework?&lt;/li&gt;
	&lt;li&gt;
		explain boxing and unboxing&lt;/li&gt;
	&lt;li&gt;
		what is MSIL and how does the .NET framework use it?&lt;/li&gt;
	&lt;li&gt;
		what is a delegate?&lt;/li&gt;
	&lt;li&gt;
		what does the static keyword do to methods? to fields? to properties?&lt;/li&gt;
	&lt;li&gt;
		what are automatic properties?&lt;/li&gt;
	&lt;li&gt;
		what does the using keyword do?&lt;/li&gt;
	&lt;li&gt;
		how is the lock keyword implemented?&lt;/li&gt;
	&lt;li&gt;
		write a method on the whiteboard to take in a string with values seperated by commas, and convert it to an array with each array element being a value that was delimited by a comma.&lt;/li&gt;
	&lt;li&gt;
		what is reflection?&lt;/li&gt;
	&lt;li&gt;
		what does the finally keyword do?&lt;/li&gt;
	&lt;li&gt;
		at what point does using a stringbuilder become faster than concatenating a string with the + operator?&lt;/li&gt;
	&lt;li&gt;
		Explain the difference between a .NET managed thread pool thread, an IO thread, a process thread, and a managed thread.&lt;/li&gt;
	&lt;li&gt;
		what are generics in .NET and why do you use them?&lt;/li&gt;
	&lt;li&gt;
		explain how the binary search algorithm works and why you&amp;#39;d want to use it.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>Top Ten Startup Scalability Killers</title>
      <link>http://developeradvocate.appspot.com:80/id/1002/Top-Ten-Startup-Scalability-Killers</link>
      <guid>http://developeradvocate.appspot.com:80/id/1002/Top-Ten-Startup-Scalability-Killers</guid>
      <pubDate>Sun, 27 Dec 2009 23:27:20 +1600</pubDate>
      <description>
        &lt;p&gt;
	Web startups that can&amp;#39;t scale to meet the demands of an ever growing base of users fail. Period. Look at friendster for a painful example of this. GigaOM recently published an interesting article outlining the top 10 mistakes startups make regarding scalability.&lt;/p&gt;
&lt;p&gt;
	Do you agree or disagree with point #10 &amp;quot;Overreliance On Third Parties To Scale&amp;quot;? The reality of the situation is that no web application can have 100% up time. Google has gone down for periods of time because of internet backbone issues. Wal-mart.com, Amazon.com and Amazon Web Services have all gone down recently due to DNS issues.&lt;/p&gt;
&lt;p&gt;
	My opinion is that cloud based architectures using google app engine and amazon web services are as reliable as anything you could build yourself. What do you think?&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;http://gigaom.com/2009/12/20/top-10-internet-startup-scalability-killers/&quot;&gt;Here is the article on GigaOM.&lt;/a&gt;&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>Harness The Power Of The Google Development Platform</title>
      <link>http://developeradvocate.appspot.com:80/id/4/Harness-The-Power-Of-The-Google-Development-Platform</link>
      <guid>http://developeradvocate.appspot.com:80/id/4/Harness-The-Power-Of-The-Google-Development-Platform</guid>
      <pubDate>Sun, 27 Dec 2009 17:00:42 +1600</pubDate>
      <description>
        &lt;p&gt;
	The google development platform is unbelievably powerful. It consists of 4 major components:&lt;/p&gt;
&lt;p&gt;
	1) &lt;strong&gt;Google App Engine&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		allows developers to build web applications which can scale infinitely to support extreme growths.&lt;/li&gt;
	&lt;li&gt;
		Allows small companies to get started for free, and then pay as they go when they can afford to. As of now, developers get 1,300,000 http requests for free per day ( according to: &lt;a href=&quot;http://code.google.com/appengine/docs/quotas.html&quot;&gt;http://code.google.com/appengine/docs/quotas.html&lt;/a&gt; ). That is a lot.&lt;/li&gt;
	&lt;li&gt;
		You can write your server code in python or java.&lt;/li&gt;
	&lt;li&gt;
		Google has made it easier to use their datastore by adding support for the Java Data Objects object relational modeling toolkit. The datastore does take some getting used to for developers who cut their teeth on sql based databases.&lt;/li&gt;
	&lt;li&gt;
		Main site: &lt;a href=&quot;http://code.google.com/appengine &quot;&gt;http://code.google.com/appengine &lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;
		A great tutorial on doing advanced data access from Google IO 2009: &lt;a href=&quot;http://code.google.com/events/io/2009/sessions/BuildingScalableComplexApps.html&quot;&gt;http://code.google.com/events/io/2009/sessions/BuildingScalableComplexApps.html&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	2) &lt;strong&gt;Google Web Toolkit&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Allows developers to easily build ajax applications in object oriented java, which are then cross compiled to javascript. The benefits here are obvious to any seasoned engineer. Object oriented programming support in javascript itself is limited, and large javascript codebases can be difficult to maintain. In addition, browser quirks make testing ajax applications written in pure javascript difficult, leading to longer development and qa cycles.&lt;/li&gt;
	&lt;li&gt;
		Google web toolkit has a rich object oriented java framework, and cross compiles your java code to javascript.&lt;/li&gt;
	&lt;li&gt;
		It minifies and optimizes the output javascript, and also outputs different javascript codes which are automatically streamlined to run in five or six different web browsers.&lt;/li&gt;
	&lt;li&gt;
		In addition, there are many features in google web toolkit which are just not available in javascript based ajax toolkits right now.&lt;/li&gt;
	&lt;li&gt;
		Code splitting allows the developer to asynchronously download sections of the application&amp;#39;s javascript on an as needed basis so the initial application loads faster.&lt;/li&gt;
	&lt;li&gt;
		GWT-RPC works similarly to how many ajax developers use JSON as an object serialization technique, except GWT-RPC is faster.&lt;/li&gt;
	&lt;li&gt;
		It&amp;#39;s faster to create ajax apps in google web toolkit (also known as GWT), and the apps you create run faster for your end users.&lt;/li&gt;
	&lt;li&gt;
		Main site: &lt;a href=&quot;http://code.google.com/webtoolkit &quot;&gt;http://code.google.com/webtoolkit &lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;
		A great tutorial on how to architect a GWT application from google IO 2009: &lt;a href=&quot;http://code.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.htm&quot;&gt;http://code.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.htm&lt;/a&gt;&lt;a href=&quot;http://code.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.html&quot;&gt;l&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	3) &lt;strong&gt;Eclipse IDE&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		While not created by google, eclipse is integral to a good google development platform setup.&lt;/li&gt;
	&lt;li&gt;
		Eclipse allows you to run the google plugin for eclipse, and locally write and debug both your app engine and google web toolkit code.&lt;/li&gt;
	&lt;li&gt;
		Main site: &lt;a href=&quot;http://www.eclipse.org/&quot;&gt;http://www.eclipse.org/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	4) &lt;strong&gt;Google Plugin For Eclipse&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		The google plugin for eclipse makes developing, testing, and deploying app engine and web toolkit apps a snap.&lt;/li&gt;
	&lt;li&gt;
		It adds all the great tooling you need to easily create an app engine / web tookit app, develop it, test it, then deploy it, simply by using the Eclipse IDE.&lt;/li&gt;
	&lt;li&gt;
		No command line required.&lt;/li&gt;
	&lt;li&gt;
		Main site: &lt;a href=&quot;http://code.google.com/eclipse/ &quot;&gt;http://code.google.com/eclipse/&amp;nbsp;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	I hope you take a look at this &lt;u&gt;amazing&lt;/u&gt; platform google has assembled. &lt;em&gt;It&amp;#39;s truly revolutionary.&amp;nbsp;&lt;/em&gt;&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>Examples For How To Use App Engine DataStore In A Variety Of Common Scenarios</title>
      <link>http://developeradvocate.appspot.com:80/id/3/Examples-For-How-To-Use-App-Engine-DataStore-In-A-Variety-Of-Common-Scenarios</link>
      <guid>http://developeradvocate.appspot.com:80/id/3/Examples-For-How-To-Use-App-Engine-DataStore-In-A-Variety-Of-Common-Scenarios</guid>
      <pubDate>Sun, 27 Dec 2009 16:26:35 +1600</pubDate>
      <description>
        &lt;p&gt;
	This is a fantastic roundup of tips from the google app engine team on how to do common data manipulation tasks using java data objects and the google app engine datastore. Highly recommended to anyone doing serious app engine development.&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;http://googleappengine.blogspot.com/2009/12/jpajdo-java-persistence-tips-year-in.html?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+GoogleAppEngineBlog+%28Google+App+Engine+Blog%29&quot;&gt;Take a look and improve your app engine datastore skills.&lt;/a&gt;&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>Run PHP On Google App Engine</title>
      <link>http://developeradvocate.appspot.com:80/id/1001/Run-PHP-On-Google-App-Engine</link>
      <guid>http://developeradvocate.appspot.com:80/id/1001/Run-PHP-On-Google-App-Engine</guid>
      <pubDate>Sat, 26 Dec 2009 23:44:13 +1600</pubDate>
      <description>
        &lt;p&gt;
	PHP is a wildly popular programming language for the web. It is easy to learn, easy to use, and has many great built in features for building web applications. Now, thanks to Caucho&amp;#39;s open source port of the php core from C to Java, you can run PHP inside the java virtual machine which runs inside google app engine.&lt;/p&gt;
&lt;p&gt;
	This way you can leverage the many great open source PHP applications which already exist and host them on app engine. You will have to rewrite the data access layer to use the app engine datastore instead of sql however.&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;http://quercus.caucho.com/&quot;&gt;Here is the link to the PHP Caucho ported from C to Java.&lt;/a&gt;&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>AppEngineBlog (AEB) is Born!</title>
      <link>http://developeradvocate.appspot.com:80/id/2/AppEngineBlog-%28AEB%29-is-Born%21</link>
      <guid>http://developeradvocate.appspot.com:80/id/2/AppEngineBlog-%28AEB%29-is-Born%21</guid>
      <pubDate>Sat, 26 Dec 2009 20:42:09 +1600</pubDate>
      <description>
        &lt;p&gt;
	I decided to fork and release my own version of pico blog. My version includes all the dependencies and bug fixes required to run the application.&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;Updated 12/31/2009&lt;/strong&gt;: I released version 1.1.0, which includes many new features:&amp;nbsp;&lt;a href=&quot;http://developeradvocate.appspot.com/id/1005/AppEngineBlog-(%22AEB%22)-Version-1.1.0-Released&quot;&gt;http://developeradvocate.appspot.com/id/1005/AppEngineBlog-(&amp;quot;AEB&amp;quot;)-Version-1.1.0-Released&lt;/a&gt;&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
    <item>
      <title>Blog Software For Google App Engine</title>
      <link>http://developeradvocate.appspot.com:80/id/1/Blog-Software-For-Google-App-Engine</link>
      <guid>http://developeradvocate.appspot.com:80/id/1/Blog-Software-For-Google-App-Engine</guid>
      <pubDate>Sat, 26 Dec 2009 18:57:41 +1600</pubDate>
      <description>
        &lt;p&gt;
	I found a fantastic piece of software written in python implementing a blog which runs on the google app engine. It took me a while to get it up and running.&lt;/p&gt;
&lt;p&gt;
	I will soon be posting a link to a .zip file which includes all dependent libraries and a bug fix required to get the app to work. It is called &amp;quot;Pico Blog&amp;quot;, and created by Brian M. Clapper.&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;http://www.clapper.org/software/python/picoblog/&quot;&gt;Here is the download link&lt;/a&gt;.&lt;/p&gt;

      </description>
      <author></author>
    </item>
    
  </channel>
</rss>
