[logback-dev] [GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v_0.9.21-3-g2e84142

added by portage for gitosis-gentoo git-noreply at pixie.qos.ch
Tue May 25 10:10:27 CEST 2010


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".

The branch, master has been updated
       via  2e841425b8fc704719db6d1f1e18af2215ea1fb5 (commit)
      from  060efd8495dedc95fc0f6abb688b8e0a1eaa1628 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=2e841425b8fc704719db6d1f1e18af2215ea1fb5
http://github.com/ceki/logback/commit/2e841425b8fc704719db6d1f1e18af2215ea1fb5

commit 2e841425b8fc704719db6d1f1e18af2215ea1fb5
Author: Ceki Gulcu <ceki at qos.ch>
Date:   Tue May 25 10:08:11 2010 +0200

    testing and documenting gafter

diff --git a/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java b/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java
index 49b909a..95ae870 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/sift/SiftingAppender.java
@@ -36,10 +36,6 @@ public class SiftingAppender extends SiftingAppenderBase<AccessEvent> {
     super.start();
   }
 
-  AppenderTracker<AccessEvent> getAppenderTracker() {
-    return appenderTracker;
-  }
-
   @Override
   protected long getTimestamp(AccessEvent event) {
     return event.getTimeStamp();
diff --git a/logback-classic/osgi-build.xml b/logback-classic/osgi-build.xml
index 615452d..045578f 100644
--- a/logback-classic/osgi-build.xml
+++ b/logback-classic/osgi-build.xml
@@ -69,7 +69,7 @@
       <copy file="lib/slf4j-api-${slf4j.version}.jar" todir="${bundlesDir}"/>
       <copy file="../logback-core/target/logback-core-${currentVersion}.jar" todir="${bundlesDir}"/>
       <copy file="target/logback-classic-${currentVersion}.jar" todir="${bundlesDir}"/>
-      <echo>value of t = @{t}</echo>
+      <echo>value of binding = @{binding}</echo>
     </sequential>
   </macrodef>
 
diff --git a/logback-classic/pom.xml b/logback-classic/pom.xml
index d1a8691..884a78a 100644
--- a/logback-classic/pom.xml
+++ b/logback-classic/pom.xml
@@ -326,7 +326,7 @@ org.slf4j.test_osgi
               sun.reflect;resolution:=optional, 
               javax.*;resolution:=optional,
               org.xml.*;resolution:=optional,
-              ch.qos.logback.core.rolling, 
+              org.slf4j, ch.qos.logback.core.rolling, 
               ch.qos.logback.core.rolling.helper,
               org.codehaus.groovy.*;resolution:=optional,
               groovy.lang.*;resolution:=optional,
diff --git a/logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF b/logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF
index fe56e16..efcb272 100644
--- a/logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF
+++ b/logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF
@@ -12,4 +12,4 @@ Bundle-SymbolicName: iBundle
 Bundle-Name: abundle
 Bundle-RequiredExecutionEnvironment: J2SE-1.3
 Export-Package: apack
-Import-Package: org.osgi.framework, org.slf4j;version=1.5, ch.qos.logback.core, ch.qos.logback.core.joran.spi, ch.qos.logback.core.util, ch.qos.logback.classic, ch.qos.logback.classic.joran
+Import-Package: org.osgi.framework, org.slf4j;version=1.6, ch.qos.logback.core, ch.qos.logback.core.joran.spi, ch.qos.logback.core.util, ch.qos.logback.classic, ch.qos.logback.classic.joran
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
index 1db63a6..471c148 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ComponentDelegate.groovy
@@ -13,60 +13,92 @@
  */
 package ch.qos.logback.classic.gaffer
 
-import ch.qos.logback.core.Appender
 import ch.qos.logback.core.spi.ContextAwareBase
 import ch.qos.logback.core.spi.LifeCycle
 import ch.qos.logback.core.spi.ContextAware
+import java.beans.Introspector
 
 /**
  * @author Ceki G&uuml;c&uuml;
  */
-
- at Mixin(ContextAwareBase)
-class ComponentDelegate {
+class ComponentDelegate extends ContextAwareBase {
 
   final Object component;
 
+  final List fieldsToCaccade = [];
+
   ComponentDelegate(Object component) {
     this.component = component;
   }
 
+  Object getDeclaredOrigin() {
+    return "ComponentDelegate"
+  }
+
   String getLabel() { "component" }
 
   String getLabelFistLetterInUpperCase() { getLabel()[0].toUpperCase() + getLabel().substring(1) }
 
   void methodMissing(String name, def args) {
-    
-    if (component.hasProperty(name)) {
-      String subComponentName
-      Class clazz
-      Closure closure
-      (subComponentName, clazz, closure) = analyzeArgs(args)
-      if (clazz != null) {
-        Object subComponent = clazz.newInstance()
-        if (subComponentName && subComponent.hasProperty(name)) {
-          subComponent.name = subComponentName;
-        }
-        if (subComponent instanceof ContextAware) {
-          subComponent.context = context;
-        }
-        if (closure) {
-          ComponentDelegate subDelegate = new ComponentDelegate(subComponent)
-          subDelegate.context = context
-          closure.delegate = subDelegate
-          closure.resolveStrategy = Closure.DELEGATE_FIRST
-          closure()
-        }
-        if (subComponent instanceof LifeCycle) {
-          subComponent.start();
+    NestingType nestingType = PropertyUtil.nestingType(component, name);
+    if (nestingType == NestingType.NA) {
+      addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no appplicable [${name}] property ")
+      return;
+    }
+
+    String subComponentName
+    Class clazz
+    Closure closure
+    (subComponentName, clazz, closure) = analyzeArgs(args)
+    if (clazz != null) {
+      Object subComponent = clazz.newInstance()
+      if (subComponentName && subComponent.hasProperty(name)) {
+        subComponent.name = subComponentName;
+      }
+      if (subComponent instanceof ContextAware) {
+        subComponent.context = context;
+      }
+      if (closure) {
+        ComponentDelegate subDelegate = new ComponentDelegate(subComponent)
+
+        cascadeFields(subDelegate);
+        for (String k: fieldsToCaccade) {
+          //println "caccading ${k} with value ${this."${k}"}"
+          //subDelegate.metaClass."${k}" = this."${k}"
         }
-        component."${name}" = subComponent;
+
+
+        subDelegate.context = context
+        closure.delegate = subDelegate
+        closure.resolveStrategy = Closure.DELEGATE_FIRST
+        closure()
       }
+      if (subComponent instanceof LifeCycle) {
+        subComponent.start();
+      }
+      PropertyUtil.attach(nestingType, component, subComponent, name)
     } else {
-      addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no [${name}] property ")
+      addError("No 'class' argument specified for [${name}] in ${getLabel()} ${getComponentName()} of type [${component.getClass().canonicalName}]");
+    }
+  }
+
+  void cascadeFields(ComponentDelegate subDelegate) {
+    for (String k: fieldsToCaccade) {
+      println "cacsading ${k} with value ${this."${k}"}"
+      subDelegate.metaClass."${k}" = this."${k}"
+    }
+  }
+
+  void propertyMissing(String name, def value) {
+    NestingType nestingType = PropertyUtil.nestingType(component, name);
+    if (nestingType == NestingType.NA) {
+      addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no appplicable [${name}] property ")
+      return;
     }
+    PropertyUtil.attach(nestingType, component, value, name)
   }
 
+
   def analyzeArgs(Object[] args) {
     String name;
     Class clazz;
@@ -121,26 +153,4 @@ class ComponentDelegate {
       return ""
 
   }
-
-  void propertyMissing(String name, def value) {
-    name = camelCasify(name);
-    if (component.hasProperty(name)) {
-      //println "-- component has property $name"
-      component."${name}" = value;
-    } else {
-      // println "-- component does not have property [$name]"
-      addError("${getLabelFistLetterInUpperCase()} ${getComponentName()} of type [${component.getClass().canonicalName}] has no [${name}] property ")
-    }
-  }
-
-  String camelCasify(String name) {
-    if(name == null || name.length() == 0)
-      return name;
-
-    String firstLetter = new String(name.getAt(0)).toLowerCase();
-    if(name.length() == 1)
-      return firstLetter
-    else
-      return firstLetter + name.substring(1);
-  }
 }
\ No newline at end of file
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationContributor.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationContributor.groovy
new file mode 100644
index 0000000..e46b367
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationContributor.groovy
@@ -0,0 +1,31 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.gaffer
+
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+public interface ConfigurationContributor {
+
+  /**
+   * The list of method mapping from the contributor into the configuration mechanism,
+   * e.g. the ConfiguratorDelegate
+   *
+   * <p>The key in the map is the method being contributed and the value is the name of
+   * the method in the target class.
+   * @return
+   */
+  public Map<String, String> getMappings()
+
+}
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
index e45b223..5bda299 100644
--- a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegate.groovy
@@ -122,6 +122,7 @@ public class ConfigurationDelegate extends ContextAwareBase {
     appenderList.add(appender)
     if (closure != null) {
       AppenderDelegate ad = new AppenderDelegate(appender);
+      copyContributions(ad, appender)
       ad.context = context;
       closure.delegate = ad;
       closure.resolveStrategy = Closure.DELEGATE_FIRST
@@ -130,6 +131,16 @@ public class ConfigurationDelegate extends ContextAwareBase {
     appender.start();
   }
 
+  private void copyContributions(AppenderDelegate appenderDelegate, Appender appender) {
+    if(appender instanceof ConfigurationContributor) {
+      ConfigurationContributor cc = (ConfigurationContributor) appender;
+      cc.getMappings().each() { oldName, newName ->
+         appenderDelegate.metaClass."${newName}" = appender.&"$oldName"
+      }
+    }
+
+  }
+
   void turboFilter(Class clazz, Closure closure = null) {
     addInfo("About to instantiate turboFilter of type [" + clazz.name + "]");
     TurboFilter turboFilter = clazz.newInstance();
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/NestedType.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/NestedType.groovy
new file mode 100644
index 0000000..b5d685a
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/NestedType.groovy
@@ -0,0 +1,23 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.gaffer
+
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+
+enum NestingType {
+  NA, SINGLE, AS_COLLECTION;
+}
+
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/PropertyUtil.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/PropertyUtil.groovy
new file mode 100644
index 0000000..7bc1811
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/PropertyUtil.groovy
@@ -0,0 +1,72 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.gaffer
+
+import java.lang.reflect.Method
+import java.beans.Introspector
+
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+class PropertyUtil {
+
+  static boolean hasAdderMethod(Object obj, String name) {
+    String addMethod = "add${upperCaseFirstLetter(name)}";
+    return obj.metaClass.respondsTo(obj, addMethod);
+  }
+
+  static NestingType nestingType(Object obj, String name) {
+    def decapitalizedName = Introspector.decapitalize(name)
+    if (obj.hasProperty(decapitalizedName)) {
+      return NestingType.SINGLE;
+    }
+    if (hasAdderMethod(obj, name)) {
+      return NestingType.AS_COLLECTION;
+    }
+    return NestingType.NA;
+  }
+
+  static void attach(NestingType nestingType, Object component, Object subComponent, String name) {
+    switch (nestingType) {
+      case NestingType.SINGLE:
+        name = Introspector.decapitalize(name)
+        component."${name}" = subComponent;
+        break;
+      case NestingType.AS_COLLECTION:
+        String firstUpperName = PropertyUtil.upperCaseFirstLetter(name)
+        component."add${firstUpperName}"(subComponent);
+        break;
+    }
+  }
+
+  static String transformFirstLetter(String s, Closure closure) {
+    if (s == null || s.length() == 0)
+      return s;
+
+    String firstLetter = new String(s.getAt(0));
+
+    String modifiedFistLetter = closure(firstLetter);
+
+    if (s.length() == 1)
+      return modifiedFistLetter
+    else
+      return modifiedFistLetter + s.substring(1);
+
+  }
+
+  static String upperCaseFirstLetter(String s) {
+    return transformFirstLetter(s, {String it -> it.toUpperCase()})
+  }
+
+}
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/sift/GSiftingAppender.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/sift/GSiftingAppender.groovy
new file mode 100644
index 0000000..f2493e7
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/sift/GSiftingAppender.groovy
@@ -0,0 +1,153 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.sift
+
+import ch.qos.logback.core.AppenderBase
+import ch.qos.logback.classic.spi.ILoggingEvent
+import ch.qos.logback.core.sift.AppenderTrackerImpl
+import ch.qos.logback.core.sift.Discriminator
+import ch.qos.logback.core.sift.AppenderTracker
+import ch.qos.logback.core.Appender
+
+import ch.qos.logback.classic.gaffer.ConfigurationContributor
+import ch.qos.logback.core.CoreConstants
+import ch.qos.logback.core.helpers.NOPAppender
+
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+class GSiftingAppender extends AppenderBase<ILoggingEvent> implements ConfigurationContributor {
+
+
+  protected AppenderTracker<ILoggingEvent> appenderTracker = new AppenderTrackerImpl<ILoggingEvent>();
+  Discriminator<ILoggingEvent> discriminator;
+  Closure builderClosure;
+
+  def Map<String, String> getMappings() {
+    return [sift: "sift"]
+  }
+
+  @Override
+  public void start() {
+    int errors = 0;
+    if (discriminator == null) {
+      addError("Missing discriminator. Aborting");
+      errors++;
+    }
+    if (!discriminator?.isStarted()) {
+      addError("Discriminator has not started successfully. Aborting");
+      errors++;
+    }
+
+    if (builderClosure == null) {
+      addError("Missing builder closure. Aborting");
+      errors++;
+    }
+    if (errors == 0) {
+      super.start();
+    }
+  }
+
+  @Override
+  public void stop() {
+    for (Appender<ILoggingEvent> appender: appenderTracker.valueList()) {
+      appender.stop();
+    }
+  }
+
+  @Override
+  protected long getTimestamp(ILoggingEvent event) {
+    return event.getTimeStamp();
+  }
+
+
+  Appender buildAppender(String value) {
+    String key = getDiscriminatorKey()
+
+    ZSiftingDelegate zd = new ZSiftingDelegate(getDiscriminatorKey(), value)
+    zd.context = context
+    zd.metaClass."$key" = value
+
+    //Closure newBuilder = builderClosure.clone()
+    builderClosure.delegate = zd;
+    builderClosure.resolveStrategy = Closure.DELEGATE_FIRST
+    Appender a = builderClosure()
+    return a
+  }
+
+  @Override
+  protected void append(ILoggingEvent event) {
+    if (!isStarted()) {
+      return;
+    }
+
+    String discriminatingValue = discriminator.getDiscriminatingValue(event);
+    long timestamp = getTimestamp(event);
+
+    Appender<ILoggingEvent> appender = appenderTracker.get(discriminatingValue, timestamp);
+    if (appender == null) {
+      try {
+        appender = buildAppender(discriminatingValue);
+        if (appender == null) {
+          appender = buildNOPAppender(discriminatingValue);
+        }
+        appenderTracker.put(discriminatingValue, appender, timestamp);
+
+      } catch (Throwable e) {
+        addError("Failed to build appender for [" + discriminatingValue + "]",
+                e);
+        return;
+      }
+    }
+    appenderTracker.stopStaleAppenders(timestamp);
+
+    appender.doAppend(event);
+  }
+
+  int nopaWarningCount = 0;
+
+  NOPAppender<ILoggingEvent> buildNOPAppender(String discriminatingValue) {
+    if (nopaWarningCount < CoreConstants.MAX_ERROR_COUNT) {
+      nopaWarningCount++;
+      addError("Failed to build an appender for discriminating value [" + discriminatingValue + "]");
+    }
+    NOPAppender<ILoggingEvent> nopa = new NOPAppender<ILoggingEvent>();
+    nopa.setContext(context);
+    nopa.start();
+    return nopa;
+  }
+
+  void build() {
+    int r = builderClosure();
+    println "r=$r"
+
+  }
+
+  void sift(Closure clo) {
+    builderClosure = clo;
+  }
+
+
+  public AppenderTracker getAppenderTracker() {
+    return appenderTracker;
+  }
+
+  public String getDiscriminatorKey() {
+    if (discriminator != null) {
+      return discriminator.getKey();
+    } else {
+      return null;
+    }
+  }
+}
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/sift/ZSiftingDelegate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/sift/ZSiftingDelegate.groovy
new file mode 100644
index 0000000..8218e58
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/sift/ZSiftingDelegate.groovy
@@ -0,0 +1,39 @@
+package ch.qos.logback.classic.sift
+
+import ch.qos.logback.core.spi.ContextAwareBase
+import ch.qos.logback.core.Appender
+import ch.qos.logback.classic.gaffer.AppenderDelegate
+import ch.qos.logback.core.util.StatusPrinter
+
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+class ZSiftingDelegate extends ContextAwareBase {
+
+  String key
+  String value
+
+  ZSiftingDelegate(String key, String value) {
+    this.key = key
+    this.value = value
+  }
+
+  Appender appender(String name, Class clazz, Closure closure = null) {
+    addInfo("About to instantiate appender of type [" + clazz.name + "]");
+    Appender appender = clazz.newInstance();
+    addInfo("Naming appender as [" + name + "]");
+    appender.name = name
+    appender.context = context
+    if (closure != null) {
+      AppenderDelegate ad = new AppenderDelegate(appender);
+      ad.metaClass."${key}" = value
+      ad.fieldsToCaccade << "${key}"
+      ad.context = context;
+      closure.delegate = ad;
+      closure.resolveStrategy = Closure.DELEGATE_FIRST
+      closure();
+    }
+    appender.start();
+    return appender;
+  }
+}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
index 5245146..1e57794 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
@@ -31,10 +31,6 @@ import ch.qos.logback.core.sift.SiftingAppenderBase;
  */
 public class SiftingAppender extends SiftingAppenderBase<ILoggingEvent> {
 
-  AppenderTracker<ILoggingEvent> getAppenderTracker() {
-    return appenderTracker;
-  }
-
   @Override
   protected long getTimestamp(ILoggingEvent event) {
     return event.getTimeStamp();
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
index 66d6b4d..7cc9a35 100644
--- a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfigurationDelegateTest.groovy
@@ -15,6 +15,8 @@ import ch.qos.logback.core.helpers.NOPAppender
 import ch.qos.logback.core.ConsoleAppender
 import ch.qos.logback.core.encoder.LayoutWrappingEncoder
 import ch.qos.logback.classic.PatternLayout
+import ch.qos.logback.core.util.StatusPrinter
+import ch.qos.logback.classic.net.SMTPAppender
 
 /**
  * @author Ceki G&uuml;c&uuml;
@@ -162,4 +164,25 @@ class ConfigurationDelegateTest {
     assertEquals("%m%n", layout.pattern)
 
   }
+
+    @Test
+  void appenderSMTP() {
+    configurationDelegate.appender("SMTP", SMTPAppender) {
+      to = "a"
+      to = "b"
+      layout (PatternLayout) {
+          pattern = "%m%n"
+      }
+    }
+       StatusPrinter.print context
+    Appender back = configurationDelegate.appenderList.find {it.name = "SMTP"}
+    assertNotNull(back)
+    assertEquals("SMTP", back.name)
+    SMTPAppender sa = back
+    PatternLayout layout =  sa.layout
+    assertEquals("%m%n", layout.pattern)
+
+    assertEquals(["a", "b"], sa.toList.sort());
+
+  }
 }
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy
index 53ee836..f35daf0 100644
--- a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/ConfiguratorTest.groovy
@@ -29,6 +29,11 @@ import ch.qos.logback.core.testUtil.StringListAppender
 import ch.qos.logback.classic.testUtil.SampleConverter
 import ch.qos.logback.core.util.StatusPrinter
 
+import ch.qos.logback.classic.boolex.JaninoEventEvaluator
+import ch.qos.logback.core.filter.EvaluatorFilter
+import ch.qos.logback.core.boolex.Matcher
+import static org.junit.Assert.assertTrue
+
 /**
  * @author Ceki G&uuml;c&uuml;
  */
@@ -100,4 +105,55 @@ class ConfiguratorTest {
     assertEquals(SampleConverter.SAMPLE_STR + " - " + msg, sla.strList.get(0));
   }
 
+  @Test
+  void evaluatorWithMatcher() {
+    File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "evaluatorWithMatcher.groovy")
+    String dslText = file.text
+    configurator.run dslText
+
+    ConsoleAppender ca = (ConsoleAppender) root.getAppender("STDOUT");
+    assertTrue ca.isStarted()
+
+    EvaluatorFilter ef = ca.getCopyOfAttachedFiltersList()[0];
+    assertTrue ef.isStarted()
+
+    JaninoEventEvaluator jee = ef.evaluator
+    assertTrue jee.isStarted()
+    Matcher m = jee.matcherList[0]
+    assertTrue m.isStarted()
+  }
+
+  @Test
+  void propertyCascading0() {
+    File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "propertyCascading0.groovy")
+    String dslText = file.text
+    configurator.run dslText
+
+    ConsoleAppender ca = (ConsoleAppender) root.getAppender("STDOUT");
+    assertTrue ca.isStarted()
+   
+    assertEquals("HELLO %m%n", ca.encoder.layout.pattern)
+  }
+  @Test
+  void propertyCascading1() {
+    File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "propertyCascading1.groovy")
+    String dslText = file.text
+    configurator.run dslText
+
+    ConsoleAppender ca = (ConsoleAppender) root.getAppender("STDOUT");
+    assertTrue ca.isStarted()
+    assertEquals("HELLO %m%n", ca.encoder.getLayout().pattern)
+  }
+
+  @Test
+  void propertyCascading2() {
+    context.putProperty("p", "HELLO");
+    File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + "propertyCascading2.groovy")
+    String dslText = file.text
+    configurator.run dslText
+
+    ConsoleAppender ca = (ConsoleAppender) root.getAppender("STDOUT");
+    assertTrue ca.isStarted()
+    assertEquals("HELLO %m%n", ca.encoder.getLayout().pattern)
+  }
 }
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/PropertyUtilTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/PropertyUtilTest.groovy
new file mode 100644
index 0000000..d2f5e7d
--- /dev/null
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/PropertyUtilTest.groovy
@@ -0,0 +1,26 @@
+package ch.qos.logback.classic.gaffer
+
+import org.junit.Test
+import static junit.framework.Assert.assertEquals
+
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+class PropertyUtilTest {
+
+
+  @Test
+  void empty() {
+    assertEquals("", PropertyUtil.upperCaseFirstLetter(""));
+    assertEquals(null, PropertyUtil.upperCaseFirstLetter(null));
+  }
+
+
+
+  @Test
+  void smoke() {
+    assertEquals("Hello", PropertyUtil.upperCaseFirstLetter("hello"));
+  }
+
+
+}
diff --git a/logback-classic/src/test/groovy/ch/qos/logback/classic/sift/GSiftingAppenderTest.groovy b/logback-classic/src/test/groovy/ch/qos/logback/classic/sift/GSiftingAppenderTest.groovy
new file mode 100644
index 0000000..f0441d0
--- /dev/null
+++ b/logback-classic/src/test/groovy/ch/qos/logback/classic/sift/GSiftingAppenderTest.groovy
@@ -0,0 +1,110 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.sift
+
+import ch.qos.logback.classic.gaffer.Configurator
+
+import ch.qos.logback.classic.Logger
+import ch.qos.logback.classic.LoggerContext
+import ch.qos.logback.core.testUtil.RandomUtil
+import org.junit.Test
+import ch.qos.logback.classic.ClassicTestConstants
+import org.slf4j.MDC
+import static junit.framework.Assert.assertNotNull
+import ch.qos.logback.core.sift.AppenderTracker
+import ch.qos.logback.core.read.ListAppender
+import ch.qos.logback.core.util.StatusPrinter
+import static junit.framework.Assert.assertEquals
+import ch.qos.logback.core.FileAppender
+import ch.qos.logback.core.status.StatusChecker
+import ch.qos.logback.core.status.Status
+import static junit.framework.Assert.assertNull
+import org.junit.After
+
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+class GSiftingAppenderTest {
+
+  LoggerContext context = new LoggerContext();
+  Logger root = context.getLogger(Logger.ROOT_LOGGER_NAME)
+  Logger logger = context.getLogger(this.getClass())
+  int diff = RandomUtil.getPositiveInt();
+  Configurator configurator = new Configurator(context);
+  StatusChecker checker = new StatusChecker(context)
+
+  @After
+  public void tearDown() {
+    MDC.clear();  
+  }
+
+  AppenderTracker execute(String path) {
+    File file = new File(ClassicTestConstants.GAFFER_INPUT_PREFIX + path)
+    String dslText = file.text
+    configurator.run dslText
+
+    GSiftingAppender sa = (GSiftingAppender) root.getAppender("SIFT");
+    assertNotNull(sa)
+    AppenderTracker tracker = sa.getAppenderTracker();
+  }
+
+  @Test
+  void noDiscriminator() {
+    AppenderTracker tracker = execute("sift/noDiscriminator.groovy")
+    logger.debug("x")
+    ListAppender unknownAppender = tracker.get("unknown", System.currentTimeMillis())
+    assertNull(unknownAppender)
+    checker.containsMatch(Status.ERROR, "Missing discriminator. Aborting")
+  }
+
+  @Test
+  void sample0() {
+    AppenderTracker tracker = execute("sift/sample0.groovy")
+    logger.debug("x")
+    ListAppender unknownAppender = tracker.get("unknown", System.currentTimeMillis())
+    assertNotNull(unknownAppender)
+
+    MDC.put("userid", "a");
+    logger.debug("y");
+    ListAppender aAppender = tracker.get("a", System.currentTimeMillis())
+    assertNotNull(aAppender)
+
+    assertEquals(1, unknownAppender.list.size);
+    assertEquals("x", unknownAppender.list[0].message)
+    assertEquals(1, aAppender.list.size);
+    assertEquals("y", aAppender.list[0].message)
+  }
+
+  @Test
+  void sample1() {
+    AppenderTracker tracker = execute("sift/sample1.groovy")
+    logger.debug("x")
+
+    StatusPrinter.print context
+    FileAppender unknownAppender = tracker.get("unknown", System.currentTimeMillis())
+    assertNotNull(unknownAppender)
+    assertEquals("FILE-unknown", unknownAppender.name)
+    assertEquals("test-unknown.log", unknownAppender.file)
+
+    MDC.put("userid", "a");
+    logger.debug("y");
+    FileAppender aAppender = tracker.get("a", System.currentTimeMillis())
+    assertNotNull(aAppender)
+    assertEquals("FILE-a", aAppender.name)
+    assertEquals("test-a.log", aAppender.file)
+    assertEquals("a - %msg%n", aAppender.encoder.pattern)
+  }
+
+
+}
diff --git a/logback-classic/src/test/input/gaffer/evaluatorWithMatcher.groovy b/logback-classic/src/test/input/gaffer/evaluatorWithMatcher.groovy
new file mode 100644
index 0000000..e73d6da
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/evaluatorWithMatcher.groovy
@@ -0,0 +1,37 @@
+//
+// Built on Wed May 19 20:51:44 CEST 2010 by logback-translator
+// For more information on configuration files in Groovy
+// please see http://logback.qos.ch/manual/groovy.html
+//
+
+import ch.qos.logback.classic.boolex.JaninoEventEvaluator
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder
+import ch.qos.logback.core.ConsoleAppender
+import ch.qos.logback.core.filter.EvaluatorFilter
+
+import static ch.qos.logback.classic.Level.DEBUG
+import static ch.qos.logback.core.spi.FilterReply.DENY
+import static ch.qos.logback.core.spi.FilterReply.NEUTRAL
+import ch.qos.logback.core.boolex.Matcher
+import ch.qos.logback.core.spi.LifeCycle
+
+appender("STDOUT", ConsoleAppender) {
+  filter(EvaluatorFilter) {
+    evaluator(JaninoEventEvaluator) {
+      Matcher aMatcher = new Matcher()
+      aMatcher.name = "odd"
+      aMatcher.regex = "statement [13579]"
+      if(aMatcher instanceof LifeCycle)
+        aMatcher.start();
+      aMatcher.start();
+      matcher = aMatcher
+      expression = "odd.matches(formattedMessage)"
+    }
+    OnMismatch = NEUTRAL
+    OnMatch = DENY
+  }
+  encoder(PatternLayoutEncoder) {
+    pattern = "%-4relative [%thread] %-5level %logger - %msg%n"
+  }
+}
+root(DEBUG, ["STDOUT"])
diff --git a/logback-classic/src/test/input/gaffer/propertyCascading0.groovy b/logback-classic/src/test/input/gaffer/propertyCascading0.groovy
new file mode 100644
index 0000000..761591a
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/propertyCascading0.groovy
@@ -0,0 +1,22 @@
+//
+// Built on Wed May 19 20:51:44 CEST 2010 by logback-translator
+// For more information on configuration files in Groovy
+// please see http://logback.qos.ch/manual/groovy.html
+//
+
+import ch.qos.logback.core.ConsoleAppender
+
+import static ch.qos.logback.classic.Level.DEBUG
+import ch.qos.logback.core.encoder.LayoutWrappingEncoder
+import ch.qos.logback.classic.PatternLayout
+
+
+def p = "HELLO"
+appender("STDOUT", ConsoleAppender) {
+  encoder(LayoutWrappingEncoder) {
+    layout(PatternLayout) {
+      pattern = "${p} %m%n"
+    }
+  }
+}
+root(DEBUG, ["STDOUT"])
diff --git a/logback-classic/src/test/input/gaffer/propertyCascading1.groovy b/logback-classic/src/test/input/gaffer/propertyCascading1.groovy
new file mode 100644
index 0000000..944ae3a
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/propertyCascading1.groovy
@@ -0,0 +1,24 @@
+//
+// Built on Wed May 19 20:51:44 CEST 2010 by logback-translator
+// For more information on configuration files in Groovy
+// please see http://logback.qos.ch/manual/groovy.html
+//
+
+import ch.qos.logback.core.ConsoleAppender
+
+import static ch.qos.logback.classic.Level.DEBUG
+
+import ch.qos.logback.core.encoder.LayoutWrappingEncoder
+import ch.qos.logback.classic.PatternLayout
+
+
+
+appender("STDOUT", ConsoleAppender) {
+  def p = "HELLO"
+  encoder(LayoutWrappingEncoder) {
+    layout(PatternLayout) {
+      pattern = "${p} %m%n"
+    }
+  }
+}
+root(DEBUG, ["STDOUT"])
diff --git a/logback-classic/src/test/input/gaffer/propertyCascading2.groovy b/logback-classic/src/test/input/gaffer/propertyCascading2.groovy
new file mode 100644
index 0000000..072ca88
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/propertyCascading2.groovy
@@ -0,0 +1,22 @@
+//
+// Built on Wed May 19 20:51:44 CEST 2010 by logback-translator
+// For more information on configuration files in Groovy
+// please see http://logback.qos.ch/manual/groovy.html
+//
+
+import ch.qos.logback.core.ConsoleAppender
+
+import static ch.qos.logback.classic.Level.DEBUG
+import ch.qos.logback.core.encoder.LayoutWrappingEncoder
+import ch.qos.logback.classic.PatternLayout
+
+
+
+appender("STDOUT", ConsoleAppender) {
+   encoder(LayoutWrappingEncoder) {
+    layout(PatternLayout) {
+      pattern = "${context.getProperty('p')} %m%n"
+    }
+  }
+}
+root(DEBUG, ["STDOUT"])
diff --git a/logback-classic/src/test/input/gaffer/sift/noDiscriminator.groovy b/logback-classic/src/test/input/gaffer/sift/noDiscriminator.groovy
new file mode 100644
index 0000000..5a40ba3
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/sift/noDiscriminator.groovy
@@ -0,0 +1,22 @@
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder
+
+import static ch.qos.logback.classic.Level.DEBUG
+import ch.qos.logback.classic.sift.GSiftingAppender
+import ch.qos.logback.classic.sift.MDCBasedDiscriminator
+import ch.qos.logback.core.FileAppender
+import ch.qos.logback.core.read.ListAppender
+
+
+appender("SIFT", GSiftingAppender) {
+  sift {
+    appender("FILE-${userid}", ListAppender) {
+      println "USERID=$userid"
+    }
+  }
+}
+
+root(DEBUG, ["SIFT"])
diff --git a/logback-classic/src/test/input/gaffer/sift/sample0.groovy b/logback-classic/src/test/input/gaffer/sift/sample0.groovy
new file mode 100644
index 0000000..34b4026
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/sift/sample0.groovy
@@ -0,0 +1,26 @@
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder
+
+import static ch.qos.logback.classic.Level.DEBUG
+import ch.qos.logback.classic.sift.GSiftingAppender
+import ch.qos.logback.classic.sift.MDCBasedDiscriminator
+import ch.qos.logback.core.FileAppender
+import ch.qos.logback.core.read.ListAppender
+
+
+appender("SIFT", GSiftingAppender) {
+  discriminator(MDCBasedDiscriminator) {
+    key = "userid"
+    defaultValue = "unknown"
+  }
+  sift {
+    appender("LIST-${userid}", ListAppender) {
+      println "USERID=$userid"
+    }
+  }
+}
+
+root(DEBUG, ["SIFT"])
diff --git a/logback-classic/src/test/input/gaffer/sift/sample1.groovy b/logback-classic/src/test/input/gaffer/sift/sample1.groovy
new file mode 100644
index 0000000..702d1c8
--- /dev/null
+++ b/logback-classic/src/test/input/gaffer/sift/sample1.groovy
@@ -0,0 +1,31 @@
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder
+
+import static ch.qos.logback.classic.Level.DEBUG
+import ch.qos.logback.classic.sift.GSiftingAppender
+import ch.qos.logback.classic.sift.MDCBasedDiscriminator
+import ch.qos.logback.core.FileAppender
+import ch.qos.logback.core.read.ListAppender
+
+
+appender("SIFT", GSiftingAppender) {
+  discriminator(MDCBasedDiscriminator) {
+    key = "userid"
+    defaultValue = "unknown"
+  }
+  sift {
+    appender("FILE-${userid}", FileAppender) {
+      file = "test-${userid}.log"
+      append = false
+      encoder(PatternLayoutEncoder) {
+        println "in encoder userid=${userid}"
+        pattern = "${userid} - %msg%n"
+      }
+    }
+  }
+}
+
+root(DEBUG, ["SIFT"])
diff --git a/logback-classic/src/test/input/gaffer/smoke.groovy b/logback-classic/src/test/input/gaffer/smoke.groovy
index 3f7a1c5..cb0fd92 100644
--- a/logback-classic/src/test/input/gaffer/smoke.groovy
+++ b/logback-classic/src/test/input/gaffer/smoke.groovy
@@ -5,18 +5,6 @@ import ch.qos.logback.classic.Level
 import ch.qos.logback.core.status.OnConsoleStatusListener
 import ch.qos.logback.classic.Logger
 
-
-context.name = "a"
-
-Logger xLogger = context.getLogger("x")
-xLogger.setLevel(Level.INFO)
-
-statusListener OnConsoleStatusListener
-
-println "hostname ${hostname}"
-
-addInfo("xxx")
-
 appender("C", ConsoleAppender) {
   encoder(LayoutWrappingEncoder) {
     layout(PatternLayout) {
@@ -24,5 +12,4 @@ appender("C", ConsoleAppender) {
     }
   }
 }
-
 root Level.WARN, ["C"]
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
index 2b036b0..7ca6684 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
@@ -57,7 +57,7 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
   
   protected Layout<E> layout;
   
-  private List<String> to = new ArrayList<String>();
+  private List<String> toList = new ArrayList<String>();
   private String from;
   private String subjectStr = null;
   private String smtpHost;
@@ -131,7 +131,7 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
         mimeMsg.setFrom();
       }
 
-      mimeMsg.setRecipients(Message.RecipientType.TO, parseAddress(to));
+      mimeMsg.setRecipients(Message.RecipientType.TO, parseAddress(toList));
 
       subjectLayout = makeSubjectLayout(subjectStr);
 
@@ -234,10 +234,10 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
   }
 
   /**
-   * Returns value of the <b>To</b> option.
+   * Returns value of the <b>toList</b> option.
    */
-  public List<String> getTo() {
-    return to;
+  public List<String> getToList() {
+    return toList;
   }
 
   /**
@@ -364,7 +364,7 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
    * of one of the recipients.
    */
   public void addTo(String to) {
-    this.to.add(to);
+    this.toList.add(to);
   }
 
   // for testing purpose only
@@ -395,7 +395,7 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
 
   /**
    * The <b>EventEvaluator</b> option takes a string value representing the name
-   * of the class implementing the {@link EventEvaluators} interface. A
+   * of the class implementing the {@link EventEvaluator} interface. A
    * corresponding object will be instantiated and assigned as the event
    * evaluator for the SMTPAppender.
    */
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java b/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java
index c87daf9..73b4d09 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java
@@ -28,7 +28,6 @@ public abstract class AppenderFactoryBase<E> {
   protected AppenderFactoryBase(List<SaxEvent> eventList) {
     this.eventList = new ArrayList<SaxEvent>(eventList);
     removeSiftElement();
-
   }
 
   void removeSiftElement() {
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
index 87a62b8..3e82fed 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
@@ -124,7 +124,7 @@ public abstract class SiftingAppenderBase<E> extends
   /**
    * @since 0.9.19
    */
-  public AppenderTracker getAppenderTracer() {
+  public AppenderTracker getAppenderTracker() {
     return appenderTracker;
   }
 
diff --git a/logback-site/src/site/pages/css/common.css b/logback-site/src/site/pages/css/common.css
index b3c76ad..bc6a4fa 100644
--- a/logback-site/src/site/pages/css/common.css
+++ b/logback-site/src/site/pages/css/common.css
@@ -14,6 +14,12 @@ a {
  text-decoration: underline;
 }
 
+.example {
+  width: 90%;
+  font-style: italic;
+}
+
+
 div.source {
  margin-top: 1em;
 }
diff --git a/logback-site/src/site/pages/css/screen.css b/logback-site/src/site/pages/css/screen.css
index 303ba61..d2cc84b 100644
--- a/logback-site/src/site/pages/css/screen.css
+++ b/logback-site/src/site/pages/css/screen.css
@@ -28,6 +28,7 @@ p.menu {
  padding-bottom: 0px; 
  margin-top: 0px;
  margin-bottom: 0px;
+ font-size: smaller;
 }
 
 
@@ -126,7 +127,7 @@ span.asGroovy {
    border-right:  2px solid #888;  
    border-bottom: 2px solid #888;    
    padding: 0px 1em 0px 1em;
-   margin:  -1ex 0px 0px 0px; 
+   margin:  -4px 4px 0 4px; 
    float: right;
 }
  
diff --git a/logback-site/src/site/pages/manual/appenders.html b/logback-site/src/site/pages/manual/appenders.html
index 5ad977a..232775b 100644
--- a/logback-site/src/site/pages/manual/appenders.html
+++ b/logback-site/src/site/pages/manual/appenders.html
@@ -335,7 +335,11 @@ public interface Appender&lt;E> extends LifeCycle, ContextAware, FilterAttachabl
 	<code>ConsoleAppender</code>.
 	</p>
 
-  <em>Example: ConsoleAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml)</em>
+
+
+  <p class="example">Example: ConsoleAppender configuration
+  (logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml)</p>
+
   <span class="asGroovy" onclick="return asGroovy('logback_Console');">View as .grovvy</span>
 
   <pre id="logback_Console" class="prettyprint source">&lt;configuration>
@@ -473,7 +477,9 @@ public interface Appender&lt;E> extends LifeCycle, ContextAware, FilterAttachabl
    <code>FileAppender</code>:
 	 </p>
 
-   <em>Example: FileAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml)</em>
+   <p class="example">Example: FileAppender configuration
+   (logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml)</p>
+
    <span class="asGroovy" onclick="return asGroovy('logback-fileAppender');">View as .grovvy</span>
    <pre id="logback-fileAppender"  class="prettyprint source">&lt;configuration>
 
@@ -497,7 +503,8 @@ public interface Appender&lt;E> extends LifeCycle, ContextAware, FilterAttachabl
    following command:
    </p>
 	
-   <p class="source">java chapters.appenders.ConfigurationTester src/main/java/chapters/appenders/conf/logback-fileAppender.xml</p>
+   <p class="source">java chapters.appenders.ConfigurationTester
+   src/main/java/chapters/appenders/conf/logback-fileAppender.xml</p>
 	
 	
    <h3>
@@ -512,8 +519,11 @@ public interface Appender&lt;E> extends LifeCycle, ContextAware, FilterAttachabl
    element. Here's an example.</p>
 
 
-   <em>Example: Uniquely named FileAppender configuration by timestamp (logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml)</em>
-  <span class="asGroovy" onclick="return asGroovy('logback-timestamp');">View as .grovvy</span>
+   <p class="example">Example: Uniquely named FileAppender
+   configuration by timestamp
+   (logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml)</p>
+
+   <span class="asGroovy" onclick="return asGroovy('logback-timestamp');">View as .grovvy</span>
    <pre id="logback-timestamp" class="prettyprint source">&lt;configuration>
 
   &lt;!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
@@ -853,8 +863,8 @@ public interface RollingPolicy extends LifeCycle {
    class="option">fileNamePattern</span> option.
    </p>
 	
-   <em>Example: Sample configuration of a <code>RollingFileAppender</code> using a 
-   <code>FixedWindowRollingPolicy</code> (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml)</em>
+   <p class="example">Example: Sample configuration of a <code>RollingFileAppender</code> using a 
+   <code>FixedWindowRollingPolicy</code> (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml)</p>
 
    <span class="asGroovy" onclick="return asGroovy('logback-RollingFixedWindow');">View as .grovvy</span>
    <pre id="logback-RollingFixedWindow" class="prettyprint source">&lt;configuration>
@@ -1165,11 +1175,10 @@ public interface RollingPolicy extends LifeCycle {
    <code>TimeBasedRollingPolicy</code>.
    </p>
 	
-   <em>Example: Sample configuration of a
+   <p class="example">Example: Sample configuration of a
    <code>RollingFileAppender</code> using a
-
    <code>TimeBasedRollingPolicy</code>
-   (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml)</em>
+   (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml)</p>
 
    <span class="asGroovy" onclick="return asGroovy('logback-RollingTimeBased');">View as .grovvy</span>
    <pre id="logback-RollingTimeBased" class="prettyprint source">&lt;configuration>
@@ -1199,10 +1208,10 @@ public interface RollingPolicy extends LifeCycle {
     mode.
     </p>
 
-   <em>Example: Sample configuration of a
+   <p class="example">Example: Sample configuration of a
    <code>RollingFileAppender</code> using a
    <code>TimeBasedRollingPolicy</code>
-   (logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml)</em>
+   (logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRolling.xml)</p>
 
   <span class="asGroovy" onclick="return asGroovy('logback-PrudentTimeBasedRolling');">View as .grovvy</span>
   <pre id="logback-PrudentTimeBasedRolling" class="prettyprint source">&lt;configuration>
@@ -1241,9 +1250,9 @@ public interface RollingPolicy extends LifeCycle {
     <p>Here is a sample configuration file demonstrating time and size
     based log file archiving.</p>
     
-  <em>Example: Sample configuration for
+  <p class="example">Example: Sample configuration for
   <code>SizeAndTimeBasedFNATP</code> 
-  (logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml)</em>
+  (logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml)</p>
 
   <span class="asGroovy" onclick="return asGroovy('logback-sizeAndTime');">View as .grovvy</span>
   <pre id="logback-sizeAndTime" class="prettyprint source">&lt;configuration>
@@ -1349,8 +1358,10 @@ public interface TriggeringPolicy&lt;E&gt; extends LifeCycle {
 		the log file reaches 5MB in size.
 		</p>
 
-    <em>Example: Sample configuration of a <code>RollingFileAppender</code> using a 
-    <code>SizeBasedTriggeringPolicy</code> (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml)</em>
+    <p class="example">Example: Sample configuration of a
+    <code>RollingFileAppender</code> using a
+    <code>SizeBasedTriggeringPolicy</code>
+    (logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml)</p>
 
     <span class="asGroovy" onclick="return asGroovy('logback-RollingSizeBased');">View as .grovvy</span>
     <pre id="logback-RollingSizeBased" class="prettyprint source">&lt;configuration>
@@ -1570,7 +1581,8 @@ public interface TriggeringPolicy&lt;E&gt; extends LifeCycle {
 			and attaches it to the root logger.
 		</p>
 
-		<em>Example: SocketAppender configuration (logback-examples/src/main/java/chapters/appenders/socket/client1.xml)</em>
+		<p class="example">Example: SocketAppender configuration
+		(logback-examples/src/main/java/chapters/appenders/socket/client1.xml)</p>
     <span class="asGroovy" onclick="return asGroovy('client1');">View as .grovvy</span>
 <pre id="client1" class="prettyprint source">&lt;configuration>
 	  
@@ -2030,9 +2042,11 @@ Context ctx = new InitialContext(env);</pre>
 			<code>JMSTopicAppender</code> is rather straightforward to configure:
 		</p>
 
-		<em>Example: JMSTopicAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSTopic.xml)</em>
+    <p class="example">Example: JMSTopicAppender configuration
+    (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSTopic.xml)</p>
+
     <span class="asGroovy" onclick="return asGroovy('logback-JMSTopic');">View as .grovvy</span>
-<pre id="logback-JMSTopic" class="prettyprint source">&lt;configuration>
+    <pre id="logback-JMSTopic" class="prettyprint source">&lt;configuration>
 
   &lt;appender name="Topic"
     class="ch.qos.logback.classic.net.JMSTopicAppender">
@@ -2099,7 +2113,10 @@ Context ctx = new InitialContext(env);</pre>
 			A typical <code>JMSQueueAppender</code> configuration file looks very
 			similar to that of a <code>JMSTopicAppender</code>.
 		</p>
-		<em>Example: JMSQueueAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSQueue.xml)</em>
+
+    <p class="example">Example: JMSQueueAppender configuration
+    (logback-examples/src/main/java/chapters/appenders/conf/logback-JMSQueue.xml)</p>
+    
     <span class="asGroovy" onclick="return asGroovy('logback-JMSQueue');">View as .grovvy</span>
     <pre id="logback-JMSQueue" class="prettyprint source">&lt;configuration>
 
@@ -2315,7 +2332,7 @@ Context ctx = new InitialContext(env);</pre>
 		<code>Email</code> application:
 		</p>	
 		
-    <em>Example: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/mail/mail1.xml)</em>	
+    <p class="example">Example: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/mail/mail1.xml)</p>	
     <span class="asGroovy" onclick="return asGroovy('mail1');">View as .grovvy</span>	
     <pre id="mail1" class="prettyprint source">&lt;configuration>	  
   &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
@@ -2431,8 +2448,8 @@ Context ctx = new InitialContext(env);</pre>
 		1024th event triggers an email message.
 		</p>
 
-    <em>Example: A <code>EventEvaluator</code> implementation
-that evaluates to <code>true</code> every 1024th event (<a href="../xref/chapters/appenders/mail/CounterBasedEvaluator.html">logback-examples/src/main/java/chapters/appenders/mail/CounterBasedEvaluator.java</a>)</em>
+    <p class="example">Example: A <code>EventEvaluator</code> implementation
+that evaluates to <code>true</code> every 1024th event (<a href="../xref/chapters/appenders/mail/CounterBasedEvaluator.html">logback-examples/src/main/java/chapters/appenders/mail/CounterBasedEvaluator.java</a>)</p>
    
    <pre class="prettyprint source">package chapters.appenders.mail;
 
@@ -2483,8 +2500,8 @@ public class CounterBasedEvaluator extends ContextAwareBase implements EventEval
 		evaluator.
 		</p>
 
-    <em>Example: <code>SMTPAppender</code> with custom 
-    <code>Evaluator</code> and buffer size (logback-examples/src/main/java/chapters/appenders/mail/mail3.xml)</em>
+    <p class="example">Example: <code>SMTPAppender</code> with custom 
+    <code>Evaluator</code> and buffer size (logback-examples/src/main/java/chapters/appenders/mail/mail3.xml)</p>
     <span class="asGroovy" onclick="return asGroovy('mail3');">View as .grovvy</span>	
     <pre id="mail3" class="prettyprint source">&lt;configuration>
   &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
@@ -2532,8 +2549,8 @@ logger.error(<b>notifyAdminMarker</b>,
    TRANSACTION_FAILURE marker.
    </p>
 
-   <em>Example: <code>SMTPAppender</code> with 
-   <code>OnMarkerEvaluator</code> (logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker.xml)</em>
+   <p class="example">Example: <code>SMTPAppender</code> with 
+   <code>OnMarkerEvaluator</code> (logback-examples/src/main/java/chapters/appenders/mail/mailWithMarker.xml)</p>
 
    <span class="asGroovy" onclick="return asGroovy('mailWithMarker');">View as .grovvy</span>	
    <pre id="mailWithMarker" class="prettyprint source">&lt;configuration>
@@ -2581,7 +2598,9 @@ logger.error(<b>notifyAdminMarker</b>,
     <p>The next example shows you how to configure
     <code>SMTPAppender</code> for Gmail with the SSL protocol. </p>
     
-    <em><code>SMTPAppender</code> to Gmail using SSL (logback-examples/src/main/java/chapters/appenders/mail/gmailSSL.xml)</em>
+    <p class="example">Example:: <code>SMTPAppender</code> to Gmail
+    using SSL
+    (logback-examples/src/main/java/chapters/appenders/mail/gmailSSL.xml)</p>
 
     <span class="asGroovy" onclick="return asGroovy('gmailSSL');">View as .grovvy</span>	
     <pre id="gmailSSL" class="prettyprint source">&lt;configuration>
@@ -2613,7 +2632,7 @@ logger.error(<b>notifyAdminMarker</b>,
     <p>The next example shows you how to configure
     <code>SMTPAppender</code> for Gmail for the STARTTLS protocol. </p>
 
-    <em>Example: <code>SMTPAppender</code> to GMAIL using STARTTLS (logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml)</em>
+    <p class="example">Example: <code>SMTPAppender</code> to GMAIL using STARTTLS (logback-examples/src/main/java/chapters/appenders/mail/gmailSTARTTLS.xml)</p>
 
     <span class="asGroovy" onclick="return asGroovy('gmailSTARTTLS');">View as .grovvy</span>	
     <pre id="gmailSTARTTLS" class="prettyprint source">&lt;configuration>	  
@@ -2933,7 +2952,7 @@ logger.error(<b>notifyAdminMarker</b>,
 			The following configuration file is what one would need.
 		</p>
 		
-    <em>Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driverManager.xml)</em>
+    <p class="example">Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-driverManager.xml)</p>
     <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-driverManager');">View as .grovvy</span>	
     <pre id="append-toMySQL-with-driverManager" class="prettyprint source">&lt;configuration>
 
@@ -3012,7 +3031,7 @@ logger.error(<b>notifyAdminMarker</b>,
 			<code>javax.sql.DataSource</code>.
 		</p>
 	
-    <em>Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml)</em>	
+    <p class="example">Example: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/db/append-with-datasource.xml)</p>	
 
 
     <span class="asGroovy" onclick="return asGroovy('append-with-datasource');">View as .grovvy</span>	
@@ -3128,9 +3147,10 @@ logger.error(<b>notifyAdminMarker</b>,
 			without any pooling.
 		</p>
     
-    <em>Example 4.<span class="autoEx"/> <code>DBAppender</code>
-    configuration without pooling
-    (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml)</em>
+    <p class="example">Example: <code>DBAppender</code> configuration
+    without pooling
+    (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource.xml)</p>
+
     <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource');">View as .grovvy</span>	
     <pre id="append-toMySQL-with-datasource" class="prettyprint source">&lt;configuration>
 
@@ -3164,7 +3184,9 @@ logger.error(<b>notifyAdminMarker</b>,
 		<em>c3p0-VERSION.jar</em> in the classpath.
 		</p>
 
-    <em>Example: <code>DBAppender</code> configuration with pooling (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml)</em>			
+    <p class="example">Example: <code>DBAppender</code> configuration
+    with pooling
+    (logback-examples/src/main/java/chapters/appenders/db/append-toMySQL-with-datasource-and-pooling.xml)</p>
     <span class="asGroovy" onclick="return asGroovy('append-toMySQL-with-datasource-and-pooling');">View as .grovvy</span>	
     <pre id="append-toMySQL-with-datasource-and-pooling" class="prettyprint source">&lt;configuration>
 
@@ -3300,7 +3322,7 @@ logger.error(<b>notifyAdminMarker</b>,
 			Here is a sample configuration using a <code>SyslogAppender</code>.
 		</p>
 		
-    <em>Example: <code>SyslogAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml)</em>	
+    <p class="example">Example: <code>SyslogAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/logback-syslog.xml)</p>	
     <span class="asGroovy" onclick="return asGroovy('logback-syslog');">View as .grovvy</span>	
     <pre id="logback-syslog" class="prettyprint source">&lt;configuration>
 
@@ -3357,11 +3379,13 @@ logger.debug("Alice says hello"); </p>
     <code>SiftingAppender</code>.</p>
 
 
-    <em>Example: <code>SiftingAppender</code>
+    <p class="example">Example: <code>SiftingAppender</code>
     configuration
-    (logback-examples/src/main/java/chapters/appenders/sift/byUserid.xml)</em>
+    (logback-examples/src/main/java/chapters/appenders/sift/byUserid.xml)</p>
 
-    <pre class="prettyprint source">&lt;configuration>
+    <span class="asGroovy" onclick="return asGroovy('byUserid');">View as .grovvy</span>
+
+    <pre id="byUserid" class="prettyprint source">&lt;configuration>
 
   <b>&lt;appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender"></b>
     &lt;!-- in the absence of the class attribute, it is assumed that the
@@ -3567,7 +3591,10 @@ public class CountingConsoleAppender extends AppenderBase&lt;ILoggingEvent> {
 		<p>
 			Here is a sample configuration of a <code>SMTPAppender</code> in the access environment.
 		</p>
-<em>Example: <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-smtp.xml)</em>					
+    <p class="example">Example: <code>SMTPAppender</code>
+    configuration
+    (logback-examples/src/main/java/chapters/appenders/conf/access/logback-smtp.xml)</p>
+
 <pre class="prettyprint source">&lt;appender name="SMTP"
   class="ch.qos.logback.access.net.SMTPAppender">
   &lt;layout class="ch.qos.logback.access.html.HTMLLayout">
@@ -3737,7 +3764,7 @@ public class CountingConsoleAppender extends AppenderBase&lt;ILoggingEvent> {
 			Here is a sample configuration that uses <code>DBAppender</code>.
 		</p>
 
-    <em>Example: DBAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml)</em>		
+    <p class="example">Example: DBAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/access/logback-DB.xml)</em>		
     <pre class="prettyprint source">&lt;configuration>
 
   &lt;appender name="DB" class="ch.qos.logback.access.db.DBAppender">
@@ -3776,7 +3803,7 @@ public class CountingConsoleAppender extends AppenderBase&lt;ILoggingEvent> {
     
     <p>Below is an example configuration file.</p>
 
-    <em>Example: SiftingAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/sift/access-siftingFile.xml)</em>		
+    <p class="example">Example: SiftingAppender configuration (logback-examples/src/main/java/chapters/appenders/conf/sift/access-siftingFile.xml)</em>		
     
     <pre class="prettyprint source">&lt;configuration>
   &lt;appender name="SIFTING" class="ch.qos.logback.access.sift.SiftingAppender">
diff --git a/logback-site/src/site/pages/manual/configuration.html b/logback-site/src/site/pages/manual/configuration.html
index d73e024..ccf5099 100644
--- a/logback-site/src/site/pages/manual/configuration.html
+++ b/logback-site/src/site/pages/manual/configuration.html
@@ -17,7 +17,7 @@
     <script type="text/javascript">prefix='../'</script>
     <script type="text/javascript" src="../js/prettify.js"></script>
     <script src="../templates/header.js" type="text/javascript"></script>
-     <script type="text/javascript" src="../js/dsl.js"></script>
+    <script type="text/javascript" src="../js/dsl.js"></script>
     <div id="left">
       <noscript>Please turn on Javascript to view this menu</noscript>
       <script src="../templates/left.js" type="text/javascript"></script>
@@ -130,9 +130,9 @@
     <code>MyApp1</code>.
     </p>
 
-    <em>Example: Simple example of <code>BasicConfigurator</code>
-    usage <a
-    href="../xref/chapters/configuration/MyApp1.html">(logback-examples/src/main/java/chapters/configuration/MyApp1.java)</a></em>
+    <p class="example">Example: Simple example of
+    <code>BasicConfigurator</code> usage <a
+    href="../xref/chapters/configuration/MyApp1.html">(logback-examples/src/main/java/chapters/configuration/MyApp1.java)</a></p>
 
     <pre class="prettyprint source">package manual.configuration;
 
@@ -155,9 +155,9 @@ public class MyApp1 {
   instantiates a Foo object. The Foo class is listed below:
   </p>
 
-  <em>Example: Small class doing logging 
+  <p class="example">Example: Small class doing logging 
   <a href="../xref/chapters/configuration/Foo.html">(logback-examples/src/main/java/chapters/configuration/Foo.java)</a>
-  </em>
+  </p>
 
   <pre class="prettyprint source">package chapters.configuration;
   
@@ -232,9 +232,9 @@ public class Foo {
    seen.
    </p>
 
-  <em>Example: Basic configuration file
-  (logback-examples/src/main/java/chapters/configuration/sample0.xml)</em>
-  <span class="asGroovy" onclick="return asGroovy('sample0');">View as .grovvy</span>
+   <p class="example">Example: Basic configuration file
+   (logback-examples/src/main/java/chapters/configuration/sample0.xml)</p>
+   <span class="asGroovy" onclick="return asGroovy('sample0');">View as .grovvy</span>
 
 
   <pre id="sample0" class="prettyprint source">&lt;configuration>
@@ -278,9 +278,9 @@ public class Foo {
    addition of two lines of code for printing internal status
    data.</p>
 
-    <em>Example: Print logback's internal status information
-    <a
-    href="../xref/chapters/configuration/MyApp2.html">(logback-examples/src/main/java/chapters/configuration/MyApp2.java)</a></em>
+    <p class="example">Example: Print logback's internal status
+    information <a
+    href="../xref/chapters/configuration/MyApp2.html">(logback-examples/src/main/java/chapters/configuration/MyApp2.java)</a></p>
 
   
 <pre class="prettyprint lang-java source">
@@ -327,9 +327,9 @@ public class Foo {
    </p>
 
 
-   <em>Example: Basic configuration file
-   using debug mode
-   (logback-examples/src/main/java/chapters/configuration/sample1.xml)</em>
+   <p class="example">Example: Basic configuration file using debug
+   mode
+   (logback-examples/src/main/java/chapters/configuration/sample1.xml)</p>
    <span class="asGroovy" onclick="return asGroovy('sample1');">View as .grovvy</span>
 
    <pre id="sample1" class="prettyprint source">
@@ -402,9 +402,10 @@ public class Foo {
    <code>&lt;configuration></code> element to true, as shown next.
 
    </p>
-  <em>Example: Scanning for changes in
-  configuration file and automatic re-configuraion
-  (logback-examples/src/main/java/chapters/configuration/scan1.xml)</em>
+  
+   <p class="example">Example: Scanning for changes in configuration
+   file and automatic re-configuraion
+   (logback-examples/src/main/java/chapters/configuration/scan1.xml)</p>
 
   <span class="asGroovy" onclick="return asGroovy('scan1');">View as .grovvy</span>
 <pre id="scan1" class="prettyprint source">
@@ -420,9 +421,8 @@ public class Foo {
    units of milliseconds, seconds, minutes or hours. Here is an
    example:</p>
 
-  <em>Example: Specifying a different
-  scanning period
-  (logback-examples/src/main/java/chapters/configuration/scan2.xml)</em>
+  <p class="example">Example: Specifying a different scanning period
+  (logback-examples/src/main/java/chapters/configuration/scan2.xml)</p>
   <span class="asGroovy" onclick="return asGroovy('scan2');">View as .grovvy</span>
   <pre id="scan2" class="prettyprint source">
 &lt;configuration scan="true" <b>scanPeriod="30 seconds"</b> > 
@@ -472,9 +472,9 @@ public class Foo {
    application, <em>MyApp3</em>, invokes JoranConfigurator on a
    configuration file passed as a parameter.</p>
    
-   <p><em>Example: Invoking
-   <code>JoranConfigurator</code> directly <a
-   href="../xref/chapters/configuration/MyApp3.html">(logback-examples/src/main/java/chapters/configuration/MyApp3.java)</a></em></p>
+   <p class="example">Example: Invoking <code>JoranConfigurator</code>
+   directly <a
+   href="../xref/chapters/configuration/MyApp3.html">(logback-examples/src/main/java/chapters/configuration/MyApp3.java)</a></p>
 
 <pre class="prettyprint source">package chapters.configuration;
 
@@ -609,8 +609,8 @@ public class MyApp3 {
    <p>It is also possible to register one or more status listeners
    within a configuration file. Here is an example.</p>
 
-   <p><em>Example: Registering a status listener
-   (logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml)</em></p>
+   <p class="example">Example: Registering a status listener
+   (logback-examples/src/main/java/chapters/configuration/onConsoleStatusListener.xml)</p>
 
    <span class="asGroovy" onclick="return asGroovy('onConsoleStatusListener');">View as .grovvy</span>
    <pre id="onConsoleStatusListener" class="prettyprint source">&lt;configuration>
@@ -767,8 +767,8 @@ public class MyApp3 {
    shows how to achieve that.
    </p>
 
-   <em>Example: Setting the level of a logger
-   (logback-examples/src/main/java/chapters/configuration/sample2.xml)</em>
+   <p class="example">Example: Setting the level of a logger
+   (logback-examples/src/main/java/chapters/configuration/sample2.xml)</p>
 
    <span class="asGroovy" onclick="return asGroovy('sample2');">View as .grovvy</span>
    <pre id="sample2" class="prettyprint source">&lt;configuration>
@@ -808,8 +808,8 @@ public class MyApp3 {
   of the <em>chapters.configuration.Foo</em> logger to <code>DEBUG</code>.
   </p>
 
-  <em>Example: Setting the level of multiple loggers
-  (logback-examples/src/main/java/chapters/configuration/sample3.xml)</em>
+  <p class="example">Example: Setting the level of multiple loggers
+  (logback-examples/src/main/java/chapters/configuration/sample3.xml)</p>
   
   <span class="asGroovy" onclick="return asGroovy('sample3');">View as .grovvy</span>
   <pre id="sample3" class="source prettyprint">&lt;configuration>
@@ -890,8 +890,8 @@ public class MyApp3 {
   <em>sample4.xml</em> is a case in point:
   </p>
 
-  <em>Example: Logger level sample
-  (logback-examples/src/main/java/chapters/configuration/sample4.xml)</em>
+  <p class="example">Example: Logger level sample
+  (logback-examples/src/main/java/chapters/configuration/sample4.xml)</p>
   <span class="asGroovy" onclick="return asGroovy('sample4');">View as .grovvy</span>
   <pre id="sample4" class="prettyprint source">&lt;configuration>
 
@@ -1015,8 +1015,9 @@ public class MyApp3 {
   configuration file illustrates:
   </p>
 
-  <em>Example: Multiple loggers
-  (logback-examples/src/main/java/chapters/configuration/multiple.xml)</em>
+  <p class="example">Example: Multiple loggers
+  (logback-examples/src/main/java/chapters/configuration/multiple.xml)</p>
+
   <span class="asGroovy" onclick="return asGroovy('multiple');">View as .grovvy</span>
   <pre id="multiple" class="prettyprint source">&lt;configuration>
 
@@ -1069,8 +1070,8 @@ public class MyApp3 {
   duplicated.
   </p>
 
-  <em>Example: Duplicate appender
-  (logback-examples/src/main/java/chapters/configuration/duplicate.xml)</em>
+  <p class="example">Example: Duplicate appender
+  (logback-examples/src/main/java/chapters/configuration/duplicate.xml)</p>
 
   <span class="asGroovy" onclick="return asGroovy('duplicate');">View as .grovvy</span>
   <pre id="duplicate" class="prettyprint source">&lt;configuration>
@@ -1117,8 +1118,8 @@ public class MyApp3 {
   set of loggers flow into a specific appender.
   </p>
 
-  <em>Example: Multiple appender
-  (logback-examples/src/main/java/chapters/configuration/restricted.xml)</em>
+  <p class="example">Example: Multiple appender
+  (logback-examples/src/main/java/chapters/configuration/restricted.xml)</p>
   <span class="asGroovy" onclick="return asGroovy('restricted');">View as .grovvy</span>
   <pre id="restricted" class="prettyprint source">&lt;configuration>
 
@@ -1163,8 +1164,8 @@ public class MyApp3 {
   of the tree.
   </p>
 
-  <em>Example: Additivity flag
-  (logback-examples/src/main/java/chapters/configuration/additivityFlag.xml)</em>
+  <p class="example">Example: Additivity flag
+  (logback-examples/src/main/java/chapters/configuration/additivityFlag.xml)</p>
 
   <span class="asGroovy" onclick="return asGroovy('additivityFlag');">View as .grovvy</span>
   <pre id="additivityFlag" class="prettyprint source">&lt;configuration>
@@ -1219,8 +1220,8 @@ public class MyApp3 {
   applications logging to the same target.
   </p>
   
-  <em>Example: Set the context name and display it
-  (logback-examples/src/main/java/chapters/configuration/contextName.xml)</em>
+  <p class="example">Example: Set the context name and display it
+  (logback-examples/src/main/java/chapters/configuration/contextName.xml)</p>
 
   <span class="asGroovy" onclick="return asGroovy('contextName');">View as .grovvy</span>
   <pre id="contextName" class="prettyprint source">&lt;configuration>
@@ -1274,11 +1275,12 @@ public class MyApp3 {
   output file.
   </p>
 
-  <em>Example: Simple Variable substitution
+  <p class="example">Example: Simple Variable substitution
   (logback-examples/src/main/java/chapters/configuration/variableSubstitution1.xml)
-  </em>
+  </p>
 
-  <span class="asGroovy" onclick="return asGroovy('variableSubstitution1');">View as .grovvy</span>
+  <span class="asGroovy" onclick="return
+  asGroovy('variableSubstitution1');">View as .grovvy</span>
   <pre id="variableSubstitution1" class="prettyprint source">&lt;configuration>
 
   <b>&lt;property name="USER_HOME" value="/home/sebastien" /></b>
@@ -1304,9 +1306,9 @@ public class MyApp3 {
   
   <p class="source">java -DUSER_HOME="/home/sebastien" MyApp2</p>
 
-  <em>Example: System Variable substitution
+  <p class="example">Example: System Variable substitution
   (logback-examples/src/main/java/chapters/configuration/variableSubstitution2.xml)
-  </em>
+  </p>
   <span class="asGroovy" onclick="return asGroovy('variableSubstitution2');">View as .grovvy</span>
   <pre id="variableSubstitution2" class="prettyprint source">&lt;configuration>
 
@@ -1328,10 +1330,10 @@ public class MyApp3 {
   how one can do such a setup.
   </p>
 
-  <em>Example: Variable substitution using a
+  <p class="example">Example: Variable substitution using a
   separate file
   (logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml)
-  </em>
+  </p>
 
   <pre class="prettyprint source">&lt;configuration>
 
@@ -1390,8 +1392,8 @@ public class MyApp3 {
    properties file shown below gives an example.
    </p>
 
-   <em>Example: Nested variable references
-   (logback-examples/src/main/java/chapters/configuration/variables2.properties)</em>
+   <p class="example">Example: Nested variable references
+   (logback-examples/src/main/java/chapters/configuration/variables2.properties)</p>
 
    <pre class="source">USER_HOME=/home/sebastien
 fileName=myApp.log
@@ -1590,8 +1592,10 @@ fileName=myApp.log
    class="attr">as</span> attribute.
    </p>
 
-   <em>Example: Insert as properties env-entries obtained via JNDI
-  (logback-examples/src/main/java/chapters/configuration/insertFromJNDI.xml)</em>
+   <p class="example">Example: Insert as properties env-entries
+   obtained via JNDI
+   (logback-examples/src/main/java/chapters/configuration/insertFromJNDI.xml)</p>
+
    <pre class="prettyprint source">&lt;configuration>
   <b>&lt;insertFromJNDI env-entry-name="java:comp/env/appName" as="<span class="green">appName"</span> /></b>
   <b>&lt;contextName><span class="green">${appName}</span>&lt;/contextName></b>
@@ -1623,8 +1627,8 @@ fileName=myApp.log
   element, as shown below:
   </p>
 
-  <em>Example: File include
-  (logback-examples/src/main/java/chapters/configuration/containingConfig.xml)</em>
+  <p class="example">Example: File include
+  (logback-examples/src/main/java/chapters/configuration/containingConfig.xml)</p>
 
   <pre class="prettyprint source">&lt;configuration>
   <b>&lt;include file="src/main/java/chapters/configuration/includedConfig.xml"/></b>
@@ -1640,8 +1644,8 @@ fileName=myApp.log
   <code>ConsoleAppender</code> could be declared as:
   </p>
 
-  <em>Example: File include
-  (logback-examples/src/main/java/chapters/configuration/includedConfig.xml)</em>
+  <p class="example">Example: File include
+  (logback-examples/src/main/java/chapters/configuration/includedConfig.xml)</p>
 
   <pre class="source"><b class="green big">&lt;included></b>
   &lt;appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
diff --git a/logback-site/src/site/pages/manual/groovy.html b/logback-site/src/site/pages/manual/groovy.html
new file mode 100644
index 0000000..78d89b8
--- /dev/null
+++ b/logback-site/src/site/pages/manual/groovy.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
+    <title>Chapter3: Logback configuration</title>
+    
+    <link rel="stylesheet" type="text/css" href="../css/common.css" />
+    <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen" />
+    <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print" />
+    <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen" />
+
+  </head>
+  <body onload="prettyPrint()">
+
+    <script type="text/javascript">prefix='../'</script>
+    <script type="text/javascript" src="../js/prettify.js"></script>
+    <script src="../templates/header.js" type="text/javascript"></script>
+    <script type="text/javascript" src="../js/dsl.js"></script>
+    <div id="left">
+      <noscript>Please turn on Javascript to view this menu</noscript>
+      <script src="../templates/left.js" type="text/javascript"></script>
+    </div>
+    <div id="right">
+      <script src="menu.js" type="text/javascript"></script>
+    </div>
+    <div id="content" class="chapter">
+      
+      <h1>Chapter 12: Groovy Configuration</h1>
+      
+      <div class="quote">
+      <p><em>It is better to be a human being dissatisfied than a pig
+      satisfied; better to be a Socrates dissatisfied than a fool
+      satisfied. And if the fool or the pig thinks otherwise, it is
+      because they have no experience of the better part.
+      </em>
+      </p>
+      <p>&mdash;JOHN STUART MILL, <em>Utilitarianism</em></p>
+    </div>
+    <script src="../templates/creative.js" type="text/javascript"></script>
+
+
+    <p>Domains-specific languages are rather pervasive. The XML-based
+    logback configuration can be be viewed as an example of a DSL. By
+    the very nature of XML, XML-based configuration files are quite
+    verbose and bulky. Moreover, a relatively large body of code in
+    logback, namely Joran, is dedicated to processes these XML-based
+    configuration files. Joran supports nifty features such as
+    variable subsitution, conditional processing and on-the-fly
+    extensibility. Not only Joran is a complex beast, the
+    user-experience it provides can be described as unsatisfactory or
+    at the very least unintuitive.
+    </p>
+
+    <p>The Groovy-based DSL described in this chapter aims to be
+    consistent, intuitive, and powerful. Everything you can do XML in
+    configuration files, you can do in Groovy in a much shorter
+    syntax. There is even a tool to automatically migrate XML
+
+
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/logback-site/src/site/pages/manual/index.html b/logback-site/src/site/pages/manual/index.html
index 8b832d0..5d0599a 100644
--- a/logback-site/src/site/pages/manual/index.html
+++ b/logback-site/src/site/pages/manual/index.html
@@ -114,8 +114,11 @@
           <a href="onJoran.html"><b>Chapter 11: Joran</b></a>
         </p></li>
 
+        <li><p><a href="groovy.html"><b>Chapter 12: Groovy
+        Configuration</b></a></p></li>
+
         <li><p>
-          <a href="migrationFromLog4j.html"><b>Chapter 12: Migration from log4j</b></a>
+          <a href="migrationFromLog4j.html"><b>Chapter 13: Migration from log4j</b></a>
         </p></li>
 
       </ul>
diff --git a/logback-site/src/site/pages/manual/menu.js b/logback-site/src/site/pages/manual/menu.js
index d7679cb..cf0f7f8 100644
--- a/logback-site/src/site/pages/manual/menu.js
+++ b/logback-site/src/site/pages/manual/menu.js
@@ -11,4 +11,5 @@ document.write('<p class="menu"><a href="mdc.html"><b>Ch8: Mapped Diagnostic Con
 document.write('<p class="menu"><a href="loggingSeparation.html"><b>Ch9: Logging Separation</b></a>');
 document.write('<p class="menu"><a href="jmxConfig.html"><b>Ch10: JMX Configurator</b></a>');
 document.write('<p class="menu"><a href="onJoran.html"><b>Ch11: Joran</b></a>');
-document.write('<p class="menu"><a href="migrationFromLog4j.html"><b>Ch12: Migration from log4j</b></a>');
+document.write('<p class="menu"><a href="groovy.html"><b>Ch12: Groovy Configuration</b></a>');
+document.write('<p class="menu"><a href="migrationFromLog4j.html"><b>Ch13: Migration from log4j</b></a>');
diff --git a/logback-site/src/site/pages/manual/migrationFromLog4j.html b/logback-site/src/site/pages/manual/migrationFromLog4j.html
index d34f043..dfc948d 100644
--- a/logback-site/src/site/pages/manual/migrationFromLog4j.html
+++ b/logback-site/src/site/pages/manual/migrationFromLog4j.html
@@ -23,7 +23,7 @@
     </div>
     <div id="content">
       
-    <h1>Chapter 12: Migration from log4j</h1> 
+    <h1>Chapter 13: Migration from log4j</h1> 
 
     <div class="quote">
       <p><em>The more things change, the more they remain the

-----------------------------------------------------------------------

Summary of changes:
 .../qos/logback/access/sift/SiftingAppender.java   |    4 -
 logback-classic/osgi-build.xml                     |    2 +-
 logback-classic/pom.xml                            |    2 +-
 logback-classic/src/IBUNDLE-META-INF/MANIFEST.MF   |    2 +-
 .../classic/gaffer/ComponentDelegate.groovy        |  112 ++++++++-------
 ...gate.groovy => ConfigurationContributor.groovy} |   21 ++--
 .../classic/gaffer/ConfigurationDelegate.groovy    |   11 ++
 .../qos/logback/classic/gaffer/NestedType.groovy   |   11 +-
 .../qos/logback/classic/gaffer/PropertyUtil.groovy |   72 +++++++++
 .../logback/classic/sift/GSiftingAppender.groovy   |  153 ++++++++++++++++++++
 .../logback/classic/sift/ZSiftingDelegate.groovy   |   39 +++++
 .../qos/logback/classic/sift/SiftingAppender.java  |    4 -
 .../gaffer/ConfigurationDelegateTest.groovy        |   23 +++
 .../logback/classic/gaffer/ConfiguratorTest.groovy |   56 +++++++
 .../logback/classic/gaffer/PropertyUtilTest.groovy |   26 ++++
 .../classic/sift/GSiftingAppenderTest.groovy       |  110 ++++++++++++++
 .../test/input/gaffer/evaluatorWithMatcher.groovy  |   37 +++++
 .../test/input/gaffer/propertyCascading0.groovy    |   22 +++
 .../test/input/gaffer/propertyCascading1.groovy    |   24 +++
 .../test/input/gaffer/propertyCascading2.groovy    |   22 +++
 .../test/input/gaffer/sift/noDiscriminator.groovy  |   22 +++
 .../src/test/input/gaffer/sift/sample0.groovy      |   26 ++++
 .../src/test/input/gaffer/sift/sample1.groovy      |   31 ++++
 logback-classic/src/test/input/gaffer/smoke.groovy |   13 --
 .../ch/qos/logback/core/net/SMTPAppenderBase.java  |   14 +-
 .../qos/logback/core/sift/AppenderFactoryBase.java |    1 -
 .../qos/logback/core/sift/SiftingAppenderBase.java |    2 +-
 logback-site/src/site/pages/css/common.css         |    6 +
 logback-site/src/site/pages/css/screen.css         |    3 +-
 logback-site/src/site/pages/manual/appenders.html  |  111 +++++++++------
 .../src/site/pages/manual/configuration.html       |  118 ++++++++--------
 logback-site/src/site/pages/manual/groovy.html     |   65 +++++++++
 logback-site/src/site/pages/manual/index.html      |    5 +-
 logback-site/src/site/pages/manual/menu.js         |    3 +-
 .../src/site/pages/manual/migrationFromLog4j.html  |    2 +-
 35 files changed, 972 insertions(+), 203 deletions(-)
 copy logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/{AppenderDelegate.groovy => ConfigurationContributor.groovy} (60%)
 copy logback-core/src/main/java/ch/qos/logback/core/db/dialect/SQLDialect.java => logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/NestedType.groovy (73%)
 create mode 100644 logback-classic/src/main/groovy/ch/qos/logback/classic/gaffer/PropertyUtil.groovy
 create mode 100644 logback-classic/src/main/groovy/ch/qos/logback/classic/sift/GSiftingAppender.groovy
 create mode 100644 logback-classic/src/main/groovy/ch/qos/logback/classic/sift/ZSiftingDelegate.groovy
 create mode 100644 logback-classic/src/test/groovy/ch/qos/logback/classic/gaffer/PropertyUtilTest.groovy
 create mode 100644 logback-classic/src/test/groovy/ch/qos/logback/classic/sift/GSiftingAppenderTest.groovy
 create mode 100644 logback-classic/src/test/input/gaffer/evaluatorWithMatcher.groovy
 create mode 100644 logback-classic/src/test/input/gaffer/propertyCascading0.groovy
 create mode 100644 logback-classic/src/test/input/gaffer/propertyCascading1.groovy
 create mode 100644 logback-classic/src/test/input/gaffer/propertyCascading2.groovy
 create mode 100644 logback-classic/src/test/input/gaffer/sift/noDiscriminator.groovy
 create mode 100644 logback-classic/src/test/input/gaffer/sift/sample0.groovy
 create mode 100644 logback-classic/src/test/input/gaffer/sift/sample1.groovy
 create mode 100644 logback-site/src/site/pages/manual/groovy.html


hooks/post-receive
-- 
Logback: the generic, reliable, fast and flexible logging framework.


More information about the logback-dev mailing list