Add a server component to the Bikeshed 'Tree' example


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7607 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/bikeshed/src/com/google/gwt/sample/stocks/client/Stocks.java b/bikeshed/src/com/google/gwt/sample/stocks/client/Stocks.java
index 2a9f608..e995851 100644
--- a/bikeshed/src/com/google/gwt/sample/stocks/client/Stocks.java
+++ b/bikeshed/src/com/google/gwt/sample/stocks/client/Stocks.java
@@ -316,7 +316,7 @@
   }
 
   private String getFormattedPrice(int price) {
-    return NumberFormat.getCurrencyFormat("USD").format((double) price / 100.0);
+    return NumberFormat.getCurrencyFormat("USD").format(price / 100.0);
   }
   
   /**
diff --git a/bikeshed/src/com/google/gwt/sample/tree/client/MyTreeModel.java b/bikeshed/src/com/google/gwt/sample/tree/client/MyTreeModel.java
index 0c6777a..81c1d40 100644
--- a/bikeshed/src/com/google/gwt/sample/tree/client/MyTreeModel.java
+++ b/bikeshed/src/com/google/gwt/sample/tree/client/MyTreeModel.java
@@ -17,19 +17,54 @@
 
 import com.google.gwt.cells.client.Cell;
 import com.google.gwt.cells.client.TextCell;
+import com.google.gwt.core.client.GWT;
 import com.google.gwt.list.shared.AsyncListModel;
 import com.google.gwt.list.shared.ListModel;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.rpc.AsyncCallback;
 
 import java.util.ArrayList;
 import java.util.List;
 
 /**
- * A factory for generating {@link AbstractTreeNodeFactory} based on the value
- * type.
+ * A demo TreeModel.
  */
 public class MyTreeModel implements TreeModel {
 
-  private static final int FANOUT = 5;
+  private static class IntegerListModel extends AsyncListModel<Integer> {
+    public IntegerListModel(final int length) {
+      super(new DataSource<Integer>() {
+        public void requestData(AsyncListModel<Integer> listModel) {
+          listModel.updateDataSize(1, true);
+          List<Integer> values = new ArrayList<Integer>(1);
+          values.add(length);
+          listModel.updateViewData(0, 1, values);
+        }
+      });
+    }
+  }
+
+  private static class StringListModel extends AsyncListModel<String> {
+    public StringListModel(final String value) {
+      super(new DataSource<String>() {
+        public void requestData(final AsyncListModel<String> listModel) {
+          String prefix = value.endsWith("...") ? value.substring(0, value.length() - 3) : value;
+          dataService.getNext(prefix, new AsyncCallback<List<String>>() {
+            public void onFailure(Throwable caught) {
+              Window.alert("Error: " + caught);
+            }
+
+            public void onSuccess(List<String> result) {
+              listModel.updateDataSize(result.size(), true);
+              listModel.updateViewData(0, result.size(), result);
+            }
+          });
+        }
+      });
+    }
+  }
+
+  private static final TreeServiceAsync dataService = GWT.create(TreeService.class);
 
   /**
    * The cell used to render integers.
@@ -46,44 +81,6 @@
    */
   private static final Cell<String> STRING_CELL = new TextCell();
 
-  /**
-   * A list of strings.
-   */
-  private static class StringListModel extends AsyncListModel<String> {
-
-    public StringListModel(final String value, final String delim) {
-      super(new DataSource<String>() {
-        public void requestData(AsyncListModel<String> listModel) {
-          listModel.updateDataSize(FANOUT, true);
-          List<String> values = new ArrayList<String>();
-          for (int i = 0; i < FANOUT; i++) {
-            values.add(value + delim + i);
-          }
-          listModel.updateViewData(0, FANOUT, values);
-        }
-      });
-    }
-  }
-
-  /**
-   * A list of integers.
-   */
-  private static class IntegerListModel extends AsyncListModel<Integer> {
-
-    public IntegerListModel() {
-      super(new DataSource<Integer>() {
-        public void requestData(AsyncListModel<Integer> listModel) {
-          listModel.updateDataSize(FANOUT, true);
-          List<Integer> values = new ArrayList<Integer>();
-          for (int i = 0; i < FANOUT; i++) {
-            values.add(i);
-          }
-          listModel.updateViewData(0, FANOUT, values);
-        }
-      });
-    }
-  }
-
   public TreeNodeFactory<?> createTreeNodeFactory(Object value) {
     if (value instanceof String) {
       return createTreeNodeFactoryHelper((String) value);
@@ -96,17 +93,17 @@
     throw new IllegalArgumentException("Unsupported object type: " + type);
   }
 
+  @SuppressWarnings("unused")
   private TreeNodeFactory<?> createTreeNodeFactoryHelper(final Integer value) {
-    ListModel<String> listModel = new StringListModel(value.toString(), ".");
-    return new DefaultTreeNodeFactory<String>(listModel, STRING_CELL, this);
+    return null;
   }
 
   private TreeNodeFactory<?> createTreeNodeFactoryHelper(final String value) {
-    if (value.endsWith("2")) {
-      ListModel<String> listModel = new StringListModel(value.toString(), "-");
+    if (value.endsWith("...")) {
+      ListModel<String> listModel = new StringListModel(value.toString());
       return new DefaultTreeNodeFactory<String>(listModel, STRING_CELL, this);
     } else {
-      ListModel<Integer> listModel = new IntegerListModel();
+      ListModel<Integer> listModel = new IntegerListModel(value.length());
       return new DefaultTreeNodeFactory<Integer>(listModel, INTEGER_CELL, this);
     }
   }
diff --git a/bikeshed/src/com/google/gwt/sample/tree/client/TreeEntryPoint.java b/bikeshed/src/com/google/gwt/sample/tree/client/TreeEntryPoint.java
index 889efd2..401de19 100644
--- a/bikeshed/src/com/google/gwt/sample/tree/client/TreeEntryPoint.java
+++ b/bikeshed/src/com/google/gwt/sample/tree/client/TreeEntryPoint.java
@@ -24,7 +24,7 @@
 public class TreeEntryPoint implements EntryPoint {
 
   public void onModuleLoad() {
-    TreeView tree = new TreeView(new MyTreeModel(), -1);
+    TreeView tree = new TreeView(new MyTreeModel(), "...");
     RootPanel.get().add(tree);
   }
 }
diff --git a/bikeshed/src/com/google/gwt/sample/tree/client/TreeService.java b/bikeshed/src/com/google/gwt/sample/tree/client/TreeService.java
new file mode 100644
index 0000000..473be0e
--- /dev/null
+++ b/bikeshed/src/com/google/gwt/sample/tree/client/TreeService.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.sample.tree.client;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+import java.util.List;
+
+/**
+ * The client side stub for the RPC service.
+ */
+@RemoteServiceRelativePath("tree")
+public interface TreeService extends RemoteService {
+  
+  List<String> getNext(String prefix);
+}
diff --git a/bikeshed/src/com/google/gwt/sample/tree/client/TreeServiceAsync.java b/bikeshed/src/com/google/gwt/sample/tree/client/TreeServiceAsync.java
new file mode 100644
index 0000000..71d3bee
--- /dev/null
+++ b/bikeshed/src/com/google/gwt/sample/tree/client/TreeServiceAsync.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.sample.tree.client;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import java.util.List;
+
+/**
+ * The async counterpart of <code>TreeService</code>.
+ */
+public interface TreeServiceAsync {
+  
+  void getNext(String prefix, AsyncCallback<List<String>> callback);
+}
diff --git a/bikeshed/src/com/google/gwt/sample/tree/server/Dictionary.java b/bikeshed/src/com/google/gwt/sample/tree/server/Dictionary.java
new file mode 100644
index 0000000..a1872ee
--- /dev/null
+++ b/bikeshed/src/com/google/gwt/sample/tree/server/Dictionary.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.sample.tree.server;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A list of words.
+ */
+public class Dictionary {
+
+  private static final String[] words = {
+      "aardvark", "aardwolf", "aaron", "aback", "abacus", "abaft", "abalone",
+      "abandon", "abandoned", "abandonment", "abandons", "abase", "abased",
+      "abasement", "abash", "abashed", "abate", "abated", "abatement",
+      "abates", "abattoir", "abattoirs", "abbe", "abbess", "abbey", "abbeys",
+      "abbot", "abbots", "abbreviate", "abbreviated", "abbreviates",
+      "abbreviating", "abbreviation", "abbreviations", "abdicate", "abdicated",
+      "abdicates", "abdicating", "abdication", "abdomen", "abdomens",
+      "abdominal", "abduct", "abducted", "abducting", "abduction",
+      "abductions", "abductor", "abductors", "abducts", "abe", "abeam", "abel",
+      "abele", "aberdeen", "aberrant", "aberration", "aberrations", "abet",
+      "abets", "abetted", "abetting", "abeyance", "abhor", "abhorred",
+      "abhorrence", "abhorrent", "abhors", "abide", "abided", "abides",
+      "abiding", "abidjan", "abies", "abilities", "ability", "abject",
+      "abjectly", "abjure", "abjured", "ablate", "ablates", "ablating",
+      "ablation", "ablative", "ablaze", "able", "ablebodied", "abler",
+      "ablest", "abloom", "ablution", "ablutions", "ably", "abnegation",
+      "abnormal", "abnormalities", "abnormality", "abnormally", "aboard",
+      "abode", "abodes", "abolish", "abolished", "abolishes", "abolishing",
+      "abolition", "abolitionist", "abolitionists", "abomb", "abominable",
+      "abominably", "abominate", "abominated", "abomination", "abominations",
+      "aboriginal", "aborigines", "abort", "aborted", "aborting", "abortion",
+      "abortionist", "abortionists", "abortions", "abortive", "aborts",
+      "abound", "abounded", "abounding", "abounds", "about", "above",
+      "abraded", "abraham", "abrasion", "abrasions", "abrasive", "abrasively",
+      "abrasiveness", "abrasives", "abreast", "abridge", "abridged",
+      "abridgement", "abridging", "abroad", "abrogate", "abrogated",
+      "abrogating", "abrogation", "abrogations", "abrupt", "abruptly",
+      "abruptness", "abscess", "abscesses", "abscissa", "abscissae",
+      "abscissas", "abscond", "absconded", "absconder", "absconding",
+      "absconds", "abseil", "abseiled", "abseiler", "abseiling", "abseils",
+      "absence", "absences", "absent", "absented", "absentee", "absenteeism",
+      "absentees", "absenting", "absently", "absentminded", "absentmindedly",
+      "absentmindedness", "absolute", "absolutely", "absoluteness",
+      "absolutes", "absolution", "absolutism", "absolutist", "absolutists",
+      "absolve", "absolved", "absolves", "absolving", "absorb", "absorbed",
+      "absorbency", "absorbent", "absorber", "absorbers", "absorbing",
+      "absorbingly", "absorbs", "absorption", "absorptions", "absorptive",
+      "absorptivity", "abstain", "abstained", "abstainer", "abstainers",
+      "abstaining", "abstains", "abstemious", "abstemiously", "abstemiousness",
+      "abstention", "abstentions", "abstinence", "abstinent", "abstract",
+      "abstracted", "abstractedly", "abstracting", "abstraction",
+      "abstractions", "abstractly", "abstracts", "abstruse", "abstrusely",
+      "absurd", "absurder", "absurdest", "absurdist", "absurdities",
+      "absurdity", "absurdly", "abundance", "abundances", "abundant",
+      "abundantly", "abuse", "abused", "abuser", "abusers", "abuses",
+      "abusing", "abusive", "abusively", "abusiveness", "abut", "abutment",
+      "abutments", "abutted", "abutting", "abuzz", "aby", "abysmal",
+      "abysmally", "abyss", "abyssal", "abysses", "acacia", "academe",
+      "academia", "academic", "academical", "academically", "academician",
+      "academicians", "academics", "academies", "academy", "acanthus",
+      "acapulco", "accede", "acceded", "acceding", "accelerate", "accelerated",
+      "accelerates", "accelerating", "acceleration", "accelerations",
+      "accelerator", "accelerators", "accelerometer", "accelerometers",
+      "accent", "accented", "accenting", "accents", "accentuate",
+      "accentuated", "accentuates", "accentuating", "accentuation", "accept",
+      "acceptability", "acceptable", "acceptably", "acceptance", "acceptances",
+      "accepted", "accepting", "acceptor", "acceptors", "accepts", "access",
+      "accessed", "accesses", "accessibility", "accessible", "accessing",
+      "accession", "accessions", "accessories", "accessory", "accidence",
+      "accident", "accidental", "accidentally", "accidentprone", "accidents",
+      "acclaim", "acclaimed", "acclaims", "acclamation", "acclamations",
+      "acclimatisation", "acclimatise", "acclimatised", "acclimatising",
+      "accolade", "accolades", "accommodate", "accommodated", "accommodates",
+      "accommodating", "accommodation", "accommodations", "accompanied",
+      "accompanies", "accompaniment", "accompaniments", "accompanist",
+      "accompany", "accompanying", "accomplice", "accomplices", "accomplish",
+      "accomplished", "accomplishes", "accomplishing", "accomplishment",
+      "accomplishments", "accord", "accordance", "accorded", "according",
+      "accordingly", "accordion", "accordionist", "accordions", "accords",
+      "accost", "accosted", "accosting", "accosts", "account",
+      "accountability", "accountable", "accountancy", "accountant",
+      "accountants", "accounted", "accounting", "accounts", "accra",
+      "accredit", "accreditation", "accredited", "accrediting", "accredits",
+      "accreted", "accretion", "accretions", "accrual", "accruals", "accrue",
+      "accrued", "accrues", "accruing", "accumulate", "accumulated",
+      "accumulates", "accumulating", "accumulation", "accumulations",
+      "accumulative", "accumulator", "accumulators", "accuracies", "accuracy",
+      "accurate", "accurately", "accursed", "accusal", "accusals",
+      "accusation", "accusations", "accusative", "accusatory", "accuse",
+      "accused", "accuser", "accusers", "accuses", "accusing", "accusingly",
+      "accustom", "accustomed", "accustoming", "ace", "aced", "acentric",
+      "acerbic", "acerbity", "acers", "aces", "acetal", "acetate", "acetates",
+      "acetic", "acetone", "acetylene", "ache", "ached", "aches", "achievable",
+      "achieve", "achieved", "achievement", "achievements", "achiever",
+      "achievers", "achieves", "achieving", "aching", "achingly", "achings",
+      "achromatic", "achy", "acid", "acidic", "acidification", "acidified",
+      "acidify", "acidifying", "acidity", "acidly", "acidophiles", "acidrain",
+      "acids", "acknowledge", "acknowledged", "acknowledgement",
+      "acknowledgements", "acknowledges", "acknowledging", "acknowledgment",
+      "acknowledgments", "acme", "acne", "acolyte", "acolytes", "aconite",
+      "acorn", "acorns", "acoustic", "acoustical", "acoustically", "acoustics",
+      "acquaint", "acquaintance", "acquaintances", "acquainted", "acquainting",
+      "acquaints", "acquiesce", "acquiesced", "acquiescence", "acquiescent",
+      "acquiescing", "acquire", "acquired", "acquirer", "acquirers",
+      "acquires", "acquiring", "acquisition", "acquisitions", "acquisitive",
+      "acquisitiveness", "acquit", "acquited", "acquites", "acquits",
+      "acquittal", "acquittals", "acquittance", "acquitted", "acquitting",
+      "acre", "acreage", "acres", "acrid", "acrimonious", "acrimoniously",
+      "acrimony", "acrobat", "acrobatic", "acrobatics", "acrobats", "acronym",
+      "acronyms", "across", "acrostic", "acrostics", "acrylic", "acrylics",
+      "act", "acted", "acting", "actings", "actinides", "action", "actionable",
+      "actions", "activate", "activated", "activates", "activating",
+      "activation", "activations", "activator", "activators", "active",
+      "actively", "actives", "activism", "activist", "activists", "activities",
+      "activity", "actor", "actors", "actress", "actresses", "acts", "actual",
+      "actualisation", "actualise", "actualised", "actualities", "actuality",
+      "actually", "actuarial", "actuaries", "actuary", "actuate", "actuated",
+      "actuates", "actuating", "actuation", "actuator", "actuators", "acuity",
+      "acumen", "acupuncture", "acupuncturist", "acupuncturists", "acute",
+      "acutely", "acuteness", "acuter", "acutest", "acyclic", "adage",
+      "adages", "adagio", "adam", "adamant", "adamantly", "adapt",
+      "adaptability", "adaptable", "adaptation", "adaptations", "adapted",
+      "adapter", "adapters", "adapting", "adaptive", "adaptively",
+      "adaptivity", "adaptor", "adaptors", "adapts", "add", "added", "addenda",
+      "addendum", "adder", "adders", "addict", "addicted", "addiction",
+      "addictions", "addictive", "addictiveness", "addicts", "adding",
+      "addition", "additional", "additionally", "additions", "additive",
+      "additively", "additives", "addle", "addled", "addles", "addling",
+      "address", "addressability", "addressable", "addressed", "addressee",
+      "addressees", "addresses", "addressing", "adds", "adduce", "adduced",
+      "adduces", "adducing", "adelaide", "aden", "adenine", "adenoid",
+      "adenoids", "adenoma", "adenomas", "adept", "adepts", "adequacy",
+      "adequate", "adequately", "adhere", "adhered", "adherence", "adherent",
+      "adherents", "adherer", "adherers", "adheres", "adhering", "adhesion",
+      "adhesions", "adhesive", "adhesiveness", "adhesives", "adhoc",
+      "adiabatic", "adiabatically", "adieu", "adieus", "adieux", "adios",
+      "adipose", "adit", "adjacency", "adjacent", "adjacently", "adjectival",
+      "adjective", "adjectives", "adjoin", "adjoined", "adjoining", "adjoins",
+      "adjourn", "adjourned", "adjourning", "adjournment", "adjourns",
+      "adjudge", "adjudged", "adjudges", "adjudicate", "adjudicated",
+      "adjudicates", "adjudicating", "adjudication", "adjudications",
+      "adjudicator", "adjudicators", "adjunct", "adjuncts", "adjure", "adjust",
+      "adjustable", "adjusted", "adjuster", "adjusting", "adjustment",
+      "adjustments", "adjusts", "adjutant", "adlib", "adlibs", "adman",
+      "admen", "admin", "administer", "administered", "administering",
+      "administers", "administrate", "administrated", "administrating",
+      "administration", "administrations", "administrative",
+      "administratively", "administrator", "administrators", "admirable",
+      "admirably", "admiral", "admirals", "admiration", "admire", "admired",
+      "admirer", "admirers", "admires", "admiring", "admiringly",
+      "admissibility", "admissible", "admission", "admissions", "admit",
+      "admits", "admittance", "admittances", "admitted", "admittedly",
+      "admitting", "admix", "admixture", "admonish", "admonished",
+      "admonishes", "admonishing", "admonishment", "admonition", "admonitions",
+      "admonitory", "ado", "adobe", "adolescence", "adolescent", "adolescents",
+      "adonis", "adopt", "adopted", "adopter", "adopting", "adoption",
+      "adoptions", "adoptive", "adopts", "adorable", "adorably", "adoration",
+      "adore", "adored", "adorer", "adorers", "adores", "adoring", "adoringly",
+      "adorn", "adorned", "adorning", "adornment", "adornments", "adorns",
+      "adrenal", "adrenalin", "adrenaline", "adrift", "adroit", "adroitly",
+      "adroitness", "adsorb", "adsorbed", "adsorption", "adulation",
+      "adulatory", "adult", "adulterate", "adulterated", "adulterates",
+      "adulterating", "adulteration", "adulterations", "adulterer",
+      "adulterers", "adulteress", "adulteresses", "adulterous", "adultery",
+      "adulthood", "adults", "adumbrate", "adumbrated", "adumbrating",
+      "advance", "advanced", "advancement", "advancements", "advancer",
+      "advances", "advancing", "advantage", "advantaged", "advantageous",
+      "advantageously", "advantages", "advent", "advents", "adventure",
+      "adventured", "adventurer", "adventurers", "adventures", "adventuring",
+      "adventurism", "adventurous", "adventurously", "adverb", "adverbial",
+      "adverbs", "adversarial", "adversaries", "adversary", "adverse",
+      "adversely", "adversities", "adversity", "advert", "adverted",
+      "advertise", "advertised", "advertisement", "advertisements",
+      "advertiser", "advertisers", "advertises", "advertising", "adverts",
+      "advice", "advices", "advisability", "advisable", "advise", "advised",
+      "advisedly", "adviser", "advisers", "advises", "advising", "advisory",
+      "advocacy", "advocate", "advocated", "advocates", "advocating", "adze",
+      "aegean", "aegina", "aegis", "aeolian", "aeon", "aeons", "aerate",
+      "aerated", "aerates", "aerating", "aeration", "aerator", "aerial",
+      "aerially", "aerials", "aerify", "aerobatic", "aerobatics", "aerobe",
+      "aerobes", "aerobic", "aerobically", "aerobics", "aerobraking",
+      "aerodrome", "aerodromes", "aerodynamic", "aerodynamically",
+      "aerodynamics", "aerofoil", "aerofoils", "aeronaut", "aeronautic",
+      "aeronautical", "aeronautics", "aeroplane", "aeroplanes", "aerosol",
+      "aerosols", "aerospace", "aesop", "aesthete", "aesthetes", "aesthetic",
+      "aesthetically", "aestheticism", "aestheticsy", "afar", "affability",
+      "affable", "affably", "affair", "affairs", "affect", "affectation",
+      "affectations", "affected", "affectedly", "affecting", "affection",
+      "affectionate", "affectionately", "affections", "affective", "affects",
+      "afferent", "affidavit", "affidavits", "affiliate", "affiliated",
+      "affiliates", "affiliating", "affiliation", "affiliations", "affine",
+      "affinities", "affinity", "affirm", "affirmation", "affirmations",
+      "affirmative", "affirmatively", "affirmed", "affirming", "affirms",
+      "affix", "affixed", "affixes", "affixing", "afflict", "afflicted",
+      "afflicting", "affliction", "afflictions", "afflicts", "affluence",
+      "affluent", "afflux", "afford", "affordability", "affordable",
+      "afforded", "affording", "affords", "afforestation", "afforested",
+      "affray", "affront", "affronted", "affronts", "afghan", "afghani",
+      "afghans", "afield", "afire", "aflame", "afloat", "afoot",
+      "aforementioned", "aforesaid", "aforethought", "afraid", "afresh",
+      "africa", "african", "africans", "afro", "afros", "aft", "after",
+      "afterbirth", "aftercare", "aftereffect", "aftereffects", "afterglow",
+      "afterlife", "afterlives", "aftermath", "afternoon", "afternoons",
+      "aftershave", "aftershocks", "aftertaste", "afterthought",
+      "afterthoughts", "afterward", "afterwards", "aga", "again", "against",
+      "agakhan", "agape", "agar", "agaragar", "agave", "agaves", "age", "aged",
+      "ageing", "ageings", "ageism", "ageless", "agencies", "agency", "agenda",
+      "agendas", "agendums", "agent", "agents", "ageold", "ages",
+      "agglomerated", "agglomerating", "agglomeration", "agglomerations",
+      "agglutinative", "aggravate", "aggravated", "aggravates", "aggravating",
+      "aggravation", "aggravations", "aggregate", "aggregated", "aggregates",
+      "aggregating", "aggregation", "aggregations", "aggression",
+      "aggressions", "aggressive", "aggressively", "aggressiveness",
+      "aggressor", "aggressors", "aggrieved", "aggrievedly", "aghast", "agile",
+      "agiler", "agility", "aging", "agings", "agio", "agitate", "agitated",
+      "agitatedly", "agitates", "agitating", "agitation", "agitations",
+      "agitator", "agitators", "agitprop", "agleam", "aglow", "agnostic",
+      "agnosticism", "agnostics", "ago", "agog", "agonies", "agonise",
+      "agonised", "agonises", "agonising", "agonisingly", "agonist",
+      "agonists", "agony", "agora", "agoraphobia", "agoraphobic", "agouti",
+      "agrarian", "agree", "agreeable", "agreeableness", "agreeably", "agreed",
+      "agreeing", "agreement", "agreements", "agrees", "agribusiness",
+      "agricultural", "agriculturalist", "agriculturalists", "agriculturally",
+      "agriculture", "agrimony", "agrochemical", "agrochemicals", "agronomist",
+      "agronomists", "agronomy", "aground", "ague", "ah", "aha", "ahead",
+      "ahem", "ahoy", "aid", "aide", "aided", "aidedecamp", "aider", "aiders",
+      "aides", "aidesdecamp", "aiding", "aids", "ail", "aileron", "ailerons",
+      "ailing", "ailment", "ailments", "ails", "aim", "aimed", "aimer",
+      "aiming", "aimless", "aimlessly", "aimlessness", "aims", "aint", "air",
+      "airbase", "airborne", "airbrush", "airbus", "airconditioned",
+      "airconditioner", "airconditioning", "aircraft", "aircrew", "aircrews",
+      "aire", "aired", "airfield", "airfields", "airflow", "airforce",
+      "airframe", "airframes", "airgun", "airier", "airiest", "airily",
+      "airiness", "airing", "airings", "airless", "airlift", "airlifted",
+      "airlifting", "airlifts", "airline", "airliner", "airliners", "airlines",
+      "airlock", "airlocks", "airmail", "airman", "airmen", "airplane",
+      "airplay", "airport", "airports", "airraid", "airs", "airship",
+      "airships", "airsick", "airsickness", "airspace", "airstream",
+      "airstrip", "airstrips", "airtight", "airtime", "airwave", "airwaves",
+      "airway", "airways", "airworthiness", "airworthy", "airy", "aisle",
+      "aisles", "aitches", "ajar", "akimbo", "akin", "ala", "alabama",
+      "alabaster", "alacarte", "alack", "alacrity", "aladdin", "alanine",
+      "alarm", "alarmed", "alarming", "alarmingly", "alarmism", "alarmist",
+      "alarms", "alas", "alaska", "alaskan", "alb", "albania", "albany",
+      "albatross", "albatrosses", "albeit", "albinism", "albino", "album",
+      "albumen", "albumin", "albums", "alchemical", "alchemist", "alchemists",
+      "alchemy", "alcohol", "alcoholic", "alcoholics", "alcoholism",
+      "alcohols", "alcove", "alcoves", "aldehyde", "aldehydes", "alder",
+      "alderman", "aldermen", "aldrin", "ale", "alehouse", "alembic", "alert",
+      "alerted", "alerting", "alertly", "alertness", "alerts", "ales",
+      "alfalfa", "alfatah", "alga", "algae", "algal", "algebra", "algebraic",
+      "algebraical", "algebraically", "algebraist", "algebras", "algeria",
+      "algerian", "algiers", "algorithm", "algorithmic", "algorithmically",
+      "algorithms", "alias", "aliases", "alibaba", "alibi", "alibis", "alien",
+      "alienate", "alienated", "alienates", "alienating", "alienation",
+      "aliened", "aliening", "aliens", "alight", "alighted", "alighting",
+      "alights", "align", "aligned", "aligning", "alignment", "alignments",
+      "aligns", "alike", "alimentary", "alimony", "aline", "alined", "alines",
+      "alining", "aliphatic", "aliquot", "aliquots", "alive", "alkali",
+      "alkalic", "alkaline", "alkalinity", "alkalis", "alkalise", "alkaloid",
+      "alkaloids", "alkanes", "alkyl", "all", "allay", "allayed", "allaying",
+      "allays", "allegation", "allegations", "allege", "alleged", "allegedly",
+      "alleges", "allegiance", "allegiances", "alleging", "allegorical",
+      "allegorically", "allegories", "allegory", "allegri", "allegro",
+      "allele", "alleles", "allelic", "allergen", "allergens", "allergic",
+      "allergies", "allergy", "alleviate", "alleviated", "alleviates",
+      "alleviating", "alleviation", "alleviations", "alley", "alleys",
+      "alleyway", "alleyways", "alliance", "alliances", "allied", "allies",
+      "alligator", "alligators", "alliterate", "alliterated", "alliterating",
+      "alliteration", "alliterations", "alliterative", "allocatable",
+      "allocate", "allocated", "allocates", "allocating", "allocation",
+      "allocations", "allocator", "allocators", "allophones", "allot",
+      "allotment", "allotments", "allotrope", "allotropic", "allots",
+      "allotted", "allotting", "allow", "allowable", "allowance", "allowances",
+      "allowed", "allowing", "allows", "alloy", "alloyed", "alloying",
+      "alloys", "allude", "alluded", "alludes", "alluding", "allure",
+      "allured", "allurement", "allurements", "allures", "alluring",
+      "alluringly", "allusion", "allusions", "allusive", "alluvia", "alluvial",
+      "alluvium", "ally", "allying", "almanac", "almanacs", "almighty",
+      "almond", "almonds", "almost", "alms", "almshouse", "almshouses", "aloe",
+      "aloes", "aloft", "aloha", "alone", "aloneness", "along", "alongside",
+      "aloof", "aloofness", "aloud", "alp", "alpaca", "alpacas", "alpha",
+      "alphabet", "alphabetic", "alphabetical", "alphabetically", "alphabets",
+      "alphanumeric", "alphas", "alpine", "alps", "already", "alright", "also",
+      "alt", "altar", "altarpiece", "altarpieces", "altars", "alter",
+      "alterable", "alteration", "alterations", "altercate", "altercation",
+      "altercations", "altered", "alterego", "altering", "alternate",
+      "alternated", "alternately", "alternates", "alternating", "alternation",
+      "alternations", "alternative", "alternatively", "alternatives",
+      "alternator", "alternators", "alters", "although", "altimeter",
+      "altimeters", "altitude", "altitudes", "alto", "altogether", "altruism",
+      "altruist", "altruistic", "altruistically", "alts", "alum", "aluminium",
+      "aluminum", "alumni", "alumnus", "alveolar", "alveoli", "always", "am",
+      "amalgam", "amalgamate", "amalgamated", "amalgamates", "amalgamating",
+      "amalgamation", "amalgamations", "amalgams", "amanuensis", "amass",
+      "amassed", "amasses", "amassing", "amateur", "amateurish",
+      "amateurishly", "amateurishness", "amateurism", "amateurs", "amatory",
+      "amaze", "amazed", "amazement", "amazes", "amazing", "amazingly",
+      "amazon", "amazons", "ambassador", "ambassadorial", "ambassadors",
+      "amber", "ambergris", "ambiance", "ambidextrous", "ambience", "ambient",
+      "ambiguities", "ambiguity", "ambiguous", "ambiguously", "ambit",
+      "ambition", "ambitions", "ambitious", "ambitiously", "ambivalence",
+      "ambivalent", "ambivalently", "amble", "ambled", "ambler", "ambles",
+      "ambling", "ambrosia", "ambulance", "ambulances", "ambulant", "ambulate",
+      "ambulatory", "ambuscade", "ambuscades", "ambush", "ambushed",
+      "ambushers", "ambushes", "ambushing", "ameliorate", "ameliorated",
+      "ameliorates", "ameliorating", "amelioration", "amen", "amenability",
+      "amenable", "amend", "amendable", "amended", "amending", "amendment",
+      "amendments", "amends", "amenities", "amenity", "amenorrhoea", "amens",
+      "america", "american", "americans", "americium", "amethyst",
+      "amethystine", "amethysts", "amiability", "amiable", "amiableness",
+      "amiably", "amicability", "amicable", "amicably", "amid", "amide",
+      "amidships", "amidst", "amigo", "amine", "amines", "amino", "amir",
+      "amiss", "amity", "amman", "ammeter", "ammeters", "ammo", "ammonia",
+      "ammonites", "ammonium", "ammunition", "amnesia", "amnesiac", "amnesic",
+      "amnesties", "amnesty", "amniotic", "amoeba", "amoebae", "amoebic",
+      "amok", "among", "amongst", "amoral", "amorality", "amorist", "amorous",
+      "amorously", "amorphous", "amortisation", "amortise", "amortised",
+      "amount", "amounted", "amounting", "amounts", "amour", "amours", "amp",
+      "ampere", "amperes", "ampersand", "ampersands", "amphetamine",
+      "amphetamines", "amphibia", "amphibian", "amphibians", "amphibious",
+      "amphitheatre", "amphitheatres", "amphora", "ample", "ampler",
+      "amplification", "amplifications", "amplified", "amplifier",
+      "amplifiers", "amplifies", "amplify", "amplifying", "amplitude",
+      "amplitudes", "amply", "ampoules", "amps", "ampule", "ampules", "ampuls",
+      "amputate", "amputated", "amputating", "amputation", "amputations",
+      "amputee", "amputees", "amuck", "amulet", "amulets", "amuse", "amused",
+      "amusement", "amusements", "amuses", "amusing", "amusingly"
+  };
+  
+  public static List<String> getNext(String prefix) {
+    String[] s = new String[26];
+    boolean[] b = new boolean[26];
+    
+    List<String> toRet = new ArrayList<String>();
+    
+    // slowwww..
+    for (String word : words) {
+      if (word.equals(prefix)) {
+        toRet.add(prefix);
+      } else if (word.startsWith(prefix)) {
+        int index = word.charAt(prefix.length()) - 'a';
+        if (s[index] == null) {
+          s[index] = word;
+        } else if (b[index] == false) {
+          s[index] = word.substring(0, prefix.length() + 1) + "...";
+          b[index] = true;
+        }
+      }
+    }
+    
+    for (int i = 0; i < 26; i++) {
+      if (s[i] != null) {
+        toRet.add(s[i]);
+      }
+    }
+    return toRet;
+  }
+}
diff --git a/bikeshed/src/com/google/gwt/sample/tree/server/TreeServiceImpl.java b/bikeshed/src/com/google/gwt/sample/tree/server/TreeServiceImpl.java
new file mode 100644
index 0000000..b1c585d
--- /dev/null
+++ b/bikeshed/src/com/google/gwt/sample/tree/server/TreeServiceImpl.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.sample.tree.server;
+
+import com.google.gwt.sample.tree.client.TreeService;
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+import java.util.List;
+
+/**
+ * The server side implementation of the RPC service.
+ */
+@SuppressWarnings("serial")
+public class TreeServiceImpl extends RemoteServiceServlet implements
+    TreeService {
+
+  public List<String> getNext(String prefix) {
+    return Dictionary.getNext(prefix);
+  }
+}
diff --git a/bikeshed/war/WEB-INF/web.xml b/bikeshed/war/WEB-INF/web.xml
index 12013ea..a2c7cb2 100644
--- a/bikeshed/war/WEB-INF/web.xml
+++ b/bikeshed/war/WEB-INF/web.xml
@@ -6,17 +6,25 @@
 <web-app>
 
   <!-- Servlets -->
-  <!--
   <servlet>
     <servlet-name>stockServlet</servlet-name>
     <servlet-class>com.google.gwt.sample.stocks.server.StockServiceImpl</servlet-class>
   </servlet>
 
+  <servlet>
+    <servlet-name>treeServlet</servlet-name>
+    <servlet-class>com.google.gwt.sample.tree.server.TreeServiceImpl</servlet-class>
+  </servlet>
+
   <servlet-mapping>
     <servlet-name>stockServlet</servlet-name>
     <url-pattern>/stocks/stock</url-pattern>
   </servlet-mapping>
-  -->
+
+  <servlet-mapping>
+    <servlet-name>treeServlet</servlet-name>
+    <url-pattern>/tree/tree</url-pattern>
+  </servlet-mapping>
 
   <!-- Default page to serve -->
   <welcome-file-list>