UiBinder now understands CssResource's imported scopes,  which
is more than I can say for myself most of the time.

Reviewed by jgw

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6363 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/client/AbstractUiBinder.java b/user/src/com/google/gwt/uibinder/client/AbstractUiBinder.java
deleted file mode 100644
index db42c19..0000000
--- a/user/src/com/google/gwt/uibinder/client/AbstractUiBinder.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2009 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.uibinder.client;
-
-import com.google.gwt.dom.client.StyleInjector;
-import com.google.gwt.resources.client.CssResource;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Extended by code generated by calls to GWT.create(Class<? extends UiBinder>).
- *
- * @param <U> The type of the root object of the generated UI, typically a
- *          subclass of {@link com.google.gwt.dom.client.Element} or
- *          {@link com.google.gwt.user.client.ui.UIObject}
- * @param <O> The type of the object that will own the generated UI
- */
-public abstract class AbstractUiBinder<U, O> implements UiBinder<U, O> {
-  private static final Set<Class<? extends CssResource>> injected =
-    new HashSet<Class<? extends CssResource>>();
-
-  /**
-   * Invokes {@link StyleInjector#injectStylesheet} on the given css's
-   * {@link CssResource#getText()}. Injection is performed only once for each
-   * CssResource subclass received (that is, we key on
-   * <code>css.getClass()</code>);
-   *
-   * @param css the resource to inject
-   */
-  protected static void ensureCssInjected(CssResource css) {
-    if (!injected.contains(css.getClass())) {
-      StyleInjector.injectStylesheet(css.getText());
-      injected.add(css.getClass());
-    }
-  }
-}
diff --git a/user/src/com/google/gwt/uibinder/rebind/BundleWriter.java b/user/src/com/google/gwt/uibinder/rebind/BundleWriter.java
index 4ba4f5d..1db5074 100644
--- a/user/src/com/google/gwt/uibinder/rebind/BundleWriter.java
+++ b/user/src/com/google/gwt/uibinder/rebind/BundleWriter.java
@@ -21,6 +21,7 @@
 import com.google.gwt.resources.client.ClientBundle;
 import com.google.gwt.resources.client.DataResource;
 import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.resources.client.CssResource.Import;
 import com.google.gwt.resources.client.ImageResource.ImageOptions;
 import com.google.gwt.resources.client.ImageResource.RepeatStyle;
 import com.google.gwt.uibinder.rebind.model.ImplicitClientBundle;
@@ -28,6 +29,8 @@
 import com.google.gwt.uibinder.rebind.model.ImplicitDataResource;
 import com.google.gwt.uibinder.rebind.model.ImplicitImageResource;
 
+import java.util.Set;
+
 /**
  * Writes source implementing an {@link ImplicitClientBundle}.
  */
@@ -43,6 +46,7 @@
   private final JClassType imageOptionType;
   private final JClassType imageResourceType;
   private final JClassType repeatStyleType;
+  private final JClassType importAnnotationType;
 
   public BundleWriter(ImplicitClientBundle bundleClass,
       PrintWriterManager writerManager, TypeOracle oracle,
@@ -58,6 +62,7 @@
     imageOptionType = oracle.findType(ImageOptions.class.getCanonicalName());
     imageResourceType = oracle.findType(ImageResource.class.getCanonicalName());
     repeatStyleType = oracle.findType(RepeatStyle.class.getCanonicalName());
+    importAnnotationType =  oracle.findType(Import.class.getCanonicalName());
   }
 
   public void write() throws UnableToCompleteException {
@@ -77,20 +82,22 @@
     }
 
     // Imports
-    writer.write("import %s;", imageResourceType.getQualifiedSourceName());
-    writer.write("import %s;", imageOptionType.getQualifiedSourceName());
     writer.write("import %s;", clientBundleType.getQualifiedSourceName());
     writer.write("import %s;", dataResourceType.getQualifiedSourceName());
+    writer.write("import %s;", imageResourceType.getQualifiedSourceName());
+    writer.write("import %s;", imageOptionType.getQualifiedSourceName());
+    writer.write("import %s;", importAnnotationType.getQualifiedSourceName());
     writer.newline();
 
     // Open interface
     writer.write("public interface %s extends ClientBundle {",
         bundleClass.getClassName());
     writer.indent();
-
+    
     // Write css methods
     for (ImplicitCssResource css : bundleClass.getCssMethods()) {
       writer.write("@Source(\"%s\")", css.getSource());
+      writeCssImports(css);
       writer.write("%s %s();", css.getClassName(), css.getName());
       writer.newline();
     }
@@ -109,6 +116,26 @@
     writer.write("}");
   }
 
+  private void writeCssImports(ImplicitCssResource css) {
+    Set<JClassType> importTypes = css.getImports();
+    int numImports = importTypes.size();
+    if (numImports > 0) {
+      if (numImports == 1) {
+        writer.write("@Import(%s.class)",
+            importTypes.iterator().next().getQualifiedSourceName());
+      } else {
+        StringBuffer b = new StringBuffer();
+        for (JClassType importType : importTypes) {
+          if (b.length() > 0) {
+            b.append(", ");
+          }
+          b.append(importType.getQualifiedSourceName()).append(".class");
+        }
+        writer.write("@Import({%s})", b);
+      }
+    }
+  }
+
   private void writeImageMethods() {
     for (ImplicitImageResource image : bundleClass.getImageMethods()) {
       if (null != image.getSource()) {
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java
index 0c2e7bd..d6dca10 100644
--- a/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java
+++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java
@@ -30,43 +30,14 @@
 import com.google.gwt.uibinder.rebind.model.ImplicitImageResource;
 import com.google.gwt.uibinder.rebind.model.OwnerField;
 
+import java.util.LinkedHashSet;
+
 /**
  * Parses the root UiBinder element, and kicks of the parsing of the rest of the
  * document.
  */
 public class UiBinderParser {
 
-  private static final String FLIP_RTL_ATTRIBUTE = "flipRtl";
-  private static final String FIELD_ATTRIBUTE = "field";
-  private static final String SOURCE_ATTRIBUTE = "src";
-  private static final String REPEAT_STYLE_ATTRIBUTE = "repeatStyle";
-
-  // TODO(rjrjr) Make all the ElementParsers receive their dependencies via
-  // constructor like this one does, and make this an ElementParser. I want
-  // guice!!!
-
-  private final UiBinderWriter writer;
-  private final TypeOracle oracle;
-  private final MessagesWriter messagesWriter;
-  private final FieldManager fieldManager;
-  private final ImplicitClientBundle bundleClass;
-  private final JClassType cssResourceType;
-  private final JClassType imageResourceType;
-  private final JClassType dataResourceType;
-
-  public UiBinderParser(UiBinderWriter writer, MessagesWriter messagesWriter,
-      FieldManager fieldManager, TypeOracle oracle,
-      ImplicitClientBundle bundleClass) {
-    this.writer = writer;
-    this.oracle = oracle;
-    this.messagesWriter = messagesWriter;
-    this.fieldManager = fieldManager;
-    this.bundleClass = bundleClass;
-    this.cssResourceType = oracle.findType(CssResource.class.getCanonicalName());
-    this.imageResourceType = oracle.findType(ImageResource.class.getCanonicalName());
-    this.dataResourceType = oracle.findType(DataResource.class.getCanonicalName());
-  }
-
   private enum Resource {
     data {
       void create(UiBinderParser parser, XMLElement elem)
@@ -96,14 +67,44 @@
     abstract void create(UiBinderParser parser, XMLElement elem)
         throws UnableToCompleteException;
   }
+  private static final String FLIP_RTL_ATTRIBUTE = "flipRtl";
+  private static final String FIELD_ATTRIBUTE = "field";
+  private static final String SOURCE_ATTRIBUTE = "src";
+  private static final String REPEAT_STYLE_ATTRIBUTE = "repeatStyle";
+
+  // TODO(rjrjr) Make all the ElementParsers receive their dependencies via
+  // constructor like this one does, and make this an ElementParser. I want
+  // guice!!!
+
+  private static final String IMPORT_ATTRIBUTE = "import";
+  private final UiBinderWriter writer;
+  private final TypeOracle oracle;
+  private final MessagesWriter messagesWriter;
+  private final FieldManager fieldManager;
+  private final ImplicitClientBundle bundleClass;
+  private final JClassType cssResourceType;
+  private final JClassType imageResourceType;
+
+  private final JClassType dataResourceType;
+
+  public UiBinderParser(UiBinderWriter writer, MessagesWriter messagesWriter,
+      FieldManager fieldManager, TypeOracle oracle,
+      ImplicitClientBundle bundleClass) {
+    this.writer = writer;
+    this.oracle = oracle;
+    this.messagesWriter = messagesWriter;
+    this.fieldManager = fieldManager;
+    this.bundleClass = bundleClass;
+    this.cssResourceType = oracle.findType(CssResource.class.getCanonicalName());
+    this.imageResourceType = oracle.findType(ImageResource.class.getCanonicalName());
+    this.dataResourceType = oracle.findType(DataResource.class.getCanonicalName());
+  }
 
   /**
    * Parses the root UiBinder element, and kicks off the parsing of the rest of
    * the document.
    */
   public String parse(XMLElement elem) throws UnableToCompleteException {
-    // TODO(rjrjr) Clearly need to break these find* methods out into their own
-    // parsers, an so need a registration scheme for uibinder-specific parsers
     findResources(elem);
     messagesWriter.findMessagesConfig(elem);
     XMLElement uiRoot = elem.consumeSingleChildElement();
@@ -117,17 +118,7 @@
       return cssResourceType;
     }
 
-    JClassType publicType = oracle.findType(typeName);
-    if (publicType == null) {
-      writer.die("In %s, no such type %s", elem, typeName);
-    }
-
-    if (!publicType.isAssignableTo(cssResourceType)) {
-      writer.die("In %s, type %s does not extend %s", elem,
-          publicType.getQualifiedSourceName(),
-          cssResourceType.getQualifiedSourceName());
-    }
-    return publicType;
+    return findCssResourceType(elem, typeName);
   }
 
   private JClassType consumeTypeAttribute(XMLElement elem)
@@ -243,8 +234,17 @@
     String name = elem.consumeAttribute(FIELD_ATTRIBUTE, "style");
     JClassType publicType = consumeCssResourceType(elem);
 
+    String importTypeNames = elem.consumeAttribute(IMPORT_ATTRIBUTE, null);
+    LinkedHashSet<JClassType> importTypes = new LinkedHashSet<JClassType>();
+    if (importTypeNames != null) {
+      String[] typeNames = importTypeNames.split("\\s+");
+      for (String type : typeNames) {
+        importTypes.add(findCssResourceType(elem, type));
+      }
+    }
+
     ImplicitCssResource cssMethod = bundleClass.createCssResource(name, source,
-        publicType, body);
+        publicType, body, importTypes);
 
     FieldWriter field = fieldManager.registerFieldOfGeneratedType(
         cssMethod.getPackageName(), cssMethod.getClassName(),
@@ -253,6 +253,21 @@
         cssMethod.getName()));
   }
 
+  private JClassType findCssResourceType(XMLElement elem, String typeName)
+      throws UnableToCompleteException {
+    JClassType publicType = oracle.findType(typeName);
+    if (publicType == null) {
+      writer.die("In %s, no such type %s", elem, typeName);
+    }
+
+    if (!publicType.isAssignableTo(cssResourceType)) {
+      writer.die("In %s, type %s does not extend %s", elem,
+          publicType.getQualifiedSourceName(),
+          cssResourceType.getQualifiedSourceName());
+    }
+    return publicType;
+  }
+
   private void findResources(XMLElement binderElement)
       throws UnableToCompleteException {
     binderElement.consumeChildElements(new XMLElement.Interpreter<Boolean>() {
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
index 7d8acb6..63340e3 100644
--- a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
+++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
@@ -1191,7 +1191,7 @@
   }
 
   private void writeClassOpen(IndentedWriter w) {
-    w.write("public class %s extends AbstractUiBinder<%s, %s> implements %s {",
+    w.write("public class %s implements UiBinder<%s, %s>, %s {",
         implClassName, uiRootType.getName(), uiOwnerType.getName(),
         baseClass.getName());
     w.indent();
@@ -1199,7 +1199,7 @@
 
   private void writeCssInjectors(IndentedWriter w) {
     for (ImplicitCssResource css : bundleClass.getCssMethods()) {
-      w.write("ensureCssInjected(%s.%s());", bundleClass.getFieldName(),
+      w.write("%s.%s().ensureInjected();", bundleClass.getFieldName(),
           css.getName());
     }
     w.newline();
@@ -1242,7 +1242,7 @@
 
   private void writeImports(IndentedWriter w) {
     w.write("import com.google.gwt.core.client.GWT;");
-    w.write("import com.google.gwt.uibinder.client.AbstractUiBinder;");
+    w.write("import com.google.gwt.uibinder.client.UiBinder;");
     w.write("import com.google.gwt.uibinder.client.UiBinderUtil;");
     w.write("import %s.%s;", uiRootType.getPackage().getName(),
         uiRootType.getName());
diff --git a/user/src/com/google/gwt/uibinder/rebind/model/ImplicitClientBundle.java b/user/src/com/google/gwt/uibinder/rebind/model/ImplicitClientBundle.java
index 6ec02e0..8f0a906 100644
--- a/user/src/com/google/gwt/uibinder/rebind/model/ImplicitClientBundle.java
+++ b/user/src/com/google/gwt/uibinder/rebind/model/ImplicitClientBundle.java
@@ -30,7 +30,7 @@
   // LinkedHashSets for consistent order across recompiles
   private final LinkedHashSet<ImplicitCssResource> cssMethods = new LinkedHashSet<ImplicitCssResource>();
   private final LinkedHashSet<ImplicitImageResource> imageMethods = new LinkedHashSet<ImplicitImageResource>();
-  private final LinkedHashSet<ImplicitDataResource> dataMethods = new LinkedHashSet<ImplicitDataResource>();
+  private final LinkedHashSet<ImplicitDataResource> dataMethods =  new LinkedHashSet<ImplicitDataResource>();
   private final String packageName;
   private final String className;
   private final String fieldName;
@@ -60,12 +60,14 @@
    * @param extendedInterface the public interface implemented by this
    *          CssResource, or null
    * @param body the inline css text
+   * @param importTypes for the {@literal @}Import annotation, if any. LinkedHashSet
+   *          to enforce deterministic order across recompiles
    * @return
    */
   public ImplicitCssResource createCssResource(String name, String source,
-      JClassType extendedInterface, String body) {
+      JClassType extendedInterface, String body, LinkedHashSet<JClassType> importTypes) {
     ImplicitCssResource css = new ImplicitCssResource(packageName, cssBaseName
-        + name, name, source, extendedInterface, body, logger);
+        + name, name, source, extendedInterface, body, logger, importTypes);
     cssMethods.add(css);
     return css;
   }
diff --git a/user/src/com/google/gwt/uibinder/rebind/model/ImplicitCssResource.java b/user/src/com/google/gwt/uibinder/rebind/model/ImplicitCssResource.java
index b0c6b30..b5c5bb6 100644
--- a/user/src/com/google/gwt/uibinder/rebind/model/ImplicitCssResource.java
+++ b/user/src/com/google/gwt/uibinder/rebind/model/ImplicitCssResource.java
@@ -29,6 +29,8 @@
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.Set;
 
 /**
@@ -42,17 +44,19 @@
   private final JClassType extendedInterface;
   private final String body;
   private final MortalLogger logger;
+  private final Set<JClassType> imports;
   private File generatedFile;
 
   ImplicitCssResource(String packageName, String className, String name,
       String source, JClassType extendedInterface, String body,
-      MortalLogger logger) {
+      MortalLogger logger, HashSet<JClassType> importTypes) {
     this.packageName = packageName;
     this.className = className;
     this.name = name;
     this.extendedInterface = extendedInterface;
     this.body = body;
     this.logger = logger;
+    this.imports = Collections.unmodifiableSet(importTypes);
 
     if (body.length() > 0) {
       assert "".equals(source); // Enforced for real by the parser
@@ -96,7 +100,7 @@
     }
 
     CssStylesheet sheet = GenerateCssAst.exec(logger.getTreeLogger(), urls);
-    return ExtractClassNamesVisitor.exec(sheet);
+    return ExtractClassNamesVisitor.exec(sheet, imports.toArray(new JClassType[imports.size()]));
   }
 
   /**
@@ -106,6 +110,10 @@
     return extendedInterface;
   }
 
+  public Set<JClassType> getImports() {
+    return imports;
+  }
+
   /**
    * @return the name of this resource. This is both its method name in the
    *         owning {@link ImplicitClientBundle} and its ui:field name
diff --git a/user/src/com/google/gwt/uibinder/sample/client/CssImportScopeSample.css b/user/src/com/google/gwt/uibinder/sample/client/CssImportScopeSample.css
new file mode 100644
index 0000000..eb1702e
--- /dev/null
+++ b/user/src/com/google/gwt/uibinder/sample/client/CssImportScopeSample.css
@@ -0,0 +1,3 @@
+.body { 
+  background-color: pink; 
+}
diff --git a/user/src/com/google/gwt/uibinder/sample/client/CssImportScopeSample.java b/user/src/com/google/gwt/uibinder/sample/client/CssImportScopeSample.java
new file mode 100644
index 0000000..1e1f90a
--- /dev/null
+++ b/user/src/com/google/gwt/uibinder/sample/client/CssImportScopeSample.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2009 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.uibinder.sample.client;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.DivElement;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.CssResource;
+import com.google.gwt.resources.client.CssResource.ImportedWithPrefix;
+import com.google.gwt.uibinder.client.UiBinder;
+import com.google.gwt.uibinder.client.UiField;
+import com.google.gwt.user.client.ui.HasText;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * Odd widget demonstrates UiBinder's integration with CssResource's obscure but
+ * crucial imported scopes feature.
+ */
+public class CssImportScopeSample extends Widget implements HasText {
+  interface Binder extends UiBinder<DivElement, CssImportScopeSample> {
+  }
+  private static final Binder binder = GWT.create(Binder.class);
+
+  interface Bundle extends ClientBundle {
+    @Source("CssImportScopeSample.css")
+    InnerStyle innerStyle();
+
+    @Source("CssImportScopeSample.css")
+    OuterStyle style();
+  }
+
+  @ImportedWithPrefix("inner")
+  interface InnerStyle extends Style {
+  }
+
+  @ImportedWithPrefix("outer")
+  interface OuterStyle extends Style {
+  }
+
+  interface Style extends CssResource {
+    String body();
+  }
+
+  @UiField(provided = true)
+  Bundle bundle = GWT.create(Bundle.class);
+  @UiField
+  Element inner;
+
+  @UiField
+  Element outer;
+
+  CssImportScopeSample() {
+    bundle.style().ensureInjected();
+    bundle.innerStyle().ensureInjected();
+    setElement(binder.createAndBindUi(this));
+  }
+
+  public String getText() {
+    return outer.getInnerText();
+  }
+
+  public void setText(String text) {
+    outer.setInnerText(text);
+  }
+
+  public void setWrappedText(String text) {
+    inner.setInnerText(text);
+  }
+}
diff --git a/user/src/com/google/gwt/uibinder/sample/client/CssImportScopeSample.ui.xml b/user/src/com/google/gwt/uibinder/sample/client/CssImportScopeSample.ui.xml
new file mode 100644
index 0000000..3c56a2c
--- /dev/null
+++ b/user/src/com/google/gwt/uibinder/sample/client/CssImportScopeSample.ui.xml
@@ -0,0 +1,26 @@
+<!-- Copyright 2009 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   -->
+<!-- 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. License for the specific language governing permissions and   -->
+<!-- limitations under the License.                                         -->
+
+<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' >
+  <ui:with field='bundle' type='com.google.gwt.uibinder.sample.client.CssImportScopeSample.Bundle' />
+  
+  <ui:style import='com.google.gwt.uibinder.sample.client.CssImportScopeSample.OuterStyle
+        com.google.gwt.uibinder.sample.client.CssImportScopeSample.InnerStyle'>
+    .outer-body .inner-body { width: 100px; background-color: red; }   
+  </ui:style>
+
+  <div class='{bundle.style.body}'> 
+    <span ui:field='outer'/>
+    <div ui:field='inner' class='{bundle.innerStyle.body}'>Inner!</div>
+  </div>
+</ui:UiBinder>
diff --git a/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.java b/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.java
index 4126a0e..2a5e0f1 100644
--- a/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.java
+++ b/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.java
@@ -58,7 +58,7 @@
   public interface Style extends CssResource {
     String menuBar();
   }
-
+  
   interface Binder extends UiBinder<Widget, WidgetBasedUi> {
   }
   private static final Binder binder = GWT.create(Binder.class);
@@ -121,6 +121,7 @@
   @UiField Image babyWidget;
   @UiField ParagraphElement simpleSpriteParagraph;
   @UiField DataResource heartCursorResource;
+  @UiField CssImportScopeSample cssImportScopeSample;
 
   public WidgetBasedUi() {
     this.bundledLabel = new Label();
diff --git a/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml b/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml
index f13963f..169888e 100644
--- a/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml
+++ b/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml
@@ -348,6 +348,9 @@
           (This one too, but even more so.)
         </span>
       </p>
+      <demo:CssImportScopeSample ui:field='cssImportScopeSample' wrappedText='Please use it.'>
+        And this one relies on CssResource's imported scopes feature
+      </demo:CssImportScopeSample>
       <h2>Evolving</h2>
       <p>
         Things change. This label uses the new ui:field attribute to declare
diff --git a/user/test/com/google/gwt/uibinder/sample/client/UiBinderTest.java b/user/test/com/google/gwt/uibinder/sample/client/UiBinderTest.java
index 0d2749f..e52cc00 100644
--- a/user/test/com/google/gwt/uibinder/sample/client/UiBinderTest.java
+++ b/user/test/com/google/gwt/uibinder/sample/client/UiBinderTest.java
@@ -25,6 +25,7 @@
 import com.google.gwt.junit.Platform;
 import com.google.gwt.junit.client.GWTTestCase;
 import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.DataResource;
 import com.google.gwt.resources.client.CssResource.NotStrict;
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.ui.DisclosurePanel;
@@ -356,6 +357,11 @@
     assertNotNull(widgetUi.heartCursorResource.getUrl());
   }
 
+  @DoNotRunWith(Platform.Htmlunit)
+  public void testCssImportedScopes() {
+    assertEquals(100, widgetUi.cssImportScopeSample.inner.getOffsetWidth());
+  }
+
   public void testSpritedElement() {
     assertEquals(widgetUi.prettyImage.getWidth(),
         widgetUi.simpleSpriteParagraph.getOffsetWidth());