From a4edbee4f05e587eeb9653aabad4e531c46ff3df Mon Sep 17 00:00:00 2001
From: Dawid Weiss <dawid.weiss@carrot-search.com>
Date: Thu, 12 Aug 2010 23:53:35 +0200
Subject: [PATCH] http://issues.carrot2.org/browse/CARROT-609

Working bindable metadata generator using APT (annotation preprocessor). Works with javac and Eclipse.
---
 .gitignore                                         |   82 ---
 applications/carrot2-webapp/build.xml              |    4 +-
 build-bamboo.xml                                   |    1 -
 build.xml                                          |  131 ++---
 .../clustering/lingo/LingoClusteringAlgorithm.java |    8 +-
 .../clustering/stc/STCClusteringAlgorithm.java     |    8 +-
 .../synthetic/ByFieldClusteringAlgorithm.java      |    6 +-
 .../synthetic/ByUrlClusteringAlgorithm.java        |    6 +-
 .../org/carrot2/core/attribute/AttributeNames.java |   19 +-
 .../src/org/carrot2/source/SearchEngineBase.java   |   12 +-
 .../source/ambient/AmbientDocumentSource.java      |    6 +-
 .../carrot2/source/ambient/FubDocumentSource.java  |    6 +-
 .../source/ambient/Odp239DocumentSource.java       |    6 +-
 .../source/lucene/LuceneDocumentSource.java        |   13 +-
 .../source/microsoft/BingDocumentSource.java       |    2 +-
 .../org/carrot2/source/xml/XmlDocumentSource.java  |   10 +-
 .../.apt_factory/org.carrot2.bindables.jar         |  Bin 0 -> 19353 bytes
 core/carrot2-util-attribute/.classpath             |    5 +
 core/carrot2-util-attribute/.factorypath           |    3 +
 .../.settings/org.eclipse.jdt.apt.core.prefs       |    5 +
 .../.settings/org.eclipse.jdt.core.prefs           |   15 +-
 core/carrot2-util-attribute/META-INF/MANIFEST.MF   |    1 +
 .../etc/eclipse/Attribute Metadata XML.launch      |   19 -
 .../etc/eclipse/attribute-metadata-xml.xml         |    5 -
 .../util/attribute/AttributeBinderTest.java        |    2 +-
 .../attribute/BindableDescriptorBuilderTest.java   |   14 +-
 .../attribute/BindableMetadataBuilderTest.java     |  199 ++----
 .../carrot2/util/attribute/NamedAttributes.java    |   15 +-
 .../test/assertions/AttributeAssertions.java       |    2 +
 .../assertions/AttributeMetadataAssertion.java     |    2 +-
 .../assertions/BindableDescriptorAssertion.java    |    1 +
 .../test/assertions/CommonMetadataAssertion.java   |    2 +-
 .../test/metadata/TestAttributeNames.java          |    5 +
 .../src/org/carrot2/util/attribute/Attribute.java  |    9 +
 .../util/attribute/AttributeDescriptor.java        |    1 +
 .../org/carrot2/util/attribute/AttributeLevel.java |   16 +
 .../carrot2/util/attribute/AttributeMetadata.java  |   83 ---
 .../src/org/carrot2/util/attribute/Bindable.java   |    7 +
 .../carrot2/util/attribute/BindableDescriptor.java |    7 +-
 .../util/attribute/BindableDescriptorBuilder.java  |   83 +---
 .../carrot2/util/attribute/BindableMetadata.java   |   67 --
 .../util/attribute/BindableMetadataBuilder.java    |  283 ---------
 .../attribute/BindableMetadataBuilderListener.java |   92 ---
 .../attribute/BindableMetadataSerializerTask.java  |  173 -----
 .../org/carrot2/util/attribute/BindableUtils.java  |   21 -
 .../org/carrot2/util/attribute/CommonMetadata.java |   81 ---
 .../carrot2/util/attribute/MetadataExtractor.java  |  206 ------
 .../util/attribute/MetadataExtractorUtils.java     |  135 ----
 .../util/attribute/metadata/AttributeMetadata.java |   84 +++
 .../util/attribute/metadata/BindableMetadata.java  |  149 +++++
 .../util/attribute/metadata/BindableProcessor.java |  666 ++++++++++++++++++++
 .../util/attribute/metadata/BuilderBase.java       |   74 +++
 .../util/attribute/metadata/CommonMetadata.java    |   81 +++
 .../attribute/metadata/MetadataExtractorUtils.java |  106 ++++
 .../util/simplexml/ListSimpleXmlWrapper.java       |    2 +-
 .../util/simplexml/MapSimpleXmlWrapper.java        |    2 +-
 .../util/simplexml/SimpleXmlWrapperValue.java      |    6 +-
 .../attribute-metadata-xml-run-configuration.png   |  Bin 18104 -> 0 bytes
 etc/ant/common/attributes.xml                      |   48 --
 lib/org.carrot2.antlib/.classpath                  |    3 +
 lib/org.carrot2.antlib/build.xml                   |    3 +-
 lib/org.carrot2.antlib/org.carrot2.antlib.jar      |  Bin 17205 -> 17919 bytes
 .../services/javax.annotation.processing.Processor |    1 -
 .../src/org/carrot2/apt/BindableProcessor.java     |  127 ----
 .../src/org/carrot2/apt/ElementVisitorBase.java    |   63 --
 .../workbench/core/ui/AttributeInfoTooltip.java    |    2 +-
 66 files changed, 1451 insertions(+), 1845 deletions(-)
 create mode 100644 core/carrot2-util-attribute/.apt_factory/org.carrot2.bindables.jar
 create mode 100644 core/carrot2-util-attribute/.factorypath
 create mode 100644 core/carrot2-util-attribute/.settings/org.eclipse.jdt.apt.core.prefs
 delete mode 100644 core/carrot2-util-attribute/etc/eclipse/Attribute Metadata XML.launch
 delete mode 100644 core/carrot2-util-attribute/etc/eclipse/attribute-metadata-xml.xml
 delete mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/AttributeMetadata.java
 delete mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadata.java
 delete mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadataBuilder.java
 delete mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadataBuilderListener.java
 delete mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadataSerializerTask.java
 delete mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/CommonMetadata.java
 delete mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/MetadataExtractor.java
 delete mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/MetadataExtractorUtils.java
 create mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/AttributeMetadata.java
 create mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/BindableMetadata.java
 create mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/BindableProcessor.java
 create mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/BuilderBase.java
 create mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/CommonMetadata.java
 create mode 100644 core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/MetadataExtractorUtils.java
 delete mode 100644 doc/assets/img/attribute-metadata-xml-run-configuration.png
 delete mode 100644 etc/ant/common/attributes.xml
 delete mode 100644 lib/org.carrot2.antlib/src/META-INF/services/javax.annotation.processing.Processor
 delete mode 100644 lib/org.carrot2.antlib/src/org/carrot2/apt/BindableProcessor.java
 delete mode 100644 lib/org.carrot2.antlib/src/org/carrot2/apt/ElementVisitorBase.java

diff --git a/.gitignore b/.gitignore
index 5c27ee5..33c360b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,87 +1,5 @@
-applications/carrot2-webapp/src/org.carrot2.webapp.filter.QueryWordHighlighter.xml
-applications/carrot2-webapp/src/org.carrot2.webapp.model.RequestModel.xml
-applications/carrot2-webapp/src/org.carrot2.webapp.source.WebDocumentSource.xml
 applications/carrot2-webapp/web/WEB-INF/web.xml
 applications/carrot2-webapp/web/skins/common/variables.xsl
-core/carrot2-util-text/src/org.carrot2.text.linguistic.BaseLanguageModelFactory.xml
-core/carrot2-algorithm-lingo/src/org.carrot2.clustering.lingo.ClusterBuilder.xml
-core/carrot2-algorithm-lingo/src/org.carrot2.clustering.lingo.LingoClusteringAlgorithm.xml
-core/carrot2-algorithm-lingo/src/org.carrot2.clustering.lingo.SimpleLabelAssigner.xml
-core/carrot2-algorithm-lingo/src/org.carrot2.clustering.lingo.TermDocumentMatrixReducer.xml
-core/carrot2-algorithm-lingo/src/org.carrot2.clustering.lingo.UniqueLabelAssigner.xml
-core/carrot2-algorithm-stc/src/org.carrot2.clustering.stc.STCClusteringAlgorithm.xml
-core/carrot2-algorithm-stc/src/org.carrot2.clustering.stc.STCClusteringParameters.xml
-core/carrot2-algorithm-synthetic/src/org.carrot2.clustering.synthetic.ByFieldClusteringAlgorithm.xml
-core/carrot2-algorithm-synthetic/src/org.carrot2.clustering.synthetic.ByUrlClusteringAlgorithm.xml
-core/carrot2-core/src/org.carrot2.source.MultipageSearchEngine.xml
-core/carrot2-core/src/org.carrot2.source.SearchEngineBase.xml
-core/carrot2-core/src/org.carrot2.source.SearchEngineStats.xml
-core/carrot2-core/src/org.carrot2.source.SimpleSearchEngine.xml
-core/carrot2-source-ambient/src/org.carrot2.source.ambient.AmbientDocumentSource.xml
-core/carrot2-source-ambient/src/org.carrot2.source.ambient.FubDocumentSource.xml
-core/carrot2-source-ambient/src/org.carrot2.source.ambient.Odp239DocumentSource.xml
-core/carrot2-source-boss/src/org.carrot2.source.boss.BossDocumentSource.xml
-core/carrot2-source-boss/src/org.carrot2.source.boss.BossImageSearchService.xml
-core/carrot2-source-boss/src/org.carrot2.source.boss.BossNewsSearchService.xml
-core/carrot2-source-boss/src/org.carrot2.source.boss.BossSearchService.xml
-core/carrot2-source-boss/src/org.carrot2.source.boss.BossWebSearchService.xml
-core/carrot2-source-etools/src/org.carrot2.source.etools.EToolsDocumentSource.xml
-core/carrot2-source-google-desktop/src/org.carrot2.source.google.GoogleDesktopDocumentSource.xml
-core/carrot2-source-google/src/org.carrot2.source.google.GoogleDocumentSource.xml
-core/carrot2-source-lucene/src/org.carrot2.source.lucene.LuceneDocumentSource.xml
-core/carrot2-source-lucene/src/org.carrot2.source.lucene.SimpleFieldMapper.xml
-core/carrot2-source-microsoft/src/org.carrot2.source.microsoft.BingDocumentSource.xml
-core/carrot2-source-opensearch/src/org.carrot2.source.opensearch.OpenSearchDocumentSource.xml
-core/carrot2-source-pubmed/src/org.carrot2.source.pubmed.PubMedDocumentSource.xml
-core/carrot2-source-solr/src/org.carrot2.source.solr.SolrDocumentSource.xml
-core/carrot2-source-xml/src/org.carrot2.source.xml.RemoteXmlSimpleSearchEngineBase.xml
-core/carrot2-source-xml/src/org.carrot2.source.xml.XmlDocumentSource.xml
-core/carrot2-source-xml/src/org.carrot2.source.xml.XmlDocumentSourceHelper.xml
-core/carrot2-source-yahoo/src/org.carrot2.source.yahoo.YahooDocumentSource.xml
-core/carrot2-source-yahoo/src/org.carrot2.source.yahoo.YahooNewsSearchService.xml
-core/carrot2-source-yahoo/src/org.carrot2.source.yahoo.YahooSearchService.xml
-core/carrot2-source-yahoo/src/org.carrot2.source.yahoo.YahooWebSearchService.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.NamedAttributes.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.binder.BindableReferenceContainer.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.binder.BindableReferenceImpl1.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.binder.BindableReferenceImpl2.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.binder.CircularReferenceContainer.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.binder.NonprimitiveAttribute.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.binder.SingleClass.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.binder.SubClass.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.binder.SuperClass.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.filtering.FilteringReferenceClass.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.filtering.FilteringSubClass.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.filtering.FilteringSuperClass.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.metadata.AttributeDescriptions.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.metadata.AttributeGroups.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.metadata.AttributeLabels.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.metadata.AttributeLevels.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.metadata.AttributeTitles.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.metadata.NoJavadoc.xml
-core/carrot2-util-attribute/src-test/org.carrot2.util.attribute.test.metadata.TestBindable.xml
-core/carrot2-util-text/src/org.carrot2.text.clustering.MultilingualClustering.xml
-core/carrot2-util-text/src/org.carrot2.text.linguistic.DefaultLanguageModelFactory.xml
-core/carrot2-util-text/src/org.carrot2.text.linguistic.ExtendedLanguageModelFactory.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.CaseNormalizer.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.DocumentAssigner.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.LabelFilterProcessor.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.LabelFormatter.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.LanguageModelStemmer.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.PhraseExtractor.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.StopListMarker.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.Tokenizer.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.filter.CompleteLabelFilter.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.filter.GenitiveLabelFilter.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.filter.MinLengthLabelFilter.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.filter.NumericLabelFilter.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.filter.QueryLabelFilter.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.filter.StopLabelFilter.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.filter.StopWordLabelFilter.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.pipeline.BasicPreprocessingPipeline.xml
-core/carrot2-util-text/src/org.carrot2.text.preprocessing.pipeline.CompletePreprocessingPipeline.xml
-core/carrot2-util-text/src/org.carrot2.text.vsm.TermDocumentMatrixBuilder.xml
 local.properties
 workbench.properties
 tmp
-workbench/org.carrot2.workbench.core/src/org.carrot2.workbench.core.ui.BenchmarkSettings.xml
diff --git a/applications/carrot2-webapp/build.xml b/applications/carrot2-webapp/build.xml
index dcc404c..abeb500 100644
--- a/applications/carrot2-webapp/build.xml
+++ b/applications/carrot2-webapp/build.xml
@@ -259,13 +259,13 @@
   <!--
        Generates metadata files for webapp-specific document sources.
     -->
-  <target name="carrot2.webapp.attributes.war" depends="basedir.check, attrs.tasks, attrs, compile">
+  <target name="carrot2.webapp.attributes.war" depends="basedir.check, compile">
   </target>
 
   <!--
        Generates metadata files for webapp-specific document sources.
     -->
-  <target name="carrot2.webapp.attributes.eclipse" depends="basedir.check, attrs.tasks, attrs, compile">
+  <target name="carrot2.webapp.attributes.eclipse" depends="basedir.check, compile">
   </target>
 
   <!--
diff --git a/build-bamboo.xml b/build-bamboo.xml
index b3356ba..46d2bc2 100644
--- a/build-bamboo.xml
+++ b/build-bamboo.xml
@@ -55,7 +55,6 @@
             <exclude name="maven-test/**" />
             <exclude name="jar/**" />
             <exclude name="classes/**" />
-            <exclude name="attrs-cache.properties" />
           </fileset>
         </copy>
     </target>
diff --git a/build.xml b/build.xml
index 8b8ac1e..ca49f56 100644
--- a/build.xml
+++ b/build.xml
@@ -257,7 +257,7 @@
        Resources.
        Copies the runtime resources to the compiled classes directory.
     -->
-  <target name="resources" depends="attrs">
+  <target name="resources">
     <mkdir dir="${build.dir}" />
 
     <copy todir="${build.dir}" includeemptydirs="false">
@@ -299,7 +299,7 @@
        Unit tests.
     -->
   <target name="test"
-          depends="compile.test, attrs, resources.test"
+          depends="compile.test, resources.test"
           description="Runs all unit tests">
     <mkdir dir="${tests.report.dir}" />
 
@@ -358,44 +358,6 @@
   </target>
 
   <!-- 
-       Attribute metadata related targets and macros.
-    -->
-  <property name="common.attribute.names.source.path"
-            location="${core.dir}/carrot2-core/src/org/carrot2/core/attribute/AttributeNames.java" />
-
-  <target name="attrs"
-          depends="compile, attrs.tasks">
-    <sequential>
-      <attributes-xml java.source="${core.dir}/carrot2-algorithm-lingo/src"        />
-      <attributes-xml java.source="${core.dir}/carrot2-algorithm-stc/src"          />
-      <attributes-xml java.source="${core.dir}/carrot2-algorithm-synthetic/src"    />
-      <attributes-xml java.source="${core.dir}/carrot2-core/src"                   />
-      <attributes-xml java.source="${core.dir}/carrot2-source-etools/src"          />
-      <attributes-xml java.source="${core.dir}/carrot2-source-yahoo/src"           />
-      <attributes-xml java.source="${core.dir}/carrot2-source-microsoft/src"       />
-      <attributes-xml java.source="${core.dir}/carrot2-source-pubmed/src"          />
-      <attributes-xml java.source="${core.dir}/carrot2-source-opensearch/src"      />
-      <attributes-xml java.source="${core.dir}/carrot2-source-boss/src"            />
-      <attributes-xml java.source="${core.dir}/carrot2-source-google/src"          />
-      <attributes-xml java.source="${core.dir}/carrot2-source-google-desktop/src"  />
-      <attributes-xml java.source="${core.dir}/carrot2-source-solr/src"            />
-      <attributes-xml java.source="${core.dir}/carrot2-source-xml/src"             />
-      <attributes-xml java.source="${core.dir}/carrot2-source-lucene/src"          />
-      <attributes-xml java.source="${core.dir}/carrot2-source-ambient/src"         />
-      <attributes-xml java.source="${core.dir}/carrot2-util-text/src"              />
-      <attributes-xml java.source="${core.dir}/carrot2-util-attribute/src-test"    />
-      <attributes-xml java.source="${workbench.dir}/org.carrot2.workbench.core/src" />
-      <attributes-xml java.source="${applications.dir}/carrot2-webapp/src" />
-    </sequential>
-  </target>
-
-  <target name="attrs.compile" depends="compile, attrs.tasks" 
-  	description="Generate custom attribute descriptors.">
-  	<fail unless="src.dir">Provide source folder to parse: -Dsrc.dir=&lt;location&gt;</fail>
-  	<attributes-xml java.source="${src.dir}" />
-  </target>
-
-  <!-- 
        Code duplication detection.
     -->
   <path id="pmd.classpath">
@@ -406,36 +368,6 @@
     <taskdef name="cpd" classname="net.sourceforge.pmd.cpd.CPDTask" classpathref="pmd.classpath" />
   </target>
 
-  <target name="attrs.tasks" depends="compile, antlib">
-    <taskdef name="metadata-serializer" 
-        classname="org.carrot2.util.attribute.BindableMetadataSerializerTask" 
-        classpathref="test.classpath" 
-        loaderRef="attrs.classloader" />
-
-    <macrodef name="attributes-xml">
-      <attribute name="java.source" />
-      <sequential>
-        <switchClassLoader loaderRef="attrs.classloader">
-          <metadata-serializer destdir="@{java.source}">
-              <commonMetadata>
-                  <path location="${common.attribute.names.source.path}" />
-              </commonMetadata>
-          
-              <fileset dir="@{java.source}">
-                  <include name="**/*.java" />
-          
-                  <modified update="true" cache="propertyfile" algorithm="digest" comparator="equal">
-                      <param name="cache.cachefile"
-                          value="${carrot2.master.basedir}/tmp/attrs-cache.properties"/>
-                      <param name="algorithm.algorithm" value="MD5" />
-                  </modified>
-              </fileset>
-          </metadata-serializer>
-        </switchClassLoader>
-      </sequential>
-    </macrodef>
-  </target>
-
   <target name="duplication"
           depends="pmd.tasks"
           if="pmd.home"
@@ -620,7 +552,7 @@
        Build core JAR.
     -->
   <target name="jar" description="Builds Carrot2 core JAR"
-    depends="compile, attrs, resources">
+    depends="compile, resources">
     <mkdir dir="${jar.dir}" />
     <jar destfile="${jar.dir}/carrot2-core-${carrot2.version}.jar">
       <fileset dir="${build.dir}">
@@ -850,7 +782,7 @@
   <!--
       Workbench compilation section.
   -->
-  <target name="workbench.plugins.gather" depends="carrot2.common.antlib.tasks, pde.build.prepare, attrs">
+  <target name="workbench.plugins.gather" depends="carrot2.common.antlib.tasks, pde.build.prepare">
     <patternset id="temporary.files">
       <exclude name="**/.svn/**" />
       <exclude name="**/tmp/**" />
@@ -1039,6 +971,59 @@
     </fail>
   </target>
 
+
+  <!--
+      Compilation and assembly of static utility JARs (apt preprocessors).
+   -->
+  <target name="utility.jars" description="Re(create) utility JARs.">
+    <property name="utilities.build.dir" location="${carrot2.master.basedir}/tmp/utility.jars" />
+
+    <delete dir="${utilities.build.dir}" failonerror="false" />
+    <mkdir dir="${utilities.build.dir}" />
+    <javac destdir="${utilities.build.dir}" compiler="modern">
+      <src location="${carrot2.master.basedir}/core/carrot2-util-attribute/src" />
+      <include name="org/carrot2/util/attribute/metadata/**" />
+      <include name="org/carrot2/util/attribute/Bindable.java" />
+      <include name="org/carrot2/util/attribute/Attribute.java" />
+      <include name="org/carrot2/util/attribute/AttributeLevel.java" />
+
+      <classpath id="utility.classpath">
+        <fileset dir=".">
+          <include name="lib/org.apache.commons/commons-lang-*.jar" />
+          <include name="lib/com.thoughtworks.qdox/*.jar" />
+          <include name="lib/org.simpleframework.xml/*.jar" />
+        </fileset>
+      </classpath>
+    </javac>
+    
+    <pathconvert property="utility.manifest.classpath" pathsep=" " dirsep="/">
+        <!-- <path refid="utility.classpath" /> -->
+        <fileset dir="${carrot2.master.basedir}">
+          <include name="lib/org.apache.commons/commons-lang-*.jar" />
+          <include name="lib/com.thoughtworks.qdox/*.jar" />
+          <include name="lib/org.simpleframework.xml/*.jar" />
+        </fileset>
+        <mapper>
+          <chainedmapper>
+             <filtermapper><replacestring
+                from="${carrot2.master.basedir}" 
+                to="../../.."/></filtermapper> 
+          </chainedmapper>
+        </mapper>
+    </pathconvert>
+
+    <jar destfile="${carrot2.master.basedir}/core/carrot2-util-attribute/.apt_factory/org.carrot2.bindables.jar">
+      <fileset dir="${utilities.build.dir}" />
+      <service type="javax.annotation.processing.Processor" provider="org.carrot2.util.attribute.metadata.BindableProcessor" />
+      <manifest>
+        <attribute name="Class-Path" value="${utility.manifest.classpath}" />
+      </manifest>
+    </jar>
+
+    <delete dir="${utilities.build.dir}" failonerror="false" />
+  </target>
+
+
   <!--
       Source code management: license headers list and replace.
     -->
@@ -1118,7 +1103,7 @@
   <!--
        Generate development files for Eclipse.
    -->
-  <target name="eclipse" depends="attrs, carrot2.webapp.eclipse.setup" description="Generate Eclipse files for development." />
+  <target name="eclipse" depends="carrot2.webapp.eclipse.setup" description="Generate Eclipse files for development." />
 
   <!--
        Pre-commit check for developers
diff --git a/core/carrot2-algorithm-lingo/src/org/carrot2/clustering/lingo/LingoClusteringAlgorithm.java b/core/carrot2-algorithm-lingo/src/org/carrot2/clustering/lingo/LingoClusteringAlgorithm.java
index d3fdf85..cfd9c24 100644
--- a/core/carrot2-algorithm-lingo/src/org/carrot2/clustering/lingo/LingoClusteringAlgorithm.java
+++ b/core/carrot2-algorithm-lingo/src/org/carrot2/clustering/lingo/LingoClusteringAlgorithm.java
@@ -37,7 +37,7 @@ import com.google.common.collect.Ordering;
 /**
  * Lingo clustering algorithm.
  */
-@Bindable(prefix = "LingoClusteringAlgorithm")
+@Bindable(prefix = "LingoClusteringAlgorithm", inherit = AttributeNames.class)
 public class LingoClusteringAlgorithm extends ProcessingComponentBase implements
     IClusteringAlgorithm
 {
@@ -56,7 +56,7 @@ public class LingoClusteringAlgorithm extends ProcessingComponentBase implements
     @Processing
     @Input
     @Internal
-    @Attribute(key = AttributeNames.QUERY)
+    @Attribute(key = AttributeNames.QUERY, inherit = true)
     public String query = null;
 
     /**
@@ -66,13 +66,13 @@ public class LingoClusteringAlgorithm extends ProcessingComponentBase implements
     @Input
     @Required
     @Internal
-    @Attribute(key = AttributeNames.DOCUMENTS)
+    @Attribute(key = AttributeNames.DOCUMENTS, inherit = true)
     public List<Document> documents;
 
     @Processing
     @Output
     @Internal
-    @Attribute(key = AttributeNames.CLUSTERS)
+    @Attribute(key = AttributeNames.CLUSTERS, inherit = true)
     public List<Cluster> clusters = null;
 
     /**
diff --git a/core/carrot2-algorithm-stc/src/org/carrot2/clustering/stc/STCClusteringAlgorithm.java b/core/carrot2-algorithm-stc/src/org/carrot2/clustering/stc/STCClusteringAlgorithm.java
index d8fd98b..c22a877 100644
--- a/core/carrot2-algorithm-stc/src/org/carrot2/clustering/stc/STCClusteringAlgorithm.java
+++ b/core/carrot2-algorithm-stc/src/org/carrot2/clustering/stc/STCClusteringAlgorithm.java
@@ -57,7 +57,7 @@ import com.google.common.collect.Lists;
  * 
  * @label STC Clustering
  */
-@Bindable(prefix = "STCClusteringAlgorithm")
+@Bindable(prefix = "STCClusteringAlgorithm", inherit = AttributeNames.class)
 public final class STCClusteringAlgorithm extends ProcessingComponentBase implements
     IClusteringAlgorithm
 {
@@ -68,7 +68,7 @@ public final class STCClusteringAlgorithm extends ProcessingComponentBase implem
     @Processing
     @Input
     @Internal
-    @Attribute(key = AttributeNames.QUERY)
+    @Attribute(key = AttributeNames.QUERY, inherit = true)
     public String query = null;
 
     /**
@@ -78,7 +78,7 @@ public final class STCClusteringAlgorithm extends ProcessingComponentBase implem
     @Input
     @Required
     @Internal
-    @Attribute(key = AttributeNames.DOCUMENTS)
+    @Attribute(key = AttributeNames.DOCUMENTS, inherit = true)
     public List<Document> documents;
 
     /**
@@ -87,7 +87,7 @@ public final class STCClusteringAlgorithm extends ProcessingComponentBase implem
     @Processing
     @Output
     @Internal
-    @Attribute(key = AttributeNames.CLUSTERS)
+    @Attribute(key = AttributeNames.CLUSTERS, inherit = true)
     public List<Cluster> clusters = null;
 
     /**
diff --git a/core/carrot2-algorithm-synthetic/src/org/carrot2/clustering/synthetic/ByFieldClusteringAlgorithm.java b/core/carrot2-algorithm-synthetic/src/org/carrot2/clustering/synthetic/ByFieldClusteringAlgorithm.java
index 26dc824..6d0ad82 100644
--- a/core/carrot2-algorithm-synthetic/src/org/carrot2/clustering/synthetic/ByFieldClusteringAlgorithm.java
+++ b/core/carrot2-algorithm-synthetic/src/org/carrot2/clustering/synthetic/ByFieldClusteringAlgorithm.java
@@ -28,7 +28,7 @@ import com.google.common.collect.Maps;
  * 
  * @label By Attribute Clustering
  */
-@Bindable(prefix = "ByAttributeClusteringAlgorithm")
+@Bindable(prefix = "ByAttributeClusteringAlgorithm", inherit = AttributeNames.class)
 public class ByFieldClusteringAlgorithm extends ProcessingComponentBase implements
     IClusteringAlgorithm
 {
@@ -38,7 +38,7 @@ public class ByFieldClusteringAlgorithm extends ProcessingComponentBase implemen
     @Processing
     @Input
     @Internal
-    @Attribute(key = AttributeNames.DOCUMENTS)
+    @Attribute(key = AttributeNames.DOCUMENTS, inherit = true)
     public List<Document> documents;
 
     /**
@@ -47,7 +47,7 @@ public class ByFieldClusteringAlgorithm extends ProcessingComponentBase implemen
     @Processing
     @Output
     @Internal
-    @Attribute(key = AttributeNames.CLUSTERS)
+    @Attribute(key = AttributeNames.CLUSTERS, inherit = true)
     public List<Cluster> clusters = null;
 
     /**
diff --git a/core/carrot2-algorithm-synthetic/src/org/carrot2/clustering/synthetic/ByUrlClusteringAlgorithm.java b/core/carrot2-algorithm-synthetic/src/org/carrot2/clustering/synthetic/ByUrlClusteringAlgorithm.java
index 3f0a3db..bcf4b1f 100644
--- a/core/carrot2-algorithm-synthetic/src/org/carrot2/clustering/synthetic/ByUrlClusteringAlgorithm.java
+++ b/core/carrot2-algorithm-synthetic/src/org/carrot2/clustering/synthetic/ByUrlClusteringAlgorithm.java
@@ -36,7 +36,7 @@ import com.google.common.collect.*;
  * 
  * @label By URL Clustering
  */
-@Bindable
+@Bindable(inherit = AttributeNames.class)
 public class ByUrlClusteringAlgorithm extends ProcessingComponentBase implements
     IClusteringAlgorithm
 {
@@ -54,7 +54,7 @@ public class ByUrlClusteringAlgorithm extends ProcessingComponentBase implements
     @Processing
     @Input
     @Internal
-    @Attribute(key = AttributeNames.DOCUMENTS)
+    @Attribute(key = AttributeNames.DOCUMENTS, inherit = true)
     public List<Document> documents;
 
     /**
@@ -63,7 +63,7 @@ public class ByUrlClusteringAlgorithm extends ProcessingComponentBase implements
     @Processing
     @Output
     @Internal
-    @Attribute(key = AttributeNames.CLUSTERS)
+    @Attribute(key = AttributeNames.CLUSTERS, inherit = true)
     public List<Cluster> clusters = null;
 
     /**
diff --git a/core/carrot2-core/src/org/carrot2/core/attribute/AttributeNames.java b/core/carrot2-core/src/org/carrot2/core/attribute/AttributeNames.java
index 4a3adc2..d842ba3 100644
--- a/core/carrot2-core/src/org/carrot2/core/attribute/AttributeNames.java
+++ b/core/carrot2-core/src/org/carrot2/core/attribute/AttributeNames.java
@@ -12,12 +12,19 @@
 
 package org.carrot2.core.attribute;
 
-import org.carrot2.core.*;
+import org.carrot2.core.IClusteringAlgorithm;
+import org.carrot2.core.IDocumentSource;
+import org.carrot2.core.IProcessingComponent;
+import org.carrot2.util.attribute.Attribute;
+import org.carrot2.util.attribute.Bindable;
 
 /**
  * Certain constant attribute names. Note that not all attributes need to be specified
  * here.
+ * 
+ * 
  */
+@Bindable(prefix = "")
 public final class AttributeNames
 {
     /**
@@ -27,6 +34,7 @@ public final class AttributeNames
      * @level Advanced
      * @group Search query
      */
+    @Attribute(key = "start")
     public static final String START = "start";
 
     /**
@@ -37,6 +45,7 @@ public final class AttributeNames
      * @level Basic
      * @group Search query
      */
+    @Attribute(key = "results")
     public static final String RESULTS = "results";
 
     /**
@@ -46,6 +55,7 @@ public final class AttributeNames
      * @level Basic
      * @group Search query
      */
+    @Attribute(key = "query")
     public static final String QUERY = "query";
 
     /**
@@ -54,6 +64,7 @@ public final class AttributeNames
      * @label Total Results
      * @group Search request information
      */
+    @Attribute(key = "results-total")
     public static final String RESULTS_TOTAL = "results-total";
 
     /**
@@ -63,6 +74,7 @@ public final class AttributeNames
      * @level Basic
      * @group Documents
      */
+    @Attribute(key = "documents")
     public static final String DOCUMENTS = "documents";
 
     /**
@@ -71,6 +83,7 @@ public final class AttributeNames
      * @label Clusters
      * @group Clusters
      */
+    @Attribute(key = "clusters")
     public static final String CLUSTERS = "clusters";
 
     /**
@@ -81,6 +94,7 @@ public final class AttributeNames
      * @label Total Processing Time
      * @group Processing status
      */
+    @Attribute(key = "processing-time-total")
     public static final String PROCESSING_TIME_TOTAL = "processing-time-total";
 
     /**
@@ -92,6 +106,7 @@ public final class AttributeNames
      * @label Data Source Processing Time
      * @group Data source status
      */
+    @Attribute(key = "processing-time-source")
     public static final String PROCESSING_TIME_SOURCE = "processing-time-source";
 
     /**
@@ -103,6 +118,7 @@ public final class AttributeNames
      * @label Clustering Algorithm Processing Time
      * @group Clustering algorithm status
      */
+    @Attribute(key = "processing-time-algorithm")
     public static final String PROCESSING_TIME_ALGORITHM = "processing-time-algorithm";
 
     /**
@@ -116,6 +132,7 @@ public final class AttributeNames
      * @level Advanced
      * @group Search request information
      */
+    @Attribute(key = "processing-result.title")
     public static final String PROCESSING_RESULT_TITLE = "processing-result.title";
 
     /*
diff --git a/core/carrot2-core/src/org/carrot2/source/SearchEngineBase.java b/core/carrot2-core/src/org/carrot2/source/SearchEngineBase.java
index e574ca6..2222d8b 100644
--- a/core/carrot2-core/src/org/carrot2/source/SearchEngineBase.java
+++ b/core/carrot2-core/src/org/carrot2/source/SearchEngineBase.java
@@ -32,37 +32,37 @@ import org.carrot2.util.attribute.constraint.NotBlank;
  * @see SimpleSearchEngine
  * @see MultipageSearchEngine
  */
-@Bindable(prefix = "SearchEngineBase")
+@Bindable(prefix = "SearchEngineBase", inherit = AttributeNames.class)
 public abstract class SearchEngineBase extends ProcessingComponentBase implements
     IDocumentSource
 {
     @Processing
     @Input
-    @Attribute(key = AttributeNames.START)
+    @Attribute(key = AttributeNames.START, inherit = true)
     @IntRange(min = 0)
     public int start = 0;
 
     @Processing
     @Input
-    @Attribute(key = AttributeNames.RESULTS)
+    @Attribute(key = AttributeNames.RESULTS, inherit = true)
     @IntRange(min = 1)
     public int results = 100;
 
     @Processing
     @Input
-    @Attribute(key = AttributeNames.QUERY)
+    @Attribute(key = AttributeNames.QUERY, inherit = true)
     @Required
     @NotBlank
     public String query;
 
     @Processing
     @Output
-    @Attribute(key = AttributeNames.RESULTS_TOTAL)
+    @Attribute(key = AttributeNames.RESULTS_TOTAL, inherit = true)
     public long resultsTotal;
 
     @Processing
     @Output
-    @Attribute(key = AttributeNames.DOCUMENTS)
+    @Attribute(key = AttributeNames.DOCUMENTS, inherit = true)
     @Internal
     public Collection<Document> documents;
 
diff --git a/core/carrot2-source-ambient/src/org/carrot2/source/ambient/AmbientDocumentSource.java b/core/carrot2-source-ambient/src/org/carrot2/source/ambient/AmbientDocumentSource.java
index 60407bc..600c057 100644
--- a/core/carrot2-source-ambient/src/org/carrot2/source/ambient/AmbientDocumentSource.java
+++ b/core/carrot2-source-ambient/src/org/carrot2/source/ambient/AmbientDocumentSource.java
@@ -24,7 +24,7 @@ import org.carrot2.util.attribute.constraint.IntRange;
  * with a set of subtopics and a list of 100 ranked documents. For more information,
  * please see <a href="http://credo.fub.it/ambient/">Ambient home page</a>.
  */
-@Bindable(prefix = "AmbientDocumentSource")
+@Bindable(prefix = "AmbientDocumentSource", inherit = AttributeNames.class)
 public class AmbientDocumentSource extends FubDocumentSource
 {
     static final FubTestCollection DATA = new FubTestCollection("/ambient");
@@ -46,13 +46,13 @@ public class AmbientDocumentSource extends FubDocumentSource
 
     @Processing
     @Input
-    @Attribute(key = AttributeNames.RESULTS)
+    @Attribute(key = AttributeNames.RESULTS, inherit = true)
     @IntRange(min = 1, max = MAX_RESULTS_PER_TOPIC)
     public int results = 100;
 
     @Processing
     @Output
-    @Attribute(key = AttributeNames.RESULTS_TOTAL)
+    @Attribute(key = AttributeNames.RESULTS_TOTAL, inherit = true)
     public long resultsTotal = MAX_RESULTS_PER_TOPIC;
 
     /**
diff --git a/core/carrot2-source-ambient/src/org/carrot2/source/ambient/FubDocumentSource.java b/core/carrot2-source-ambient/src/org/carrot2/source/ambient/FubDocumentSource.java
index 64e0a38..9ef5843 100644
--- a/core/carrot2-source-ambient/src/org/carrot2/source/ambient/FubDocumentSource.java
+++ b/core/carrot2-source-ambient/src/org/carrot2/source/ambient/FubDocumentSource.java
@@ -23,12 +23,12 @@ import org.carrot2.util.attribute.constraint.IntRange;
 /**
  * A base document source for test collections developed at Fondazione Ugo Bordoni. 
  */
-@Bindable(prefix = "FubDocumentSource")
+@Bindable(prefix = "FubDocumentSource", inherit = AttributeNames.class)
 public class FubDocumentSource extends ProcessingComponentBase implements IDocumentSource
 {
     @Processing
     @Output
-    @Attribute(key = AttributeNames.DOCUMENTS)
+    @Attribute(key = AttributeNames.DOCUMENTS, inherit = true)
     @Internal
     public List<Document> documents;
 
@@ -47,7 +47,7 @@ public class FubDocumentSource extends ProcessingComponentBase implements IDocum
 
     @Processing
     @Output
-    @Attribute(key = AttributeNames.QUERY)
+    @Attribute(key = AttributeNames.QUERY, inherit = true)
     public String query;
 
     /**
diff --git a/core/carrot2-source-ambient/src/org/carrot2/source/ambient/Odp239DocumentSource.java b/core/carrot2-source-ambient/src/org/carrot2/source/ambient/Odp239DocumentSource.java
index 0992662..6e115c4 100644
--- a/core/carrot2-source-ambient/src/org/carrot2/source/ambient/Odp239DocumentSource.java
+++ b/core/carrot2-source-ambient/src/org/carrot2/source/ambient/Odp239DocumentSource.java
@@ -22,7 +22,7 @@ import org.carrot2.util.attribute.constraint.IntRange;
  * Serves documents from the ODP239 test set. For more details, please see:
  * http://credo.fub.it/odp239/.
  */
-@Bindable(prefix = "Odp239DocumentSource")
+@Bindable(prefix = "Odp239DocumentSource", inherit = AttributeNames.class)
 public class Odp239DocumentSource extends FubDocumentSource
 {
     static final FubTestCollection DATA = new FubTestCollection("/odp239");
@@ -44,13 +44,13 @@ public class Odp239DocumentSource extends FubDocumentSource
 
     @Processing
     @Input
-    @Attribute(key = AttributeNames.RESULTS)
+    @Attribute(key = AttributeNames.RESULTS, inherit = true)
     @IntRange(min = 1, max = MAX_RESULTS_PER_TOPIC)
     public int results = MAX_RESULTS_PER_TOPIC;
 
     @Processing
     @Output
-    @Attribute(key = AttributeNames.RESULTS_TOTAL)
+    @Attribute(key = AttributeNames.RESULTS_TOTAL, inherit = true)
     public long resultsTotal = MAX_RESULTS_PER_TOPIC;
 
     /**
diff --git a/core/carrot2-source-lucene/src/org/carrot2/source/lucene/LuceneDocumentSource.java b/core/carrot2-source-lucene/src/org/carrot2/source/lucene/LuceneDocumentSource.java
index ada1b24..a7cfeb5 100644
--- a/core/carrot2-source-lucene/src/org/carrot2/source/lucene/LuceneDocumentSource.java
+++ b/core/carrot2-source-lucene/src/org/carrot2/source/lucene/LuceneDocumentSource.java
@@ -40,7 +40,7 @@ import com.google.common.collect.Maps;
  * The index should be binary-compatible with the Lucene version actually imported by this
  * plugin.
  */
-@Bindable(prefix = "LuceneDocumentSource")
+@Bindable(prefix = "LuceneDocumentSource", inherit = AttributeNames.class)
 public final class LuceneDocumentSource extends ProcessingComponentBase implements
     IDocumentSource
 {
@@ -58,18 +58,18 @@ public final class LuceneDocumentSource extends ProcessingComponentBase implemen
 
     @Processing
     @Input
-    @Attribute(key = AttributeNames.RESULTS)
+    @Attribute(key = AttributeNames.RESULTS, inherit = true)
     @IntRange(min = 1)
     public int results = 100;
 
     @Processing
     @Output
-    @Attribute(key = AttributeNames.RESULTS_TOTAL)
+    @Attribute(key = AttributeNames.RESULTS_TOTAL, inherit = true)
     public long resultsTotal;
 
     @Processing
     @Output
-    @Attribute(key = AttributeNames.DOCUMENTS)
+    @Attribute(key = AttributeNames.DOCUMENTS, inherit = true)
     @Internal
     public Collection<Document> documents;
 
@@ -135,13 +135,14 @@ public final class LuceneDocumentSource extends ProcessingComponentBase implemen
      * A pre-parsed {@link Query} object or a {@link String} parsed using the built-in
      * {@link QueryParser} over a set of search fields returned from the
      * {@link #fieldMapper}.
-     * 
+     *
      * @label Query
      * @group Search query
+     * @level Basic
      */
     @Input
     @Processing
-    @Attribute(key = AttributeNames.QUERY)
+    @Attribute(key = AttributeNames.QUERY, inherit = false) /* false intentional! */
     @Required
     @ImplementingClasses(classes =
     {
diff --git a/core/carrot2-source-microsoft/src/org/carrot2/source/microsoft/BingDocumentSource.java b/core/carrot2-source-microsoft/src/org/carrot2/source/microsoft/BingDocumentSource.java
index 9c59092..d3d6693 100644
--- a/core/carrot2-source-microsoft/src/org/carrot2/source/microsoft/BingDocumentSource.java
+++ b/core/carrot2-source-microsoft/src/org/carrot2/source/microsoft/BingDocumentSource.java
@@ -39,7 +39,7 @@ import com.google.common.collect.Lists;
  * @see "http://www.bing.com/developers"
  * @see "http://msdn.microsoft.com/en-us/library/dd251056.aspx"
  */
-@Bindable(prefix = "BingDocumentSource")
+@Bindable(prefix = "BingDocumentSource", inherit = AttributeNames.class)
 public final class BingDocumentSource extends MultipageSearchEngine
 {
     /** Application ID assigned to Carrot Search s.c. */
diff --git a/core/carrot2-source-xml/src/org/carrot2/source/xml/XmlDocumentSource.java b/core/carrot2-source-xml/src/org/carrot2/source/xml/XmlDocumentSource.java
index ed8af66..3f09f9c 100644
--- a/core/carrot2-source-xml/src/org/carrot2/source/xml/XmlDocumentSource.java
+++ b/core/carrot2-source-xml/src/org/carrot2/source/xml/XmlDocumentSource.java
@@ -37,7 +37,7 @@ import com.google.common.collect.*;
  * 
  * @see #xml
  */
-@Bindable(prefix = "XmlDocumentSource")
+@Bindable(prefix = "XmlDocumentSource", inherit = AttributeNames.class)
 public class XmlDocumentSource extends ProcessingComponentBase implements IDocumentSource
 {
     /**
@@ -149,7 +149,7 @@ public class XmlDocumentSource extends ProcessingComponentBase implements IDocum
     @Input
     @Output
     @Processing
-    @Attribute(key = AttributeNames.QUERY)
+    @Attribute(key = AttributeNames.QUERY, inherit = true)
     public String query;
 
     /**
@@ -158,7 +158,7 @@ public class XmlDocumentSource extends ProcessingComponentBase implements IDocum
      */
     @Input
     @Processing
-    @Attribute(key = AttributeNames.RESULTS)
+    @Attribute(key = AttributeNames.RESULTS, inherit = true)
     @IntRange(min = 1)
     public int results = 100;
 
@@ -181,7 +181,7 @@ public class XmlDocumentSource extends ProcessingComponentBase implements IDocum
      */
     @Output
     @Processing
-    @Attribute(key = AttributeNames.PROCESSING_RESULT_TITLE)
+    @Attribute(key = AttributeNames.PROCESSING_RESULT_TITLE, inherit = true)
     public String title;
 
     /**
@@ -189,7 +189,7 @@ public class XmlDocumentSource extends ProcessingComponentBase implements IDocum
      */
     @Processing
     @Output
-    @Attribute(key = AttributeNames.DOCUMENTS)
+    @Attribute(key = AttributeNames.DOCUMENTS, inherit = true)
     public List<Document> documents;
 
     /**
diff --git a/core/carrot2-util-attribute/.apt_factory/org.carrot2.bindables.jar b/core/carrot2-util-attribute/.apt_factory/org.carrot2.bindables.jar
new file mode 100644
index 0000000000000000000000000000000000000000..4787aa865e0c24718fd91b487a56216808258de2
GIT binary patch
literal 19353
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

literal 0
HcmV?d00001

diff --git a/core/carrot2-util-attribute/.classpath b/core/carrot2-util-attribute/.classpath
index e007562..0fcb5d4 100644
--- a/core/carrot2-util-attribute/.classpath
+++ b/core/carrot2-util-attribute/.classpath
@@ -4,5 +4,10 @@
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="src" path="src-test"/>
+	<classpathentry kind="src" path=".apt_generated">
+		<attributes>
+			<attribute name="optional" value="true"/>
+		</attributes>
+	</classpathentry>
 	<classpathentry kind="output" path="tmp/eclipse"/>
 </classpath>
diff --git a/core/carrot2-util-attribute/.factorypath b/core/carrot2-util-attribute/.factorypath
new file mode 100644
index 0000000..c6a55e0
--- /dev/null
+++ b/core/carrot2-util-attribute/.factorypath
@@ -0,0 +1,3 @@
+<factorypath>
+    <factorypathentry kind="WKSPJAR" id="/carrot2-util-attribute/.apt_factory/org.carrot2.bindables.jar" enabled="true" runInBatchMode="false"/>
+</factorypath>
diff --git a/core/carrot2-util-attribute/.settings/org.eclipse.jdt.apt.core.prefs b/core/carrot2-util-attribute/.settings/org.eclipse.jdt.apt.core.prefs
new file mode 100644
index 0000000..76791cd
--- /dev/null
+++ b/core/carrot2-util-attribute/.settings/org.eclipse.jdt.apt.core.prefs
@@ -0,0 +1,5 @@
+#Thu Aug 12 15:46:15 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.apt.aptEnabled=true
+org.eclipse.jdt.apt.genSrcDir=.apt_generated
+org.eclipse.jdt.apt.reconcileEnabled=true
diff --git a/core/carrot2-util-attribute/.settings/org.eclipse.jdt.core.prefs b/core/carrot2-util-attribute/.settings/org.eclipse.jdt.core.prefs
index 522affe..e7846d3 100644
--- a/core/carrot2-util-attribute/.settings/org.eclipse.jdt.core.prefs
+++ b/core/carrot2-util-attribute/.settings/org.eclipse.jdt.core.prefs
@@ -1,7 +1,8 @@
-#Fri Jul 24 11:49:41 CEST 2009
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.6
+#Thu Aug 12 15:46:15 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.processAnnotations=enabled
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/core/carrot2-util-attribute/META-INF/MANIFEST.MF b/core/carrot2-util-attribute/META-INF/MANIFEST.MF
index e8ea026..ed23b8d 100644
--- a/core/carrot2-util-attribute/META-INF/MANIFEST.MF
+++ b/core/carrot2-util-attribute/META-INF/MANIFEST.MF
@@ -5,6 +5,7 @@ Bundle-SymbolicName: org.carrot2.util.attribute
 Bundle-Version: 0.0.0.QUALIFIER
 Export-Package: org.carrot2.util.attribute,
  org.carrot2.util.attribute.constraint,
+ org.carrot2.util.attribute.metadata,
  org.carrot2.util.attribute.test.binder,
  org.carrot2.util.attribute.test.filtering,
  org.carrot2.util.attribute.test.metadata,
diff --git a/core/carrot2-util-attribute/etc/eclipse/Attribute Metadata XML.launch b/core/carrot2-util-attribute/etc/eclipse/Attribute Metadata XML.launch
deleted file mode 100644
index e1e1f05..0000000
--- a/core/carrot2-util-attribute/etc/eclipse/Attribute Metadata XML.launch	
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.ant.AntLaunchConfigurationType">
-<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
-<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${workspace}"/>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/carrot2-util-attribute/etc/eclipse/attribute-metadata-xml.xml"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="1"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
-<listEntry value="org.eclipse.ui.externaltools.launchGroup"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="carrot2-util-attribute"/>
-<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
-<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${resource_loc:/carrot2-util-attribute/etc/eclipse/attribute-metadata-xml.xml}"/>
-<stringAttribute key="process_factory_id" value="org.eclipse.ant.ui.remoteAntProcessFactory"/>
-</launchConfiguration>
diff --git a/core/carrot2-util-attribute/etc/eclipse/attribute-metadata-xml.xml b/core/carrot2-util-attribute/etc/eclipse/attribute-metadata-xml.xml
deleted file mode 100644
index 8f05b75..0000000
--- a/core/carrot2-util-attribute/etc/eclipse/attribute-metadata-xml.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<project name="Attribute Metadata XML generator for Eclipse" default="attributes-eclipse">
-  <target name="attributes-eclipse">
-    <ant dir="../../../../" antfile="build.xml" target="attrs" />
-  </target>
-</project>
diff --git a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/AttributeBinderTest.java b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/AttributeBinderTest.java
index 167b268..38ab0fb 100644
--- a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/AttributeBinderTest.java
+++ b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/AttributeBinderTest.java
@@ -270,7 +270,7 @@ public class AttributeBinderTest
         @Output
         @Required
         @Attribute
-        private Class initInputOutputClass;
+        private Class<?> initInputOutputClass;
     }
 
     @Bindable
diff --git a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/BindableDescriptorBuilderTest.java b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/BindableDescriptorBuilderTest.java
index a6eed98..ec91a7f 100644
--- a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/BindableDescriptorBuilderTest.java
+++ b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/BindableDescriptorBuilderTest.java
@@ -21,7 +21,16 @@ import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.carrot2.util.attribute.constraint.ImplementingClasses;
-import org.carrot2.util.attribute.test.binder.*;
+import org.carrot2.util.attribute.metadata.AttributeMetadata;
+import org.carrot2.util.attribute.test.binder.BindableReferenceContainer;
+import org.carrot2.util.attribute.test.binder.BindableReferenceImpl1;
+import org.carrot2.util.attribute.test.binder.BindableReferenceImpl2;
+import org.carrot2.util.attribute.test.binder.CircularReferenceContainer;
+import org.carrot2.util.attribute.test.binder.NonprimitiveAttribute;
+import org.carrot2.util.attribute.test.binder.NotBindable;
+import org.carrot2.util.attribute.test.binder.SingleClass;
+import org.carrot2.util.attribute.test.binder.SubClass;
+import org.carrot2.util.attribute.test.binder.SuperClass;
 import org.junit.Assert;
 import org.junit.Test;
 import org.simpleframework.xml.core.Persister;
@@ -185,8 +194,7 @@ public class BindableDescriptorBuilderTest
                 new AttributeDescriptor(referenceClass
                     .getDeclaredField("processingInputInt"), 10, Lists
                     .<Annotation> newArrayList(), new AttributeMetadata(
-                    "Processing input int", null, null))).hasMetadata(
-                new BindableMetadata());
+                    "Processing input int", null, null)));
     }
 
     @Test
diff --git a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/BindableMetadataBuilderTest.java b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/BindableMetadataBuilderTest.java
index 1c27ff8..b5f9c62 100644
--- a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/BindableMetadataBuilderTest.java
+++ b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/BindableMetadataBuilderTest.java
@@ -1,4 +1,3 @@
-
 /*
  * Carrot2 project.
  *
@@ -12,85 +11,30 @@
 
 package org.carrot2.util.attribute;
 
-import static org.junit.Assert.*;
-import static org.junit.Assume.assumeTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
-import java.io.*;
 import java.util.Map;
 
-import org.apache.commons.lang.StringUtils;
-import org.apache.tools.ant.Project;
-import org.carrot2.util.attribute.test.metadata.*;
-import org.junit.BeforeClass;
+import org.carrot2.util.attribute.metadata.AttributeMetadata;
+import org.carrot2.util.attribute.metadata.BindableMetadata;
+import org.carrot2.util.attribute.metadata.CommonMetadata;
+import org.carrot2.util.attribute.test.metadata.AttributeDescriptions;
+import org.carrot2.util.attribute.test.metadata.AttributeGroups;
+import org.carrot2.util.attribute.test.metadata.AttributeLabels;
+import org.carrot2.util.attribute.test.metadata.AttributeLevels;
+import org.carrot2.util.attribute.test.metadata.AttributeTitles;
+import org.carrot2.util.attribute.test.metadata.NoJavadoc;
+import org.carrot2.util.attribute.test.metadata.TestBindable;
+import org.junit.Ignore;
 import org.junit.Test;
-import org.slf4j.LoggerFactory;
 
 public class BindableMetadataBuilderTest
 {
-    private static final String SOURCE_PATH_PROPERTY = "source.paths";
-    private static final String COMMON_ATTRIBUTE_NAMES_SOURCE_PATH_PROPERTY = "common.attribute.names.source.path";
-    static Map<String, BindableMetadata> bindableMetadata;
-
-    /**
-     * @return Return <code>true</code> if source path property is available and tests can
-     *         proceed.
-     */
-    private static boolean sourcePathAvailable()
-    {
-        return !StringUtils.isBlank(System.getProperty(SOURCE_PATH_PROPERTY))
-            && !StringUtils.isBlank(COMMON_ATTRIBUTE_NAMES_SOURCE_PATH_PROPERTY);
-    }
-
-    /**
-     * Generates metadata once for all the tests, which will significantly speed up
-     * processing. The metadata is stored in a static field though, which might be an
-     * issue if the test cases are executed in some parallel way.
-     */
-    @BeforeClass
-    public static void generateMetadata() throws FileNotFoundException, IOException
-    {
-        if (!sourcePathAvailable())
-        {
-            LoggerFactory.getLogger(BindableMetadataBuilderTest.class)
-                .warn(
-                    "Some tests skipped: provide path to sources of test classes in the '"
-                        + SOURCE_PATH_PROPERTY
-                        + "' JVM property and a path to the common attribute names class source in the "
-                        + COMMON_ATTRIBUTE_NAMES_SOURCE_PATH_PROPERTY + " property");
-
-            // Return, the tests that require this property will be ignored.
-            return;
-        }
-
-        final Project project = new Project();
-        project.setName("Test");
-
-        final BindableMetadataBuilder builder;
-        final String sourcePaths = System.getProperty(SOURCE_PATH_PROPERTY);
-
-        builder = new BindableMetadataBuilder(project);
-        builder.addCommonMetadataSource(new File(System
-            .getProperty(COMMON_ATTRIBUTE_NAMES_SOURCE_PATH_PROPERTY)));
-
-        final String [] paths = sourcePaths.split(File.pathSeparator);
-        for (final String path : paths)
-        {
-            builder.addSource(new File(path));
-        }
-
-        final BindableMetadataBuilderListener.MapStorageListener mapListener = new BindableMetadataBuilderListener.MapStorageListener();
-        builder.addListener(mapListener);
-
-        builder.buildAttributeMetadata();
-
-        bindableMetadata = mapListener.getBindableMetadata();
-    }
-
     @Test
     public void testEmptyJavadoc()
     {
-        assumeTrue(sourcePathAvailable());
-
         final Class<?> clazz = NoJavadoc.class;
         final String fieldName = "noJavadoc";
 
@@ -103,21 +47,20 @@ public class BindableMetadataBuilderTest
     @Test
     public void testSingleWordLabel()
     {
-        assumeTrue(sourcePathAvailable());
         checkLabel(AttributeLabels.class, "singleWordLabel", "word");
     }
 
     @Test
     public void testMultiWordLabel()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkLabel(AttributeLabels.class, "multiWordLabel", "multi word label");
     }
 
     @Test
     public void testMultiSentenceLabel()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkLabel(AttributeLabels.class, "multiSentenceLabel",
             "First label sentence. Second label sentence.");
     }
@@ -125,56 +68,56 @@ public class BindableMetadataBuilderTest
     @Test
     public void testLabelWithComment()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkLabel(AttributeLabels.class, "labelWithComment", "word");
     }
 
     @Test
     public void testNoTitle()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkTitle(AttributeTitles.class, "noTitle", null);
     }
 
-    @Test
+    // TODO: http://issues.carrot2.org/browse/CARROT-707
+    @Test @Ignore
     public void testEmptyTitle()
     {
-        assumeTrue(sourcePathAvailable());
         checkTitle(AttributeTitles.class, "emptyTitle", "");
     }
 
     @Test
     public void testTitleWithPeriod()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkTitle(AttributeTitles.class, "titleWithPeriod", "Title with period");
     }
 
     @Test
     public void testLabelNotDefined()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkLabelOrTitle(AttributeTitles.class, "titleWithPeriod", "Title with period");
     }
 
     @Test
     public void testLabelDefined()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkLabelOrTitle(AttributeTitles.class, "titleWithLabel", "label");
     }
 
     @Test
     public void testTitleWithoutPeriod()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkTitle(AttributeTitles.class, "titleWithoutPeriod", "Title without period");
     }
 
     @Test
     public void testTitleWithDescription()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkTitle(AttributeTitles.class, "titleWithDescription",
             "Title with description");
     }
@@ -182,14 +125,13 @@ public class BindableMetadataBuilderTest
     @Test
     public void testTitleWithLabel()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkTitle(AttributeTitles.class, "titleWithLabel", "Title with label");
     }
 
     @Test
     public void testTitleWithExtraSpace()
     {
-        assumeTrue(sourcePathAvailable());
 
         // Note that this scenario is not supported
         checkTitle(AttributeTitles.class, "titleWithExtraSpace", "Title with extra space");
@@ -198,7 +140,6 @@ public class BindableMetadataBuilderTest
     @Test
     public void testTitleWithExclamationMark()
     {
-        assumeTrue(sourcePathAvailable());
 
         // Note that this scenario is not supported
         checkTitle(AttributeTitles.class, "titleWithExclamationMark",
@@ -210,7 +151,6 @@ public class BindableMetadataBuilderTest
     @Test
     public void testTitleWithExtraPeriods()
     {
-        assumeTrue(sourcePathAvailable());
 
         // Note that this scenario is not supported
         checkTitle(AttributeTitles.class, "titleWithExtraPeriods",
@@ -221,7 +161,6 @@ public class BindableMetadataBuilderTest
     @Test
     public void testTitleWithLink()
     {
-        assumeTrue(sourcePathAvailable());
 
         // Note that this scenario is not supported
         checkTitle(AttributeTitles.class, "titleWithLink",
@@ -232,18 +171,16 @@ public class BindableMetadataBuilderTest
     @Test
     public void testDescriptionWithLinks()
     {
-        assumeTrue(sourcePathAvailable());
 
         // Note that this scenario is not supported
         checkTitle(AttributeTitles.class, "descriptionWithLinks", "Title");
         checkDescription(AttributeTitles.class, "descriptionWithLinks",
             "Description with <code>titleAtTheBottom</code> and <code>String</code> links.");
     }
-    
+
     @Test
     public void testTitleAtTheBottomNotSupported()
     {
-        assumeTrue(sourcePathAvailable());
 
         // Note that this scenario is not supported
         checkTitle(AttributeTitles.class, "titleAtTheBottom", null);
@@ -252,21 +189,21 @@ public class BindableMetadataBuilderTest
     @Test
     public void testNoDescriptionNoTitle()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkDescription(AttributeDescriptions.class, "noDescriptionNoTitle", null);
     }
 
     @Test
     public void testNoDescription()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkDescription(AttributeDescriptions.class, "noDescription", null);
     }
 
     @Test
     public void testSingleSentenceDescription()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkDescription(AttributeDescriptions.class, "singleSentenceDescription",
             "Single sentence description.");
     }
@@ -274,7 +211,7 @@ public class BindableMetadataBuilderTest
     @Test
     public void testTwoSentenceDescription()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkDescription(AttributeDescriptions.class, "twoSentenceDescription",
             "Description sentence 1. Description sentence 2.");
     }
@@ -282,7 +219,7 @@ public class BindableMetadataBuilderTest
     @Test
     public void testDescriptionWithExtraSpace()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkDescription(AttributeDescriptions.class, "descriptionWithExtraSpace",
             "Description with extra space.");
     }
@@ -290,7 +227,6 @@ public class BindableMetadataBuilderTest
     @Test
     public void testNamedAttributeNoJavadoc()
     {
-        assumeTrue(sourcePathAvailable());
 
         final Class<NamedAttributes> clazz = NamedAttributes.class;
         final String fieldName = "noJavadoc";
@@ -303,7 +239,6 @@ public class BindableMetadataBuilderTest
     @Test
     public void testNamedAttributeLabelOverride()
     {
-        assumeTrue(sourcePathAvailable());
 
         final Class<NamedAttributes> clazz = NamedAttributes.class;
         final String fieldName = "labelOverride";
@@ -316,7 +251,6 @@ public class BindableMetadataBuilderTest
     @Test
     public void testNamedAttributeTitleOverride()
     {
-        assumeTrue(sourcePathAvailable());
 
         final Class<NamedAttributes> clazz = NamedAttributes.class;
         final String fieldName = "titleOverride";
@@ -329,7 +263,6 @@ public class BindableMetadataBuilderTest
     @Test
     public void testNamedAttributeTitleDescriptionOverride()
     {
-        assumeTrue(sourcePathAvailable());
 
         final Class<NamedAttributes> clazz = NamedAttributes.class;
         final String fieldName = "titleDescriptionOverride";
@@ -342,7 +275,6 @@ public class BindableMetadataBuilderTest
     @Test
     public void testNamedAttributeNoDotInKey()
     {
-        assumeTrue(sourcePathAvailable());
 
         final Class<NamedAttributes> clazz = NamedAttributes.class;
         final String fieldName = "noDotInKey";
@@ -353,83 +285,69 @@ public class BindableMetadataBuilderTest
     }
 
     @Test
-    public void testClassNotInSourcePath()
-    {
-        assumeTrue(sourcePathAvailable());
-
-        final Class<NamedAttributes> clazz = NamedAttributes.class;
-        final String fieldName = "classNotInSourcePath";
-
-        checkLabel(clazz, fieldName, null);
-        checkTitle(clazz, fieldName, null);
-        checkDescription(clazz, fieldName, null);
-    }
-
-    @Test
     public void testBindableMetadata()
     {
-        assumeTrue(sourcePathAvailable());
-        final BindableMetadata metadata = bindableMetadata.get(TestBindable.class
-            .getName());
+        final BindableMetadata metadata = BindableDescriptorBuilder.buildDescriptor(
+            new TestBindable(), true).metadata;
+
         assertNotNull(metadata);
-        assertEquals("Some test bindable", metadata.title);
-        assertEquals("Description.", metadata.description);
-        assertEquals("Test Bindable", metadata.label);
+        assertEquals("Some test bindable", metadata.getTitle());
+        assertEquals("Description.", metadata.getDescription());
+        assertEquals("Test Bindable", metadata.getLabel());
     }
 
     @Test
     public void testBasicLevel()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkLevel(AttributeLevels.class, "basicLevel", AttributeLevel.BASIC);
     }
 
     @Test
     public void testMediumLevel()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkLevel(AttributeLevels.class, "mediumLevel", AttributeLevel.MEDIUM);
     }
 
     @Test
     public void testAdvancedLevel()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkLevel(AttributeLevels.class, "advancedLevel", AttributeLevel.ADVANCED);
     }
 
     @Test
     public void testUnknownLevel()
     {
-        assumeTrue(sourcePathAvailable());
+
         assertNull(getLevel(AttributeLevels.class, "unknownLevel"));
     }
 
     @Test
     public void testNoLevel()
     {
-        assumeTrue(sourcePathAvailable());
+
         assertNull(getLevel(AttributeLevels.class, "noLevel"));
     }
 
     @Test
     public void testOneWordGroup()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkGroup(AttributeGroups.class, "oneWordGroup", "Group");
     }
 
     @Test
     public void testMultiWordGroup()
     {
-        assumeTrue(sourcePathAvailable());
+
         checkGroup(AttributeGroups.class, "multiWordGroup", "Multi word group");
     }
 
     @Test
     public void testNoGroup()
     {
-        assumeTrue(sourcePathAvailable());
         assertNull(getGroup(AttributeGroups.class, "noGroup"));
     }
 
@@ -564,20 +482,25 @@ public class BindableMetadataBuilderTest
      */
     private CommonMetadata getAttributeMetadata(Class<?> componentClass, String fieldName)
     {
-        final Map<String, AttributeMetadata> componentAttributeMetadata = bindableMetadata
-            .get(componentClass.getName()).getAttributeMetadata();
-        if (componentAttributeMetadata == null)
+        try
         {
-            return null;
-        }
+            final Map<String, AttributeMetadata> componentAttributeMetadata =
+                BindableDescriptorBuilder.buildDescriptor(
+                    componentClass.newInstance(), true).metadata.getAttributeMetadata();
+    
+            if (componentAttributeMetadata == null)
+            {
+                return null;
+            }
+
+            final CommonMetadata fieldAttributeMetadata = 
+                componentAttributeMetadata.get(fieldName);
 
-        final CommonMetadata fieldAttributeMetadata = componentAttributeMetadata
-            .get(fieldName);
-        if (fieldAttributeMetadata == null)
+            return fieldAttributeMetadata;
+        }
+        catch (Exception e)
         {
-            return null;
+            throw new RuntimeException(e);
         }
-
-        return fieldAttributeMetadata;
     }
 }
diff --git a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/NamedAttributes.java b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/NamedAttributes.java
index 81eb375..17a6d05 100644
--- a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/NamedAttributes.java
+++ b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/NamedAttributes.java
@@ -17,7 +17,7 @@ import org.carrot2.util.attribute.test.metadata.TestAttributeNames;
 /**
  * Test named attribute container.
  */
-@Bindable
+@Bindable(inherit = TestAttributeNames.class)
 @SuppressWarnings("unused")
 public class NamedAttributes
 {
@@ -25,7 +25,7 @@ public class NamedAttributes
 
     @TestInit
     @Input
-    @Attribute(key = TestAttributeNames.TITLE_DESCRIPTION_LABEL)
+    @Attribute(key = TestAttributeNames.TITLE_DESCRIPTION_LABEL, inherit = true)
     private int noJavadoc;
 
     /**
@@ -33,7 +33,7 @@ public class NamedAttributes
      */
     @TestInit
     @Input
-    @Attribute(key = TestAttributeNames.TITLE_DESCRIPTION_LABEL)
+    @Attribute(key = TestAttributeNames.TITLE_DESCRIPTION_LABEL, inherit = true)
     private int labelOverride;
 
     /**
@@ -41,7 +41,7 @@ public class NamedAttributes
      */
     @TestInit
     @Input
-    @Attribute(key = TestAttributeNames.TITLE_DESCRIPTION_LABEL)
+    @Attribute(key = TestAttributeNames.TITLE_DESCRIPTION_LABEL, inherit = true)
     private int titleOverride;
 
     /**
@@ -49,16 +49,11 @@ public class NamedAttributes
      */
     @TestInit
     @Input
-    @Attribute(key = TestAttributeNames.TITLE_DESCRIPTION_LABEL)
+    @Attribute(key = TestAttributeNames.TITLE_DESCRIPTION_LABEL, inherit = true)
     private int titleDescriptionOverride;
 
     @TestInit
     @Input
     @Attribute(key = TEST)
     private int noDotInKey;
-
-    @TestInit
-    @Input
-    @Attribute(key = BindableMetadataBuilder.ATTRIBUTE_KEY_PARAMETER)
-    private int classNotInSourcePath;
 }
diff --git a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/AttributeAssertions.java b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/AttributeAssertions.java
index 312cca0..5cb303b 100644
--- a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/AttributeAssertions.java
+++ b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/AttributeAssertions.java
@@ -13,6 +13,8 @@
 package org.carrot2.util.attribute.test.assertions;
 
 import org.carrot2.util.attribute.*;
+import org.carrot2.util.attribute.metadata.AttributeMetadata;
+import org.carrot2.util.attribute.metadata.CommonMetadata;
 
 /**
  * Assertions for the attribute-related classes.
diff --git a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/AttributeMetadataAssertion.java b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/AttributeMetadataAssertion.java
index 87b3d63..0e41ef4 100644
--- a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/AttributeMetadataAssertion.java
+++ b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/AttributeMetadataAssertion.java
@@ -14,7 +14,7 @@ package org.carrot2.util.attribute.test.assertions;
 
 import static org.fest.assertions.Assertions.assertThat;
 
-import org.carrot2.util.attribute.AttributeMetadata;
+import org.carrot2.util.attribute.metadata.AttributeMetadata;
 
 /**
  * Assertions on {@link AttributeMetadata}.
diff --git a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/BindableDescriptorAssertion.java b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/BindableDescriptorAssertion.java
index ae33181..cd1fc14 100644
--- a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/BindableDescriptorAssertion.java
+++ b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/BindableDescriptorAssertion.java
@@ -15,6 +15,7 @@ package org.carrot2.util.attribute.test.assertions;
 import static org.carrot2.util.attribute.test.assertions.AttributeAssertions.assertThat;
 
 import org.carrot2.util.attribute.*;
+import org.carrot2.util.attribute.metadata.BindableMetadata;
 import org.fest.assertions.Assertions;
 
 /**
diff --git a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/CommonMetadataAssertion.java b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/CommonMetadataAssertion.java
index 79a7366..5a8e166 100644
--- a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/CommonMetadataAssertion.java
+++ b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/assertions/CommonMetadataAssertion.java
@@ -14,7 +14,7 @@ package org.carrot2.util.attribute.test.assertions;
 
 import static org.fest.assertions.Assertions.assertThat;
 
-import org.carrot2.util.attribute.CommonMetadata;
+import org.carrot2.util.attribute.metadata.CommonMetadata;
 
 /**
  * Assertions on {@link CommonMetadata}.
diff --git a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/metadata/TestAttributeNames.java b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/metadata/TestAttributeNames.java
index 3ac2cc4..c969b22 100644
--- a/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/metadata/TestAttributeNames.java
+++ b/core/carrot2-util-attribute/src-test/org/carrot2/util/attribute/test/metadata/TestAttributeNames.java
@@ -12,9 +12,13 @@
 
 package org.carrot2.util.attribute.test.metadata;
 
+import org.carrot2.util.attribute.Attribute;
+import org.carrot2.util.attribute.Bindable;
+
 /**
  *
  */
+@Bindable
 public class TestAttributeNames
 {
     /**
@@ -22,5 +26,6 @@ public class TestAttributeNames
      *
      * @label label
      */
+    @Attribute(key = "title-description-label")
     public static final String TITLE_DESCRIPTION_LABEL = "title-description-label";
 }
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/Attribute.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/Attribute.java
index f68a64a..907c6d3 100644
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/Attribute.java
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/Attribute.java
@@ -42,4 +42,13 @@ public @interface Attribute
      * the attribute field as returned by {@link Field#getName()}.
      */
     String key() default "";
+
+    /**
+     * If true, inherit attribute documentation from another attribute (field). Used in conjunction with
+     * {@link Bindable#inherit()}. The {@link #key()} of this attribute must match exactly one of
+     * the inherited attributes.
+     *
+     * @see Bindable#inherit()
+     */
+    boolean inherit() default false;
 }
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/AttributeDescriptor.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/AttributeDescriptor.java
index 68bc4bc..c54e3be 100644
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/AttributeDescriptor.java
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/AttributeDescriptor.java
@@ -19,6 +19,7 @@ import java.util.*;
 import org.apache.commons.lang.ClassUtils;
 import org.carrot2.util.ListUtils;
 import org.carrot2.util.attribute.constraint.*;
+import org.carrot2.util.attribute.metadata.AttributeMetadata;
 import org.simpleframework.xml.*;
 
 import com.google.common.base.Function;
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/AttributeLevel.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/AttributeLevel.java
index b7e548f..b7618d8 100644
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/AttributeLevel.java
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/AttributeLevel.java
@@ -27,4 +27,20 @@ public enum AttributeLevel
     {
         return StringUtils.capitalize(name().toLowerCase());
     }
+
+    /**
+     * Robust version of valueOf, accepting invalid values.
+     */
+    public static AttributeLevel robustValueOf(String value)
+    {
+        if (value == null) return null;
+        try
+        {
+            return valueOf(value.toUpperCase());
+        }
+        catch (Exception e)
+        {
+            return null;
+        }
+    }
 }
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/AttributeMetadata.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/AttributeMetadata.java
deleted file mode 100644
index c2b7705..0000000
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/AttributeMetadata.java
+++ /dev/null
@@ -1,83 +0,0 @@
-
-/*
- * Carrot2 project.
- *
- * Copyright (C) 2002-2010, Dawid Weiss, Stanisław Osiński.
- * All rights reserved.
- *
- * Refer to the full license file "carrot2.LICENSE"
- * in the root folder of the repository checkout or at:
- * http://www.carrot2.org/carrot2.LICENSE
- */
-
-package org.carrot2.util.attribute;
-
-import org.simpleframework.xml.Element;
-import org.simpleframework.xml.Root;
-
-/**
- * Human-readable metadata about an attribute. Metadata contains such elements as title,
- * label and description.
- */
-@Root(name = "attribute-metadata")
-public class AttributeMetadata extends CommonMetadata
-{
-    @Element(required = false)
-    private String group;
-
-    @Element(required = false)
-    private AttributeLevel level;
-
-    AttributeMetadata()
-    {
-    }
-
-    AttributeMetadata(String title, String label, String description)
-    {
-        this(title, label, description, null, null);
-    }
-
-    AttributeMetadata(String title, String label, String description, String group,
-        AttributeLevel level)
-    {
-        this.title = title;
-        this.label = label;
-        this.description = description;
-        this.group = group;
-        this.level = level;
-    }
-
-    @Override
-    public String toString()
-    {
-        return "[" + title + ", " + label + ", " + description + "]";
-    }
-
-    /**
-     * Returns the label of the group this attribute belongs to or <code>null</code> if
-     * the attribute is not assigned to any group.
-     */
-    public String getGroup()
-    {
-        return group;
-    }
-
-    void setGroup(String group)
-    {
-        this.group = group;
-    }
-
-    /**
-     * Returns the attribute level (basic, medium, advanced) or <code>null</code> if the
-     * attribute has no level assigned.
-     */
-    public AttributeLevel getLevel()
-    {
-        return level;
-    }
-
-    void setLevel(AttributeLevel level)
-    {
-        this.level = level;
-    }
-}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/Bindable.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/Bindable.java
index 7dac7c5..b616ee4 100644
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/Bindable.java
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/Bindable.java
@@ -32,4 +32,11 @@ public @interface Bindable
      * {@link Bindable#prefix()} works with attribute keys, see {@link Attribute#key()};
      */
     String prefix() default "";
+
+    /**
+     * Inherit attribute descriptions (metadata) from other bindable types. Each attribute
+     * should use <code>inherit</code> key to indicate which attribute it inherits 
+     * metadata from.
+     */
+    Class<?>[] inherit() default {};
 }
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableDescriptor.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableDescriptor.java
index ad9613b..3dd4e78 100644
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableDescriptor.java
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableDescriptor.java
@@ -17,6 +17,9 @@ import java.lang.reflect.Field;
 import java.util.*;
 import java.util.Map.Entry;
 
+import org.carrot2.util.attribute.metadata.AttributeMetadata;
+import org.carrot2.util.attribute.metadata.BindableMetadata;
+
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 import com.google.common.collect.Lists;
@@ -327,7 +330,9 @@ public class BindableDescriptor
             AttributeDescriptor attributeDescriptor);
     }
 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings({
+        "unchecked", "rawtypes"
+    })
     static void buildAttributeGroups(
         Map<String, AttributeDescriptor> newAttributeDescriptors,
         Map<Object, Map<String, AttributeDescriptor>> newAttributeGroups,
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableDescriptorBuilder.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableDescriptorBuilder.java
index 9543136..1eb4762 100644
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableDescriptorBuilder.java
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableDescriptorBuilder.java
@@ -12,16 +12,18 @@
 
 package org.carrot2.util.attribute;
 
-import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
-import org.carrot2.util.CloseableUtils;
 import org.carrot2.util.attribute.constraint.IsConstraint;
-import org.carrot2.util.resource.IResource;
-import org.carrot2.util.resource.ResourceUtilsFactory;
-import org.simpleframework.xml.core.Persister;
+import org.carrot2.util.attribute.metadata.AttributeMetadata;
+import org.carrot2.util.attribute.metadata.BindableMetadata;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -75,8 +77,8 @@ public class BindableDescriptorBuilder
         }
 
         // Load metadata
-        final BindableMetadata bindableMetadata = buildMetadataForBindableHierarchy(
-            clazz, loadMetadata);
+        final BindableMetadata bindableMetadata =
+            loadMetadata ? BindableMetadata.forClassWithParents(clazz) : null;
 
         // Build descriptors for direct attributes
         final Map<String, AttributeDescriptor> attributeDescriptors = buildAttributeDescriptors(
@@ -141,71 +143,6 @@ public class BindableDescriptorBuilder
     }
 
     /**
-     * Builds bindable metadata for a {@link Bindable} class.
-     */
-    private static BindableMetadata buildMetadataForBindableHierarchy(
-        final Class<?> clazz, boolean loadMetadata)
-    {
-        if (!loadMetadata)
-        {
-            return null;
-        }
-
-        final Collection<Class<?>> classesFromBindableHerarchy = BindableUtils
-            .getClassesFromBindableHerarchy(clazz);
-
-        final BindableMetadata bindableMetadata = getBindableMetadata(clazz);
-
-        for (final Class<?> bindableClass : classesFromBindableHerarchy)
-        {
-            if (bindableClass != clazz)
-            {
-                final BindableMetadata moreMetadata = getBindableMetadata(bindableClass);
-                bindableMetadata.getInternalAttributeMetadata().putAll(
-                    moreMetadata.getAttributeMetadata());
-            }
-        }
-
-        return bindableMetadata;
-    }
-
-    /**
-     * Deserializes metadata for a {@link Bindable} class.
-     */
-    private static BindableMetadata getBindableMetadata(final Class<?> clazz)
-    {
-        final IResource metadataXml = ResourceUtilsFactory.getDefaultResourceUtils()
-            .getFirst(clazz.getName() + ".xml", clazz);
-        BindableMetadata bindableMetadata = null;
-        if (metadataXml != null)
-        {
-            InputStream inputStream = null;
-            try
-            {
-                inputStream = metadataXml.open();
-                bindableMetadata = new Persister().read(BindableMetadata.class,
-                    inputStream);
-            }
-            catch (final Exception e)
-            {
-                throw new RuntimeException("Could not load attribute metadata from: "
-                    + metadataXml, e);
-            }
-            finally
-            {
-                CloseableUtils.close(inputStream);
-            }
-
-            return bindableMetadata;
-        }
-        else
-        {
-            throw new RuntimeException("Could not load attribute metadata from: "
-                + clazz.getName() + ".xml");
-        }
-    }
-
-    /**
      * Builds {@link AttributeDescriptor} for a field from a {@link Bindable} type.
      */
     private static AttributeDescriptor buildAttributeDescriptor(
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadata.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadata.java
deleted file mode 100644
index d741534..0000000
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadata.java
+++ /dev/null
@@ -1,67 +0,0 @@
-
-/*
- * Carrot2 project.
- *
- * Copyright (C) 2002-2010, Dawid Weiss, Stanisław Osiński.
- * All rights reserved.
- *
- * Refer to the full license file "carrot2.LICENSE"
- * in the root folder of the repository checkout or at:
- * http://www.carrot2.org/carrot2.LICENSE
- */
-
-package org.carrot2.util.attribute;
-
-import java.util.Collections;
-import java.util.Map;
-
-import org.simpleframework.xml.ElementMap;
-import org.simpleframework.xml.Root;
-
-/**
- * Human-readable metadata for a {@link Bindable} type.
- */
-@Root(name = "component-metadata")
-public class BindableMetadata extends CommonMetadata
-{
-    @ElementMap(name = "attributes", entry = "attribute", key = "field-name", inline = false, attribute = true)
-    private Map<String, AttributeMetadata> attributeMetadataInternal;
-
-    BindableMetadata()
-    {
-    }
-
-    /**
-     * Returns metadata for all attributes in the bindable type.
-     * 
-     * @return metadata for all attributes in the bindable type. Key in the map represents
-     *         the attribute key as defined by {@link Attribute#key()}. The returned map
-     *         is unmodifiable.
-     */
-    public Map<String, AttributeMetadata> getAttributeMetadata()
-    {
-        return Collections.unmodifiableMap(attributeMetadataInternal);
-    }
-
-    /**
-     * Returns the internal (modifiable) map of attribute metadata.
-     */
-    Map<String, AttributeMetadata> getInternalAttributeMetadata()
-    {
-        return attributeMetadataInternal;
-    }
-
-    /**
-     * Sets internal (modifiable) map of attribute metadata.
-     */
-    void setAttributeMetadata(Map<String, AttributeMetadata> attributeMetadata)
-    {
-        this.attributeMetadataInternal = attributeMetadata;
-    }
-
-    @Override
-    public String toString()
-    {
-        return "[" + title + ", " + label + ", " + description + "]";
-    }
-}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadataBuilder.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadataBuilder.java
deleted file mode 100644
index 85c9795..0000000
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadataBuilder.java
+++ /dev/null
@@ -1,283 +0,0 @@
-
-/*
- * Carrot2 project.
- *
- * Copyright (C) 2002-2010, Dawid Weiss, Stanisław Osiński.
- * All rights reserved.
- *
- * Refer to the full license file "carrot2.LICENSE"
- * in the root folder of the repository checkout or at:
- * http://www.carrot2.org/carrot2.LICENSE
- */
-
-package org.carrot2.util.attribute;
-
-import java.io.*;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.tools.ant.Project;
-import org.carrot2.util.StreamUtils;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.thoughtworks.qdox.JavaDocBuilder;
-import com.thoughtworks.qdox.directorywalker.*;
-import com.thoughtworks.qdox.model.*;
-
-/**
- * Builds metadata for {@link Bindable} types.
- */
-class BindableMetadataBuilder
-{
-    /** A field used in tests */
-    static final String ATTRIBUTE_KEY_PARAMETER = "key";
-
-    /**
-     * ANT project this builder belongs to.
-     */
-    private final Project project;
-
-    /**
-     * Metadata extractors for attributes.
-     */
-    private static final MetadataExtractor [] ATTRIBUTE_METADATA_EXTRACTORS = new MetadataExtractor []
-    {
-        MetadataExtractor.LABEL_EXTRACTOR, MetadataExtractor.GROUP_EXTRACTOR,
-        MetadataExtractor.LEVEL_EXTRACTOR, MetadataExtractor.TITLE_EXTRACTOR,
-        MetadataExtractor.DESCRIPTION_EXTRACTOR
-    };
-
-    /**
-     * Metadata extractors for bindable types.
-     */
-    private static final MetadataExtractor [] BINDABLE_METADATA_EXTRACTORS = new MetadataExtractor []
-    {
-        MetadataExtractor.LABEL_EXTRACTOR, MetadataExtractor.TITLE_EXTRACTOR,
-        MetadataExtractor.DESCRIPTION_EXTRACTOR
-    };
-
-    /** JavaDoc parser */
-    private final JavaDocBuilder javaDocBuilder = new JavaDocBuilder();
-
-    /**
-     * List of fully qualified names of classes containing common attribute keys. An
-     * example of such a class can be org.carrot2.core.attribute.AttributeNames. If the
-     * key of an attribute is taken from any class on this list, the metadata from the
-     * actual field will be complemented by the metadata provided for the constant
-     * defining the key.
-     */
-    private final List<String> commonMetadataSources;
-
-    /**
-     * Metadata listeners, useful for tests and serialization application.
-     */
-    private final List<BindableMetadataBuilderListener> listeners = Lists.newArrayList();
-
-    /**
-     * Creates a {@link BindableMetadataBuilder} with empty commonMetadataSources.
-     */
-    BindableMetadataBuilder(Project project)
-    {
-        this.project = project;
-        commonMetadataSources = Lists.newArrayList();
-    }
-
-    /**
-     * Adds Java sources to be parsed.
-     */
-    void addSource(File file) throws FileNotFoundException, IOException
-    {
-        if (file.isDirectory())
-        {
-            addSourceTree(file);
-        }
-        else
-        {
-            addJavaSourceFile(file);
-        }
-    }
-
-    /**
-     * A directory traversal optimized to look only for classes that have {@link Bindable}
-     * annotation (avoiding full source code parse).
-     */
-    public void addSourceTree(File file)
-    {
-        final DirectoryScanner scanner = new DirectoryScanner(file);
-        scanner.addFilter(new SuffixFilter(".java"));
-        scanner.scan(new FileVisitor()
-        {
-            public void visitFile(File currentFile)
-            {
-                try
-                {
-                    addJavaSourceFile(currentFile);
-                }
-                catch (IOException e)
-                {
-                    throw new RuntimeException(e);
-                }
-            }
-        });
-    }
-
-    /**
-     * Adds a class to commonMetadataSources.
-     */
-    void addCommonMetadataSource(File file) throws FileNotFoundException, IOException
-    {
-        commonMetadataSources.add(addJavaSourceFile(file).getClasses()[0]
-            .getFullyQualifiedName());
-    }
-
-    /**
-     * Adds a metadata listener.
-     */
-    void addListener(BindableMetadataBuilderListener listener)
-    {
-        listeners.add(listener);
-    }
-
-    /**
-     * Builds attribute metadata, notifying all the listeners when
-     * {@link BindableMetadata} gets built.
-     */
-    void buildAttributeMetadata()
-    {
-
-        final JavaSource [] javaSources = javaDocBuilder.getSources();
-        for (final JavaSource javaSource : javaSources)
-        {
-            for (JavaClass javaClass : javaSource.getClasses())
-            {
-                if (MetadataExtractorUtils.hasAnnotation(javaClass, Bindable.class))
-                {
-                    final BindableMetadata bindableMetadata = new BindableMetadata();
-                    buildBindableMetadata(javaClass, bindableMetadata);
-                    buildAttributeMetadata(javaClass, bindableMetadata);
-
-                    for (final BindableMetadataBuilderListener listener : listeners)
-                    {
-                        listener.bindableMetadataBuilt(javaClass, bindableMetadata);
-                    }
-                }
-                else
-                {
-                    project.log("Skipping non-@Bindable class: "
-                        + javaClass.getFullyQualifiedName() + " from "
-                        + javaSource.getURL(), Project.MSG_DEBUG);
-                }
-            }
-        }
-    }
-
-    /**
-     * Fills {@link BindableMetadata} with data collected from the Java class.
-     */
-    private void buildBindableMetadata(JavaClass javaClass,
-        BindableMetadata bindableMetadata)
-    {
-        for (final MetadataExtractor extractor : BINDABLE_METADATA_EXTRACTORS)
-        {
-            extractor.extractMetadataItem(javaClass, javaDocBuilder, bindableMetadata);
-        }
-    }
-
-    /**
-     * Fills {@link BindableMetadata} with {@link AttributeMetadata} data collected from
-     * the Java class.
-     */
-    private void buildAttributeMetadata(JavaClass bindable,
-        BindableMetadata bindableMetadata)
-    {
-        final Map<String, AttributeMetadata> result = Maps.newLinkedHashMap();
-
-        final JavaField [] fields = bindable.getFields();
-        for (final JavaField javaField : fields)
-        {
-            if (MetadataExtractorUtils.hasAnnotation(javaField, Attribute.class))
-            {
-                final AttributeMetadata metadata = new AttributeMetadata();
-                for (final MetadataExtractor extractor : ATTRIBUTE_METADATA_EXTRACTORS)
-                {
-                    // First extract with the common metadata source
-                    final JavaField commonMetadataSource = resolveCommonMetadataSource(javaField);
-                    if (commonMetadataSource != null)
-                    {
-                        extractor.extractMetadataItem(commonMetadataSource,
-                            javaDocBuilder, metadata);
-                    }
-
-                    // Then override with the actual metadata source
-                    extractor.extractMetadataItem(javaField, javaDocBuilder, metadata);
-                }
-
-                result.put(javaField.getName(), metadata);
-            }
-        }
-
-        bindableMetadata.setAttributeMetadata(result);
-    }
-
-    /**
-     * Resolves additional metadata from commonMetadataSources.
-     */
-    private JavaField resolveCommonMetadataSource(JavaField originalField)
-    {
-        final Annotation annotation = MetadataExtractorUtils.getAnnotation(originalField,
-            Attribute.class);
-
-        // This bit is not really well documented in QDocs (well, nothing is, really...),
-        // so let's convert the value to a string and proceed
-        final Object namedParameter = annotation
-            .getNamedParameter(ATTRIBUTE_KEY_PARAMETER);
-        if (namedParameter == null)
-        {
-            return null;
-        }
-
-        final String keyExpression = namedParameter.toString();
-        final int dotIndex = keyExpression.indexOf('.');
-        if (dotIndex <= 0)
-        {
-            return null;
-        }
-
-        final String [] split = keyExpression.split("\\.");
-        final String className = split[0];
-        final String fieldName = split[1];
-
-        for (final String metadataSourceClassName : commonMetadataSources)
-        {
-            if (metadataSourceClassName.indexOf(className) >= 0)
-            {
-                final JavaClass commonClass = javaDocBuilder
-                    .getClassByName(metadataSourceClassName);
-                if (commonClass != null)
-                {
-                    final JavaField commonField = commonClass.getFieldByName(fieldName);
-                    if (commonField != null)
-                    {
-                        return commonField;
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Adds a Java source from a {@link File} read assuming UTF-8 encoding.
-     */
-    private JavaSource addJavaSourceFile(File currentFile)
-        throws UnsupportedEncodingException, IOException, FileNotFoundException
-    {
-        String source = new String(StreamUtils.readFullyAndClose(new FileInputStream(
-            currentFile)), "UTF-8");
-
-        return javaDocBuilder.addSource(new StringReader(source), currentFile
-            .getAbsolutePath());
-    }
-}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadataBuilderListener.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadataBuilderListener.java
deleted file mode 100644
index 868d976..0000000
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadataBuilderListener.java
+++ /dev/null
@@ -1,92 +0,0 @@
-
-/*
- * Carrot2 project.
- *
- * Copyright (C) 2002-2010, Dawid Weiss, Stanisław Osiński.
- * All rights reserved.
- *
- * Refer to the full license file "carrot2.LICENSE"
- * in the root folder of the repository checkout or at:
- * http://www.carrot2.org/carrot2.LICENSE
- */
-
-package org.carrot2.util.attribute;
-
-import java.io.File;
-import java.util.Map;
-
-import org.simpleframework.xml.core.Persister;
-import org.simpleframework.xml.stream.Format;
-
-import com.google.common.collect.Maps;
-import com.thoughtworks.qdox.model.JavaClass;
-
-/**
- * Allows to get notifications about {@link BindableMetadata} being built by
- * {@link BindableMetadataBuilder}.
- */
-abstract class BindableMetadataBuilderListener
-{
-    /**
-     * Invoked after {@link BindableMetadata} has been built.
-     * 
-     * @param bindable the Java class for which the metadata has been built.
-     * @param bindableMetadata metadata that has been built.
-     */
-    abstract void bindableMetadataBuilt(JavaClass bindable,
-        BindableMetadata bindableMetadata);
-
-    /**
-     * Stores attribute metadata in a map using fully qualified class names as keys.
-     * Useful for unit testing.
-     */
-    static class MapStorageListener extends BindableMetadataBuilderListener
-    {
-        private final Map<String, BindableMetadata> bindableMetadata = Maps
-            .newLinkedHashMap();
-
-        public void bindableMetadataBuilt(JavaClass bindable, BindableMetadata metadata)
-        {
-            bindableMetadata.put(bindable.getFullyQualifiedName(), metadata);
-        }
-
-        public Map<String, BindableMetadata> getBindableMetadata()
-        {
-            return bindableMetadata;
-        }
-    }
-
-    /**
-     * Saves the attribute metadata information next to the Java source file defining the
-     * component.
-     */
-    static class XmlSerializerListener extends BindableMetadataBuilderListener
-    {
-        private final File outputDir;
-
-        public XmlSerializerListener(File outputDir)
-        {
-            this.outputDir = outputDir;
-        }
-
-        public void bindableMetadataBuilt(JavaClass bindable,
-            BindableMetadata bindableMetadata)
-        {
-            try
-            {
-                final File xmlFile = new File(outputDir, bindable.getFullyQualifiedName()
-                    + ".xml");
-
-                System.out.println("Writing: " + xmlFile);
-
-                final Persister persister = new Persister(new Format(2,
-                    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
-                persister.write(bindableMetadata, xmlFile);
-            }
-            catch (final Exception e)
-            {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadataSerializerTask.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadataSerializerTask.java
deleted file mode 100644
index a275a1d..0000000
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableMetadataSerializerTask.java
+++ /dev/null
@@ -1,173 +0,0 @@
-
-/*
- * Carrot2 project.
- *
- * Copyright (C) 2002-2010, Dawid Weiss, Stanisław Osiński.
- * All rights reserved.
- *
- * Refer to the full license file "carrot2.LICENSE"
- * in the root folder of the repository checkout or at:
- * http://www.carrot2.org/carrot2.LICENSE
- */
-
-package org.carrot2.util.attribute;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.apache.tools.ant.*;
-import org.apache.tools.ant.types.*;
-import org.apache.tools.ant.types.resources.FileResource;
-
-/**
- * An ANT task for building XML metadata for classes annotated with {@link Bindable}.
- */
-public final class BindableMetadataSerializerTask extends Task
-{
-    /**
-     * Metadata builder.
-     */
-    private BindableMetadataBuilder builder;
-
-    /**
-     * Destination directory.
-     */
-    private File destDir;
-    
-    /** A list of input files. */
-    private ArrayList<File> inputFiles = new ArrayList<File>();
-
-    /** A list of metadata files. */
-    private ArrayList<Path> metadataFiles = new ArrayList<Path>();
-
-    @Override
-    public void setProject(Project project)
-    {
-        super.setProject(project);
-        builder = new BindableMetadataBuilder(project);        
-    }
-
-    /**
-     * Set destination directory.
-     */
-    public void setDestdir(File destDir)
-    {
-        this.destDir = destDir;
-    }
-
-    /**
-     * Add a set of files to process.
-     */
-    public void addConfiguredFileset(FileSet set)
-    {
-        add(set);
-    }
-
-    /**
-     * Create nested element for common metadata files.
-     */
-    public Path createCommonMetadata()
-    {
-        Path p = new Path(getProject());
-        metadataFiles.add(p);
-        return p;
-    }
-
-    /**
-     * Add a collection of resources to process.
-     */
-    @SuppressWarnings("unchecked")
-    public void add(ResourceCollection res)
-    {
-        final Iterator<Resource> i = res.iterator();
-        while (i.hasNext())
-        {
-            final Resource r = i.next();
-            if (!(r instanceof FileResource))
-            {
-                throw new BuildException("Only file resources are supported: " + r);
-            }
-            addForProcessing((FileResource) r);
-        }
-    }
-
-    /**
-     * Add a file resource for processing.
-     */
-    private void addForProcessing(FileResource res)
-    {
-        inputFiles.add(res.getFile());
-    }
-
-    /**
-     * Execute the task.
-     */
-    @SuppressWarnings("unchecked")
-    @Override
-    public void execute() throws BuildException
-    {
-        validate();
-
-        if (inputFiles.size() == 0)
-        {
-            // No input files to process, exit immediately to avoid parsing metadata files.
-            log("No input files, exiting.", Project.MSG_WARN);
-            return;
-        }
-
-        for (File f : inputFiles)
-        {
-            log("Adding file for processing: " + f, Project.MSG_VERBOSE);
-            try
-            {
-                builder.addSource(f);
-            }
-            catch (IOException e)
-            {
-                throw new BuildException("Could not process file: " + f, e);
-            }
-        }
-
-        for (Path p : metadataFiles)
-        {
-            Iterator<Resource> i = p.iterator();
-            while (i.hasNext())
-            {
-                final Resource r = i.next();
-                if (!(r instanceof FileResource))
-                {
-                    throw new BuildException("Only file resources supported: " + r);
-                }
-
-                final FileResource fr = (FileResource) r;
-                final File f = fr.getFile();
-
-                log("Adding metadata file: " + f, Project.MSG_VERBOSE);
-                try
-                {
-                    builder.addCommonMetadataSource(f);
-                }
-                catch (IOException e)
-                {
-                    throw new BuildException("Could not add metadata file: " + f);
-                }
-            }
-        }
-        
-        builder.addListener(new BindableMetadataBuilderListener.XmlSerializerListener(
-            destDir));
-        builder.buildAttributeMetadata();
-    }
-
-    /**
-     * Validate arguments.
-     */
-    private void validate()
-    {
-        if (destDir == null) throw new BuildException("destdir attribute is required.");
-        if (!destDir.isDirectory()) throw new BuildException("Not a directory: "
-            + destDir.getAbsolutePath());
-    }
-}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableUtils.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableUtils.java
index 8c8fb5c..662c288 100644
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableUtils.java
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/BindableUtils.java
@@ -18,7 +18,6 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
 
-import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
 /**
@@ -63,26 +62,6 @@ final class BindableUtils
     }
 
     /**
-     * Returns all {@link Bindable} from the hierarchy of the provided <code>clazz</code>.
-     */
-    static Collection<Class<?>> getClassesFromBindableHerarchy(Class<?> clazz)
-    {
-        final Collection<Class<?>> classes = Lists.newArrayList();
-
-        while (clazz != null)
-        {
-            if (clazz.getAnnotation(Bindable.class) != null)
-            {
-                classes.add(clazz);
-            }
-
-            clazz = clazz.getSuperclass();
-        }
-
-        return classes;
-    }
-
-    /**
      * Computes the attribute key according to the definition in {@link Attribute#key()}.
      */
     static String getKey(Field field)
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/CommonMetadata.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/CommonMetadata.java
deleted file mode 100644
index e989943..0000000
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/CommonMetadata.java
+++ /dev/null
@@ -1,81 +0,0 @@
-
-/*
- * Carrot2 project.
- *
- * Copyright (C) 2002-2010, Dawid Weiss, Stanisław Osiński.
- * All rights reserved.
- *
- * Refer to the full license file "carrot2.LICENSE"
- * in the root folder of the repository checkout or at:
- * http://www.carrot2.org/carrot2.LICENSE
- */
-
-package org.carrot2.util.attribute;
-
-import org.apache.commons.lang.StringUtils;
-import org.simpleframework.xml.Element;
-
-/**
- * Common metadata items for {@link BindableMetadata} and {@link AttributeMetadata}.
- */
-public class CommonMetadata
-{
-    @Element(required = false, data = true)
-    protected String title;
-
-    @Element(required = false)
-    protected String label;
-
-    @Element(required = false, data = true)
-    protected String description;
-
-    /**
-     * A one sentence summary of the element. Could be presented as a header of the tool
-     * tip of the corresponding UI component.
-     */
-    public String getTitle()
-    {
-        return title;
-    }
-
-    protected void setTitle(String title)
-    {
-        this.title = title;
-    }
-
-    /**
-     * A short label for the element which can be presented as the label of the
-     * corresponding UI component.
-     */
-    public String getLabel()
-    {
-        return label;
-    }
-
-    protected void setLabel(String label)
-    {
-        this.label = label;
-    }
-
-    /**
-     * Returns the label if it is not-<code>null</code>, otherwise returns title.
-     */
-    public String getLabelOrTitle()
-    {
-        return StringUtils.isNotBlank(label) ? label : title;
-    }
-    
-    /**
-     * A longer, possibly multi sentence, description of the element. Could be presented
-     * as a body of the tool tip of the corresponding UI component.
-     */
-    public String getDescription()
-    {
-        return description;
-    }
-
-    protected void setDescription(String plainTextDescription)
-    {
-        this.description = plainTextDescription;
-    }
-}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/MetadataExtractor.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/MetadataExtractor.java
deleted file mode 100644
index bc3daba..0000000
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/MetadataExtractor.java
+++ /dev/null
@@ -1,206 +0,0 @@
-
-/*
- * Carrot2 project.
- *
- * Copyright (C) 2002-2010, Dawid Weiss, Stanisław Osiński.
- * All rights reserved.
- *
- * Refer to the full license file "carrot2.LICENSE"
- * in the root folder of the repository checkout or at:
- * http://www.carrot2.org/carrot2.LICENSE
- */
-
-package org.carrot2.util.attribute;
-
-import org.apache.commons.lang.StringUtils;
-
-import com.thoughtworks.qdox.JavaDocBuilder;
-import com.thoughtworks.qdox.model.AbstractJavaEntity;
-import com.thoughtworks.qdox.model.DocletTag;
-
-/**
- * Extracts certain items of metadata from Java source.
- */
-abstract class MetadataExtractor
-{
-    /**
-     * Extracts attribute/ bindable descriptions. Anything in the JavaDoc comment that
-     * follows after its first sentence becomes a description.
-     */
-    static DescriptionExtractor DESCRIPTION_EXTRACTOR = new DescriptionExtractor();
-
-    /**
-     * Extracts attribute/ bindable titles. The first sentence of the JavaDoc comment
-     * becomes the title.
-     */
-    static TitleExtractor TITLE_EXTRACTOR = new TitleExtractor();
-
-    /**
-     * Extracts attribute labels from the "label" JavaDoc tag.
-     */
-    static SimpleTagExtractor LABEL_EXTRACTOR = new SimpleTagExtractor("label",
-        new LabelSetter());
-
-    /**
-     * Extracts attribute group name from the "group" JavaDoc tag.
-     */
-    static SimpleTagExtractor GROUP_EXTRACTOR = new SimpleTagExtractor("group",
-        new GroupSetter());
-
-    /**
-     * Extracts attribute levels from the "level" JavaDoc tag.
-     */
-    static SimpleTagExtractor LEVEL_EXTRACTOR = new SimpleTagExtractor("level",
-        new LevelSetter());
-
-    /**
-     * Extracts some metadata from the provided Java source element and sets it on the
-     * provided <code>attributeMetadata</code>.
-     */
-    abstract boolean extractMetadataItem(AbstractJavaEntity javaEntity,
-        JavaDocBuilder javaDocBuilder, CommonMetadata attributeMetadata);
-
-    /**
-     * Extracts attribute/ bindable descriptions. Anything in the JavaDoc comment that
-     * follows after its first sentence becomes a description.
-     */
-    private static class DescriptionExtractor extends MetadataExtractor
-    {
-        public boolean extractMetadataItem(AbstractJavaEntity javaEntity,
-            JavaDocBuilder javaDocBuilder, CommonMetadata attributeMetadata)
-        {
-            final String comment = MetadataExtractorUtils.toPlainText(javaEntity
-                .getComment());
-            if (comment == null)
-            {
-                return false;
-            }
-
-            final int next = MetadataExtractorUtils
-                .getEndOfFirstSentenceCharIndex(comment);
-            if (next > 0 && next < comment.length())
-            {
-                final String description = comment.substring(next + 1).trim();
-                if (description.length() > 0)
-                {
-                    attributeMetadata.setDescription(description);
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Extracts attribute/ bindable titles. The first sentence of the JavaDoc comment
-     * becomes the title.
-     */
-    private static class TitleExtractor extends MetadataExtractor
-    {
-        public boolean extractMetadataItem(AbstractJavaEntity javaEntity,
-            JavaDocBuilder javaDocBuilder, CommonMetadata attributeMetadata)
-        {
-            final String comment = MetadataExtractorUtils.toPlainText(javaEntity
-                .getComment());
-            if (comment == null)
-            {
-                return false;
-            }
-
-            final int next = MetadataExtractorUtils
-                .getEndOfFirstSentenceCharIndex(comment);
-            if (next >= 0)
-            {
-                // Strip off the last "."
-                final String firstSentence = comment.substring(0, next).trim();
-                attributeMetadata.setTitle(firstSentence);
-                return true;
-            }
-            else
-            {
-                attributeMetadata.setTitle(comment);
-                return true;
-            }
-        }
-    }
-
-    /**
-     * Extracts metadata from JavaDoc simple tags.
-     */
-    private static class SimpleTagExtractor extends MetadataExtractor
-    {
-        private String tagName;
-        private IMetadataValueSetter valueSetter;
-
-        public SimpleTagExtractor(String tagName, IMetadataValueSetter valueSetter)
-        {
-            this.tagName = tagName;
-            this.valueSetter = valueSetter;
-        }
-
-        public boolean extractMetadataItem(AbstractJavaEntity javaEntity,
-            JavaDocBuilder javaDocBuilder, CommonMetadata attributeMetadata)
-        {
-            final DocletTag labelTag = javaEntity.getTagByName(tagName);
-            if (labelTag != null && !StringUtils.isBlank(labelTag.getValue()))
-            {
-                valueSetter.setMetadataValue(attributeMetadata, labelTag.getValue());
-                return true;
-            }
-            else
-            {
-                return false;
-            }
-        }
-
-        static interface IMetadataValueSetter
-        {
-            void setMetadataValue(CommonMetadata metadata, String value);
-        }
-    }
-
-    private static class LabelSetter implements SimpleTagExtractor.IMetadataValueSetter
-    {
-        public void setMetadataValue(CommonMetadata metadata, String value)
-        {
-            metadata.setLabel(value);
-        }
-    }
-
-    private static class GroupSetter implements SimpleTagExtractor.IMetadataValueSetter
-    {
-        public void setMetadataValue(CommonMetadata metadata, String value)
-        {
-            if (metadata instanceof AttributeMetadata)
-            {
-                ((AttributeMetadata) metadata).setGroup(value);
-            }
-        }
-    }
-
-    private static class LevelSetter implements SimpleTagExtractor.IMetadataValueSetter
-    {
-        public void setMetadataValue(CommonMetadata metadata, String value)
-        {
-            if (value == null)
-            {
-                return;
-            }
-
-            try
-            {
-                if (metadata instanceof AttributeMetadata)
-                {
-                    ((AttributeMetadata) metadata).setLevel(AttributeLevel.valueOf(value
-                        .toUpperCase()));
-                }
-            }
-            catch (Throwable e)
-            {
-                // Thrown if unknown enum
-                org.slf4j.LoggerFactory.getLogger(MetadataExtractor.class).warn(
-                    "Ignoring unknown attribute level: " + value);
-            }
-        }
-    }
-}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/MetadataExtractorUtils.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/MetadataExtractorUtils.java
deleted file mode 100644
index e13a4e0..0000000
--- a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/MetadataExtractorUtils.java
+++ /dev/null
@@ -1,135 +0,0 @@
-
-/*
- * Carrot2 project.
- *
- * Copyright (C) 2002-2010, Dawid Weiss, Stanisław Osiński.
- * All rights reserved.
- *
- * Refer to the full license file "carrot2.LICENSE"
- * in the root folder of the repository checkout or at:
- * http://www.carrot2.org/carrot2.LICENSE
- */
-
-package org.carrot2.util.attribute;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import com.thoughtworks.qdox.model.AbstractJavaEntity;
-import com.thoughtworks.qdox.model.Annotation;
-
-/**
- * A number of utility methods for working with JavaDoc comments.
- */
-final class MetadataExtractorUtils
-{
-    /**
-     * Extracts the first sentence of a JavaDoc comment.
-     */
-    private static final Pattern FIRST_SENTENCE_PATTERN = Pattern
-        .compile("\\.(?<!((\\w\\.){2,5}+))(\\s|\\z)");
-
-    /**
-     * Converts a JavaDoc link to text.
-     */
-    private static final Pattern LINK_TO_TEXT_PATTERN = Pattern
-        .compile("\\{@link\\s(.+?)\\}");
-
-    /**
-     * Matching of '#' characters in links.
-     */
-    private static final Pattern SPACE_HASH_PATTERN = Pattern.compile(">#");
-    private static final Pattern TYPE_HASH_PATTERN = Pattern.compile("([^>])#");
-
-    private MetadataExtractorUtils()
-    {
-        // No instantiation
-    }
-
-    /**
-     * Checks if the Java source element has the required annotation.
-     */
-    static boolean hasAnnotation(AbstractJavaEntity javaEntity,
-        Class<?> requestedAnnotationClass)
-    {
-        return getAnnotation(javaEntity, requestedAnnotationClass) != null;
-    }
-
-    /**
-     * Returns a required annotation for the provided Java source element.
-     */
-    static Annotation getAnnotation(AbstractJavaEntity javaEntity,
-        Class<?> requestedAnnotationClass)
-    {
-        for (final Annotation annotation : javaEntity.getAnnotations())
-        {
-            if (requestedAnnotationClass.getName()
-                .equals(annotation.getType().getValue()))
-            {
-                return annotation;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the index of the last character of the first JavaDoc sentence.
-     */
-    static int getEndOfFirstSentenceCharIndex(String text)
-    {
-        final Matcher matcher = FIRST_SENTENCE_PATTERN.matcher(text);
-        if (matcher.find())
-        {
-            return matcher.start();
-        }
-        else
-        {
-            return -1;
-        }
-    }
-
-    /**
-     * Converts multiple space, tab, return characters into one space.
-     */
-    static String normalizeSpaces(String string)
-    {
-        if (string == null)
-        {
-            return null;
-        }
-        return string.replaceAll("[\\t\\r\\n]+", " ");
-    }
-
-    /**
-     * Converts in-line link tag to text.
-     */
-    static String renderInlineTags(String comment)
-    {
-        String content = comment;
-        content = LINK_TO_TEXT_PATTERN.matcher(comment).replaceAll("<code>$1</code>");
-        content = SPACE_HASH_PATTERN.matcher(content).replaceAll(">");
-        content = TYPE_HASH_PATTERN.matcher(content).replaceAll("$1.");
-        return content;
-    }
-
-    /**
-     * Converts JavaDoc comment body to plain text. Currently only normalizes space and
-     * renders links. In the future, we might think of dealing with HTML properly.
-     */
-    static String toPlainText(String comment)
-    {
-        if (comment == null)
-        {
-            return null;
-        }
-        final String normalizedSpace = normalizeSpaces(comment);
-        final String linksRendered = renderInlineTags(normalizedSpace);
-        final String trimmed = linksRendered.trim();
-        if (trimmed.length() == 0)
-        {
-            return null;
-        }
-
-        return trimmed;
-    }
-}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/AttributeMetadata.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/AttributeMetadata.java
new file mode 100644
index 0000000..0cd9729
--- /dev/null
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/AttributeMetadata.java
@@ -0,0 +1,84 @@
+
+/*
+ * Carrot2 project.
+ *
+ * Copyright (C) 2002-2010, Dawid Weiss, Stanisław Osiński.
+ * All rights reserved.
+ *
+ * Refer to the full license file "carrot2.LICENSE"
+ * in the root folder of the repository checkout or at:
+ * http://www.carrot2.org/carrot2.LICENSE
+ */
+
+package org.carrot2.util.attribute.metadata;
+
+import org.carrot2.util.attribute.AttributeLevel;
+import org.simpleframework.xml.Element;
+import org.simpleframework.xml.Root;
+
+/**
+ * Human-readable metadata about an attribute. Metadata contains such elements as title,
+ * label and description.
+ */
+@Root(name = "attribute-metadata")
+public class AttributeMetadata extends CommonMetadata
+{
+    @Element(required = false)
+    private String group;
+
+    @Element(required = false)
+    private AttributeLevel level;
+
+    public AttributeMetadata()
+    {
+    }
+
+    public AttributeMetadata(String title, String label, String description)
+    {
+        this(title, label, description, null, null);
+    }
+
+    public AttributeMetadata(String title, String label, String description, String group,
+        AttributeLevel level)
+    {
+        this.title = title;
+        this.label = label;
+        this.description = description;
+        this.group = group;
+        this.level = level;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "[" + title + ", " + label + ", " + description + "]";
+    }
+
+    /**
+     * Returns the label of the group this attribute belongs to or <code>null</code> if
+     * the attribute is not assigned to any group.
+     */
+    public String getGroup()
+    {
+        return group;
+    }
+
+    public void setGroup(String group)
+    {
+        this.group = group;
+    }
+
+    /**
+     * Returns the attribute level (basic, medium, advanced) or <code>null</code> if the
+     * attribute has no level assigned.
+     */
+    public AttributeLevel getLevel()
+    {
+        return level;
+    }
+
+    public void setLevel(AttributeLevel level)
+    {
+        this.level = level;
+    }
+}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/BindableMetadata.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/BindableMetadata.java
new file mode 100644
index 0000000..99e128e
--- /dev/null
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/BindableMetadata.java
@@ -0,0 +1,149 @@
+
+/*
+ * Carrot2 project.
+ *
+ * Copyright (C) 2002-2010, Dawid Weiss, Stanisław Osiński.
+ * All rights reserved.
+ *
+ * Refer to the full license file "carrot2.LICENSE"
+ * in the root folder of the repository checkout or at:
+ * http://www.carrot2.org/carrot2.LICENSE
+ */
+
+package org.carrot2.util.attribute.metadata;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.carrot2.util.attribute.Attribute;
+import org.carrot2.util.attribute.Bindable;
+import org.simpleframework.xml.ElementMap;
+import org.simpleframework.xml.Root;
+import org.simpleframework.xml.core.Persister;
+
+/**
+ * Human-readable metadata for a {@link Bindable} type.
+ */
+@Root(name = "component-metadata")
+public class BindableMetadata extends CommonMetadata
+{
+    @ElementMap(name = "attributes", entry = "attribute", key = "field-name", inline = false, attribute = true)
+    private Map<String, AttributeMetadata> attributeMetadataInternal; 
+
+    BindableMetadata()
+    {
+    }
+
+    /**
+     * Returns metadata for all attributes in the bindable type.
+     * 
+     * @return metadata for all attributes in the bindable type. Key in the map represents
+     *         the attribute key as defined by {@link Attribute#key()}. The returned map
+     *         is unmodifiable.
+     */
+    public Map<String, AttributeMetadata> getAttributeMetadata()
+    {
+        return Collections.unmodifiableMap(attributeMetadataInternal);
+    }
+
+    void setAttributeMetadata(Map<String, AttributeMetadata> map)
+    {
+        attributeMetadataInternal = map;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "[" + title + ", " + label + ", " + description + "]";
+    }
+
+    /**
+     * Load metadata of a given bindable class, merged with bindable attributes from 
+     * parent classes marked with {@link Bindable} as well.
+     */
+    public static BindableMetadata forClassWithParents(final Class<?> clazz)
+    {
+        final BindableMetadata bindable = getBindableMetadata(clazz);
+
+        for (final Class<?> bindableClass : 
+            getClassesFromBindableHerarchy(clazz.getSuperclass()))
+        {
+            final BindableMetadata moreMetadata = getBindableMetadata(bindableClass);
+            bindable.attributeMetadataInternal.putAll(
+                moreMetadata.getAttributeMetadata());
+        }
+
+        return bindable;
+    }
+
+    /**
+     * Returns all {@link Bindable} from the hierarchy of the provided <code>clazz</code>,
+     * including <code>clazz</code>.
+     */
+    static Collection<Class<?>> getClassesFromBindableHerarchy(Class<?> clazz)
+    {
+        final Collection<Class<?>> classes = new ArrayList<Class<?>>();
+
+        while (clazz != null)
+        {
+            if (clazz.getAnnotation(Bindable.class) != null)
+            {
+                classes.add(clazz);
+            }
+
+            clazz = clazz.getSuperclass();
+        }
+
+        return classes;
+    }
+
+    /**
+     * Deserializes metadata for a {@link Bindable} class.
+     */
+    private static BindableMetadata getBindableMetadata(final Class<?> clazz)
+    {
+        BindableMetadata bindableMetadata = null;
+        InputStream inputStream = null;
+        try
+        {
+            final String name = clazz.getName() + ".xml";
+            inputStream = clazz.getClassLoader().getResourceAsStream(
+                name);
+            if (inputStream == null)
+                throw new IOException("No such resource: " + name);
+
+            bindableMetadata = new Persister().read(BindableMetadata.class,
+                inputStream);
+            
+            // Quickfix for a bug in SimpleXML: https://sourceforge.net/tracker/?func=detail&atid=661526&aid=3043930&group_id=112203
+            for (Map.Entry<String, AttributeMetadata> e 
+                : bindableMetadata.attributeMetadataInternal.entrySet())
+            {
+                if (e.getValue() == null)
+                    e.setValue(new AttributeMetadata());
+            }
+        }
+        catch (final Exception e)
+        {
+            throw new RuntimeException("Could not load attribute metadata for: "
+                + clazz, e);
+        }
+        finally
+        {
+            try
+            {
+                if (inputStream != null) inputStream.close();
+            }
+            catch (IOException e)
+            {
+                // ignore.
+            }
+        }
+
+        return bindableMetadata;
+    }
+}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/BindableProcessor.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/BindableProcessor.java
new file mode 100644
index 0000000..a6bdace
--- /dev/null
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/BindableProcessor.java
@@ -0,0 +1,666 @@
+package org.carrot2.util.attribute.metadata;
+
+import static javax.lang.model.SourceVersion.RELEASE_6;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.tools.FileObject;
+import javax.tools.StandardLocation;
+
+import org.carrot2.util.attribute.Attribute;
+import org.carrot2.util.attribute.AttributeLevel;
+import org.carrot2.util.attribute.Bindable;
+import org.carrot2.util.attribute.metadata.AttributeMetadata;
+import org.carrot2.util.attribute.metadata.BindableMetadata;
+import org.carrot2.util.attribute.metadata.CommonMetadata;
+import org.simpleframework.xml.core.Persister;
+import org.simpleframework.xml.stream.Format;
+
+import com.thoughtworks.qdox.parser.Builder;
+import com.thoughtworks.qdox.parser.ParseException;
+import com.thoughtworks.qdox.parser.impl.JFlexLexer;
+import com.thoughtworks.qdox.parser.impl.Parser;
+import com.thoughtworks.qdox.parser.structs.TagDef;
+
+/**
+ * Java6+ compatible annotation processor for parsing <code>Bindable</code>-annotated
+ * types and generating their metadata.
+ */
+@SupportedAnnotationTypes("org.carrot2.util.attribute.Bindable")
+@SupportedSourceVersion(RELEASE_6)
+public final class BindableProcessor extends AbstractProcessor
+{
+    /**
+     * Empty package name.
+     */
+    private final static CharSequence EMPTY_PACKAGE_NAME = "";
+    
+    /**
+     * We must use type mirrors, so this is a hardcoded name for:
+     * {@link Bindable#inherit()}.
+     */
+    private final static String INHERIT_ATTRIBUTE_NAME = "inherit";
+
+    /**
+     * Mirror element utilities.
+     */
+    private Elements elementUtils;
+
+    /**
+     * Apt filer utilities.
+     */
+    private Filer filer;
+
+    /**
+     * Collected types annotated with {@link Bindable}.
+     */
+    private final ArrayList<TypeElement> bindableTypes = new ArrayList<TypeElement>();
+
+    /**
+     * Inheritance dependencies.
+     */
+    private final HashMap<String, List<String>> dependencies = new HashMap<String, List<String>>();
+
+    /**
+     * Already emitted bindable metadata for referencing current round.
+     */
+    private final HashMap<String, BindableMetadata> thisRoundMetadata = 
+        new HashMap<String, BindableMetadata>();
+    
+    /**
+     * Type name to reflected type mapping.
+     */
+    private final HashMap<String, TypeElement> nameToType =
+        new HashMap<String, TypeElement>();
+
+    /**
+     * Initialize processing environment.
+     */
+    @Override
+    public synchronized void init(ProcessingEnvironment processingEnv)
+    {
+        super.init(processingEnv);
+
+        elementUtils = this.processingEnv.getElementUtils();
+        filer = this.processingEnv.getFiler();
+        bindableTypes.clear();
+    }
+
+    /**
+     * Process a set of roots for the current round (apt callback).
+     */
+    @Override
+    public boolean process(Set<? extends TypeElement> ann, RoundEnvironment env)
+    {
+        if (env.errorRaised())
+        {
+            return false;
+        }
+
+        if (!env.processingOver())
+        {
+            // Scan for all types marked with @Bindable
+            for (TypeElement e : 
+                ElementFilter.typesIn(env.getElementsAnnotatedWith(Bindable.class)))
+            {
+                // e can be null in Eclipse...
+                if (e != null) bindableTypes.add(e);
+            }
+        }
+        else
+        {
+            // Do the final processing.
+            final long start = System.currentTimeMillis();
+            try
+            {
+                processBindables();
+            }
+            catch (RuntimeException e)
+            {
+                throw new RuntimeException("Exception thrown, bindables: "
+                    + bindableTypes, e);
+            }
+            if (bindableTypes.size() > 0)
+            {
+                System.out.println(bindableTypes.size() + 
+                    " @Bindable metadata processed in: " + 
+                    ((System.currentTimeMillis() - start) / 1000.0) + " secs.");
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * All bindable types have been collected, do the actual processing.
+     */
+    private void processBindables()
+    {
+        /*
+         * We need to sort bindables and process them in topological order because of
+         * attribute inheritance. 
+         */
+        final List<TypeElement> sorted = topoSortForInheritance();
+
+        final HashSet<String> rootSet = new HashSet<String>();
+        for (TypeElement type : bindableTypes)
+            rootSet.add(getName(type));
+
+        // For every (new) bindable type, create and emit attribute metadata.
+        for (TypeElement type : sorted)
+        {
+            // We skip those types in the dependency list, that are not in the root set.
+            if (!rootSet.contains(getName(type)))
+                continue;
+
+            // Extract the bindable's title, description and label.
+            final Map<String, String> tags = new HashMap<String, String>();
+            final String javaDoc = processJavaDoc(type, tags);
+            final BindableMetadata metadata = new BindableMetadata();
+            extractTitleDescription(metadata, javaDoc);
+            metadata.setLabel(tags.get("label"));
+
+            // Collect inherited metadata, if any.
+            final Map<String, AttributeMetadata> inheritedMetadata = new HashMap<String, AttributeMetadata>();
+            extractInheritedAttributeMetadata(type, inheritedMetadata);
+
+            // Collect this bindable's attribute metadata.
+            final Map<String, AttributeMetadata> attributeMetadata = new LinkedHashMap<String, AttributeMetadata>();
+            extractAttributeMetadata(type, attributeMetadata, inheritedMetadata);
+            metadata.setAttributeMetadata(attributeMetadata);
+
+            // Emit auxiliary metadata files (XMLs, classes, etc.).
+            thisRoundMetadata.put(getName(type), metadata);
+            emitXML(metadata, type);
+        }
+    }
+
+    /**
+     * Sort topologically to account for attribute inheritance. Types not inheriting from anything come first.
+     */
+    private List<TypeElement> topoSortForInheritance()
+    {
+        dependencies.clear();
+        nameToType.clear();
+
+        // Calculate initial type names.
+        for (TypeElement type : bindableTypes)
+        {
+            final String name = getName(type);
+
+            if (nameToType.containsKey(name)) 
+                throw new RuntimeException("Sanity check: two classes with the same on input: "
+                    + name);
+
+            nameToType.put(name, type);
+        }
+
+        // Calculate inheritance dependencies.
+        for (TypeElement type : bindableTypes)
+        {
+            final String name = getName(type);
+            dependencies.put(name, extractInheritClassNames(type));
+        }
+
+        // Reorder input.
+        final ArrayList<String> reordered = new ArrayList<String>();
+        final HashSet<String> processed = new HashSet<String>();
+        for (String e : dependencies.keySet())
+        {
+            mark(e, reordered, processed, dependencies);
+        }
+
+        ArrayList<TypeElement> reorderedTypes = new ArrayList<TypeElement>();
+        for (String name : reordered)
+        {
+            reorderedTypes.add(nameToType.get(name));
+        }
+
+        return reorderedTypes;
+    }
+
+    /**
+     * Depth-first descent, no cycle checks.
+     */
+    private static void mark(String e, ArrayList<String> reordered, HashSet<String> processed,
+        HashMap<String, List<String>> dependencies)
+    {
+        if (processed.contains(e))
+            return;
+        processed.add(e);
+        
+        if (dependencies.get(e) != null)
+        {
+            for (String dep : dependencies.get(e))
+            {
+                mark(dep, reordered, processed, dependencies);
+            }
+        }
+        reordered.add(e);
+    }
+
+    /**
+     * Extract class names from {@link Bindable#inherit()} attribute.
+     */
+    private List<String> extractInheritClassNames(TypeElement type)
+    {
+        final ArrayList<String> clazzNames = new ArrayList<String>();
+        for (AnnotationMirror m : type.getAnnotationMirrors())
+        {
+            final Map<? extends ExecutableElement, ? extends AnnotationValue> values = 
+                elementUtils.getElementValuesWithDefaults(m);
+
+            for (ExecutableElement e : values.keySet())
+            {
+                if (e.getSimpleName().toString().equals(INHERIT_ATTRIBUTE_NAME))
+                {
+                    @SuppressWarnings("unchecked")
+                    List<? extends AnnotationValue> clazzMirrors = 
+                        (List<? extends AnnotationValue>) values.get(e).getValue();
+
+                    for (AnnotationValue clazzMirror : clazzMirrors)
+                    {
+                        TypeMirror typeMirror = (TypeMirror) clazzMirror.getValue();
+                        TypeElement elem = (TypeElement) processingEnv.getTypeUtils().asElement(typeMirror);
+                        String typeName = elementUtils.getBinaryName(elem).toString();
+                        if (!nameToType.containsKey(typeName))
+                            nameToType.put(typeName, elem);
+                        clazzNames.add(typeName);
+                    }
+                }
+            }
+        }
+        return clazzNames;
+    }
+
+    /**
+     * Simple names for a given type.
+     */
+    private String getName(TypeElement type)
+    {
+        return elementUtils.getBinaryName(type).toString();
+    }
+
+    /**
+     * Extract attribute metadata from an existing class. 
+     */
+    private void extractInheritedAttributeMetadata(TypeElement type,
+        Map<String, AttributeMetadata> inheritedMetadata)
+    {
+        // For each class, attempt to load its metadata.
+        for (String clazzName : dependencies.get(getName(type)))
+        {
+            final BindableMetadata metadata;
+
+            /*
+             * Check if the metadata for this class is not part of the current
+             * round. If so, we can't generate and read a resource in the same
+             * round, so we use a local cache.  
+             */
+            if (thisRoundMetadata.containsKey(clazzName))
+            {
+                metadata = thisRoundMetadata.get(clazzName);
+            }
+            else
+            {
+                /*
+                 * The class is already compiled so no source code level may be available for it.
+                 * But since it's already compiled, we may simply load its own bindable metadata,
+                 * it should (must?) be available.
+                 */
+                metadata = readMetadataFromResource(clazzName);
+            }
+            
+            final TypeElement depType = nameToType.get(clazzName);
+            final Map<String, String> fieldNameToAttributeKey = new HashMap<String, String>();
+            for (VariableElement field : ElementFilter.fieldsIn(depType.getEnclosedElements()))
+            {
+                Attribute a = field.getAnnotation(Attribute.class);
+                if (a != null)
+                {
+                    fieldNameToAttributeKey.put(field.getSimpleName().toString(), 
+                        getAttributeKey(field, a));
+                }
+            }
+
+            for (Map.Entry<String, AttributeMetadata> e : metadata.getAttributeMetadata().entrySet())
+            {
+                if (inheritedMetadata.containsKey(e.getKey()))
+                {
+                    throw new RuntimeException("Duplicate key from inherited bindable classes: "
+                        + e.getKey());
+                }
+                
+                // http://issues.carrot2.org/browse/CARROT-706
+                // Remap names of inherited attributes from actual field names to their associated keys.
+                final String key = fieldNameToAttributeKey.get(e.getKey());
+                if (key == null)
+                {
+                    throw new RuntimeException("Type: " + clazzName + " does not have a field named: " + e.getKey());
+                }
+
+                inheritedMetadata.put(key, e.getValue());
+            }            
+        }
+    }
+
+    /**
+     * Read metadata from a resource location somewhere.
+     */
+    private BindableMetadata readMetadataFromResource(String clazzName)
+    {
+        InputStream is = null;
+        try
+        {
+            FileObject resource = getResourceOrNull(StandardLocation.CLASS_OUTPUT, 
+                EMPTY_PACKAGE_NAME, metadataFileName(clazzName));
+            
+            if (resource == null)
+            {
+                resource = getResourceOrNull(StandardLocation.CLASS_PATH, 
+                    EMPTY_PACKAGE_NAME, metadataFileName(clazzName));
+            }
+            
+            if (resource == null)
+            {
+                throw new IOException("Resource not found: "
+                    + metadataFileName(clazzName));
+            }
+
+            is = resource.openInputStream();
+            return new Persister().read(BindableMetadata.class, is);
+        }
+        catch (Exception e)
+        {
+            if (is != null) closeQuietly(is);
+            throw new RuntimeException("Could not load metadata from class: "
+                + clazzName, e);
+        }
+    }
+
+    /**
+     * Return a FileObject or <code>null</code> if it isn't accessible.
+     */
+    private FileObject getResourceOrNull(StandardLocation location,
+        CharSequence pkg, String relativeName)
+    {
+        try
+        {
+            return filer.getResource(location, pkg, relativeName);
+        }
+        catch (IOException e)
+        {
+            return null;
+        }
+    }
+
+    /**
+     * Extract attribute metadata to a string.
+     */
+    private void extractAttributeMetadata(TypeElement type,
+        Map<String, AttributeMetadata> attributeMetadata,
+        Map<String, AttributeMetadata> inheritedMetadata)
+    {
+        for (VariableElement field : ElementFilter.fieldsIn(type.getEnclosedElements()))
+        {
+            Attribute attr = field.getAnnotation(Attribute.class);
+            if (attr != null)
+            {
+                final Map<String, String> tags = new HashMap<String, String>();
+                final String javaDoc = processJavaDoc(field, tags);
+
+                final AttributeMetadata metadata = new AttributeMetadata();
+                extractTitleDescription(metadata, javaDoc);
+                metadata.setLabel(tags.get("label"));
+                metadata.setGroup(tags.get("group"));
+                metadata.setLevel(AttributeLevel.robustValueOf(tags.get("level")));
+
+                final String attributeKey = getAttributeKey(field, attr);
+                if (attr.inherit())
+                {
+                    AttributeMetadata inherited = inheritedMetadata.get(attributeKey);
+                    if (inherited == null)
+                        throw new RuntimeException("Class " + type.getSimpleName() 
+                            + " has no inherited attribute with key: "
+                            + attributeKey + ", inherited attributes: " + formatInherited(inheritedMetadata));
+
+                    metadata.setTitle(notNull(metadata.getTitle(), inherited.getTitle()));
+                    metadata.setDescription(notNull(metadata.getDescription(), inherited.getDescription()));
+                    metadata.setGroup(notNull(metadata.getGroup(), inherited.getGroup()));
+                    metadata.setLabel(notNull(metadata.getLabel(), inherited.getLabel()));
+                    metadata.setLevel(notNull(metadata.getLevel(), inherited.getLevel()));
+                }
+
+                // See http://issues.carrot2.org/browse/CARROT-706
+                final String fieldName = field.getSimpleName().toString();
+                attributeMetadata.put(fieldName, metadata);
+            }
+        }
+    }
+
+    /**
+     * Format inherited metadata.
+     */
+    private String formatInherited(Map<String, AttributeMetadata> inheritedMetadata)
+    {
+        StringBuilder builder = new StringBuilder();
+        for (Map.Entry<String, AttributeMetadata> e : inheritedMetadata.entrySet())
+        {
+            builder.append("\n\t");
+            builder.append("Key: ").append(e.getKey());
+            builder.append(" Description: ").append(e.getValue().getLabelOrTitle());
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Return the attribute's key.
+     */
+    private String getAttributeKey(VariableElement field, Attribute attr)
+    {
+        if (attr.key().length() > 0)
+        {
+            return attr.key();
+        }
+        else
+        {
+            String bindablePrefix = getBindablePrefix((TypeElement) field.getEnclosingElement());
+            if (bindablePrefix == null)
+                return field.getSimpleName().toString();
+            else
+                return bindablePrefix + "." + field.getSimpleName();
+        }
+    }
+
+    /**
+     * Return the bindable's prefix or <code>null</code> if empty/ not present.
+     */
+    private String getBindablePrefix(TypeElement bindable)
+    {
+        String prefix = bindable.getAnnotation(Bindable.class).prefix().trim();
+        if (prefix.length() > 0)
+            return prefix;
+        else
+            return null;
+    }
+
+    /**
+     * Pick the first non-null value.
+     */
+    private <T> T notNull(T... objects)
+    {
+        for (T t : objects)
+            if (t != null) return t;
+
+        return null;
+    }
+
+    /**
+     * Emit bindable matadata as an XML file.
+     */
+    private void emitXML(BindableMetadata metadata, TypeElement type)
+    {
+        OutputStream os = null;
+        try
+        {
+            final FileObject out = filer.createResource(StandardLocation.CLASS_OUTPUT,
+                EMPTY_PACKAGE_NAME, metadataFileName(type), type);
+            os = out.openOutputStream();
+
+            final Persister p = new Persister(new Format(2, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
+            p.write(metadata, os);
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException("Could not serialize metadata for: "
+                + type.toString(), e);
+        }
+        finally
+        {
+            if (os != null) closeQuietly(os);
+        }
+    }
+
+    /**
+     * Return the resource name for a metadata XML file associated with the given type. 
+     */
+    private String metadataFileName(TypeElement type)
+    {
+        return elementUtils.getBinaryName(type).toString() + ".xml";
+    }
+
+    /**
+     * Return the resource name for a metadata XML file associated with the given class
+     * name. 
+     */
+    private String metadataFileName(String clazzName)
+    {
+        return clazzName + ".xml";
+    }
+
+    /*
+     * 
+     */
+    private void closeQuietly(Closeable os)
+    {
+        try
+        {
+            os.close();
+        }
+        catch (IOException e)
+        {
+            // Ignore.
+        }
+    }
+
+    /**
+     * Extract title and description in one step.
+     */
+    private void extractTitleDescription(CommonMetadata metadata, String javaDoc)
+    {
+        if (javaDoc == null || javaDoc.trim().isEmpty()) return;
+
+        final String comment = MetadataExtractorUtils.toPlainText(javaDoc);
+        if (comment == null)
+        {
+            return;
+        }
+
+        final int next = MetadataExtractorUtils.getEndOfFirstSentenceCharIndex(comment);
+        if (next > 0 && next < comment.length())
+        {
+            final String description = comment.substring(next + 1).trim();
+            if (description.length() > 0)
+            {
+                metadata.setDescription(description);
+            }
+        }
+
+        if (next >= 0)
+        {
+            final String firstSentence = comment.substring(0, next).trim();
+            if (firstSentence.length() > 0)
+            {
+                metadata.setTitle(firstSentence);
+            }
+        }
+        else
+        {
+            metadata.setTitle(comment);
+        }
+    }
+
+    /**
+     * Process JavaDoc of an element and extract taglets.
+     */
+    private String processJavaDoc(Element e, final Map<String, String> tags)
+    {
+        final StringBuilder javaDocText = new StringBuilder();
+
+        final String javaDoc = elementUtils.getDocComment(e);
+        if (javaDoc == null || javaDoc.trim().length() == 0)
+        {
+            return null;
+        }
+
+        /*
+         * Use qdox to parse the JavaDoc part. JavaDoc is partially parsed 
+         * by apt infrastructure, but we can fake it easily. 
+         */
+        final JFlexLexer lexer = new JFlexLexer(
+            new StringReader("/** " + javaDoc + " */"));
+
+        final Builder builder = new BuilderBase()
+        {
+            @Override
+            public void addJavaDoc(String arg0)
+            {
+                javaDocText.append(arg0);
+            }
+
+            @Override
+            public void addJavaDocTag(TagDef tag)
+            {
+                tags.put(tag.name, tag.text);
+            }
+        };
+
+        final Parser parser = new Parser(lexer, builder);
+        try
+        {
+            parser.parse();
+        }
+        catch (ParseException x)
+        {
+            throw new RuntimeException("Could not parse JavaDoc of: " + e.toString(), x);
+        }
+
+        return javaDocText.toString();
+    }
+}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/BuilderBase.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/BuilderBase.java
new file mode 100644
index 0000000..3cc7ca9
--- /dev/null
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/BuilderBase.java
@@ -0,0 +1,74 @@
+package org.carrot2.util.attribute.metadata;
+
+import com.thoughtworks.qdox.model.Annotation;
+import com.thoughtworks.qdox.model.Type;
+import com.thoughtworks.qdox.parser.Builder;
+import com.thoughtworks.qdox.parser.structs.ClassDef;
+import com.thoughtworks.qdox.parser.structs.FieldDef;
+import com.thoughtworks.qdox.parser.structs.MethodDef;
+import com.thoughtworks.qdox.parser.structs.PackageDef;
+import com.thoughtworks.qdox.parser.structs.TagDef;
+import com.thoughtworks.qdox.parser.structs.TypeDef;
+
+/**
+ * Empty implementation of qdox's builder.
+ */
+class BuilderBase implements Builder
+{
+    @Override
+    public void addAnnotation(Annotation arg0)
+    {
+    }
+
+    @Override
+    public void addField(FieldDef arg0)
+    {
+    }
+
+    @Override
+    public void addImport(String arg0)
+    {
+    }
+
+    @Override
+    public void addJavaDoc(String arg0)
+    {
+    }
+
+    @Override
+    public void addJavaDocTag(TagDef arg0)
+    {
+    }
+
+    @Override
+    public void addMethod(MethodDef arg0)
+    {
+    }
+
+    @Override
+    public void addPackage(PackageDef arg0)
+    {
+    }
+
+    @Override
+    public void beginClass(ClassDef arg0)
+    {
+    }
+
+    @Override
+    public Type createType(TypeDef arg0)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Type createType(String arg0, int arg1)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void endClass()
+    {
+    }
+}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/CommonMetadata.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/CommonMetadata.java
new file mode 100644
index 0000000..9ad9072
--- /dev/null
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/CommonMetadata.java
@@ -0,0 +1,81 @@
+
+/*
+ * Carrot2 project.
+ *
+ * Copyright (C) 2002-2010, Dawid Weiss, Stanisław Osiński.
+ * All rights reserved.
+ *
+ * Refer to the full license file "carrot2.LICENSE"
+ * in the root folder of the repository checkout or at:
+ * http://www.carrot2.org/carrot2.LICENSE
+ */
+
+package org.carrot2.util.attribute.metadata;
+
+import org.apache.commons.lang.StringUtils;
+import org.simpleframework.xml.Element;
+
+/**
+ * Common metadata items for {@link BindableMetadata} and {@link AttributeMetadata}.
+ */
+public class CommonMetadata
+{
+    @Element(required = false, data = true)
+    protected String title;
+
+    @Element(required = false)
+    protected String label;
+
+    @Element(required = false, data = true)
+    protected String description;
+
+    /**
+     * A one sentence summary of the element. Could be presented as a header of the tool
+     * tip of the corresponding UI component.
+     */
+    public String getTitle()
+    {
+        return title;
+    }
+
+    public void setTitle(String title)
+    {
+        this.title = title;
+    }
+
+    /**
+     * A short label for the element which can be presented as the label of the
+     * corresponding UI component.
+     */
+    public String getLabel()
+    {
+        return label;
+    }
+
+    public void setLabel(String label)
+    {
+        this.label = label;
+    }
+
+    /**
+     * Returns the label if it is not-<code>null</code>, otherwise returns title.
+     */
+    public String getLabelOrTitle()
+    {
+        return StringUtils.isNotBlank(label) ? label : title;
+    }
+    
+    /**
+     * A longer, possibly multi sentence, description of the element. Could be presented
+     * as a body of the tool tip of the corresponding UI component.
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+    public void setDescription(String plainTextDescription)
+    {
+        this.description = plainTextDescription;
+    }
+}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/MetadataExtractorUtils.java b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/MetadataExtractorUtils.java
new file mode 100644
index 0000000..4f37032
--- /dev/null
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/attribute/metadata/MetadataExtractorUtils.java
@@ -0,0 +1,106 @@
+
+/*
+ * Carrot2 project.
+ *
+ * Copyright (C) 2002-2010, Dawid Weiss, Stanisław Osiński.
+ * All rights reserved.
+ *
+ * Refer to the full license file "carrot2.LICENSE"
+ * in the root folder of the repository checkout or at:
+ * http://www.carrot2.org/carrot2.LICENSE
+ */
+
+package org.carrot2.util.attribute.metadata;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A number of utility methods for working with JavaDoc comments.
+ */
+final class MetadataExtractorUtils
+{
+    /**
+     * Extracts the first sentence of a JavaDoc comment.
+     */
+    private static final Pattern FIRST_SENTENCE_PATTERN = Pattern
+        .compile("\\.(?<!((\\w\\.){2,5}+))(\\s|\\z)");
+
+    /**
+     * Converts a JavaDoc link to text.
+     */
+    private static final Pattern LINK_TO_TEXT_PATTERN = Pattern
+        .compile("\\{@link\\s(.+?)\\}");
+
+    /**
+     * Matching of '#' characters in links.
+     */
+    private static final Pattern SPACE_HASH_PATTERN = Pattern.compile(">#");
+    private static final Pattern TYPE_HASH_PATTERN = Pattern.compile("([^>])#");
+
+    private MetadataExtractorUtils()
+    {
+        // No instantiation
+    }
+
+    /**
+     * Returns the index of the last character of the first JavaDoc sentence.
+     */
+    static int getEndOfFirstSentenceCharIndex(String text)
+    {
+        final Matcher matcher = FIRST_SENTENCE_PATTERN.matcher(text);
+        if (matcher.find())
+        {
+            return matcher.start();
+        }
+        else
+        {
+            return -1;
+        }
+    }
+
+    /**
+     * Converts multiple space, tab, return characters into one space.
+     */
+    static String normalizeSpaces(String string)
+    {
+        if (string == null)
+        {
+            return null;
+        }
+        return string.replaceAll("[\\t\\r\\n]+", " ");
+    }
+
+    /**
+     * Converts in-line link tag to text.
+     */
+    static String renderInlineTags(String comment)
+    {
+        String content = comment;
+        content = LINK_TO_TEXT_PATTERN.matcher(comment).replaceAll("<code>$1</code>");
+        content = SPACE_HASH_PATTERN.matcher(content).replaceAll(">");
+        content = TYPE_HASH_PATTERN.matcher(content).replaceAll("$1.");
+        return content;
+    }
+
+    /**
+     * Converts JavaDoc comment body to plain text. Currently only normalizes space and
+     * renders links. In the future, we might think of dealing with HTML properly.
+     */
+    static String toPlainText(String comment)
+    {
+        if (comment == null)
+        {
+            return null;
+        }
+        final String normalizedSpace = normalizeSpaces(comment);
+        final String linksRendered = renderInlineTags(normalizedSpace);
+        final String trimmed = linksRendered.trim();
+        if (trimmed.length() == 0)
+        {
+            return null;
+        }
+
+        return trimmed;
+    }
+}
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/simplexml/ListSimpleXmlWrapper.java b/core/carrot2-util-attribute/src/org/carrot2/util/simplexml/ListSimpleXmlWrapper.java
index 7325cf2..111ad04 100644
--- a/core/carrot2-util-attribute/src/org/carrot2/util/simplexml/ListSimpleXmlWrapper.java
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/simplexml/ListSimpleXmlWrapper.java
@@ -24,7 +24,7 @@ import org.simpleframework.xml.core.Persist;
 @Root(name = "list")
 @SuppressWarnings(
 {
-    "unchecked", "unused"
+    "unchecked", "unused", "rawtypes"
 })
 class ListSimpleXmlWrapper implements ISimpleXmlWrapper<List>
 {
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/simplexml/MapSimpleXmlWrapper.java b/core/carrot2-util-attribute/src/org/carrot2/util/simplexml/MapSimpleXmlWrapper.java
index b0f3faa..1f74f6e 100644
--- a/core/carrot2-util-attribute/src/org/carrot2/util/simplexml/MapSimpleXmlWrapper.java
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/simplexml/MapSimpleXmlWrapper.java
@@ -27,7 +27,7 @@ import org.simpleframework.xml.core.Persist;
 @Root(name = "map")
 @SuppressWarnings(
 {
-    "unchecked", "unused"
+    "unchecked", "unused", "rawtypes"
 })
 class MapSimpleXmlWrapper implements ISimpleXmlWrapper<Map>
 {
diff --git a/core/carrot2-util-attribute/src/org/carrot2/util/simplexml/SimpleXmlWrapperValue.java b/core/carrot2-util-attribute/src/org/carrot2/util/simplexml/SimpleXmlWrapperValue.java
index 6c6d112..7c214c1 100644
--- a/core/carrot2-util-attribute/src/org/carrot2/util/simplexml/SimpleXmlWrapperValue.java
+++ b/core/carrot2-util-attribute/src/org/carrot2/util/simplexml/SimpleXmlWrapperValue.java
@@ -115,7 +115,9 @@ public class SimpleXmlWrapperValue
      * 
      * @return the actual value or <code>null</code> if value cannot be unwrapped
      */
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings({
+        "unchecked", "rawtypes"
+    })
     Object unwrap()
     {
         if (value != null)
@@ -161,7 +163,7 @@ public class SimpleXmlWrapperValue
         {
             if (wrapper instanceof ISimpleXmlWrapper)
             {
-                return ((ISimpleXmlWrapper) wrapper).getValue();
+                return ((ISimpleXmlWrapper<?>) wrapper).getValue();
             }
             else
             {
diff --git a/doc/assets/img/attribute-metadata-xml-run-configuration.png b/doc/assets/img/attribute-metadata-xml-run-configuration.png
deleted file mode 100644
index 4c26dc10c3789fe2d94a2b5f1a554f6dc0211340..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 18104
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
XH_TOA7If?%P=LYH)z4*}Q$iB}SU=||

diff --git a/etc/ant/common/attributes.xml b/etc/ant/common/attributes.xml
deleted file mode 100644
index dead932..0000000
--- a/etc/ant/common/attributes.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<project name="carrot2.common.attributes">
-  <path id="attrs.classpath">
-      <fileset dir="${carrot2.master.basedir}">
-          <include name="tmp/jar/carrot2-core*.jar" />
-          <include name="lib/com.thoughtworks.qdox/*.jar" />
-          <include name="lib/com.google.guava/*.jar" />
-          <include name="lib/org.apache.commons/*.jar" />
-          <include name="lib/org.simpleframework.xml/*.jar" />
-          <include name="lib/org.codehaus.woodstox/*.jar" />
-      </fileset>
-  </path>
-
-  <property name="common.attribute.names.source.path"
-            location="${carrot2.master.basedir}/core/carrot2-core/src/org/carrot2/core/attribute/AttributeNames.java" />
-
-  <target name="tasks">
-    <taskdef name="metadata-serializer" 
-             classname="org.carrot2.util.attribute.BindableMetadataSerializerTask" 
-             classpathref="attrs.classpath" 
-             loaderRef="attrs.classloader" />
-
-    <macrodef name="attributes-xml">
-      <attribute name="java.source" />
-      <sequential>
-        <switchClassLoader loaderRef="attrs.classloader">
-          <mkdir dir="${lingo3g.master.basedir}/tmp" />
-
-          <metadata-serializer destdir="@{java.source}">
-            <commonMetadata>
-                <path location="${common.attribute.names.source.path}" />
-            </commonMetadata>
-
-            <fileset dir="@{java.source}">
-                <include name="**/*.java" />
-
-                <modified update="true" cache="propertyfile" algorithm="digest" comparator="equal">
-                    <param name="cache.cachefile"
-                        value="${lingo3g.master.basedir}/tmp/attrs-cache.properties"/>
-                    <param name="algorithm.algorithm" value="MD5" />
-                </modified>
-            </fileset>
-          </metadata-serializer>
-        </switchClassLoader>
-      </sequential>
-    </macrodef>
-  </target>
-</project>
diff --git a/lib/org.carrot2.antlib/.classpath b/lib/org.carrot2.antlib/.classpath
index f957b6a..b0d9964 100644
--- a/lib/org.carrot2.antlib/.classpath
+++ b/lib/org.carrot2.antlib/.classpath
@@ -3,5 +3,8 @@
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANT_HOME"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/com.thoughtworks.qdox"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/org.simpleframework.xml"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/carrot2-util-attribute"/>
 	<classpathentry kind="output" path="tmp/eclipse"/>
 </classpath>
diff --git a/lib/org.carrot2.antlib/build.xml b/lib/org.carrot2.antlib/build.xml
index 20fc200..c79f649 100644
--- a/lib/org.carrot2.antlib/build.xml
+++ b/lib/org.carrot2.antlib/build.xml
@@ -20,7 +20,8 @@
 
     <target name="jar" depends="clean">
         <mkdir dir="${carrot2.common.antlib.basedir}/tmp/classes" />
-        <javac debug="true" destdir="${carrot2.common.antlib.basedir}/tmp/classes" source="1.5" target="1.5" includeantruntime="true">
+
+        <javac debug="true" destdir="${carrot2.common.antlib.basedir}/tmp/classes" includeantruntime="true">
             <src path="${carrot2.common.antlib.basedir}/src" />
         </javac>
         <copy todir="${carrot2.common.antlib.basedir}/tmp/classes">
diff --git a/lib/org.carrot2.antlib/org.carrot2.antlib.jar b/lib/org.carrot2.antlib/org.carrot2.antlib.jar
index d0257d6c47938722aeb339776e2c1af723f39331..ce230e6fda08240e8942e96e146b6b7f7441bd69 100644
GIT binary patch
delta 16018
zcmZX5b9iLmwrx7LZQHhO+qSLhsN$q!+qOHlZQJa0(9!Gjd-t7t&wcgJ{JyF&_ujQ?
zeYM6MbB-3^x3B1L2+DF`;IJSd&>$cRZtw{R)L`;|19$X4VT9<Pa7Kml_e}wi|M5ag
zQu&7YpSek5-`K(aUL(o(+x<WIrvYLViociUM+X66{foy>N(aRQ`1#{&V0==pZ?D^z
z#uqDWD%-aqJ=k|T6ri-Wr1n@dE5H@hlxSyMDJI&qvQ19e6H$W(Lt`lSVKIp)7X^!^
zIBt}3zKA1Z&_$KM1onQsroAV>Z1XiuQmzYse0ZL^-13~}{>r({_B+kcQp^Ue2mOj6
zi5#Te!4iW&)Y=CHY*ik#Vh?cBOFG889DUFVA`cU=sP8M@2Wp`csoxi1mmWBy6Jb8b
zm%muUx3uf&-=L5^!wx=Iv<pSW!<0aodLt8IaS~OI48DZ6`>R&}qH)2A*<XB#L4LJ|
zkKa?-A3GgdJT3B;U-RdWA{&^(Quk+xq8eIK*;h7{MvPnqn9;_K{^)~o!HGLCho2tU
z1@9?7P=}`*o|27;fRoBqzqf#xH)Jzw2cFWVFL!9|)=|0UX2`f_u6$3pVK;C}39fW(
znqBD5Hlx-y(6sg_yMCm2tj@jQLd|us+6r~_fw@&)aYoB(7j4_G(G^ou8I)bOS-enF
zzSNsI(=;jsY`SreywY^HCb2S3nTMhVs4{9H>p19^wn>UusQp5ODERG}87F^uA*tnP
z6u+-u`fLtwGN*W+LC|Ry^=!<1^gFA$Nu4)+fnfAW6MC1`QfXju`x}>wN&F>`@5Cj$
z8t_<kmH;`f7+>r;MnRAl7B@3<mRu6T)=9+TK7&RcaOiGpoON^d20!a8KKIzwFE!eX
zw#mSiHoXyNRm=ss=fI!N+L&vjH!$z0q=aBU-^6OXpdeDstz=f|GADh^pIJ?pd9|i%
zOG3`C$=t%t;D6{{+%_nS2X(FlHQi3L-3TuwV)k0knI4z$V1KII#zbA<d=-FiwP8So
zVeUQxxN-HVW5%LO*BPim6fIcHel+8gD)&`<O)2?V&p15PsWZAGXN5jRSJyC|XH;@P
zN83|*VAqK2sCMsxv8&t=PEjhH<O8E!kY8#;FBlxPJoRgYwBRz6Qj)T`FnNRATA@6P
z5sPf!@T;Y>P8~o=qY0Tw9htsEuGZ}Q6Y2N}u$=7R0~|i1^Q<$Qe}w&9jaRv<Z{&%G
z1@^>a>reOe-;^BCd}?1q;V)A41WQ<mW<rY%rLdVYWZC6#NSfNs&>38zpRYTdV)yh8
zWV0T(sh`<t$0LB3=y%Q6!&bqJUaqDAoepdeX7}{qORHZxvomC{CWDe;#!$Rs3<pgB
zU91PClWA41<lep&&X=?ZJXc!IJw(#_OG-cI)?`Z#6*@7v5G~m(Cms(vrP6)1qo!dk
z<HI#NNhU6<QHvZamd*7Cn_gOj&ksE~{GoO+;sna}{nqOC*?VT6+$a%3VW?w<88)M_
zD28nf*7{)Q@Aw1r_rtw|!V34Lyj2DP@%Ly5Lc?;nfxx^bd-iwG-laRb_e_Z5eJ;@x
z(dxxJy&yGi>9gBAKZr|l%LALN{zwP}IszeM-;aAqnx%I3o^6hU*hXPoqcHlLbr-+h
zeQwJQV?_G3D{_ksoI@R_Q&t<BEC*tX_S#U@p<hrz)4uO2gINulgL!wSqNJ37l`!OH
zj&}$EMPgkhdJFa{TZZ>6Njypfq!#-ZSN|$cl8e#c?mZHO+-F{Zw1}KflpCYNV`n5o
zXWE6;jsN}wIMF5{M)rp;LqgZt5aHB}pCm(`Kok2PQ6RY*)1}uH*k`JKMcLwE=kW^R
zdVE&L=I9z)^vn>|rUx8B_OujW)>4KP!r^%1HnbprM%?IF^imwt=Ygh-HuLnVbo-Lh
z<|237;LI1NtL|qkB1wfy4(baY6`aigCniVq%Pg%u!r`-Ii;-7XOh_(2K1%lw3ZoH6
zif^4$PzD+4&C!{Lc!x6Y3{Cq|{%`z_-L>N`R<Y+xSM{nH`Ww<vP+^^b(vwE1Fxye*
z>#0xUFKtdox$I;xic{Rh-yRx_8^da8{HdkeIrd^nR|n#rxM4blp1^JEEJkuY%5D5n
z)}384HsCT<b9z~H2GzXu8qRo~Wp3?2MGONXj!DNe<RPD^3*mLryKKdg6qpx3wKv)>
zZ9Nds%KSRTIq4SzxJd&fuZ@*)EGc{E?XZHESYTsx0hN8w3&>Q>l9KE8JQzi_zem3m
zzdo$RAnsu3$FzaBwyLU*&0tHWTaxB5C=oAZhIcmozAx;k&`0LRQppa-4K##KYVvRC
zGe=)O8^XjzhztmG8+eh6kftf4h(A+HXN{>eXlWo(k9QWPgO>*+fDNWk{4QHooGr4%
zZs`gQeK}<j+X6Btq4_LH0GaKO;rPOAMXV6Z{B=l3rU(kC;BdA|(iL_k;1S-_K}|GZ
zY!C#p2j|1uLs^|lmOS0fsA>m}hu1n;;@vjMofVOfDc-e6)Y-N*UC#NVzVAOs4}V#N
z<);8#sx#R}&s6{)EQD#|cY5H}K2z7Wd~r<}Td{AicaRWDq}lMx;i*R~OgO2}ujA4I
z-0|M3HTLl<5|_(rNG3*h0mX(j(Y0e{B8`<jwDDoj#H<lDDePTmB2zW!X3=)D<3;=Z
zAj^`GmDo<W;$p0tQCI?%C~P%?#=qsq6BF=?Cicz<LW%%duvd<K4DBhqX@Z_<rj&KO
zU~(*rHu6FJ9fI`XGO)K48f@gr668(oiPk0F-+4p9nq3jDw}j<Z4?OkbN2$HgZ~Ixc
z$X#Yo%Qt1_Yleg*uXEP=0T>lGcMe#qx^Z|JN!#ziJs`J37}>GTE%-Y?fhlt~2Dp_l
z<<Yw9HaCDn|Kg#9B4NR-K#V0UVTqCr<rylD!Xw5~#onrVT~v=sbAhY`z(qK$!n7{x
z8wQT$mr(lb>1&q8l^+hA)VXZAI<B`)BSpR_HMt^_KPp-9$8;j0j%$_j&%k~OUETOX
z2mkRMnO|NhOIqX+68w>=eRUkBhl=$a&(xT)Z5{w7hi$G%hIj{wC0eA;pqkKTgix7^
zRxLRpQYa$EbJG33DS65l<36A0(!yX;^QDC>CCN5;vW6-T=*i9v>GNYbMS<@SgVv0w
zKg4To7#^IUPvasIjZo2jS(j2reM0CFQil%5rS}zT;$xf(qQ_bo4|E5qf*w3sk70Yf
zCTRhZee2|1n0L_IzR8L44LF1(;ko%UFc<N212US=&>V3px8M#ja}zQTw&IXozyhZv
z1Xn(>9W?%mMnqWdi^RGuqw)Y~EwmWii=QF#HOca1dSB6S>iR_o21VfX^pR|PNaggf
zVa2MF6<D-6D1)o93zfW<$<ao)cIf9TQ<s1)9pgYuO=q2iu&0%L7f%GU<5~(aYb*gE
zbx%XCz}dUVlp+vHWm596_s<w%L5(kGH$*dUh!R5c($I$X$TOrM2YP{nl}M10p@w&6
z;;iZu`)|YilV93HOc9X$Qm>0k0YMwHW)Qb@_l2PzY(?7Yp&k-2)z=c*n>vqn6sxKm
z6nz-_6$+sG<G(Q*g0{qsAo}c32#*^DYgaMzee1++LckknK^n{(p$~iIVB0djvM4T{
zUWxu6O@#*e7Zrto-Lo751p%>z00E)=7qtXP+SprYsLC^%*_*hzg{fVuE()Uy*vP4g
z!ZJJ*5bFvSmlzk7=Lb^{v$Cosd@~uzv(c6#Cg<3u<qvV%(_=2OkhFTtn|V==^GZsN
z*S(u{e7ae8o9#Y5dCsfb{U%?OpO1F#Ih24h8LHg~OUXiU=n2mQp<>OlrQ(dW2zvwA
z?+J!VPhg=tECBB~;O&~)Lv=(aXsbTQ*j_Wi^}?^JJm*|pd4J=9p%tN<Iu5V;BbYR2
zu(iB<nOU-F;SkbQYCtJ}RAV!5PzJE#-C)h3A<W@&NMe$PwxVo>ZauO`tFE%%uy1KK
zGQF|uHuouxE6~&Hw2N{>j=3XfqBQ{wp;@2RUf$UhOtZ@2u2%VJFioELCZKw#;~2rY
z%brcY)2SZCYbX-43TQuxQ?Z?Dz~vt-z7pWh=<kr;3tK`>mAe#1J2`K!`Bi8I(<UR7
zo#0N*mOw_ikrqW6K2}H<>J4K&mY<1=j*wx*i(tgIPG!_(ta$GC8Dlu|wuS;41_Hx~
zO7)*=Ej#V`QXJLO70<I_nG#B~rP;|zmSZqVbB4#$weG>;SaU1Aff6`A7;@f<N?%q%
zp+h#KMk((j6qyS7LG|edCwx1?)yhIMo`#}$UYx5m*<<oAxoa_Y=oxmzA#6P3Igl1g
zVE%#Rbw(#Rv9vrtCj_%+<U0YwQ_Y#A@QZmXGGE5nB>UI_VWHtWiku5OkTTkGc0xJq
z8x$zhgkro8##%P9zWssvMH;`qVfPVV7ZZr}A3}(RgY)veLKG~nMqv?@aoNNd%t}GP
zA6!Dpphh~8E=SRAO{I`AUV}2Kr0(I4NYm9yv#r9rOdIx5=u);zD&aalCg{>!%vuSN
zJ)*fZEYCl|+&e||oTtX4yoog2)e+ATf|G($GhQfPoRy0SJlLb~LQ*FwXB6`g7UK|#
zd{grdlBmu;_ZFPvIPnn5w#Qm<^cjx%g80u}kDuns!tl3H`;DCB!c3I(B7^~m)w=Y<
z*B}U_THnsFr*!Bnrr8wbwXtd1HWW2ua0sp_X6K}ksiH~1l*{>7Ma9XsnX|qFjv_%z
zObXkds!JREEg4oCwM6&&kSsoJ_7f`bSIDjpa=`4=6~(3uk>FKFPw%eJ>@BC&*XMco
z>Nj^2#yEm>)gN|!r_2nva_oTC7=L`0Z1kjHY#vs9oMCQU7K%(YSjFg1d3={_^oS<d
z8JZU$wqWHR3&gJaU3;(-42Dv~$)*eEF3NNgY!BWjBtJ#wFW8>4JsX_ap$0{2qi`z=
zf1}6Q$P=hSA47H_^}Ar@uOjZi7_8wl3J5k>L(Mxh2rP8{<ol=?IaI)bB&F2}!C_z%
zvB~-#%t!K$%|_0L<;+<^{*l`-%p&fXtn`Z?&vxb+z6)F_NB;-VMa(N2LJZ_UuyvPF
z9<Dz)hYR*b2ZlAADkg@mz+sM2-u=QyfX&9evo*(!*JJXU|L9iD;L323b=wf;cZEU`
zDyiRfHHpb<z75Xc@Hv2`$XT0c5+^u1XWp&Iw;%nNG0TBsW?X2qm$W1kx_z76*=&Yc
zPVJ36&(Gu(0uI<X8@=$3KCr{MeL~uKJEiT+y!<8ZeHd^pI~fPqCfOo21l^2I95QtV
zGTS_-_m3xbra5c%Sx`6LTr*rSzPF}Q6s=i#gma(U6ZpRGTI&EU!k`EFV?)5OQe~6%
zhI;Cw!0Hiw?&Js#nVLI9?|szA8C@gIiFNBHA!3t=`4+ljg8V0BL~G0<P^_816so^8
zU6WF43inaRY=!=cFR3g6fi*D>^~BtLk`?+A+6z_#*%50d?xl~A5)@4gGE56CGoy2s
zB8`RB>uCexTPpxQ+-g|r%9O<H(eF{$R@5}BJu=Gh$^<@l4vx07L2kJFB{+)ks_?!N
zO&kQN{Dt4M@`Z*`PMb)!rOx`K@omOD=I5o3qee{!|M&hu!(oiZ)y9%88=XyO_DN5U
z!<h5-YuZ5I2dyERRf~0LZ;963HR<MiJ<3)fqlsU7V+_EdqtnJl<k2Ry%a^eX&R4x4
z7JZafl^|#UQOSLaQP({|HA>2I+SJ{q2)6cs&}3-4Fk^@i0}1Ar=<ubt*f10G<Q;cz
z>G}C}=b;S@o?z0b#?Qz$a`shSwc*W|k|?9dq@8{ZjNTCqpmrG2^b6zDq_@&A$d1-M
zo<FgPLIuFs#+SyCAI1_)K{XEpWmBudS)=^C@X$8t4~<w8!{-Qx*FwIE(s@VWzPlX(
z`t{sZ@Jc_Nr}P;k1?4hUv+KtaKCqX^5qI5TqyKNwYxI_ma<{f>)s>`ML2cKWVjwGa
zV~;^FozWcKVK1R{(X=uq@g%@~f;Ewj6&t5jngMWR5y;~bSGPx~a_3@zm}l%^ti5KM
z7bsPGV){kh@*;+AC~U?vnCVO<fLl0(O%?4sQ$f=%cuLr>hW;j~Ni>^AXB&4H#rF;D
zxNs>Gmd1X^N@j`jMk#rI9o1{`Ze|x<7d5L2d?+JyLLYZUqNDdvGmlWSA9)ejq~_Ln
zhzMBMVM68K#24l>LgjmjiY!o6r;ED~SM>e3$-hPXlbdffZPp8)SPr!B9b0#-WpkTP
zH~gNgxHMhxDS+fpw8`z4kAc!$fJE9WK>c(O_!MLC2xaRViN2=o`wO461(%aF3Q<X{
zDjt?SB7t}q3A`utBdAu<2~m8Ji1?4Ajs{>#Z%bc-T$hsdJD7=hVT<@p>C_WN1T<Y_
z2od#pBH`XJ*;ZFV4{$AE8t%tw{*PqVcwn@37w{#)&YHgw#N!u#ChFwcl-Vn2=GR$>
zX6ScRj33Ih-y=6M=UAJE)jE4HdsW$MNJOis*?<1V6m8QA4aK<-U~`{$H|{Hk&(H)I
zdh>-8hYMnt>^H(k(G=#E7%|N?X`Lkqnar_iZE%UN>vOd;PNfX9z^iBxP^e;`loLXA
z?8b~ebqV$(;)K7at}%uCa_d~~ixm)l%C?6mwGamWU@emKe#z|{Br6ctTt(%<l|6Fi
zPFQXck5fCjltW%8K=xrymJVP@u%`wj%sZ2EmDI^(pvfVhBS!eQ=p*@pk|I<?*}ZfX
z6*}Ssz-h;T<H0^?6yt)XcpMPy(N*#({YE(Q(Z`kF;z2*hsQrW<73Yd?oy68b{|t%b
zb@}B}-Tl2qg!*l+H1q`OK{?=-{*Ud`Mo70#F{Z_cF+^J@t{1{(`_CS}#299P+KsFv
zDWDHX_FGT#q=5w|Luxb!YmOYU;^vJ0z_hu7FEhr_D0@OLbjF>cA38$6UpE&MMM6$l
zM)I;to8_e6t##_adRf<tzERDPM(vEl{$W*XVh5OLzP^?j)8KQ@dQ`kX;HR2u`Sm<Y
z!J(!4h9Awow*VvI`;Km&J#r1;o;>i2v-zU7J2I1>qk1v)i|RVP$Il&s&+Vt6eAn|P
z)Vc@VIR#Aa9$LI-oWFDZ3<lhzygU7*9rre{?Z;ct?YU|_P^f@%lJn!<4fiURdcj32
zV4m@QBj~_4IS`MO-7`rAlh6%wc)^_vl}CWOgI+ZyrI#fkBQUGHGM@v8mlVmT8yqpo
zA&HD)drbe30NxXk6v_2i*8MD=f1v^DXqscICWcvN#oQ|)C$SXNyfLM^NnN~P&&S&Y
z@!pFf6ut>9(SUkNu04>kN5;*2qbLk?L^=$l9ZUa=FfVN4e?swsS{68mqY~KXM6viB
zxS(~|q+3(xxdOYY1o6}0>GNb@T*Q;OxWniIb<+;nebD<N5lULMslb~$?VU3N49mSp
zX~52aKk=WH6#XnL=<et+VQZ6TVp4klADsHHY%4G$(?aU}mtE|l{KGElg`tx4gb|ap
zv5)~I{pj{Z#M|bP(ZUsu)aax%6(q=FNunq@_LSp&mR9Q-!{nF^rX`y5m`j-pw*9o$
zb`o@vEK4gJns$2U(}n_Ny}yahl&)3Ie@#!FwBk*ipYu?J-~Q>D^#k;-w+VV5Yk*YU
zIbz$fRPV(x`(rZ>kKXz4;3p5}xN?(+caZ~@vCy{&B(Vn*ADwY-`mrXRnc~Lw<zRdC
zfv#J1d*677H13R{k-{2~jS>d6#JDjBT*g10aY((zYY7qd?OX%tLlc;L;?P`wA^3bK
zK*WbPpeu#m)gUX%o|g?Q9m+uLA{HSkjqlr3jM_k04Oly;_)0zq(%tru>GaTrpB@43
z1R!SVxapXgk~oq&Ega@s2nFbfJr!~|vPv0dlfisjH=EsS{}8as<u`iNc?w6L+LK}I
z7V3QHwa6C<+l0@jtz7A+Hs{e6Yo8L9G`k!99Gt;D?-{WXuK`;4p#yQ8I8}WQeLq!f
z>x!UDAXjm01`U~%QEM*I@3=AqlA8hf%hHz)9YKx)U1FDt_v8z<lr8FIsT@Z;e2<$S
zkSrH^)AmOE6&6jU-L$nO*U9q)Z5(!a5(tUD8w(|*eBQ(ejqZH6kO22IblUib9oQ$o
zXl5ins_tT>i}CE~l(XY6%phT=nu4nbofA%34LE;MUjYZJaBe40s}_o!l_r1!&2%HV
z{4zUsr$>gE1ZQ4@yzzeXBqnX`x@D?Yzu|0*u~%)I7NadJxzhv=O{UnzMFt}N#8Hm+
zTOKIooT_}+7wh9MUVDa)c<MOsm8@VaZ5?{r6*RZ>++F_kCAL<RQU(a71&#4QfsWbe
zVqpn)%IcVW(N{1qUnDWwLs9@UfD(Zw(Q?BQ9{U?z5-Yb6o7akadWXHL7q?Ccy)?uw
z7Bo-BARN%bxkMP}Icrg-DZG>|cwQ7By?jE^)M?3QT#ThnSmOq6hZE~L?64@Wqw2e5
zDNQf6jc8D+;w=l80m_E<s!Jm`Ox2KpNK-D05vyHh8iMcG_nTIbF&q$zuS+pn$g?0m
zEXQ4DtUiowXsNFrbBKX~#$C4ub%iX^C_G%ntpu2j`58qtvG}m=3Z8!;<*hIrf6p6&
zx(vnoq)ZU&aap%=Rikl__O3oWdk56-9)DS#NSCbX)E$&9f8jAi)5dp9zckYB*P{&#
zGLn5Vs_@3cieM2SPzSv0nno}mch>Z!yy3lT4*wNLgG$m8a2MWg%U?p8PaNJ|fPS2o
zO&dQhBZT&6X+MKkHQqH;EgK}lVzZ;b+6{<(J96ZVhqH_Ex)}JXC>-L4DdN$e;Ad-t
zr`!sKbliQ!&Z<)#78S)5p)P;$==bC2274`f?8Ja2;w7n8Spj}1T^h^wTDF{rv@U+U
z%D*noSeoSSjAuJ+`~5zmhmjYOJu?emQRPXM`Z1aHNb*Wrk1{2hZa*Lr08o_EX^L7#
zBgTNX&4|gh#IvE+oK8Ed4V=VYAz*vqq>pUXkK#1XdbKUjWUUyNFDVCJ`J&EDEuf^#
zuh&IiQOgx7qyd7N&XaEHGAjm)(Xj4PUrkG2G96a00vF1r1aXQ)L-dN9kvFyCH$!W4
zw|$~ty=_qP2Y?0&9GT6{8JsWF^Bw}P&t5(aW9V$f<Vi&tt5_tx`XDuBWf7!~VtpF#
z=z5d0qaeK<YXTh)<C+&!FjjG6lyE^x+*X$zyUb=r69A4kwowKC^(fTZ@58^%kbk4y
zUE_<5^SqR$24UfkP{#d|fnVy2_oWwx=MsHV2q(yzpUNOITRRY`qe_c+s}H>A0WVV?
zm^r7-tltnR_pIOt??{AfKq@TZPG!ZT6R95IsTaI9*;dD=W5=^YYsft5ll9j2ulAOz
zP855L5Ct^NE(VmKK`&ZZ)cj@=!Rd!k{8TAFOsA^%80J2Ki!siQh6r|2@X;IOrahuf
zymQl`NrOWRlGac#Mqe({W(TEkl^{j_WlY9V^r9RKz>kKIY#?`~Xe)YQ9<9|rBAX%S
zq4Gi}!tDp*eodA$=-^eu`u;3Kj!sF7JD^>7s{#Zcwr@y{%Skm%nJ^+vR`~@VJPyM(
zjBz|%Jr3i+V7e>7zB4K4etxmjNU8*}_^Vrf-yQ#Mm9c6J`IbRP%T|_{U>M73ImLNm
z%Evn&WPp!U7%kK<82#3OHtNk9yzPzOw#TzI!IZLjN6D_g_et=$XK?m{_vha03PYq=
z90CA2gqmK6_$C2n-$1}K9|mTMlxIK?LK<e$K;#wC<*ba~pK}0?7^$|E*S~$>gOAB{
zV8{|grU*n-n@rLkBy}|NtSv*_tk2nK+v9F=@}j-M*@~HEma}_3UzF(%7?^QW#)=QY
zB`6a(%8&Dj103;~2l{E`M>RG3VA<`tZ2^|mQt3Rnv}&vMln?eFro;|$o__QY>_4ki
z?P)@^1$@Utw}$P+Am0^hdco2(GIx5QIV1UYM@Y*Q5;c?3k9KyvCdI{PL34A+IF?n!
zIyPT}R=(Lm$_f0#*~X5BP!vJ&-Y9IRT}Wp>0BH;Av=;@#&dgG$0KUbS5pZ9dDGad3
zrwcf9trB)MI(3F(>?fe!%bjSlRCo6OK`S^!bTwKJjdUo>KM?naTJwPAsTbwX8@Smc
zIGIagk01n?5@~FiGhgnANp?Tjlx7AP7n%6ZrT4DlBQ~I8G6HfeNr;Vd_Uy;FqbIsw
zLwp<@Ynp2DFO{Sa?EDy1s@BH04r@TyxQ%@6Q@cyA^j{eaBB?;-hs%iLULJIJJjYGk
z<v7SS(=N3TYd2wb`bEE)Hpg;E$c&vTo77i}`4<IZuNs^)_Rexz{Nl~to!aVPBws+z
zEbZG%W|M@;RygBc{|ob3jM&;fKf$|7(Ayje{Rh{7%O3wCCRWh)_8~HV)jpP_03u0%
zffK3-x&RnDtUW{nL!cc*GSa3*v*yBxxD2ksT=)X}e49zeT!KgH6{6sa(mU2~5nJ|q
zsF$J`uhuMUQL{d%n;pN?Ew@>Mo10mq-9QlQf*eWAHr9IQzbdOFq|6qJAx&5#4DHAk
z$9KPxs#0a8g8m;%qpZ|iIGkO%Ld^t#o3~uYb$uJHCx__}6=SawGIe6ap|#^U?&2**
zj2jt>-)cZhkAjH}6tTiX1aPrhx)g5#pIxj^lH0Ci8h3&4E~%|F%D6-rvILT@TOZw*
zS%X;|7Hy^!)WFeW5#qD@?g-$6kvzMM?Ui2~bVSKpyo&G6kk?R;`>>+}Bl;kq@pQ64
zeaoVJN~dvQaSNyW;L!SMDo+h~a7C?m`vT=?0)a(;^rNjlk^zo06O%B1SUIz(CM+EC
zYb@P?pHrNVhTmlEb(YU!O|O{sVY*MnCy+D6EiR1Bx3q=n4b9>6!F#!S;g9keqE>EV
zGxtLgcJ{fkcFjuXiK~5DRlzo(h?k=nu2nQQBG06T7p}6~LK^KFt{)0WW2XD}BrT!Y
zi(5}|ZIZd2>KCmNVmrI(fZaTm&ZIJPENb|UZ$Ee1Uswk<c{&Z6fCa{;C;mh#v57u<
zmQlmi^L-hwEFu6=1fo#}^qZJIsa;qgW)(Fqul`6%gs2HkarshN#44Vt8hNSqpU?v@
z@?GWR!d=%7x`nc_?0PiN5wQnQRC6hFgM}hxQDjbCA+l&(oLkyjm8we<3cC6GSmk|%
zVBAdXib|7MVoZTssx_zo+-F6l2epd-wawU)7)4M3IqI8^i^9kPS*0>b_A=Dn&P)_E
zN1~U?)D*H|;0d%pK#?3YB1s83XJ`#fR}#ASgM{{(Ccqd#Ba!xskeg~LeyA3NLd9EI
zTFqqR#6O?bISGN-=O>6DPU<*sO(eD^O2D?&Xv!CvZ&$6jjYf58CNGwks+dV<kYS`=
zz}q<hgwA+sp+R@;xkd4mJn+c|0?(RL=sc*sj{DGRx2TMgP}@>8PhiBl`Bf~Bzmu##
zbS0APYU=jj_S}vc8@cm8Otl1Pc|(yZuf*lZ$R&_G>qphX=lb+)TJ144r;1FXnNXkC
zv%rKe7)dY5_#(g5!o!q&#A`mio9s;x9FJQ9EUKx2I6}$-C1IoWyp|JJxhRfbCD=pV
zR$tky^s%jtpNjs-_)YD72~t632$%SX7x>Q&{mS@7^rK+>M{CV8@zrBybg`rGdS5(h
zz-t*+vu#fNGAv00pJ(aLkFpW)N;dYVB&C#VT85`$8<=Z5iRdE1i5naw;HztiL---U
zTl6_wU}8}KmpR_q)E^l3V6A-o<AhPa3$?^ICopz9lGDF9@1#S#F}1xeb_qx#HWGJ>
zC->6@vBZVn6SoD%+cc~eO0f-!4*d!=Ar+)aPyB&YC(E4bET?Lv=eveonY4dg@QHLO
zH8gi0MI!%#Tl#2X*r0`eBnf*dS;Vr#1x#sW3mUl+^9PLFZi27DM-;n{<=J>Psozu_
zjWaE1o><}$$vD^0DMQqmco^nv-+`!RSCpOlg>UkBl)FEfsdthngM6^IM!hge_Re$S
z)&KfuLoAtmyafXR$@*J%i6#XRF(vJg69Fbui>Pb=Hi8SnI@i!gOB1qGWo2wPLV@X>
z3R$7TzgknVq*_RQ$U6=nl)e-7$q^a@i{YpG@Q~iAfnANLS^f#|OkTY=xqdetT6SN*
zpX++T())j*WDiO$Y^9u-A>d5erVk1rX!w&p-&A@382AZ9$7J`93U_r=8MM+)ECrMv
zxM9R&ODe3wv>(63577bbKOg|(2w8j#W*m3)WgK#hxo2xz=z0S%*r=veXg}ySjj_2p
z4tZ0@uft4|&FgJm!(azvJ1<+{ll*e=rm(kQ?5j+`x18Q2w^_puqf-PQaj#X1kFt-o
zMN$e>`4^`vJRmLl9bkcO9+N0aod7+A{hE6qgSjFjivDRX#p--1DGjSRDS8KwQ<r6y
zNF7hy9j5)wTQGm66^SZ0G}ZDiiTX0cLGk<gfy98H3}JFfw-fbixDHG2(k><KBnDE0
z$BBCi`zk#rrOca1pux88VB_3|$%bZC-?%p8eW+x${npqdsOt5{MX$YUX#oD2%Sy<;
z%h$f8+RgSXd>*t+s7&T)CC>7#c&Y*ON$W0ZjnwM2OLTNrw67*5WpTFK+I6hZZfd}J
zNPiqgLde`yYTg;Ls>5J*EEkzkJnD+_OYaye+EfqzVK#!pbmK9(g`a~oE@aLIn`u+A
zueBCj&lpzi0@TWk^hR-f(}1m=vb4k8F$a$j#<puMo_V(GTBmOGMOH_{;ixzb94AyA
z3_ISQzRozNdyK)YFO`^1K>nKRVHk4-`7s-DVmbo~|L?8OW&MU-itwQb{&IXRMP4gz
zA_4a1c@#tAamSuObvOczi+37cb<VS$Xo~={&k|vxh#g`*?iypZcR-x&V}-V&+GA?3
zU}=Wk1c$E{+aoO%a*}~qQ@VY&b1@>!s7%L<xjECkFL(^>8|C_B^PlfCX6&{l4~PdP
ztIC0}xB4Vm<V1V4JET?NZU|0?xUulJ#6%?YB!r~qvL$&ayAp*zqmK~RK&0SiqlesS
zhcd6;q_kZ%iGh!$hk)%b(O3fUZjtiE(R{-Q<+{Ue=oVayEP8{TAYWuVp!!da(3GuF
zS=2X}0cGkC)EpW5By3p)SaIbK%tQ8iA(kgR)!8Ppx`Gdqj3y)IPA~(>sPKfw&~IBJ
zxLy^w&(ymYKYGHbO?e)z((VKm(0OHP9^E7(CsKlBlNFImk^r}A(n*qLyCennqivJT
zCAXv>0_w+5)c4l`kV(lDXH+`Fqz&4nITu40>&iQ?A3uM!<JeNamMgQ;2jp3(k}uUn
z1fjsnUrX(q3gyo6z+A8o6i>Fr|C~~E$(Rv>za}^uD4f4V`nYVbtOtPn=Mhx-5v~Q3
z0|f%oiTp3R6GX%a_`e;^60J8cbSs=dO23S0OK1`jn>OSu%&4r(QsoK+WC-v`gl{kq
zVil}id@?|KzRM|ka&N6>O$R$YTRA3mnqXZy8;YzA;+4yL*QLXIe1TD-ccBZFJ0B}b
ztVD$HF{HO?FQ491zui+mrrpo|3qCE7>S3n??eM~=B7lo}zV>*A8Li}Dgt5G3T-A#_
zK1<B_gjLCFwmiVl*XT!$k^24LLZ*;<(Ma<i1B2?IT#N-+H}P!evUD(y-NP6%YWf27
z@1^1E!5BPb;U^(hnn+LD9Z_50C!qSnMyoi|fIAD@=T-cy4?jCPAEn0XEixR<>MfI*
zW-(|Z0`Qf{yp{bWfMKQnvohbd%c29=O<`priEb_M`qRW|`aI5zTYt;sZ2f#VQ$UiW
z%nDv0hb@@qcezO!!>DpTzOu4TeN9Y%jSd6`(lfR8!I@O7Ls4ylmpolve(Q66pt{oW
z<GXU@Zp-xh93;eiv+;eiFQDZtvt!9}b7j<50Wex3Y|+b;yt-XDZAM5-)zq-s7_N%5
z-OAwQAUoT|!<OUfVKpT4I}?Y{5j^wuc<Z7=)BX&Tf-}=+@mdpEmh)B(dB@hmXJf&T
z&FK*%z8Jx;ZY&x?Q*!ot(Lrsb-+YaLvjXsDy0n*}JHqL{ddH)Aw{QNdX1#zo@u}`O
z2q5uoy7LI9#=lLQeu>_SRDFwOD?kkqRgn<c(vEu-(5<yZb=nmcp^3}JTFGK-9>wU=
z>6Ah~d=x)}BZ~!vu_btW#W372GKk4(FuCmZco3*H8*{Y;x8uQ9h%?IWxM@8?-M%!V
z;-cw|$H__-1PhxAA(^3R+m*q_A7bir2+#(QSatsGk*!4qR#{uYJE7^|u@4Vc)<KaG
z;m|3$MxeWZs|-J9p#01aoVT03=T`0BCdDjrX-=A-x^ML#nOKn4#n@uI=dLqW*bDR(
zDWjlSZFG&JPIVoH1s>*XI!SYnSfQ&sZ~D*hiEAL})oX|tWLPiH#UjzPe|@>D07L}q
z_Mu+(Nm(pkOMyrS-w^N`WCr8!GJ%ZtbM;#6j?}k^xPdXN81_FgcFFX9^-pJGy)XBF
zmL5g0tSlGrgYL{Zqc|-nWqsW1xo@@u^Y#*BM$W-drPgaHpE8FOvJnv|<mWKhe=?{F
zVJz<S7YA!_?K_BGSs(}vVju{O0=kNWUzQripRUJz!y_1bk?)KSP;&xX^=w~K=<WLn
z5qdGp`91BZ$L<#MV{4*`l|(j!7qS-P>@IP*){dj=XfL}6dl!QyuGpSIOZAf}AFnbg
z)-v?fS<}uC&)2WA&0FaL*2dcLGIj6<<9xR6CZdaTNg~_-m@EDAH(4R=1}HN>4B0ZJ
zVNV{>&4!b+{*FoBU4Hgt-FT*-2!4%p{S@IhIsQ#Mt3iCCtJch@lnP<pC6g44jz6I@
zWJ}#tF-o_1MMPr4Lnd^D_{+bvxjHZXCN~Q(Y132*fA`*8138Ne(ap8zuDQ`8LeR_D
zp_QSilq$0|C7mI&L(ZKe11R}=JeRUAwZvod$wtCtWah8NmpgVepswJz%=)CgIbd@p
z$ZIj_k;wR3tNJl?8ju0o&7{Wmf`0!e3&kqWC;M88dodQ-Pgr3RJULZH9bTT8J?<_m
z_mQ*pVFCh`f1kzPO6k|}y~@>|mI#s{rtvjp>KJ35xcPVQ`JGfbXh2(P{*6;NcdV8I
z&7O<;0gRwq-Xk;Kd%!nKipo1;-^fa1E1t*ne61aj4|0~=6sgDHvjD<BjD?E#%KI`B
zdYUn0f~$WP-`(ye=&P;2QwW$C)C<N5{HoU-RpG$8#BZ2k`o27iheof-P>UjWPIik@
zYhaCHCpX79I@%C=q6JVgrMayv<!Yu`+8!IG(3&ysh2}`DzcN_z46|r#IAmXGRV<8a
zoV2@?vz89s9dUSH*_j!^q9IZ7gOZ}CrZzeLO!>SjP@oc>c(ps#E%iieHz^tGnN5q8
z-&1_pRUa^**b2bajgB$bv`6&e^tzY)zFHsJ;)x@t59(wLVF%d5{VCDgEl$K>5-Kr$
zyyc=l;#RF;rBi8WC4w4vQ}p}ttOe<SgmpebsvhaBo397?E_F`<019UA0Fm4OtyXi-
z<hEx}Yrgy-zwjN3PlNw~uyXYv$*`LG1$|R&4lLD(^qE#`CJLg;Q_=Ldu-+y3%{g2R
z(rP%^$?TrW`7$6JERZZx+7HIAvoP|^i6uS4_3l$G2H&Jk(7&F{-+GnZLxxrI%rcK#
zc1TGiHd~5YwpAB(9+i577db+$ak@8~7BC17z2ibUb?I!`ZlI(Yw5#&G%SQMW!FNy9
zd^r08@+rFWB}?=NujY-f`<;mTAkRC4weG-(u#V5#i4SnueuujsXHuL%qDt@;13PG9
zVz$9HO9~fKErA0Q@;DEh>xC+|h4RoY7;&btRDrE&Li;5_wQhNfyOCeXU2RIP{cx&M
zKsuUXx25ALa8yTkTX4L)<ajX?w`8AsDurxez=pyXv?QM_(fyvRO*}v!sd<22TI2y4
z&b8z7i(4j(A73ySG&>oqLpZeG=XSV}Iq)I|oEgLU=L*F~A3-teh<PB91?hY3X<O><
z+u+34|2opgh5Ncr|5lZoNzTk%fK6325o7^0QBIvyy(7}#&IoDfG!1YG#|e!F<OF4H
ze#Jx@ZS6)EFVX(^mpvop5@VT^p4UAoohSR?0?~Z$wVRBco5eDwU#GY6c_5N^no{^5
zEbL?zL*G$Dc!A8-{ZR)EanQNe*z+i20Cc4k!dO%JbF06@1Nx(I^494~0OsNRV*xKM
zbMnD%jMdFn?_4X-Pzr<9dxqSk72W$U@(__)pZ)P7jUFcK1G=vF?|O){4tg}_>m3dc
z6#{#TL4lH`SJ@0!*tV!2S@8QlTyiTT7<^QkaBnvI4tLFH-`jC+>|JLypA%W=z3lTy
zaF8dQXWfn?4i46A<Xi!>fHqap+LST-A3>;GFQTP!?`~1>HIb9==qc9g6tXN?5<Q(n
z#F%{ZIqf|du##xuq-sCVb@LMWo1WuN<*t4w>)o-Mj%%i+!j=w3B?WDsG0#PDf?dmQ
ziADo$z}URU=hQf!_4_>=qr-6$(pt03&h)lsC&?Dk@?cx38ZGmT0E|7eM~SeCXx%0$
zljhcSR}$Z;_<@L~)Z@me-_hSrc*a6)_Ao4Mf=}29PMPaW`uj*z*?)50K~BO)W+6rt
zRLJiIbgrG0$|^Q<#*H~l<`_Fb3l048Ntk4X*T6fWP^+Na0G7MYlIWqP5sVjIcEYFy
zj+U&o(%PggKQgHz0X9aIPt)WqvFlKMl29q<6>fPHnYtlKTCm(<D->Yd{qpVlmp~JK
zig87=tF0W-thwy1$grYf>&;6nQ1k9F-XvJIBQ>G(i|vpc=it8pm3efLs*z|)xrD9h
zd{dB@DzfZp??W!MIa0JkLOI+aH2q+z!dW%@VYN(SQCHS50NRxnuvO215J5FMjgQOm
zI_M9{ZdI!CkKjLS;;jc8G=;rmn1W*Vm*~DfZ@?wzM<Z6TW;u!#=a6|sivASQ@6JEo
zb7QMn^%bQap~pG`Z<-!uPwv0LVRiNz9=t^KFpEyJG(JIiP<(#-Phxww&3A$X0RjqA
zo)pK%25?(aNB`P(>|Eb2Ww=@>G^S7%Y+Y}S#whn6({eCr@W-Ufr(VCh=KMh^mnh*5
z<oez3;=k(Re=I`iJmN@@F`s~C^`3?Qdn@azmENV4>93yWHp|odtE-nB@bT-?38eIn
zIUHrm@*ejjl!t2S6+a_N+W`4w8~((tJwlF_5m42hC`M$-)=vB0f{*De5b`WupDu=Y
zYvnA4-$OH1122gDDQ4nmb(e5Q1m`9dR#7<d!|=p1_6`2^wd(||=_=i^`zP|BRz0Da
zeBE3;SFU0=xm>I$H;74hfz?*|(a)IGnbCEoo0(y&MJoGML?u>yh93O@Ha@dx_=y;;
zLjZipuhvN>4z0?qUPny=Mr6Mwr};+*l+i5Nc6%uJw-bS0!&dp-=YfjGb6}hSL%5|g
z6E%~!!tQ}v>!3~F{1=3!pM{U4@EAP@ft0v9K&CSY3yH;?jL>Qu7pzJd|DNLTGi<K;
z#(*6Uwa9!&RRjrm$)7D#=%(jFf6i;j3)rRPr6O#uqm>hR3({_jw#B=RFaZplMH(yy
z>8pIp(-Y(pBUG8Uf=a>lK*zv|8dgvd^o%axvgYReHeGYO_)!a$1R4tL-orH<Wkl#?
z?h4}xYU8*<sZzNj4d9H>Zc@zF#Z48)_Nqp5u8~>Oe7O>f<`Ug>!)f(W@@lo=10-gh
zN04`qh&e_M{z;UPwms~;Ja<78fVO$U$kc8-=MfMrwbKSFcvb8(mg2O=T#7#gDLcL7
z4*NK$4hqOet3;4kYX?>Ji-i>6Z!5csO|patpE^326}{bYfEU7Dt|Av!?0*v^fpH4<
z6m1p!b9`Z7`#P{9`Ud2x%p}o32V7`5w2crM8k%CuCc;MwIB??XQwNx;Wk%^x*&rnH
z&#HsX+5q39a2OY>Fnt}EBe$WIIIT4|6Y&`}X(J1-$zcB)PTEzgrLz&eE(_rhG*Nb8
zcMVB!{`}le#}qo8qv&p_VA6Q-8@T0CpgIF3Y*6SN75S4IKPT0T<wIhp3pfsIEZHS^
z6KEhx5rmRlSeNn?lE^E9f_?2C!A)1um568QiArW^fE}j(2;R{sj)gg2&O6gbLi`ax
zP}vNtF{Rr3?Ls5}4`0Ot^)lmv8d+sDi>^p5xFDq#s7bs&ObktAIXa1{LS{)?t^ihq
z?5jN7dJ@^L*%#Z9qoCOCG=RhU^%E0vL=T%hZCA83tj2EaOYnh!oy;hogs^Crx<pcU
zO;W^WvIr9xM=d6+m9c-sDi-Bhwlwgh+m-!*4N<hTlPVFJjnY68l5FxGlbcSjOMB^G
zLT==?Cfh0<BR?nPfg0i+61W)d0=~!{c3A$SJ8DsT2wrfQ$6thR7cfWk8%n=Fz8#49
zk?_^$F@9MPk%L$_%R>0;Pj;meYF&V~SVnR}VditiqR0iG#H<(T2NMH2hEpYX@j?BI
zzxkJBh67$PD5yMn6swO)eVV0=(DjzDuH()R>gF@ym|*hU^lDG4T}64p%=GLF#ac>A
zA~|`@&ZNu8@lmuSKR{<vPN@0oZp7aKTZ9nx2dahF0kxtqt%tf3IEE|l4HOYYS;1nh
zvW^1%Z&b&2JQTAmDV$0k!Up;1F4FNBboB{}5IhNLq|2U%0nG(LJ2+45GeaI=ybOKv
zQL+>|4ySEv47FK>%`vbCpVX=rOI7?b0_QQT!h|o07l9HNZ!Ef=cyY9z?mUrA&8FA=
zBQ`u_COyCY*E~jddpub_I0%S23<wDGKlV9jF)To==DI4L6uJNdI2o{?UJ}`-zmcQ?
zIU2ta8Egav91pc&DAC0^y99^BT6l_@jiJv+?lYL_uBpmCVMwFlSLWB4Qn9|GWBd>M
zpnU2SU&rTc!GPP2wyx7#F2FmCF?tv8fV6G;3W{(ejzGG~G*%^F)gj`IZTcc}-Qr#v
zZx29Jc2E>Lnirn_Tzh1-vZE}sIWx(oKcKq&Bnaq){#pqP$L+DOZV022;2i8`h$qS3
zIO5}1N!Aoha5wnmw(xNcF5q!+SkuQe=x5eNV#{#diUntKW}`w~aCtBc-efJXrYc1b
zqFV{0vrmE+ERRo#hZ~UFs@k(wT`acHa|J{dkZ{%yAZNQYvUf9BteZBpcT;Y`8%-`s
zTTQU|1cr5`UJxNdTFewi0N;n@Z#v`fH7<{8T0+(5DHpm@+1=QDZhUCMt-|EwaC3hg
zBk~L|BlBg|O$eN@TJvAZjnDZF$Qz+RtnR|jI^Ux+H$(}TU{XL}F#m!VI0irJ=msQ|
z{}!YUX#HC=%>7o(JSlPRa7P!fqa>{g^_y&NZl#e=xy+|}xNNy)<<YvM?}o$BZ!qJL
zKyBq<=;&zagX`JBC48lL%>mwWybE7W-DDIJGmKJJ=Xyrf(%fj%vTTpK6RFVQv<FiU
zzVZ%R5C_9SG8V1&#qZ&+z^4;`4FWvEjN4sh7g9T>aFDfE>rIHEq6_L6{X4CXo0h4u
zB`eS4WT_^KAV{Nl8Ffl^`EKh7F#I4ARm`Q-`LoC)f*6hv><2mb@{RYX+Q}2YA)#xl
zgrV@Tyh3^=Q{OkOG7q+(ty|*jxo+@-+X`jAWEQygR6xe1DN~4HWH;&UI06vVUz2~V
z-ACbikIey64aAr5{z~5KQDz1WLB1Z9Xx{4{6Y10@7qu=C#P21GJ8bUh=uPMxsxvvA
z9~u-2+4c4dsV#a<k{QkJ41R+`kh;@_a{CieM=kxDT!!hv8s}(!jU$872=8Nwh95jw
zrd0AOpP|*Zg<W)8QnSbmqkwJ+)89yz6OMCFe7Yj-mvLRORqhO7{da^00^eG^#(Si(
z^gz<ils40^h-2r0WlyxfOXq|!=Lm&BqI-pne}f>*qWE9TcK#i^7!lSNIXEMmq&}RF
ze?FH<gRRx-02OSd5q!aqmBOhlLSe}(=!)SrSJsT-FLJ{Niy(4UAOg6a-&;W=rp`U?
zQ5%6yx8Eb?86GdPM3Ce;r60gk3$`k_0MEAThE}zMQ*qzn3Idwpdql1GVg8hF{*0gT
zhT%ovNShNas$nv&_G~5G+nU^+YvtA#ee-tqE)PXK)_}=5j7=EXb;&g$5}3F!^$xr9
zRx7Ruy`lR0V8bU-9|fRg<E>6uiu=8)2k6XIG>h$A8P5VZUtAOlVmGpmPQi8BsMFeH
z(#R!PqFJWq&-j0<K4LTqkDj5rn4i&iDZ%5s2V)pTOBKsv-N*hA{HEGu3Zwc3S+OAg
z%lDon;DVi&1Cax6-^xEUUZ#QNPbtl8dY^%Ruu>$6OfL&A+yOV+z>|nyEFl8dVBLJR
z$$RXD{Eq^Y2P6H`s<TwZf@C-aj7bL}m%J||Ww~#l=wSbL7AI*5aR19poRlaa^iNz8
zVEQLQ3Ud7ug#`uwaSsOxivJVG1Vs@4W%c-P7jY7nkSg*2=l=K~rsU$F75F5QZx~6$
zNYF{8LRkNR|9fa21cdQFz&l9)1;$H45QZoI&l$M?4c5Z`2mD<G;qO!&?mu9w|JRoO
zYeM;-=IG)eG?M=U<0RD+q0s;LQb7O9WG(RTM&tjN*hcp6L`D&Uf9~=hJ)-}3eq+l2
z0`vU?{Fiq8Z|V3yfOWM00PjR-{{jBHBK>>&|6GwQ)_;J+NRUZCm@$%UMgQ-r{1<r#
rDgXOx()`DjXE^?yP|Jq=|9#Q_IKuuTk(}?}iO^zHkf_4{`t<(*w64qE

delta 15325
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

diff --git a/lib/org.carrot2.antlib/src/META-INF/services/javax.annotation.processing.Processor b/lib/org.carrot2.antlib/src/META-INF/services/javax.annotation.processing.Processor
deleted file mode 100644
index a69ab80..0000000
--- a/lib/org.carrot2.antlib/src/META-INF/services/javax.annotation.processing.Processor
+++ /dev/null
@@ -1 +0,0 @@
-org.carrot2.apt.BindableProcessor
\ No newline at end of file
diff --git a/lib/org.carrot2.antlib/src/org/carrot2/apt/BindableProcessor.java b/lib/org.carrot2.antlib/src/org/carrot2/apt/BindableProcessor.java
deleted file mode 100644
index 7e3e9e0..0000000
--- a/lib/org.carrot2.antlib/src/org/carrot2/apt/BindableProcessor.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package org.carrot2.apt;
-
-import static javax.lang.model.SourceVersion.RELEASE_6;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.Filer;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.annotation.processing.RoundEnvironment;
-import javax.annotation.processing.SupportedAnnotationTypes;
-import javax.annotation.processing.SupportedSourceVersion;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.Elements;
-import javax.tools.FileObject;
-import javax.tools.StandardLocation;
-
-/**
- * Java6+ compatible annotation processor for parsing <code>Bindable</code>-annotated
- * types and generating their metadata.
- */
-@SupportedAnnotationTypes("org.carrot2.util.attribute.Bindable")
-@SupportedSourceVersion(RELEASE_6)
-public final class BindableProcessor extends AbstractProcessor
-{
-    /**
-     * Bindable annotation class name, fully qualified.
-     */
-    private final static String BINDABLE_CLASS = "org.carrot2.util.attribute.Bindable";
-
-    /**
-     * Mirror element utilities.
-     */
-    private Elements elementUtils;
-
-    /**
-     * Apt filer utilities.
-     */
-    private Filer filer;
-
-    /**
-     * Visitor scanning for {@link #BINDABLE_CLASS}.
-     */
-    private final ElementVisitor<List<TypeElement>, List<TypeElement>> visitor = new ElementVisitorBase<List<TypeElement>, List<TypeElement>>()
-    {
-        @Override
-        public List<TypeElement> visitType(TypeElement e, List<TypeElement> bindables)
-        {
-            for (AnnotationMirror annotation : e.getAnnotationMirrors())
-            {
-                String name = elementUtils.getBinaryName(
-                    (TypeElement) annotation.getAnnotationType().asElement()).toString();
-
-                if (BINDABLE_CLASS.equals(name)) bindables.add(e);
-            }
-
-            return bindables;
-        }
-    };
-
-    /**
-     * Initialize processing environment.
-     */
-    @Override
-    public synchronized void init(ProcessingEnvironment processingEnv)
-    {
-        super.init(processingEnv);
-        elementUtils = this.processingEnv.getElementUtils();
-        filer = this.processingEnv.getFiler();
-    }
-
-    /**
-     * Process a set of roots for the current round.
-     */
-    @Override
-    public boolean process(Set<? extends TypeElement> ann, RoundEnvironment env)
-    {
-        if (env.errorRaised() || env.processingOver())
-        {
-            return false;
-        }
-
-        // Scan for all types marked with @Bindable
-        final ArrayList<TypeElement> bindableTypes = new ArrayList<TypeElement>(); 
-        for (Element e : env.getRootElements())
-        {
-            e.accept(visitor, bindableTypes);
-        }
-
-        // For every bindable type, create and emit attribute metadata.
-        for (TypeElement type : bindableTypes)
-        {
-            final String clazzName = elementUtils.getBinaryName(type).toString();
-            final String metadataFileName = clazzName + ".apt.xml";
-
-            touch(metadataFileName, type);
-        }
-
-        return false;
-    }
-
-    /**
-     * Create an empty file corresponding to bindable metadata.  
-     */
-    private void touch(String metadataFileName, TypeElement type)
-    {
-        try
-        {
-            FileObject res = filer.createResource(
-                StandardLocation.CLASS_OUTPUT, "", metadataFileName, type);
-
-            res.openOutputStream().close();
-        }
-        catch (IOException e)
-        {
-            throw new RuntimeException("Could not process metadata file: " +
-                metadataFileName, e);
-        }
-    }
-}
diff --git a/lib/org.carrot2.antlib/src/org/carrot2/apt/ElementVisitorBase.java b/lib/org.carrot2.antlib/src/org/carrot2/apt/ElementVisitorBase.java
deleted file mode 100644
index 2213b17..0000000
--- a/lib/org.carrot2.antlib/src/org/carrot2/apt/ElementVisitorBase.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.carrot2.apt;
-
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.element.VariableElement;
-
-/**
- * An empty implementation of {@link ElementVisitor}.
- */
-class ElementVisitorBase<R, P> implements ElementVisitor<R, P>
-{
-    @Override
-    public R visit(Element e)
-    {
-        return null;
-    }
-
-    @Override
-    public R visit(Element e, P p)
-    {
-        return null;
-    }
-
-    @Override
-    public R visitExecutable(ExecutableElement e, P p)
-    {
-        return null;
-    }
-
-    @Override
-    public R visitPackage(PackageElement e, P p)
-    {
-        return null;
-    }
-
-    @Override
-    public R visitType(TypeElement e, P p)
-    {
-        return null;
-    }
-
-    @Override
-    public R visitTypeParameter(TypeParameterElement e, P p)
-    {
-        return null;
-    }
-
-    @Override
-    public R visitUnknown(Element e, P p)
-    {
-        return null;
-    }
-
-    @Override
-    public R visitVariable(VariableElement e, P p)
-    {
-        return null;
-    }
-}
diff --git a/workbench/org.carrot2.workbench.core/src/org/carrot2/workbench/core/ui/AttributeInfoTooltip.java b/workbench/org.carrot2.workbench.core/src/org/carrot2/workbench/core/ui/AttributeInfoTooltip.java
index 548e834..48eee00 100644
--- a/workbench/org.carrot2.workbench.core/src/org/carrot2/workbench/core/ui/AttributeInfoTooltip.java
+++ b/workbench/org.carrot2.workbench.core/src/org/carrot2/workbench/core/ui/AttributeInfoTooltip.java
@@ -15,7 +15,7 @@ package org.carrot2.workbench.core.ui;
 import static org.carrot2.workbench.core.ui.StyledTextContentBuilder.BOLD;
 
 import org.carrot2.util.attribute.AttributeDescriptor;
-import org.carrot2.util.attribute.AttributeMetadata;
+import org.carrot2.util.attribute.metadata.AttributeMetadata;
 import org.carrot2.workbench.core.WorkbenchCorePlugin;
 import org.carrot2.workbench.core.preferences.PreferenceConstants;
 import org.eclipse.core.runtime.*;
-- 
1.7.0.2.msysgit.0


