### Question:
Rule { public List<Rule> flatten() { List<Rule> flat = new ArrayList<Rule>(); if (parts.isEmpty()) { flat.add(this); } else { for (Rule r : parts) { if (r != this) { r = merge(r); } flat.add(r); } } return flat; }  Map<String, Object> properties(); List<Selector> getSelectors(); List<Rule> nested(); boolean has(String key); Object get(String key); void put(String key, Object val); void putAll(Map<String, Object> map); void add(Rule rule); T eval(String key, Class<T> clazz); T eval(Object obj, String key, Class<T> clazz); T eval(Object obj, String key, Class<T> clazz, T def); T[] evalArray(Object obj, String key, Class<T> clazz, T[] def); RGB color(Object obj, String key, RGB def); String string(Object obj, String key, String def); Integer number(Object obj, String key, Integer def); Double number(Object obj, String key, Double def); Float number(Object obj, String key, Float def); Boolean bool(Object obj, String key, Boolean def); Integer[] numbers(Object obj, String key, Integer... def); Double[] numbers(Object obj, String key, Double... def); Float[] numbers(Object obj, String key, Float... def); List<Rule> flatten(); Rule merge(Rule other); @Override String toString(); String toString(int indent); @Override int hashCode(); @Override boolean equals(Object obj);  }### Answer:
@Test public void testFlatten() throws Exception { Style style = new StyleBuilder().rule().select("#widgets").filter("cost > 12") .rule().select("::costly").filter("cost > 20").set("color", "yellow").endRule() .rule().select("::expensive").filter("cost > 30").set("color", "red").endRule() .set("color", "green").endRule().style(); assertEquals(1, style.getRules().size()); Rule r = style.getRules().get(0); assertEquals(1, r.getSelectors().size()); Selector s = r.getSelectors().get(0); assertEquals("widgets", s.getId()); assertEquals(CQL.parse("cost > 12"), s.getFilter()); assertEquals(2, r.nested().size()); s = r.nested().get(0).getSelectors().get(0); assertEquals("costly", s.getAttachment()); assertEquals(CQL.parse("cost > 20"), s.getFilter()); s = r.nested().get(1).getSelectors().get(0); assertEquals("expensive", s.getAttachment()); assertEquals(CQL.parse("cost > 30"), s.getFilter()); List<Rule> flat = r.flatten(); assertEquals(3, flat.size()); r = flat.get(0); assertEquals(1,r.getSelectors().size()); s = r.getSelectors().get(0); assertEquals("widgets", s.getId()); assertEquals("costly", s.getAttachment()); assertEquals(CQL.parse("cost > 12 AND cost > 20"), s.getFilter()); assertEquals("yellow", r.get("color")); r = flat.get(1); assertEquals(1,r.getSelectors().size()); s = r.getSelectors().get(0); assertEquals("widgets", s.getId()); assertEquals("expensive", s.getAttachment()); assertEquals(CQL.parse("cost > 12 AND cost > 30"), s.getFilter()); assertEquals("red", r.get("color")); r = flat.get(2); assertEquals(1,r.getSelectors().size()); s = r.getSelectors().get(0); assertEquals("widgets", s.getId()); assertNull(s.getAttachment()); assertEquals(CQL.parse("cost > 12"), s.getFilter()); assertEquals("green", r.get("color")); }