diff --git a/.gitignore b/.gitignore
index a8b6931..1ad0f80 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,8 @@
-build
+/build
+/target
+
+*~
 .*.swp
-.gradle
+
+.classpath
+.project
diff --git a/README b/README.md
similarity index 80%
rename from README
rename to README.md
index 0dead99..03b27ff 100644
--- a/README
+++ b/README.md
@@ -1,3 +1,5 @@
+# Introduction
+
 The C Preprocessor is an interesting standard. It appears to be
 derived from the de-facto behaviour of the first preprocessors, and
 has evolved over the years. Implementation is therefore difficult.
@@ -11,3 +13,8 @@ head examined).
 This project has has been used to successfully preprocess much of
 the source code of the GNU C library. As of version 1.2.5, it can
 also preprocess the Apple Objective C library.
+
+# Documentation
+
+* [JavaDoc API](http://shevek.github.io/jcpp/docs/javadoc/)
+* [Coverage Report](http://shevek.github.io/jcpp/docs/cobertura/)
diff --git a/build.gradle b/build.gradle
deleted file mode 100644
index c99935d..0000000
--- a/build.gradle
+++ /dev/null
@@ -1,66 +0,0 @@
-// Establish version and status
-ext.githubProjectName = rootProject.name // Change if github project name is not the same as the root project's name
-group = "org.anarres"
-
-buildscript {
-    repositories {
-        // mavenLocal()
-        mavenCentral() // maven { url 'http://jcenter.bintray.com' }
-    }
-    apply from: file('gradle/buildscript.gradle'), to: buildscript 
-}
-
-allprojects {
-    repositories { 
-        // mavenLocal()
-        mavenCentral() // maven { url: 'http://jcenter.bintray.com' }
-    }
-}
-
-apply plugin: 'idea'
-
-apply from: file('gradle/convention.gradle')
-apply from: file('gradle/maven.gradle')
-apply from: file('gradle/check.gradle')
-apply from: file('gradle/license.gradle')
-// apply from: file('gradle/release.gradle')
-
-apply plugin: 'application'
-apply plugin: VelocityPlugin
-
-dependencies {
-    compile 'com.google.code.findbugs:jsr305:2.0.2'
-	compile 'gnu.getopt:java-getopt:1.0.13'
-	compile 'org.apache.ant:ant:1.7.0'
-
-    testCompile 'junit:junit:4.8.1'
-}
-
-velocity {
-	def p = project
-	context {
-		version = p.version
-	}
-}
-
-test {
-	systemProperty 'org.apache.commons.logging.Log', 'org.apache.commons.logging.impl.SimpleLog'
-	systemProperty 'org.apache.commons.logging.simplelog.defaultlog', 'debug'
-
-	testLogging {
-		if (System.properties['test.single']) {
-			// events "passed", "skipped", "failed"
-			events "started", "passed", "skipped", "failed"
-			showExceptions true
-			exceptionFormat "full"
-			showStandardStreams true
-		} else {
-			events "failed"
-		}       
-
-		debug { 
-			events "started", "passed", "skipped", "failed", "standard_out", "standard_error"
-			exceptionFormat "full"
-		}       
-	}       
-}
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
deleted file mode 100644
index 324859d..0000000
--- a/buildSrc/build.gradle
+++ /dev/null
@@ -1,12 +0,0 @@
-apply plugin: 'groovy'
-apply plugin: 'idea'
-
-repositories {
-	mavenCentral()
-}
-
-dependencies {
-	compile gradleApi()
-	compile 'org.apache.velocity:velocity:1.7'
-}
-
diff --git a/buildSrc/src/main/groovy/VelocityPlugin.groovy b/buildSrc/src/main/groovy/VelocityPlugin.groovy
deleted file mode 100644
index cc8741a..0000000
--- a/buildSrc/src/main/groovy/VelocityPlugin.groovy
+++ /dev/null
@@ -1,33 +0,0 @@
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-import org.apache.velocity.VelocityContext
-import org.apache.velocity.app.VelocityEngine
-import org.apache.velocity.runtime.log.SystemLogChute
-
-class VelocityPluginExtension {
-	String inputDir = "src/main/velocity"
-	String outputDir = "build/generated-sources/velocity"
-	Map<String, Object> contextValues = [:]
-	def context(Closure closure) {
-		contextValues.with closure
-	}
-}
-
-class VelocityPlugin implements Plugin<Project> {
-	void apply(Project project) {
-
-		project.extensions.create("velocity", VelocityPluginExtension)
-
-		project.task('velocityVpp', type: VelocityTask) {
-			description "Preprocesses velocity template files."
-			inputDir = project.file(project.velocity.inputDir)
-			outputDir = project.file(project.velocity.outputDir)
-			contextValues = project.velocity.contextValues
-		}
-
-		project.compileJava.dependsOn(project.velocityVpp)
-		project.sourceSets.main.java.srcDir project.velocity.outputDir
-
-	}
-}
-
diff --git a/buildSrc/src/main/groovy/VelocityTask.groovy b/buildSrc/src/main/groovy/VelocityTask.groovy
deleted file mode 100644
index 6a36903..0000000
--- a/buildSrc/src/main/groovy/VelocityTask.groovy
+++ /dev/null
@@ -1,58 +0,0 @@
-import org.apache.velocity.VelocityContext
-import org.apache.velocity.app.VelocityEngine
-import org.apache.velocity.runtime.log.SystemLogChute
-import org.gradle.api.DefaultTask
-import org.gradle.api.tasks.InputDirectory
-import org.gradle.api.tasks.OutputDirectory
-import org.gradle.api.tasks.TaskAction
-
-class VelocityTask extends DefaultTask {
-
-	@InputDirectory
-	File inputDir
-
-	@OutputDirectory
-	File outputDir
-
-	String filter = '**/*.java'
-
-	File includeDir
-
-	Map<String, Object> contextValues = [:]
-
-	@TaskAction
-	void run() {
-		outputDir.deleteDir()
-		outputDir.mkdirs()
-		// println "Velocity: $inputDir -> $outputDir"
-
-		VelocityEngine engine = new VelocityEngine()
-		engine.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS, SystemLogChute.class.name)
-		engine.setProperty(VelocityEngine.RESOURCE_LOADER, "file")
-		engine.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_CACHE, "true")
-		if (includeDir != null)
-			engine.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, includeDir.getAbsolutePath())
-		def inputFiles = project.fileTree(
-			dir: inputDir,
-			include: filter
-		)
-		inputFiles.visit { e ->
-			if (e.file.isFile()) {
-				File outputFile = e.relativePath.getFile(outputDir)
-				VelocityContext context = new VelocityContext()
-				contextValues.each { context.put(it.key, it.value) }
-				context.put('project', project)
-				context.put('package', e.relativePath.parent.segments.join('.'))
-				context.put('class', e.relativePath.lastName.replaceFirst("\\.java\$", ""))
-				// println "Parsing ${e.file}"
-				e.file.withReader { reader ->
-					outputFile.parentFile.mkdirs()
-					outputFile.withWriter { writer ->
-						engine.evaluate(context, writer, e.relativePath.toString(), reader)
-					}
-				}
-			}
-		}
-	}
-}
-
diff --git a/codequality/HEADER b/codequality/HEADER
deleted file mode 100644
index 3102e4b..0000000
--- a/codequality/HEADER
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright ${year} Netflix, Inc.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/codequality/checkstyle.xml b/codequality/checkstyle.xml
deleted file mode 100644
index 47c01a2..0000000
--- a/codequality/checkstyle.xml
+++ /dev/null
@@ -1,188 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE module PUBLIC
-    "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
-    "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
-
-<module name="Checker">
-
-    <!-- Checks that a package-info.java file exists for each package.     -->
-    <!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocPackage -->
-    <!--
-    <module name="JavadocPackage">
-      <property name="allowLegacy" value="true"/>
-    </module>
-    -->
-
-    <!-- Checks whether files end with a new line.                        -->
-    <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
-    <module name="NewlineAtEndOfFile"/>
-
-    <!-- Checks that property files contain the same keys.         -->
-    <!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
-    <module name="Translation"/>
-
-    <!-- Checks for Size Violations.                    -->
-    <!-- See http://checkstyle.sf.net/config_sizes.html -->
-    <module name="FileLength"/>
-
-    <!-- Checks for whitespace                               -->
-    <!-- See http://checkstyle.sf.net/config_whitespace.html -->
-    <module name="FileTabCharacter"/>
-
-    <!-- Miscellaneous other checks.                   -->
-    <!-- See http://checkstyle.sf.net/config_misc.html -->
-    <module name="RegexpSingleline">
-       <property name="format" value="\s+$"/>
-       <property name="minimum" value="0"/>
-       <property name="maximum" value="0"/>
-       <property name="message" value="Line has trailing spaces."/>
-       <property name="severity" value="info"/>
-    </module>
-
-    <module name="TreeWalker">
-
-        <!-- Checks for Javadoc comments.                     -->
-        <!-- See http://checkstyle.sf.net/config_javadoc.html -->
-        <module name="JavadocMethod">
-          <property name="scope" value="package"/>
-          <property name="allowMissingParamTags" value="true"/>
-          <property name="allowMissingThrowsTags" value="true"/>
-          <property name="allowMissingReturnTag" value="true"/>
-          <property name="allowThrowsTagsForSubclasses" value="true"/>
-          <property name="allowUndeclaredRTE" value="true"/>
-          <property name="allowMissingPropertyJavadoc" value="true"/>
-        </module>
-        <module name="JavadocType">
-          <property name="scope" value="package"/>
-        </module>
-        <module name="JavadocVariable">
-          <property name="scope" value="package"/>
-        </module>
-        <module name="JavadocStyle">
-          <property name="checkEmptyJavadoc" value="true"/>
-        </module>
-
-        <!-- Checks for Naming Conventions.                  -->
-        <!-- See http://checkstyle.sf.net/config_naming.html -->
-        <module name="ConstantName"/>
-        <module name="LocalFinalVariableName"/>
-        <module name="LocalVariableName"/>
-        <module name="MemberName"/>
-        <module name="MethodName"/>
-        <module name="PackageName"/>
-        <module name="ParameterName"/>
-        <module name="StaticVariableName"/>
-        <module name="TypeName"/>
-
-        <!-- Checks for imports                              -->
-        <!-- See http://checkstyle.sf.net/config_import.html -->
-        <module name="AvoidStarImport"/>
-        <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
-        <module name="RedundantImport"/>
-        <module name="UnusedImports"/>
-
-
-        <!-- Checks for Size Violations.                    -->
-        <!-- See http://checkstyle.sf.net/config_sizes.html -->
-        <module name="LineLength">
-          <!-- what is a good max value? -->
-          <property name="max" value="120"/>
-          <!-- ignore lines like "$File: //depot/... $" -->
-          <property name="ignorePattern" value="\$File.*\$"/>
-          <property name="severity" value="info"/>
-        </module>
-        <module name="MethodLength"/>
-        <module name="ParameterNumber"/>
-
-
-        <!-- Checks for whitespace                               -->
-        <!-- See http://checkstyle.sf.net/config_whitespace.html -->
-        <module name="EmptyForIteratorPad"/>
-        <module name="GenericWhitespace"/>
-        <module name="MethodParamPad"/>
-        <module name="NoWhitespaceAfter"/>
-        <module name="NoWhitespaceBefore"/>
-        <module name="OperatorWrap"/>
-        <module name="ParenPad"/>
-        <module name="TypecastParenPad"/>
-        <module name="WhitespaceAfter"/>
-        <module name="WhitespaceAround"/>
-
-        <!-- Modifier Checks                                    -->
-        <!-- See http://checkstyle.sf.net/config_modifiers.html -->
-        <module name="ModifierOrder"/>
-        <module name="RedundantModifier"/>
-
-
-        <!-- Checks for blocks. You know, those {}'s         -->
-        <!-- See http://checkstyle.sf.net/config_blocks.html -->
-        <module name="AvoidNestedBlocks"/>
-        <module name="EmptyBlock">
-          <property name="option" value="text"/>
-        </module>
-        <module name="LeftCurly"/>
-        <module name="NeedBraces"/>
-        <module name="RightCurly"/>
-
-
-        <!-- Checks for common coding problems               -->
-        <!-- See http://checkstyle.sf.net/config_coding.html -->
-        <!-- <module name="AvoidInlineConditionals"/> -->
-        <module name="EmptyStatement"/>
-        <module name="EqualsHashCode"/>
-        <module name="HiddenField">
-          <property name="ignoreConstructorParameter" value="true"/>
-          <property name="ignoreSetter" value="true"/>
-          <property name="severity" value="warning"/>
-        </module>
-        <module name="IllegalInstantiation"/>
-        <module name="InnerAssignment"/>
-        <module name="MagicNumber">
-          <property name="severity" value="warning"/>
-        </module>
-        <module name="MissingSwitchDefault"/>
-        <!-- Problem with finding exception types... -->
-        <module name="RedundantThrows">
-          <property name="allowUnchecked" value="true"/>
-          <property name="suppressLoadErrors" value="true"/>
-          <property name="severity" value="info"/>
-        </module>
-        <module name="SimplifyBooleanExpression"/>
-        <module name="SimplifyBooleanReturn"/>
-
-        <!-- Checks for class design                         -->
-        <!-- See http://checkstyle.sf.net/config_design.html -->
-        <!-- <module name="DesignForExtension"/> -->
-        <module name="FinalClass"/>
-        <module name="HideUtilityClassConstructor"/>
-        <module name="InterfaceIsType"/>
-        <module name="VisibilityModifier"/>
-
-
-        <!-- Miscellaneous other checks.                   -->
-        <!-- See http://checkstyle.sf.net/config_misc.html -->
-        <module name="ArrayTypeStyle"/>
-        <!-- <module name="FinalParameters"/> -->
-        <module name="TodoComment">
-          <property name="format" value="TODO"/>
-          <property name="severity" value="info"/>
-        </module>
-        <module name="UpperEll"/>
-
-        <module name="FileContentsHolder"/> <!-- Required by comment suppression filters -->
-
-    </module>
-
-    <!-- Enable suppression comments -->
-    <module name="SuppressionCommentFilter">
-      <property name="offCommentFormat" value="CHECKSTYLE IGNORE\s+(\S+)"/>
-      <property name="onCommentFormat" value="CHECKSTYLE END IGNORE\s+(\S+)"/>
-      <property name="checkFormat" value="$1"/>
-    </module>
-    <module name="SuppressWithNearbyCommentFilter">
-      <!-- Syntax is "SUPPRESS CHECKSTYLE name" -->
-      <property name="commentFormat" value="SUPPRESS CHECKSTYLE (\w+)"/>
-      <property name="checkFormat" value="$1"/>
-      <property name="influenceFormat" value="1"/>
-    </module>
-</module>
diff --git a/gradle.properties b/gradle.properties
deleted file mode 100644
index 156e86d..0000000
--- a/gradle.properties
+++ /dev/null
@@ -1 +0,0 @@
-version=1.4.1
diff --git a/gradle/buildscript.gradle b/gradle/buildscript.gradle
deleted file mode 100644
index 3163aa9..0000000
--- a/gradle/buildscript.gradle
+++ /dev/null
@@ -1,11 +0,0 @@
-// Executed in context of buildscript
-repositories {
-    // Repo in addition to maven central
-    repositories { maven { url 'http://dl.bintray.com/content/netflixoss/external-gradle-plugins/' } } // For gradle-release
-}
-dependencies {
-    classpath 'nl.javadude.gradle.plugins:license-gradle-plugin:0.6.1'
-    classpath 'com.mapvine:gradle-cobertura-plugin:0.1'
-    // classpath 'gradle-release:gradle-release:1.1.5'
-    classpath 'org.ajoberstar:gradle-git:0.5.0'
-}
diff --git a/gradle/check.gradle b/gradle/check.gradle
deleted file mode 100644
index 78f8180..0000000
--- a/gradle/check.gradle
+++ /dev/null
@@ -1,25 +0,0 @@
-// Checkstyle
-// apply plugin: 'checkstyle'
-// checkstyle {
-//     ignoreFailures = true 
-//     configFile = rootProject.file('codequality/checkstyle.xml')
-// }
-
-// FindBugs
-apply plugin: 'findbugs'
-findbugs {
-    ignoreFailures = true
-}
-findbugsTest.enabled = false
-
-// PMD
-// apply plugin: 'pmd'
-// tasks.withType(Pmd) { reports.html.enabled true }
-
-apply plugin: 'cobertura'
-cobertura {
-    sourceDirs = sourceSets.main.java.srcDirs
-    format = 'html'
-    includes = ['**/*.java', '**/*.groovy']
-    excludes = []
-}
diff --git a/gradle/convention.gradle b/gradle/convention.gradle
deleted file mode 100644
index 22023ea..0000000
--- a/gradle/convention.gradle
+++ /dev/null
@@ -1,88 +0,0 @@
-apply plugin: 'java' // Plugin as major conventions, overwrites status
-
-sourceCompatibility = 1.5
-
-// GRADLE-2087 workaround, perform after java plugin
-status = project.hasProperty('preferredStatus')?project.preferredStatus:(version.contains('SNAPSHOT')?'snapshot':'release')
-
-// Indenting to align with multi-project branch
-    task sourcesJar(type: Jar, dependsOn:classes) {
-        from sourceSets.main.allSource
-        classifier 'sources'
-        extension 'jar'
-    }
-
-    task javadocJar(type: Jar, dependsOn:javadoc) {
-        from javadoc.destinationDir
-        classifier 'javadoc'
-        extension 'jar'
-    }
-
-    configurations.add('sources')
-    configurations.add('javadoc')
-    configurations.archives {
-        extendsFrom configurations.sources
-        extendsFrom configurations.javadoc
-    }
-
-    // When outputing to an Ivy repo, we want to use the proper type field
-    gradle.taskGraph.whenReady {
-        def isNotMaven = !it.hasTask(project.uploadMavenCentral)
-        if (isNotMaven) {
-            def artifacts = project.configurations.sources.artifacts
-            def sourceArtifact = artifacts.iterator().next()
-            sourceArtifact.type = 'sources'
-        }
-    }
-
-    artifacts {
-        sources(sourcesJar) {
-            // Weird Gradle quirk where type will be used for the extension, but only for sources
-            type 'jar'
-        }
-        javadoc(javadocJar) {
-            type 'javadoc'
-        }
-    }
-
-    configurations {
-        provided {
-            description = 'much like compile, but indicates you expect the JDK or a container to provide it. It is only available on the compilation classpath, and is not transitive.'
-            transitive = true
-            visible = true
-        }
-    }
-
-    project.sourceSets {
-        main.compileClasspath += project.configurations.provided
-        main.runtimeClasspath -= project.configurations.provided
-        test.compileClasspath += project.configurations.provided
-        test.runtimeClasspath += project.configurations.provided
-    }
-
-/*
-apply plugin: 'github-pages' // Used to create publishGhPages task
-
-def docTasks = [:]
-[Javadoc,ScalaDoc,Groovydoc].each{ Class docClass ->
-    tasks.withType(docClass).each { docTask ->
-        docTasks[docTask.name] = docTask
-        processGhPages.dependsOn(docTask)
-    }
-}
-
-githubPages {
-    repoUri = "git@github.com:Netflix/${rootProject.githubProjectName}.git"
-    pages {
-        docTasks.each { shortName, docTask ->
-            from(docTask.outputs.files) {
-                into "docs/${shortName}"
-            }
-        }
-    }
-}
-*/
-
-wrapper {
-	gradleVersion = '1.10'
-}
diff --git a/gradle/license.gradle b/gradle/license.gradle
deleted file mode 100644
index 59b75b3..0000000
--- a/gradle/license.gradle
+++ /dev/null
@@ -1,8 +0,0 @@
-// Dependency for plugin was set in buildscript.gradle
-
-apply plugin: 'license' //nl.javadude.gradle.plugins.license.LicensePlugin
-license {
-    header rootProject.file('codequality/HEADER')
-    ext.year = Calendar.getInstance().get(Calendar.YEAR)
-    skipExistingHeaders true
-}
diff --git a/gradle/maven.gradle b/gradle/maven.gradle
deleted file mode 100644
index 0513719..0000000
--- a/gradle/maven.gradle
+++ /dev/null
@@ -1,69 +0,0 @@
-// Maven side of things
-apply plugin: 'maven' // Java plugin has to have been already applied for the conf2scope mappings to work
-apply plugin: 'signing'
-
-signing {
-    required { gradle.taskGraph.hasTask(uploadMavenCentral) }
-    sign configurations.archives
-}
-
-/**
- * Publishing to Maven Central example provided from http://jedicoder.blogspot.com/2011/11/automated-gradle-project-deployment-to.html
- * artifactory will execute uploadArchives to force generation of ivy.xml, and we don't want that to trigger an upload to maven
- * central, so using custom upload task.
- */
-task uploadMavenCentral(type:Upload, dependsOn: signArchives) {
-    configuration = configurations.archives
-    onlyIf { ['release', 'snapshot'].contains(project.status) }
-	repositories.mavenDeployer {
-		beforeDeployment { signing.signPom(it) }
-
-		// To test deployment locally, use the following instead of oss.sonatype.org
-		//repository(url: "file://localhost/${rootProject.rootDir}/repo")
-
-		def sonatypeUsername = rootProject.hasProperty('sonatypeUsername')?rootProject.sonatypeUsername:''
-		def sonatypePassword = rootProject.hasProperty('sonatypePassword')?rootProject.sonatypePassword:''
-
-		repository(url: 'https://oss.sonatype.org/service/local/staging/deploy/maven2') {
-			authentication(userName: sonatypeUsername, password: sonatypePassword)
-		}
-
-		snapshotRepository(url: 'https://oss.sonatype.org/content/repositories/snapshots/') {
-			authentication(userName: sonatypeUsername, password: sonatypePassword)
-		}
-
-		// Prevent datastamp from being appending to artifacts during deployment
-		uniqueVersion = false
-	  
-		// Closure to configure all the POM with extra info, common to all projects
-		pom.project {
-			name "${project.name}"
-			description "Java C Preprocessor"
-			developers {
-				developer {
-					id 'shevek'
-					name 'Shevek'
-					email 'github@anarres.org'
-				}
-			}
-			licenses {
-				license {
-					name 'The Apache Software License, Version 2.0'
-					url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-					distribution 'repo'
-				}
-			}
-			url "https://github.com/shevek/${rootProject.githubProjectName}"
-			scm {
-				connection "scm:git:git@github.com:shevek/${rootProject.githubProjectName}.git"
-				url "scm:git:git@github.com:shevek/${rootProject.githubProjectName}.git"
-				developerConnection "scm:git:git@github.com:shevek/${rootProject.githubProjectName}.git"
-			}
-			issueManagement {
-				system 'github'
-				url "https://github.com/shevek/${rootProject.githubProjectName}/issues"
-			}
-		}
-	}
-}
-
diff --git a/gradle/netflix-oss.gradle b/gradle/netflix-oss.gradle
deleted file mode 100644
index a87bc54..0000000
--- a/gradle/netflix-oss.gradle
+++ /dev/null
@@ -1 +0,0 @@
-apply from: 'http://artifacts.netflix.com/gradle-netflix-local/artifactory.gradle'
diff --git a/gradle/release.gradle b/gradle/release.gradle
deleted file mode 100644
index 6e3c20e..0000000
--- a/gradle/release.gradle
+++ /dev/null
@@ -1,60 +0,0 @@
-apply plugin: 'release'
-
-[ uploadIvyLocal: 'uploadLocal', uploadArtifactory: 'artifactoryPublish', buildWithArtifactory: 'build' ].each { key, value ->
-    // Call out to compile against internal repository
-    task "${key}"(type: GradleBuild) {
-        startParameter = project.gradle.startParameter.newInstance()
-        doFirst {
-            startParameter.projectProperties = [status: project.status, preferredStatus: project.status]
-        }
-        startParameter.addInitScript( file('gradle/netflix-oss.gradle') )
-        startParameter.getExcludedTaskNames().add('check')
-        tasks = [ 'build', value ]
-    }
-}
-
-// Marker task for following code to key in on
-task releaseCandidate(dependsOn: release)
-task forceCandidate {
-    onlyIf { gradle.taskGraph.hasTask(releaseCandidate) }
-    doFirst { project.status = 'candidate' }
-}
-task forceRelease {
-    onlyIf { !gradle.taskGraph.hasTask(releaseCandidate) }
-    doFirst { project.status = 'release' }
-}
-release.dependsOn([forceCandidate, forceRelease])
-
-task releaseSnapshot(dependsOn: [uploadArtifactory, uploadMavenCentral])
-
-// Ensure our versions look like the project status before publishing
-task verifyStatus << {
-    def hasSnapshot = version.contains('-SNAPSHOT')
-    if (project.status == 'snapshot' && !hasSnapshot) {
-        throw new GradleException("Version (${version}) needs -SNAPSHOT if publishing snapshot")
-    }
-}
-uploadArtifactory.dependsOn(verifyStatus)
-uploadMavenCentral.dependsOn(verifyStatus)
-
-// Ensure upload happens before taggging, hence upload failures will leave repo in a revertable state
-preTagCommit.dependsOn([uploadArtifactory, uploadMavenCentral])
-
-
-gradle.taskGraph.whenReady { taskGraph ->
-    def hasRelease = taskGraph.hasTask('commitNewVersion')
-    def indexOf = { return taskGraph.allTasks.indexOf(it) }
-
-    if (hasRelease) {
-        assert indexOf(build) < indexOf(unSnapshotVersion), 'build target has to be after unSnapshotVersion'
-        assert indexOf(uploadMavenCentral) < indexOf(preTagCommit), 'preTagCommit has to be after uploadMavenCentral'
-        assert indexOf(uploadArtifactory) < indexOf(preTagCommit), 'preTagCommit has to be after uploadArtifactory'
-    }
-}
-
-// Prevent plugin from asking for a version number interactively
-ext.'gradle.release.useAutomaticVersion' = "true"
-
-release {
-    git.requireBranch = null
-}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 5838598..0000000
Binary files a/gradle/wrapper/gradle-wrapper.jar and /dev/null differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 40aa5f8..0000000
--- a/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Fri Dec 27 05:48:20 PST 2013
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip
diff --git a/gradlew b/gradlew
deleted file mode 100755
index 91a7e26..0000000
--- a/gradlew
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/env bash
-
-##############################################################################
-##
-##  Gradle start up script for UN*X
-##
-##############################################################################
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn ( ) {
-    echo "$*"
-}
-
-die ( ) {
-    echo
-    echo "$*"
-    echo
-    exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-case "`uname`" in
-  CYGWIN* )
-    cygwin=true
-    ;;
-  Darwin* )
-    darwin=true
-    ;;
-  MINGW* )
-    msys=true
-    ;;
-esac
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
-    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
-    ls=`ls -ld "$PRG"`
-    link=`expr "$ls" : '.*-> \(.*\)$'`
-    if expr "$link" : '/.*' > /dev/null; then
-        PRG="$link"
-    else
-        PRG=`dirname "$PRG"`"/$link"
-    fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
-    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
-        # IBM's JDK on AIX uses strange locations for the executables
-        JAVACMD="$JAVA_HOME/jre/sh/java"
-    else
-        JAVACMD="$JAVA_HOME/bin/java"
-    fi
-    if [ ! -x "$JAVACMD" ] ; then
-        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-    fi
-else
-    JAVACMD="java"
-    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
-    MAX_FD_LIMIT=`ulimit -H -n`
-    if [ $? -eq 0 ] ; then
-        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
-            MAX_FD="$MAX_FD_LIMIT"
-        fi
-        ulimit -n $MAX_FD
-        if [ $? -ne 0 ] ; then
-            warn "Could not set maximum file descriptor limit: $MAX_FD"
-        fi
-    else
-        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
-    fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
-    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
-    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
-    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
-    # We build the pattern for arguments to be converted via cygpath
-    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
-    SEP=""
-    for dir in $ROOTDIRSRAW ; do
-        ROOTDIRS="$ROOTDIRS$SEP$dir"
-        SEP="|"
-    done
-    OURCYGPATTERN="(^($ROOTDIRS))"
-    # Add a user-defined pattern to the cygpath arguments
-    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
-        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
-    fi
-    # Now convert the arguments - kludge to limit ourselves to /bin/sh
-    i=0
-    for arg in "$@" ; do
-        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
-        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
-
-        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
-            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
-        else
-            eval `echo args$i`="\"$arg\""
-        fi
-        i=$((i+1))
-    done
-    case $i in
-        (0) set -- ;;
-        (1) set -- "$args0" ;;
-        (2) set -- "$args0" "$args1" ;;
-        (3) set -- "$args0" "$args1" "$args2" ;;
-        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
-        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
-        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
-        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
-        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
-        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
-    esac
-fi
-
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
-    JVM_OPTS=("$@")
-}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
-
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
deleted file mode 100644
index aec9973..0000000
--- a/gradlew.bat
+++ /dev/null
@@ -1,90 +0,0 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem  Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windowz variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
diff --git a/lib/ant/ant-contrib.jar b/lib/ant/ant-contrib.jar
deleted file mode 100644
index 6e04e84..0000000
Binary files a/lib/ant/ant-contrib.jar and /dev/null differ
diff --git a/lib/checkstyle/checkstyle-all-4.1.jar b/lib/checkstyle/checkstyle-all-4.1.jar
deleted file mode 100644
index ea018b6..0000000
Binary files a/lib/checkstyle/checkstyle-all-4.1.jar and /dev/null differ
diff --git a/lib/checkstyle/commons-beanutils-core.jar b/lib/checkstyle/commons-beanutils-core.jar
deleted file mode 100644
index ce79cbe..0000000
Binary files a/lib/checkstyle/commons-beanutils-core.jar and /dev/null differ
diff --git a/lib/checkstyle/commons-cli.jar b/lib/checkstyle/commons-cli.jar
deleted file mode 100644
index 22a004e..0000000
Binary files a/lib/checkstyle/commons-cli.jar and /dev/null differ
diff --git a/lib/checkstyle/commons-collections.jar b/lib/checkstyle/commons-collections.jar
deleted file mode 100644
index f66c6d2..0000000
Binary files a/lib/checkstyle/commons-collections.jar and /dev/null differ
diff --git a/lib/checkstyle/commons-logging.jar b/lib/checkstyle/commons-logging.jar
deleted file mode 100644
index b99c937..0000000
Binary files a/lib/checkstyle/commons-logging.jar and /dev/null differ
diff --git a/lib/cobertura/asm-3.2.jar b/lib/cobertura/asm-3.2.jar
deleted file mode 100644
index 2a83445..0000000
Binary files a/lib/cobertura/asm-3.2.jar and /dev/null differ
diff --git a/lib/cobertura/asm-tree-3.2.jar b/lib/cobertura/asm-tree-3.2.jar
deleted file mode 100644
index 4ab3528..0000000
Binary files a/lib/cobertura/asm-tree-3.2.jar and /dev/null differ
diff --git a/lib/cobertura/cobertura.jar b/lib/cobertura/cobertura.jar
deleted file mode 100644
index 438fe55..0000000
Binary files a/lib/cobertura/cobertura.jar and /dev/null differ
diff --git a/lib/cobertura/jakarta-oro-2.0.8.jar b/lib/cobertura/jakarta-oro-2.0.8.jar
deleted file mode 100644
index 23488d2..0000000
Binary files a/lib/cobertura/jakarta-oro-2.0.8.jar and /dev/null differ
diff --git a/lib/findbugs/lib/annotations.jar b/lib/findbugs/lib/annotations.jar
deleted file mode 100644
index e16db1f..0000000
Binary files a/lib/findbugs/lib/annotations.jar and /dev/null differ
diff --git a/lib/findbugs/lib/asm-3.0.jar b/lib/findbugs/lib/asm-3.0.jar
deleted file mode 100644
index 7a5c727..0000000
Binary files a/lib/findbugs/lib/asm-3.0.jar and /dev/null differ
diff --git a/lib/findbugs/lib/asm-analysis-3.0.jar b/lib/findbugs/lib/asm-analysis-3.0.jar
deleted file mode 100644
index c5f795f..0000000
Binary files a/lib/findbugs/lib/asm-analysis-3.0.jar and /dev/null differ
diff --git a/lib/findbugs/lib/asm-commons-3.0.jar b/lib/findbugs/lib/asm-commons-3.0.jar
deleted file mode 100644
index 2971530..0000000
Binary files a/lib/findbugs/lib/asm-commons-3.0.jar and /dev/null differ
diff --git a/lib/findbugs/lib/asm-tree-3.0.jar b/lib/findbugs/lib/asm-tree-3.0.jar
deleted file mode 100644
index c6347fe..0000000
Binary files a/lib/findbugs/lib/asm-tree-3.0.jar and /dev/null differ
diff --git a/lib/findbugs/lib/asm-util-3.0.jar b/lib/findbugs/lib/asm-util-3.0.jar
deleted file mode 100644
index 9515986..0000000
Binary files a/lib/findbugs/lib/asm-util-3.0.jar and /dev/null differ
diff --git a/lib/findbugs/lib/asm-xml-3.0.jar b/lib/findbugs/lib/asm-xml-3.0.jar
deleted file mode 100644
index b3d1a64..0000000
Binary files a/lib/findbugs/lib/asm-xml-3.0.jar and /dev/null differ
diff --git a/lib/findbugs/lib/bcel.jar b/lib/findbugs/lib/bcel.jar
deleted file mode 100644
index be093c8..0000000
Binary files a/lib/findbugs/lib/bcel.jar and /dev/null differ
diff --git a/lib/findbugs/lib/buggy.icns b/lib/findbugs/lib/buggy.icns
deleted file mode 100644
index b1f4660..0000000
Binary files a/lib/findbugs/lib/buggy.icns and /dev/null differ
diff --git a/lib/findbugs/lib/dom4j-full.jar b/lib/findbugs/lib/dom4j-full.jar
deleted file mode 100644
index 1efbf7e..0000000
Binary files a/lib/findbugs/lib/dom4j-full.jar and /dev/null differ
diff --git a/lib/findbugs/lib/findbugs-ant.jar b/lib/findbugs/lib/findbugs-ant.jar
deleted file mode 100644
index 3a2740e..0000000
Binary files a/lib/findbugs/lib/findbugs-ant.jar and /dev/null differ
diff --git a/lib/findbugs/lib/findbugs.jar b/lib/findbugs/lib/findbugs.jar
deleted file mode 100644
index 10c8f78..0000000
Binary files a/lib/findbugs/lib/findbugs.jar and /dev/null differ
diff --git a/lib/findbugs/lib/findbugsGUI.jar b/lib/findbugs/lib/findbugsGUI.jar
deleted file mode 100644
index 8cf6984..0000000
Binary files a/lib/findbugs/lib/findbugsGUI.jar and /dev/null differ
diff --git a/lib/findbugs/lib/jsr305.jar b/lib/findbugs/lib/jsr305.jar
deleted file mode 100644
index 90119cb..0000000
Binary files a/lib/findbugs/lib/jsr305.jar and /dev/null differ
diff --git a/lib/findbugs/plugin/coreplugin.jar b/lib/findbugs/plugin/coreplugin.jar
deleted file mode 100644
index 0f9c317..0000000
Binary files a/lib/findbugs/plugin/coreplugin.jar and /dev/null differ
diff --git a/lib/findbugs/xsl/default.xsl b/lib/findbugs/xsl/default.xsl
deleted file mode 100644
index e8f30d4..0000000
--- a/lib/findbugs/xsl/default.xsl
+++ /dev/null
@@ -1,376 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-  FindBugs - Find bugs in Java programs
-  Copyright (C) 2004,2005 University of Maryland
-  Copyright (C) 2005, Chris Nappin
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-  
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-  
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
--->
-
-<!--
-  A simple XSLT stylesheet to transform FindBugs XML results
-  annotated with messages into HTML.
-
-  If you want to experiment with modifying this stylesheet,
-  or write your own, you need to generate XML output from FindBugs
-  using a special option which lets it know to include
-  human-readable messages in the XML.  Invoke the findbugs script
-  as follows:
-
-    findbugs -textui -xml:withMessages -project myProject.fb > results.xml
-
-  Then you can use your favorite XSLT implementation to transform
-  the XML output into HTML. (But don't use xsltproc. It generates well-nigh
-  unreadable output, and generates incorrect output for the
-  <script> element.)
-
-  Authors:
-  David Hovemeyer
-  Chris Nappin (summary table)
--->
-
-<xsl:stylesheet
-	version="1.0"
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-
-<xsl:output
-	method="xml"
-	indent="yes"
-	omit-xml-declaration="yes"
-	standalone="yes"
-    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
-	doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
-	encoding="UTF-8"/>
-
-<xsl:variable name="literalNbsp">&amp;nbsp;</xsl:variable>
-
-<!--xsl:key name="bug-category-key" match="/BugCollection/BugInstance" use="@category"/-->
-
-<xsl:variable name="bugTableHeader">
-	<tr class="tableheader">
-		<th align="left">Code</th>
-		<th align="left">Warning</th>
-	</tr>
-</xsl:variable>
-
-<xsl:template match="/">
-	<html>
-	<head>
-		<title>FindBugs Report</title>
-		<style type="text/css">
-		.tablerow0 {
-			background: #EEEEEE;
-		}
-
-		.tablerow1 {
-			background: white;
-		}
-
-		.detailrow0 {
-			background: #EEEEEE;
-		}
-
-		.detailrow1 {
-			background: white;
-		}
-
-		.tableheader {
-			background: #b9b9fe;
-			font-size: larger;
-		}
-
-		.tablerow0:hover, .tablerow1:hover {
-			background: #aaffaa;
-		}
-
-		.priority-1 {
-		    color: red;
-		    font-weight: bold;
-		}
-		.priority-2 {
-		    color: orange;
-		    font-weight: bold;
-		}
-		.priority-3 {
-		    color: green;
-		    font-weight: bold;
-		}
-		.priority-4 {
-		    color: blue;
-		    font-weight: bold;
-		}
-		</style>
-		<script type="text/javascript">
-			function toggleRow(elid) {
-				if (document.getElementById) {
-					element = document.getElementById(elid);
-					if (element) {
-						if (element.style.display == 'none') {
-							element.style.display = 'block';
-							//window.status = 'Toggle on!';
-						} else {
-							element.style.display = 'none';
-							//window.status = 'Toggle off!';
-						}
-					}
-				}
-			}
-		</script>
-	</head>
-
-	<xsl:variable name="unique-catkey" select="/BugCollection/BugCategory/@category"/>
-	<!--xsl:variable name="unique-catkey" select="/BugCollection/BugInstance[generate-id() = generate-id(key('bug-category-key',@category))]/@category"/-->
-
-	<body>
-
-		<h1><a href="http://findbugs.sourceforge.net">FindBugs</a> Report</h1>
-
-	<h2>Project Information</h2>	
-	<xsl:apply-templates select="/BugCollection/Project"/>
-
-	<h2>Metrics</h2>
-	<xsl:apply-templates select="/BugCollection/FindBugsSummary"/>
-
-	<h2>Contents</h2>
-	<ul>
-		<xsl:for-each select="$unique-catkey">
-			<xsl:sort select="." order="ascending"/>
-			<xsl:variable name="catkey" select="."/>
-			<xsl:variable name="catdesc" select="/BugCollection/BugCategory[@category=$catkey]/Description"/>
-			
-			<li><a href="#Warnings_{$catkey}"><xsl:value-of select="$catdesc"/> Warnings</a></li>
-		</xsl:for-each>
-
-		<li><a href="#Details">Details</a></li>
-	</ul>
-
-	<h1>Summary</h1>
-	<table width="500" cellpadding="5" cellspacing="2">
-	    <tr class="tableheader">
-			<th align="left">Warning Type</th>
-			<th align="right">Number</th>
-		</tr>
-
-		<xsl:for-each select="$unique-catkey">
-			<xsl:sort select="." order="ascending"/>
-			<xsl:variable name="catkey" select="."/>
-			<xsl:variable name="catdesc" select="/BugCollection/BugCategory[@category=$catkey]/Description"/>
-			<xsl:variable name="styleclass">
-				<xsl:choose><xsl:when test="position() mod 2 = 1">tablerow0</xsl:when>
-					<xsl:otherwise>tablerow1</xsl:otherwise>
-				</xsl:choose>
-			</xsl:variable>
-			
-		<tr class="{$styleclass}">
-			<td><a href="#Warnings_{$catkey}"><xsl:value-of select="$catdesc"/> Warnings</a></td>
-			<td align="right"><xsl:value-of select="count(/BugCollection/BugInstance[(@category=$catkey) and not(@last)])"/></td>
-		</tr>
-		</xsl:for-each>
-
-		<xsl:variable name="styleclass">
-			<xsl:choose><xsl:when test="count($unique-catkey) mod 2 = 0">tablerow0</xsl:when>
-				<xsl:otherwise>tablerow1</xsl:otherwise>
-			</xsl:choose>
-		</xsl:variable>
-		<tr class="{$styleclass}">
-		    <td><b>Total</b></td>
-		    <td align="right"><b><xsl:value-of select="count(/BugCollection/BugInstance[not(@last)])"/></b></td>
-		</tr>
-	</table>
-
-	<h1>Warnings</h1>
-
-	<p>Click on a warning row to see full context information.</p>
-
-	<xsl:for-each select="$unique-catkey">
-		<xsl:sort select="." order="ascending"/>
-		<xsl:variable name="catkey" select="."/>
-		<xsl:variable name="catdesc" select="/BugCollection/BugCategory[@category=$catkey]/Description"/>
-			
-		<xsl:call-template name="generateWarningTable">
-			<xsl:with-param name="warningSet" select="/BugCollection/BugInstance[(@category=$catkey) and not(@last)]"/>
-			<xsl:with-param name="sectionTitle"><xsl:value-of select="$catdesc"/> Warnings</xsl:with-param>
-			<xsl:with-param name="sectionId">Warnings_<xsl:value-of select="$catkey"/></xsl:with-param>
-		</xsl:call-template>
-	</xsl:for-each>
-
-	<h1><a name="Details">Details</a></h1>
-
-	<xsl:apply-templates select="/BugCollection/BugPattern">
-		<xsl:sort select="@abbrev"/>
-		<xsl:sort select="ShortDescription"/>
-	</xsl:apply-templates>
-
-	</body>
-	</html>
-</xsl:template>
-
-<xsl:template match="Project">
-	<p>Project: 
-		<xsl:choose>
-			<xsl:when test='string-length(/BugCollection/Project/@projectName)>0'><xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when>
-			<xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise>
-		</xsl:choose>
-	</p>
-	<p>FindBugs version: <xsl:value-of select="/BugCollection/@version"/></p>
-	
-	<p>Code analyzed:</p>
-	<ul>
-		<xsl:for-each select="./Jar">
-			<li><xsl:value-of select="text()"/></li>
-		</xsl:for-each>
-	</ul>
-	<p><br/><br/></p>
-</xsl:template>
-
-<xsl:template match="BugInstance[not(@last)]">
-	<xsl:variable name="warningId"><xsl:value-of select="generate-id()"/></xsl:variable>
-
-	<tr class="tablerow{position() mod 2}" onclick="toggleRow('{$warningId}');">
-
-	<td>
-	    <span><xsl:attribute name="class">priority-<xsl:value-of select="@priority"/></xsl:attribute>
-	        <xsl:value-of select="@abbrev"/>
-        </span>
-	</td>
-
-	<td>
-	<xsl:value-of select="LongMessage"/>
-	</td>
-
-	</tr>
-
-	<!-- Add bug annotation elements: Class, Method, Field, SourceLine, Field -->
-	<tr class="detailrow{position() mod 2}">
-		<td/>
-		<td>
-			<p id="{$warningId}" style="display: none;">
-				<a href="#{@type}">Bug type <xsl:value-of select="@type"/> (click for details)</a>
-				<xsl:for-each select="./*/Message">
-					<br/><xsl:value-of select="text()" disable-output-escaping="no"/>
-				</xsl:for-each>
-			</p>
-		</td>
-	</tr>
-</xsl:template>
-
-<xsl:template match="BugPattern">
-	<h2><a name="{@type}"><xsl:value-of select="@type"/>: <xsl:value-of select="ShortDescription"/></a></h2>
-	<xsl:value-of select="Details" disable-output-escaping="yes"/>
-</xsl:template>
-
-<xsl:template name="generateWarningTable">
-	<xsl:param name="warningSet"/>
-	<xsl:param name="sectionTitle"/>
-	<xsl:param name="sectionId"/>
-
-	<h2><a name="{$sectionId}"><xsl:value-of select="$sectionTitle"/></a></h2>
-	<table class="warningtable" width="100%" cellspacing="0">
-		<xsl:copy-of select="$bugTableHeader"/>
-		<xsl:apply-templates select="$warningSet">
-			<xsl:sort select="@abbrev"/>
-			<xsl:sort select="Class/@classname"/>
-		</xsl:apply-templates>
-	</table>
-</xsl:template>
-
-<xsl:template match="FindBugsSummary">
-    <xsl:variable name="kloc" select="@total_size div 1000.0"/>
-    <xsl:variable name="format" select="'#######0.00'"/>
-
-	<p><xsl:value-of select="@total_size"/> lines of code analyzed,
-	in <xsl:value-of select="@total_classes"/> classes, 
-	in <xsl:value-of select="@num_packages"/> packages.</p>
-	<table width="500" cellpadding="5" cellspacing="2">
-	    <tr class="tableheader">
-			<th align="left">Metric</th>
-			<th align="right">Total</th>
-			<th align="right">Density*</th>
-		</tr>
-		<tr class="tablerow0">
-			<td>High Priority Warnings</td>
-			<td align="right"><xsl:value-of select="@priority_1"/></td>
-			<td align="right">
-			    <xsl:choose>
-                    <xsl:when test= "number($kloc) &gt; 0.0 and number(@priority_1) &gt; 0.0">
-        			    <xsl:value-of select="format-number(@priority_1 div $kloc, $format)"/>
-                    </xsl:when>
-                    <xsl:otherwise>
-        			    <xsl:value-of select="format-number(0.0, $format)"/>
-                    </xsl:otherwise>
-			    </xsl:choose>
-			</td>
-		</tr>
-		<tr class="tablerow1">
-			<td>Medium Priority Warnings</td>
-			<td align="right"><xsl:value-of select="@priority_2"/></td>
-			<td align="right">
-			    <xsl:choose>
-                    <xsl:when test= "number($kloc) &gt; 0.0 and number(@priority_2) &gt; 0.0">
-        			    <xsl:value-of select="format-number(@priority_2 div $kloc, $format)"/>
-                    </xsl:when>
-                    <xsl:otherwise>
-        			    <xsl:value-of select="format-number(0.0, $format)"/>
-                    </xsl:otherwise>
-			    </xsl:choose>
-			</td>
-		</tr>
-
-    <xsl:choose>
-		<xsl:when test="@priority_3">
-			<tr class="tablerow1">
-				<td>Low Priority Warnings</td>
-				<td align="right"><xsl:value-of select="@priority_3"/></td>
-				<td align="right">
-                    <xsl:choose>
-                        <xsl:when test= "number($kloc) &gt; 0.0 and number(@priority_3) &gt; 0.0">
-        			        <xsl:value-of select="format-number(@priority_3 div $kloc, $format)"/>
-                        </xsl:when>
-                        <xsl:otherwise>
-        		            <xsl:value-of select="format-number(0.0, $format)"/>
-                        </xsl:otherwise>
-			        </xsl:choose>
-				</td>
-			</tr>
-			<xsl:variable name="totalClass" select="tablerow0"/>
-		</xsl:when>
-		<xsl:otherwise>
-		    <xsl:variable name="totalClass" select="tablerow1"/>
-		</xsl:otherwise>
-	</xsl:choose>
-
-		<tr class="$totalClass">
-			<td><b>Total Warnings</b></td>
-			<td align="right"><b><xsl:value-of select="@total_bugs"/></b></td>
-            <xsl:choose>
-                <xsl:when test="number($kloc) &gt; 0.0">
-  					<td align="right"><b><xsl:value-of select="format-number(@total_bugs div $kloc, $format)"/></b></td>
-                </xsl:when>
-                <xsl:otherwise>
-					<td align="right"><b><xsl:value-of select="format-number(0.0, $format)"/></b></td>
-                </xsl:otherwise>
-	        </xsl:choose>
-		</tr>
-	</table>
-	<p><i>(* Defects per Thousand lines of non-commenting source statements)</i></p>
-	<p><br/><br/></p>
-
-</xsl:template>
-
-</xsl:stylesheet>
-
-<!-- vim:set ts=4: -->
diff --git a/lib/findbugs/xsl/fancy-hist.xsl b/lib/findbugs/xsl/fancy-hist.xsl
deleted file mode 100644
index 8086600..0000000
--- a/lib/findbugs/xsl/fancy-hist.xsl
+++ /dev/null
@@ -1,1127 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
-  Copyright (C) 2005, 2006 Etienne Giraudy, InStranet Inc
-  Copyright (C) 2005, 2007 Etienne Giraudy
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
--->
-
-<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >
-   <xsl:output
-         method="xml" indent="yes"
-         doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
-         doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
-         encoding="UTF-8"/>
-
-   <xsl:variable name="apos" select="&quot;'&quot;"/>
-   <xsl:key name="lbc-code-key"        match="/BugCollection/BugInstance" use="concat(@category,@abbrev)" />
-   <xsl:key name="lbc-bug-key"         match="/BugCollection/BugInstance" use="concat(@category,@abbrev,@type)" />
-   <xsl:key name="lbp-class-b-t"  match="/BugCollection/BugInstance" use="concat(Class/@classname,@type)" />
-
-<xsl:template match="/" >
-
-<html>
-   <head>
-      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-      <title>
-         FindBugs (<xsl:value-of select="/BugCollection/@version" />) 
-         Analysis for 
-         <xsl:choose>
-            <xsl:when test='string-length(/BugCollection/Project/@projectName)>0'><xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when>
-            <xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise>
-         </xsl:choose>
-      </title>
-      <style type="text/css">
-         html, body, div, form {
-            margin:0px;
-            padding:0px;
-         }
-         body {
-            padding:3px;
-         }
-         a, a:link , a:active, a:visited, a:hover {
-            text-decoration: none; color: black;
-         }
-         #navlist {
-                 padding: 3px 0;
-                 margin-left: 0;
-                 border-bottom: 1px solid #778;
-                 font: bold 12px Verdana, sans-serif;
-         }
-         #navlist li {
-                 list-style: none;
-                 margin: 0;
-                 display: inline;
-         }
-         #navlist li a {
-                 padding: 3px 0.5em;
-                 margin-left: 3px;
-                 border: 1px solid #778;
-                 border-bottom: none;
-                 background: #DDE;
-                 text-decoration: none;
-         }
-         #navlist li a:link { color: #448; }
-         #navlist li a:visited { color: #667; }
-         #navlist li a:hover {
-                 color: #000;
-                 background: #AAE;
-                 border-color: #227;
-         }
-         #navlist li a.current {
-                 background: white;
-                 border-bottom: 1px solid white;
-         }
-         #filterWrapper {
-            margin-bottom:5px;
-         }
-         #displayWrapper {
-            margin-top:5px;
-         }
-         .message {
-            background:#BBBBBB;
-           border: 1px solid #778;
-         }
-         .displayContainer {
-            border:1px solid #555555;
-            margin-top:3px;
-            padding: 3px;
-            display:none;
-         }
-         #summaryContainer table,
-         #historyContainer table {
-            border:1px solid black;
-         }
-         #summaryContainer th,
-         #historyContainer th {
-            background: #aaaaaa;
-            color: white;
-         }
-         #summaryContainer th, #summaryContainer td,
-         #historyContainer th, #historyContainer td {
-            padding: 2px 4px 2px 4px;
-         }
-         .summary-name {
-            background: #eeeeee;
-            text-align:left;
-         }
-         .summary-size {
-            background: #eeeeee;
-            text-align:center;
-         }
-         .summary-priority-all {
-            background: #dddddd;
-            text-align:center;
-         }
-         .summary-priority-1 {
-            background: red;
-            text-align:center;
-         }
-         .summary-priority-2 {
-            background: orange;
-            text-align:center;
-         }
-         .summary-priority-3 {
-            background: green;
-            text-align:center;
-         }
-         .summary-priority-4 {
-            background: blue;
-            text-align:center;
-         }
-
-         .bugList-level1 {
-            margin-bottom:5px;
-         }
-         .bugList-level1, .bugList-level2, .bugList-level3, .bugList-level4 {
-            background-color: #ffffff;
-            margin-left:15px;
-            padding-left:10px;
-         }
-         .bugList-level1-label, .bugList-level2-label, .bugList-level3-label, .bugList-level4-label {
-            background-color: #bbbbbb;
-            border: 1px solid black;
-            padding: 1px 3px 1px 3px;;
-         }
-         .bugList-level2-label, .bugList-level3-label, .bugList-level4-label {
-            border-width: 0px 1px 1px 1px;
-         }
-         .bugList-level4-label {
-            background-color: #ffffff;
-            border: 0px 0px 1px 0px;
-         }
-         .bugList-level4 {
-            border: 0px 1px 1px 1px;
-         }
-
-         .bugList-level4-inner {
-            border-style: solid;
-            border-color: black;
-            border-width: 0px 1px 1px 1px;
-         }
-         .b-r {
-            font-size: 10pt; font-weight: bold; padding: 0 0 0 60px;
-         }
-         .b-d {
-            font-weight: normal; background: #ccccc0;
-            padding: 0 5px 0 5px; margin: 0px;
-         }
-         .b-1 {
-            background: red; height: 0.5em; width: 1em;
-            margin-right: 0.5em;
-         }
-         .b-2 {
-            background: orange; height: 0.5em; width: 1em;
-            margin-right: 0.5em;
-         }
-         .b-3 {
-            background: green; height: 0.5em; width: 1em;
-            margin-right: 0.5em;
-         }
-         .b-4 {
-            background: blue; height: 0.5em; width: 1em;
-            margin-right: 0.5em;
-         }
-
-      </style>
-      <script type='text/javascript'><xsl:text disable-output-escaping='yes'><![CDATA[
-         var menus            = new Array('summary','info','history','listByCategories','listByPackages');
-         var selectedMenuId   = "summary";
-         var selectedVersion  = -1;
-         var selectedPriority = 4;
-         var lastVersion      = 0;
-
-         var bPackageNamesPopulated = false;
-
-         var filterContainerId              = "filterWrapper";
-         var messageContainerId             = "messageContainer";
-         var summaryContainerId             = "summaryContainer";
-         var infoContainerId                = "infoContainer";
-         var historyContainerId             = "historyContainer";
-         var listByCategoriesContainerId    = "listByCategoriesContainer";
-         var listByPackagesContainerId      = "listByPackagesContainer";
-
-         var idxCatKey = 0; var idxCatDescr = 1; var idxBugCat = 1;
-         var idxCodeKey = 0; var idxCodeDescr = 1; var idxBugCode = 2;
-         var idxPatternKey = 2; var idxPatternDescr = 3; var idxBugPattern = 3;
-         var idxBugKey = 0; var idxBugDescr = 6;
-         var idxBugClass = 6, idxBugPackage = 7;
-
-         // main init function
-         function init() {
-            loadFilter();
-            selectMenu(selectedMenuId);
-            lastVersion = versions.length - 1;
-         }
-
-         // menu callback function
-         function selectMenu(menuId) {
-            document.getElementById(selectedMenuId).className="none";
-            document.getElementById(menuId).className="current";
-            if (menuId!=selectedMenuId) {
-               hideMenu(selectedMenuId);
-               selectedMenuId = menuId;
-            }
-            if (menuId=="summary")           displaySummary();
-            if (menuId=="info")              displayInfo();
-            if (menuId=="history")           displayHistory();
-            if (menuId=="listByCategories")  displayListByCategories();
-            if (menuId=="listByPackages")    displayListByPackages();
-         }
-
-         // display filter
-         function loadFilter() {
-            var versionsBox = document.findbugsForm.versions.options;
-            versionsBox[0] = new Option(" -- All Versions -- ","-1");
-            versionsBox.selectedIndex = 0;
-            if (versions.length>=1) {
-               for (x=0; versions.length>1 && x<versions.length; x++) {
-                  versionsBox[x+1] = new Option(" Bugs at release: "+versions[versions.length-x-1][1], versions[versions.length-x-1][0]);
-               }
-            }
-
-            var prioritiesBox = document.findbugsForm.priorities.options;
-            prioritiesBox[0] = new Option(" -- All priorities -- ", "4");
-            prioritiesBox[1] = new Option(" P1 bugs ", "1");
-            prioritiesBox[2] = new Option(" P1 and P2 bugs ", "2");
-            prioritiesBox[3] = new Option(" P1, P2 and P3 bugs ", "3");
-         }
-
-         // display a message
-         function displayMessage(msg) {
-            var container = document.getElementById(messageContainerId);
-            container.innerHTML = "<div class='message'>"+msg+"</div>";
-         }
-
-         // reset displayed message
-         function resetMessage() {
-            var container = document.getElementById(messageContainerId);
-            container.innerHTML = "";
-         }
-
-         function hideMenu(menuId) {
-            var container = menuId+"Container";
-            document.getElementById(container).style.display="none";
-         }
-
-         // filter callback function
-         function filter() {
-            var versionsBox = document.findbugsForm.versions.options;
-            selectedVersion = versionsBox[versionsBox.selectedIndex].value;
-
-            var prioritiesBox = document.findbugsForm.priorities.options;
-            selectedPriority = prioritiesBox[prioritiesBox.selectedIndex].value;
-
-            selectMenu(selectedMenuId);
-         }
-
-         // display summary tab
-         function displaySummary() {
-            resetMessage();
-            hide(filterContainerId);
-            var container = document.getElementById(summaryContainerId);
-            container.style.display="block";
-         }
-
-         // display info tab
-         function displayInfo() {
-            resetMessage();
-            hide(filterContainerId);
-            var container = document.getElementById(infoContainerId);
-            container.style.display="block";
-         }
-
-         // display history tab
-         function displayHistory() {
-            displayMessage("Loading history...");
-            hide(filterContainerId);
-            var container = document.getElementById(historyContainerId);
-            var content = "";
-            var i=0;
-            var p = [0,0,0,0,0];
-            var f = [0,0,0,0,0];
-
-            content += "<table><tr><th>Release</th><th>Bugs</th><th>Bugs p1</th><th>Bugs p2</th><th>Bugs p3</th><th>Bugs Exp.</th></tr>";
-
-            for (i=(versions.length-1); i>0; i--) {
-               v = countBugsVersion(i, 4);
-               t = countTotalBugsVersion(i);
-               o = countFixedButActiveBugsVersion(i);
-               f = countFixedBugsInVersion(i);
-               content += "<tr>";
-               content += "<td class='summary-name'>" + versions[i][1] + "</td>";
-               content += "<td class='summary-priority-all'> " + (t[0] + o[0]) + " (+" + v[0] + " / -" + f[0] + ") </td>";
-               content += "<td class='summary-priority-1'  > " + (t[1] + o[1]) + " (+" + v[1] + " / -" + f[1] + ") </td>";
-               content += "<td class='summary-priority-2'  > " + (t[2] + o[2]) + " (+" + v[2] + " / -" + f[2] + ") </td>";
-               content += "<td class='summary-priority-3'  > " + (t[3] + o[3]) + " (+" + v[3] + " / -" + f[3] + ") </td>";
-               content += "<td class='summary-priority-4'  > " + (t[4] + o[4]) + " (+" + v[4] + " / -" + f[4] + ") </td>";
-               content += "</tr>";
-            }
-
-            t = countTotalBugsVersion(0);
-            o = countFixedButActiveBugsVersion(0);
-            content += "<tr>";
-            content += "<td class='summary-name'>" + versions[0][1] + "</td>";
-            content += "<td class='summary-priority-all'> " + (t[0] + o[0]) + " </td>";
-            content += "<td class='summary-priority-1'  > " + (t[1] + o[1]) + " </td>";
-            content += "<td class='summary-priority-2'  > " + (t[2] + o[2]) + " </td>";
-            content += "<td class='summary-priority-3'  > " + (t[3] + o[3]) + " </td>";
-            content += "<td class='summary-priority-4'  > " + (t[4] + o[4]) + " </td>";
-            content += "</tr>";
-
-            content += "</table>";
-            container.innerHTML = content;
-            container.style.display="block";
-            resetMessage();
-         }
-
-         // display list by cat tab
-         function displayListByCategories() {
-            show(filterContainerId);
-            var container = document.getElementById(listByCategoriesContainerId);
-            container.innerHTML = "";
-            container.style.display="block";
-            displayMessage("Loading stats (categories)...");
-            container.innerHTML = displayLevel1("lbc", "Stats by Bug Categories");
-            resetMessage();
-         }
-
-         // display list by package tab
-         function displayListByPackages() {
-            show(filterContainerId);
-            var container = document.getElementById(listByPackagesContainerId);
-            container.style.display="block";
-            if (!bPackageNamesPopulated) {
-               displayMessage("Initializing...");
-               populatePackageNames();
-            }
-            displayMessage("Loading stats (packages)...");
-            container.innerHTML = displayLevel1("lbp", "Stats by Bug Package");
-            resetMessage();
-         }
-
-         // callback function for list item click
-         function toggleList(listType, containerId, id1, id2, id3) {
-            var container = document.getElementById(containerId);
-            if (container.style.display=="block") {
-               container.style.display="none";
-            } else {
-               if (listType=="lbc") {
-                  if (id1.length>0 && id2.length==0 && id3.length==0) {
-                     displayCategoriesCodes(containerId, id1);
-                  } else if (id1.length>0 && id2.length>0 && id3.length==0) {
-                     displayCategoriesCodesPatterns(containerId, id1, id2);
-                  } else if (id1.length>0 && id2.length>0 && id3.length>0) {
-                     displayCategoriesCodesPatternsBugs(containerId, id1, id2, id3);
-                  } else {
-                     // ???
-                  }
-               } else if (listType=="lbp") {
-                  if (id1.length>0 && id2.length==0 && id3.length==0) {
-                     displayPackageCodes(containerId, id1);
-                  } else if (id1.length>0 && id2.length>0 && id3.length==0) {
-                     displayPackageClassPatterns(containerId, id1, id2);
-                  } else if (id1.length>0 && id2.length>0 && id3.length>0) {
-                     displayPackageClassPatternsBugs(containerId, id1, id2, id3);
-                  } else {
-                     // ???
-                  }
-               } else {
-                  // ????
-               }
-            }
-         }
-
-         // list by categories, display bug cat>codes
-         function displayCategoriesCodes(containerId, catId) {
-            displayMessage("Loading stats (codes)...");
-            var container = document.getElementById(containerId);
-            container.style.display="block";
-            if (container.innerHTML=="Loading..." || container.innerHTML=="") {
-               container.innerHTML = displayLevel2("lbc", catId);
-            }
-            resetMessage();
-         }
-
-         // list by categories, display bug package>codes
-         function displayPackageCodes(containerId, packageId) {
-            displayMessage("Loading stats (codes)...");
-            var container = document.getElementById(containerId);
-            container.style.display="block";
-            if (container.innerHTML=="Loading..." || container.innerHTML=="") {
-               container.innerHTML = displayLevel2("lbp", packageId);
-            }
-            resetMessage();
-         }
-
-         // list by categories, display bug cat>codes>patterns
-         function displayCategoriesCodesPatterns(containerId, catId, codeId) {
-            displayMessage("Loading stats (patterns)...");
-            var container = document.getElementById(containerId);
-            container.style.display="block";
-            if (container.innerHTML=="Loading..." || container.innerHTML=="")
-               container.innerHTML = displayLevel3("lbc", catId, codeId);
-            resetMessage();
-         }
-
-         // list by package, display bug package>class>patterns
-         function displayPackageClassPatterns(containerId, packageId, classId) {
-            displayMessage("Loading stats (patterns)...");
-            var container = document.getElementById(containerId);
-            container.style.display="block";
-            if (container.innerHTML=="Loading..." || container.innerHTML=="")
-               container.innerHTML = displayLevel3("lbp", packageId, classId);
-            resetMessage();
-         }
-
-         // list by categories, display bug cat>codes>patterns>bugs
-         function displayCategoriesCodesPatternsBugs(containerId, catId, codeId, patternId) {
-            displayMessage("Loading stats (bugs)...");
-            var container = document.getElementById(containerId);
-            container.style.display="block";
-            if (container.innerHTML=="Loading..." || container.innerHTML=="")
-               container.innerHTML = displayLevel4("lbc", catId, codeId, patternId);
-            resetMessage();
-         }
-
-         // list by package, display bug package>class>patterns>bugs
-         function displayPackageClassPatternsBugs(containerId, packageId, classId, patternId) {
-            displayMessage("Loading stats (bugs)...");
-            var container = document.getElementById(containerId);
-            container.style.display="block";
-            if (container.innerHTML=="Loading..." || container.innerHTML=="")
-               container.innerHTML = displayLevel4("lbp",  packageId, classId, patternId);
-            resetMessage();
-         }
-
-         // generate level 1 list
-         function displayLevel1(list, title) {
-            var content = "";
-            var content2 = "";
-
-            content += "<h3>"+title+"</h3>";
-            content += getPriorityLegend();
-            content2 += "<div class='bugList'>";
-
-            var id = "";
-            var containerId = "";
-            var subContainerId = "";
-            var prefixSub = "";
-            var prefixId = "";
-            var p = [0,0,0,0,0];
-            var numberOfBugs = 0;
-            var label = "";
-            var max = 0;
-            if (list=="lbc") {
-               max = categories.length;
-            } else if (list=="lbp") {
-               max = packageStats.length;
-            }
-
-            for (var x=0; x<max -1; x++) {
-               if (list=="lbp" && packageStats[x][1]=="0") continue;
-
-               if (list=="lbc") {
-                  id = categories[x][idxCatKey];
-                  label = categories[x][idxCatDescr];
-                  containerId = "categories-" + id;
-                  subContainerId = "cat-"+id;
-                  p = countBugsCat(selectedVersion, selectedPriority, id, idxBugCat);
-               }
-               if (list=="lbp") {
-                  id = packageStats[x][0];
-                  label = packageStats[x][0];
-                  containerId = "packages-" + id;
-                  subContainerId = "package-"+id;
-                  p = countBugsPackage(selectedVersion, selectedPriority, id, idxBugPackage);
-               }
-
-               subContainerId = prefixSub+id;
-
-               var total = p[1]+p[2]+p[3]+p[4];
-               if (total > 0) {
-                  content2 += addListItem( 1, containerId, label, total, p, subContainerId,
-                                          "toggleList('" + list + "', '" + subContainerId + "', '"+ id + "', '', '')"
-                                          );
-               }
-               numberOfBugs += total;
-            }
-            content2 += "</div>";
-            content += "<h4>Total number of bugs";
-            if (selectedVersion!=-1) {
-               content += " (introduced in release " + versions[selectedVersion][1] +")";
-            }
-            content += ": "+numberOfBugs+"</h4>";
-            return content+content2;
-         }
-
-         // generate level 2 list
-        function displayLevel2(list, id1) {
-            var content = "";
-            var code = "";
-            var containerId = "";
-            var subContainerId = "";
-            var p = [0,0,0,0,0];
-            var max = 0;
-            var id2 = "";
-            if (list=="lbc") {
-               max = codes.length;
-            } else if (list=="lbp") {
-               max = classStats.length;
-            }
-
-            for (var x=0; x<max -1; x++) {
-               if (list=="lbp" && classStats[x][3]=="0") continue;
-
-               if (list=="lbc") {
-                  id2 = codes[x][idxCodeKey];
-                  label = codes[x][idxCodeDescr];
-                  containerId = "codes-"+id1;
-                  subContainerId = "cat-" + id1 + "-code-" + id2;
-                  p = countBugsCode(selectedVersion, selectedPriority, id1, idxBugCat, id2, idxBugCode);
-               }
-               if (list=="lbp") {
-                  id2 = classStats[x][0];
-                  label = classStats[x][0];
-                  containerId = "packages-"+id1;
-                  subContainerId = "package-" + id1 + "-class-" + id2;
-                  p = countBugsClass(selectedVersion, selectedPriority, id1, idxBugPackage, id2, idxBugClass);
-               }
-
-               var total = p[1]+p[2]+p[3]+p[4];
-               if (total > 0) {
-                  content += addListItem( 2, containerId, label, total, p, subContainerId,
-                                          "toggleList('"+ list + "', '" + subContainerId + "', '"+ id1 + "', '"+ id2 + "', '')"
-                                          );
-               }
-            }
-            return content;
-         }
-
-         // generate level 3 list
-        function displayLevel3(list, id1, id2) {
-            var content = "";
-            var containerId = "";
-            var subContainerId = "";
-            var p = [0,0,0,0,0];
-            var max = 0;
-            var label = "";
-            var id3 = "";
-
-            if (list=="lbc") {
-               max = patterns.length;
-            } else if (list=="lbp") {
-               max = patterns.length;
-            }
-
-            for (var x=0; x<max -1; x++) {
-               //if (list=="lbp" && (patterns[x][0]!=id1 || patterns[x][1]!=id2)) continue;
-               //if (list=="lbp" && classStats[x][3]=="0") continue;
-
-               if (list=="lbc") {
-                  id3 = patterns[x][idxPatternKey];;
-                  label = patterns[x][idxPatternDescr];
-                  containerId = "patterns-"+id1;
-                  subContainerId = "cat-" + id1 + "-code-" + id2 + "-pattern-" + id3;
-                  p = countBugsPattern(selectedVersion, selectedPriority, id1, idxBugCat, id2, idxBugCode, id3, idxBugPattern);
-               }
-               if (list=="lbp") {
-                  id3 = patterns[x][idxPatternKey];;
-                  label = patterns[x][idxPatternDescr];
-                  containerId = "classpatterns-"+id1;
-                  subContainerId = "package-" + id1 + "-class-" + id2 + "-pattern-" + id3;
-                  p = countBugsClassPattern(selectedVersion, selectedPriority, id2, idxBugClass, id3, idxBugPattern);
-               }
-
-               var total = p[1]+p[2]+p[3]+p[4];
-               if (total > 0) {
-                  content += addListItem( 3, containerId, label, total, p, subContainerId,
-                                          "toggleList('" + list + "', '" + subContainerId + "', '"+ id1 + "', '"+ id2 + "', '"+ id3 + "')"
-                                          );
-               }
-            }
-            return content;
-         }
-
-         // generate level 4 list
-        function displayLevel4(list, id1, id2, id3) {
-            var content = "";
-            var bug = "";
-            var bugP = 0;
-            var containerId = "";
-            var subContainerId = "";
-            var bugId = "";
-            var label = "";
-            var p = [0,0,0,0,0];
-            for (var x=0; x<bugs.length -1; x++) {
-               bug = bugs[x];
-               if (list=="lbc") {
-                  if ( bug[1]!=id1 || bug[2]!=id2 || bug[3]!=id3 ) continue;
-                  if ( selectedVersion!=-1
-                     && selectedVersion!=bug[5]) continue;
-                  if ( selectedPriority!=4
-                     && selectedPriority<bug[4]) continue;
-
-                  subContainerId = "cat-" + id1 + "-code-" + id2 + "-pattern-" + id3 + "-bug-" + bug[0];
-               }
-               if (list=="lbp") {
-                  if ( bug[7]!=id1 || bug[6]!=id2 || bug[3]!=id3 ) continue;
-                  if ( selectedVersion!=-1
-                     && selectedVersion!=bug[5]) continue;
-                  if ( selectedPriority!=4
-                     && selectedPriority<bug[4]) continue;
-
-                  subContainerId = "package-" + id1 + "-class-" + id2 + "-pattern-" + id3 + "-bug-" + bug[0];
-               }
-
-               bugId = "b-uid-" + bug[0];
-               label = bug[idxBugDescr];
-               containerId = "bugs-"+bugId;
-               bugP = bug[4];
-               p[bugP]++;
-               var total = p[1]+p[2]+p[3]+p[4];
-               if (total > 0) {
-                  content += addBug(   4, containerId, label, bugP, bug[5], subContainerId,
-                                       "showbug('" + bugId + "', '" + subContainerId + "', '"+id3+"')");
-               }
-            }
-            return content;
-         }
-
-
-         function addListItem(level, id, label, total, p, subId, onclick) {
-            var content = "";
-
-            content += "<div class='bugList-level"+level+"' >";
-            content += "<div class='bugList-level"+level+"-label' id='"+id+"' >";
-            content += "<a href='' onclick=\"" + onclick + ";return false;\" ";
-            content += ">";
-            content += "<strong>"+label+"</strong>";
-            content += " "+total+" bugs";
-            if (selectedPriority>1)
-               content += " <em>("+p[1];
-            if (selectedPriority>=2)
-               content += "/"+p[2];
-            if (selectedPriority>=3)
-               content += "/"+p[3];
-            if (selectedPriority>=4)
-               content += "/"+p[4];
-            if (selectedPriority>1)
-               content += ")</em>";
-            content += "</a>";
-            content += "</div>";
-            content += "<div class='bugList-level"+level+"-inner' id='"+subId+"' style='display:none;'>Loading...</div>";
-            content += "</div>";
-            return content;
-         }
-
-         function addBug( level, id, label, p, version, subId, onclick) {
-            var content = "";
-
-            content += "<div class='bugList-level" + level + "' id='" + id + "'>";
-            content += "<div class='bugList-level" + level + "-label' id='" + id + "'>";
-            content += "<span class='b-" + p + "'>&nbsp;&nbsp;&nbsp;</span>";
-            content += "<a href='' onclick=\"" + onclick + ";return false;\">";
-            if (version==lastVersion) {
-               content += "<span style='color:red;font-weight:bold;'>NEW!</span> ";
-            }
-            content += "<strong>" + label + "</strong>";
-            if (version==0) {
-               content += " <em>since release first historized release</em>";
-            } else {
-               content += " <em>since release " + versions[version][1] + "</em>";
-            }
-            content += "</a>";
-            content += "</div>";
-            content += "<div class='bugList-level" + level + "-inner' id='" + subId + "' style='display:none;'>Loading...</div>";
-            content += "</div>";
-            return content;
-         }
-
-         function countBugsVersion(version, priority) {
-            return countBugs(version, priority, "", -1, "", -1, "", -1, "", -1, "", -1);
-         }
-
-         function countBugsCat(version, priority, cat, idxCat) {
-            return countBugs(version, priority, cat, idxCat, "", -1, "", -1, "", -1, "", -1);
-         }
-
-         function countBugsPackage(version, priority, packageId, idxPackage) {
-            return countBugs(version, priority, "", -1, "", -1, "", -1, packageId, idxPackage, "", -1);
-         }
-
-         function countBugsCode(version, priority, cat, idxCat, code, idxCode) {
-            return countBugs(version, priority, cat, idxCat, code, idxCode, "", -1, "", -1, "", -1);
-         }
-
-         function countBugsPattern(version, priority, cat, idxCat, code, idxCode, packageId, idxPattern) {
-            return countBugs(version, priority, cat, idxCat, code, idxCode, packageId, idxPattern, "", -1, "", -1);
-         }
-
-         function countBugsClass(version, priority, id1, idxBugPackage, id2, idxBugClass) {
-            return countBugs(version, priority, "", -1, "", -1, "", -1, id1, idxBugPackage, id2, idxBugClass);
-         }
-
-         function countBugsClassPattern(version, priority, id2, idxBugClass, id3, idxBugPattern) {
-            return countBugs(version, priority, "", -1, "", -1, id3, idxBugPattern, "", -1, id2, idxBugClass);
-         }
-
-         function countBugs(version, priority, cat, idxCat, code, idxCode, pattern, idxPattern, packageId, idxPackage, classId, idxClass) {
-            var count = [0,0,0,0,0];
-            var last=1000000;
-            for (var x=0; x<bugs.length-1; x++) {
-               var bug = bugs[x];
-
-               var bugCat = bug[idxCat];
-               var bugP = bug[4];
-               var bugCode = bug[idxCode];
-               var bugPattern = bug[idxPattern];
-
-               if (     (version==-1    || version==bug[5])
-                     && (priority==4    || priority>=bug[4])
-                     && (idxCat==-1     || bug[idxCat]==cat)
-                     && (idxCode==-1    || bug[idxCode]==code)
-                     && (idxPattern==-1 || bug[idxPattern]==pattern)
-                     && (idxPackage==-1 || bug[idxPackage]==packageId)
-                     && (idxClass==-1   || bug[idxClass]==classId)
-                     ) {
-                  count[bug[4]]++;
-               }
-            }
-            count[0] = count[1] + count[2] + count[3] + count[4];
-            return count;
-         }
-
-         function countFixedBugsInVersion(version) {
-            var count = [0,0,0,0,0];
-            var last=1000000;
-            for (var x=0; x<fixedBugs.length-1; x++) {
-               var bug = fixedBugs[x];
-
-               var bugP = bug[4];
-
-               if ( version==-1 || version==(bug[6]+1)) {
-                  count[bug[4]]++;
-               }
-            }
-            count[0] = count[1] + count[2] + count[3] + count[4];
-            return count;
-         }
-
-         function countFixedButActiveBugsVersion(version) {
-            var count = [0,0,0,0,0];
-            var last=1000000;
-            for (var x=0; x<fixedBugs.length-1; x++) {
-               var bug = fixedBugs[x];
-
-               var bugP = bug[4];
-
-               if ( version==-1 || (version >=bug[5] && version<=bug[6]) ) {
-                  count[bug[4]]++;
-               }
-            }
-            count[0] = count[1] + count[2] + count[3] + count[4];
-            return count;
-         }
-
-         function countTotalBugsVersion(version) {
-            var count = [0,0,0,0,0];
-            var last=1000000;
-            for (var x=0; x<bugs.length-1; x++) {
-               var bug = bugs[x];
-
-               var bugP = bug[4];
-
-               if (version==-1 || version>=bug[5]) {
-                  count[bug[4]]++;
-               }
-            }
-            count[0] = count[1] + count[2] + count[3] + count[4];
-            return count;
-         }
-
-         function getPriorityLegend() {
-            var content = "";
-            content += "<h5><span class='b-1'>&nbsp;&nbsp;&nbsp;</span> P1 ";
-            content += "<span class='b-2'>&nbsp;&nbsp;&nbsp;</span> P2 ";
-            content += "<span class='b-3'>&nbsp;&nbsp;&nbsp;</span> P3 ";
-            content += "<span class='b-4'>&nbsp;&nbsp;&nbsp;</span> Exp ";
-            content += "</h5>";
-            return content;
-         }
-
-         function populatePackageNames() {
-            for (var i=0; i<bugs.length; i++) {
-               var classId = bugs[i][6];
-               var idx = classId.lastIndexOf('.');
-               var packageId = "";
-
-               if (idx>0) {
-                  packageId = classId.substring(0, idx);
-               }
-
-               bugs[i][7] = packageId;
-            }
-         }
-
-         function showbug(bugId, containerId, patternId) {
-            var bugplaceholder   = document.getElementById(containerId);
-            var bug              = document.getElementById(bugId);
-
-            if ( bugplaceholder==null) {
-               alert(buguid+'-ph-'+list+' - '+buguid+' - bugplaceholder==null');
-               return;
-            }
-            if ( bug==null) {
-               alert(buguid+'-ph-'+list+' - '+buguid+' - bug==null');
-               return;
-            }
-
-            var newBug = bug.innerHTML;
-            var pattern = document.getElementById('tip-'+patternId).innerHTML;
-            toggle(containerId);
-            bugplaceholder.innerHTML = newBug + pattern;
-         }
-         function toggle(foo) {
-            if( document.getElementById(foo).style.display == "none") {
-               show(foo);
-            } else {
-               if( document.getElementById(foo).style.display == "block") {
-                  hide(foo);
-               } else {
-                  show(foo);
-               }
-            }
-         }
-         function show(foo) {
-            document.getElementById(foo).style.display="block";
-         }
-         function hide(foo) {
-            document.getElementById(foo).style.display="none";
-         }
-
-         window.onload = function(){
-            init();
-         };
-      ]]></xsl:text></script>
-      <script type='text/javascript'>
-         // versions fields: release id, release label
-         var versions = new Array(
-            <xsl:for-each select="/BugCollection/History/AppVersion">
-               [ "<xsl:value-of select="@sequence" />", "<xsl:value-of select="@release" />" ],
-            </xsl:for-each>
-               [ "<xsl:value-of select="/BugCollection/@sequence" />", "<xsl:value-of select="/BugCollection/@release" />" ]
-            );
-
-         // categories fields: category id, category label
-         var categories = new Array(
-            <xsl:for-each select="/BugCollection/BugCategory">
-               <xsl:sort select="@category" order="ascending" />
-               [ "<xsl:value-of select="@category" />", "<xsl:value-of select="Description" />" ],
-            </xsl:for-each>
-               [ "", "" ]
-            );
-
-         // codes fields: code id, code label
-         var codes = new Array(
-            <xsl:for-each select="/BugCollection/BugCode">
-               <xsl:sort select="@abbrev" order="ascending" />
-               [ "<xsl:value-of select="@abbrev" />", "<xsl:value-of select="Description" />" ],
-            </xsl:for-each>
-               [ "", "" ]
-            );
-
-         // patterns fields: category id, code id, pattern id, pattern label
-         var patterns = new Array(
-            <xsl:for-each select="/BugCollection/BugPattern">
-               <xsl:sort select="@type" order="ascending" />
-               [ "<xsl:value-of select="@category" />", "<xsl:value-of select="@abbrev" />", "<xsl:value-of select="@type" />", "<xsl:value-of select="translate(ShortDescription, '&quot;', $apos)" />" ],
-
-            </xsl:for-each>
-               [ "", "", "", "" ]
-            );
-
-         // class stats fields: class name, package name, isInterface, total bugs, bugs p1, bugs p2, bugs p3, bugs p4
-         var classStats = new Array(
-            <xsl:for-each select="/BugCollection/FindBugsSummary/PackageStats/ClassStats">
-               <xsl:sort select="@class" order="ascending" />
-               [ "<xsl:value-of select="@class" />", "<xsl:value-of select="../@package" />", "<xsl:value-of select="@interface" />", "<xsl:value-of select="@bugs" />", "<xsl:value-of select="@priority_1" />", "<xsl:value-of select="@priority_2" />", "<xsl:value-of select="@priority_3" />", "<xsl:value-of select="@priority_4" />" ],
-            </xsl:for-each>
-               [ "", "", "", "", "", "", "", "" ]
-            );
-
-         // package stats fields: package name, total bugs, bugs p1, bugs p2, bugs p3, bugs p4
-         var packageStats = new Array(
-            <xsl:for-each select="/BugCollection/FindBugsSummary/PackageStats">
-               <xsl:sort select="@package" order="ascending" />
-               [ "<xsl:value-of select="@package" />", "<xsl:value-of select="@total_bugs" />", "<xsl:value-of select="@priority_1" />", "<xsl:value-of select="@priority_2" />", "<xsl:value-of select="@priority_3" />", "<xsl:value-of select="@priority_4" />" ],
-            </xsl:for-each>
-               [ "", "", "", "", "", "" ]
-            );
-
-
-         // bugs fields: bug id, category id, code id, pattern id, priority, release id, class name, packagename (populated by javascript)
-         var bugs = new Array(
-            <xsl:for-each select="/BugCollection/BugInstance[string-length(@last)=0]">
-
-               [ "<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" />",
-                 "<xsl:value-of select="@category" />",
-                 "<xsl:value-of select="@abbrev" />",
-                 "<xsl:value-of select="@type" />",
-                 <xsl:value-of select="@priority" />,
-                 <xsl:choose><xsl:when test='string-length(@first)=0'>0</xsl:when><xsl:otherwise><xsl:value-of select="@first" /></xsl:otherwise></xsl:choose>,
-                 "<xsl:value-of select="Class/@classname" />",
-                 ""],
-            </xsl:for-each>
-               [ "", "", "", "", 0, 0, "", "" ]
-            );
-
-         // bugs fields: bug id, category id, code id, pattern id, priority, first release id, fixed release id, class name
-         var fixedBugs = new Array(
-            <xsl:for-each select="/BugCollection/BugInstance[string-length(@last)>0]">
-
-               [ "<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" />",
-                 "<xsl:value-of select="@category" />",
-                 "<xsl:value-of select="@abbrev" />",
-                 "<xsl:value-of select="@type" />",
-                 <xsl:value-of select="@priority" />,
-                 <xsl:choose><xsl:when test='string-length(@first)=0'>0</xsl:when><xsl:otherwise><xsl:value-of select="@first" /></xsl:otherwise></xsl:choose>,
-                 <xsl:choose><xsl:when test='string-length(@last)>0'><xsl:value-of select="@last" /></xsl:when><xsl:otherwise>-42</xsl:otherwise></xsl:choose>,
-                 "<xsl:value-of select="Class/@classname" />" ],
-            </xsl:for-each>
-               [ "", "", "", "", 0, 0, 0, "" ]
-            );
-
-      </script>
-   </head>
-   <body>
-      <h3>
-         <a href="http://findbugs.sourceforge.net">FindBugs</a> (<xsl:value-of select="/BugCollection/@version" />) 
-         Analysis for 
-         <xsl:choose>
-            <xsl:when test='string-length(/BugCollection/Project/@projectName)>0'><xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when>
-            <xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise>
-         </xsl:choose>
-      </h3>
-
-      <div id='menuWrapper' style=''>
-         <div id="navcontainer">
-            <ul id="navlist">
-               <li><a id='summary'           class="current" href="#" onclick="selectMenu('summary'); return false;"         >Summary</a></li>
-               <li><a id='history'           class="none"    href="#" onclick="selectMenu('history'); return false;"         >History</a></li>
-               <li><a id='listByCategories'  class="none"    href="#" onclick="selectMenu('listByCategories'); return false;">Browse By Categories</a></li>
-               <li><a id='listByPackages'    class="none"    href="#" onclick="selectMenu('listByPackages'); return false;"  >Browse by Packages</a></li>
-               <li><a id='info'              class="none"    href="#" onclick="selectMenu('info'); return false;"            >Info</a></li>
-            </ul>
-         </div>
-      </div>
-
-      <div id='displayWrapper'>
-
-      <div style='height:25px;'>
-         <div id='messageContainer' style='float:right;'>
-            Computing data...
-         </div>
-         <div id='filterWrapper' style='display:none;'>
-            <form name='findbugsForm'>
-               <div id='filterContainer' >
-                  <select name='versions' onchange='filter()'>
-                     <option value="loading">Loading filter...</option>
-                  </select>
-                  <select name='priorities' onchange='filter()'>
-                     <option value="loading">Loading filter...</option>
-                  </select>
-               </div>
-            </form>
-         </div>
-      </div>
-         <div id='summaryContainer'          class='displayContainer'>
-            <h3>Package Summary</h3>
-            <table>
-               <tr>
-                  <th>Package</th>
-                  <th>Code Size</th>
-                  <th>Bugs</th>
-                  <th>Bugs p1</th>
-                  <th>Bugs p2</th>
-                  <th>Bugs p3</th>
-                  <th>Bugs Exp.</th>
-               </tr>
-               <tr>
-                  <td class='summary-name'>
-                     Overall
-                     (<xsl:value-of select="/BugCollection/FindBugsSummary/@num_packages" /> packages),
-                     (<xsl:value-of select="/BugCollection/FindBugsSummary/@total_classes" /> classes)
-                  </td>
-                  <td class='summary-size'><xsl:value-of select="/BugCollection/FindBugsSummary/@total_size" /></td>
-                  <td class='summary-priority-all'><xsl:value-of select="/BugCollection/FindBugsSummary/@total_bugs" /></td>
-                  <td class='summary-priority-1'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_1" /></td>
-                  <td class='summary-priority-2'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_2" /></td>
-                  <td class='summary-priority-3'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_3" /></td>
-                  <td class='summary-priority-4'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_4" /></td>
-               </tr>
-               <xsl:for-each select="/BugCollection/FindBugsSummary/PackageStats">
-                  <xsl:sort select="@package" order="ascending" />
-                  <xsl:if test="@total_bugs!='0'" >
-                     <tr>
-                        <td class='summary-name'><xsl:value-of select="@package" /></td>
-                        <td class='summary-size'><xsl:value-of select="@total_size" /></td>
-                        <td class='summary-priority-all'><xsl:value-of select="@total_bugs" /></td>
-                        <td class='summary-priority-1'><xsl:value-of select="@priority_1" /></td>
-                        <td class='summary-priority-2'><xsl:value-of select="@priority_2" /></td>
-                        <td class='summary-priority-3'><xsl:value-of select="@priority_3" /></td>
-                        <td class='summary-priority-4'><xsl:value-of select="@priority_4" /></td>
-                     </tr>
-                  </xsl:if>
-               </xsl:for-each>
-            </table>
-         </div>
-
-         <div id='infoContainer'             class='displayContainer'>
-            <div id='analyzed-files'>
-               <h3>Analyzed Files:</h3>
-               <ul>
-                  <xsl:for-each select="/BugCollection/Project/Jar">
-                     <li><xsl:apply-templates /></li>
-                  </xsl:for-each>
-               </ul>
-            </div>
-            <div id='used-libraries'>
-               <h3>Used Libraries:</h3>
-               <ul>
-                  <xsl:for-each select="/BugCollection/Project/AuxClasspathEntry">
-                     <li><xsl:apply-templates /></li>
-                  </xsl:for-each>
-                  <xsl:if test="count(/BugCollection/Project/AuxClasspathEntry)=0" >
-                     <li>None</li>
-                  </xsl:if>
-               </ul>
-            </div>
-            <div id='analysis-error'>
-               <h3>Analysis Errors:</h3>
-               <ul>
-                  <xsl:variable name="error-count"
-                                select="count(/BugCollection/Errors/MissingClass)" />
-                  <xsl:if test="$error-count=0" >
-                     <li>None</li>
-                  </xsl:if>
-                  <xsl:if test="$error-count>0" >
-                     <li>Missing ref classes for analysis:
-                        <ul>
-                           <xsl:for-each select="/BugCollection/Errors/MissingClass">
-                              <li><xsl:apply-templates /></li>
-                           </xsl:for-each>
-                        </ul>
-                     </li>
-                  </xsl:if>
-               </ul>
-            </div>
-         </div>
-         <div id='historyContainer'          class='displayContainer'>Loading...</div>
-         <div id='listByCategoriesContainer' class='displayContainer'>Loading...</div>
-         <div id='listByPackagesContainer'   class='displayContainer'>Loading...</div>
-      </div>
-
-      <div id='bug-collection' style='display:none;'>
-      <!-- advanced tooltips -->
-      <xsl:for-each select="/BugCollection/BugPattern">
-         <xsl:variable name="b-t"><xsl:value-of select="@type" /></xsl:variable>
-         <div>
-            <xsl:attribute name="id">tip-<xsl:value-of select="$b-t" /></xsl:attribute>
-            <xsl:attribute name="class">tip</xsl:attribute>
-            <xsl:value-of select="/BugCollection/BugPattern[@type=$b-t]/Details" disable-output-escaping="yes" />
-         </div>
-      </xsl:for-each>
-
-      <!-- bug descriptions - hidden -->
-      <xsl:for-each select="/BugCollection/BugInstance[not(@last)]">
-            <div style="display:none;" class='bug'>
-               <xsl:attribute name="id">b-uid-<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" /></xsl:attribute>
-               <xsl:for-each select="*/Message">
-                  <div class="b-r"><xsl:apply-templates /></div>
-               </xsl:for-each>
-               <div class="b-d">
-                  <xsl:value-of select="LongMessage" disable-output-escaping="no" />
-               </div>
-            </div>
-      </xsl:for-each>
-      </div>
-   </body>
-</html>
-</xsl:template>
-
-
-</xsl:transform>
-
diff --git a/lib/findbugs/xsl/fancy.xsl b/lib/findbugs/xsl/fancy.xsl
deleted file mode 100644
index 5d152dd..0000000
--- a/lib/findbugs/xsl/fancy.xsl
+++ /dev/null
@@ -1,846 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
-  Copyright (C) 2005, 2006 Etienne Giraudy, InStranet Inc
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
--->
-
-<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >
-   <xsl:output
-         method="xml" indent="yes"
-         doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
-         doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
-         encoding="UTF-8"/>
-
-    <!-- 
-        Parameter for specifying HTMLized sources location; if current dir, use "./" 
-        If not passed, no links to sources are generated.
-        because of back-compatibility reasons. 
-        The source filename should be package.class.java.html
-        The source can have line no anchors like #11 -->
-    <xsl:param name="htmlsrcpath"></xsl:param>
-
-   <!--xsl:key name="lbc-category-key"    match="/BugCollection/BugInstance" use="@category" /-->
-   <xsl:key name="lbc-code-key"        match="/BugCollection/BugInstance" use="concat(@category,@abbrev)" />
-   <xsl:key name="lbc-bug-key"         match="/BugCollection/BugInstance" use="concat(@category,@abbrev,@type)" />
-   <xsl:key name="lbp-class-b-t"  match="/BugCollection/BugInstance" use="concat(Class/@classname,@type)" />
-
-<xsl:template match="/" >
-
-<html>
-   <head>
-      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-      <title>
-        FindBugs (<xsl:value-of select="/BugCollection/@version" />) 
-         Analysis for 
-         <xsl:choose>
-            <xsl:when test='string-length(/BugCollection/Project/@projectName)>0'><xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when>
-            <xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise>
-         </xsl:choose>
-      </title>
-      <script type="text/javascript">
-         function show(foo) {
-            document.getElementById(foo).style.display="block";
-         }
-         function hide(foo) {
-            document.getElementById(foo).style.display="none";
-         }
-         function toggle(foo) {
-            if( document.getElementById(foo).style.display == "none") {
-               show(foo);
-            } else {
-               if( document.getElementById(foo).style.display == "block") {
-                  hide(foo);
-               } else {
-                  show(foo);
-               }
-            }
-         }
-
-         function showmenu(foo) {
-            if( document.getElementById(foo).style.display == "none") {
-               hide("bug-summary");
-               document.getElementById("bug-summary-tab").className="menu-tab";
-               hide("analysis-data");
-               document.getElementById("analysis-data-tab").className="menu-tab";
-               //hide("list-by-b-t");
-               //document.getElementById("list-by-b-t-tab").className="menu-tab";
-               hide("list-by-package");
-               document.getElementById("list-by-package-tab").className="menu-tab";
-               hide("list-by-category");
-               document.getElementById("list-by-category-tab").className="menu-tab";
-               document.getElementById(foo+"-tab").className="menu-tab-selected";
-               show(foo);
-
-            }
-            // else menu already selected!
-         }
-         function showbug(buguid, list) {
-            var bugplaceholder   = document.getElementById(buguid+'-ph-'+list);
-            var bug              = document.getElementById(buguid);
-
-            if ( bugplaceholder==null) {
-               alert(buguid+'-ph-'+list+' - '+buguid+' - bugplaceholder==null');
-               return;
-            }
-            if ( bug==null) {
-               alert(buguid+'-ph-'+list+' - '+buguid+' - bug==null');
-               return;
-            }
-
-            var oldBug = bugplaceholder.innerHTML;
-            var newBug = bug.innerHTML;
-            //alert(oldBug);
-            //alert(newBug);
-            toggle(buguid+'-ph-'+list);
-            bugplaceholder.innerHTML = newBug;
-         }
-      </script>
-      <script type='text/javascript'><xsl:text disable-output-escaping='yes'><![CDATA[
-         // Extended Tooltip Javascript
-         // copyright 9th August 2002, 3rd July 2005
-         // by Stephen Chapman, Felgall Pty Ltd
-
-         // permission is granted to use this javascript provided that the below code is not altered
-         var DH = 0;var an = 0;var al = 0;var ai = 0;if (document.getElementById) {ai = 1; DH = 1;}else {if (document.all) {al = 1; DH = 1;} else { browserVersion = parseInt(navigator.appVersion); if (navigator.appName.indexOf('Netscape') != -1) if (browserVersion == 4) {an = 1; DH = 1;}}} 
-         function fd(oi, wS) {if (ai) return wS ? document.getElementById(oi).style:document.getElementById(oi); if (al) return wS ? document.all[oi].style: document.all[oi]; if (an) return document.layers[oi];}
-         function pw() {return window.innerWidth != null? window.innerWidth: document.body.clientWidth != null? document.body.clientWidth:null;}
-         function mouseX(evt) {if (evt.pageX) return evt.pageX; else if (evt.clientX)return evt.clientX + (document.documentElement.scrollLeft ?  document.documentElement.scrollLeft : document.body.scrollLeft); else return null;}
-         function mouseY(evt) {if (evt.pageY) return evt.pageY; else if (evt.clientY)return evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop); else return null;}
-         function popUp(evt,oi) {if (DH) {var wp = pw(); ds = fd(oi,1); dm = fd(oi,0); st = ds.visibility; if (dm.offsetWidth) ew = dm.offsetWidth; else if (dm.clip.width) ew = dm.clip.width; if (st == "visible" || st == "show") { ds.visibility = "hidden"; } else {tv = mouseY(evt) + 20; lv = mouseX(evt) - (ew/4); if (lv < 2) lv = 2; else if (lv + ew > wp) lv -= ew/2; if (!an) {lv += 'px';tv += 'px';} ds.left = lv; ds.top = tv; ds.visibility = "visible";}}}
-      ]]></xsl:text></script>
-      <style type='text/css'>
-         html, body {
-            background-color: #ffffff;
-         }
-         a, a:link , a:active, a:visited, a:hover {
-            text-decoration: none; color: black;
-         }
-         .b-r a {
-            text-decoration: underline; color: blue;
-         }
-         div, span {
-            vertical-align: top;
-         }
-         p {
-            margin: 0px;
-         }
-         h1 {
-            /*font-size: 14pt;*/
-            color: red;
-         }
-         #menu {
-            margin-bottom: 10px;
-         }
-         #menu ul {
-            margin-left: 0;
-            padding-left: 0;
-            display: inline;
-         }
-         #menu ul li {
-            margin-left: 0;
-            margin-bottom: 0;
-            padding: 2px 15px 5px;
-            border: 1px solid #000;
-            list-style: none;
-            display: inline;
-         }
-         #menu ul li.here {
-            border-bottom: 1px solid #ffc;
-            list-style: none;
-            display: inline;
-         }
-         .menu-tab {
-            background: white;
-         }
-         .menu-tab:hover {
-            background: grey;
-         }
-         .menu-tab-selected {
-            background: #aaaaaa;
-         }
-         #analysis-data ul {
-            margin-left: 15px;
-         }
-         #analyzed-files, #used-libraries, #analysis-error {
-           margin: 2px;
-           border: 1px black solid;
-           padding: 2px;
-           float: left;
-           overflow:auto;
-         }
-         #analyzed-files {
-           width: 25%;
-         }
-         #used-libraries {
-           width: 25%;
-         }
-         #analysis-error {
-           width: 40%;
-         }
-         div.summary {
-            width:100%;
-            text-align:left;
-         }
-         .summary table {
-            border:1px solid black;
-         }
-         .summary th {
-            background: #aaaaaa;
-            color: white;
-         }
-         .summary th, .summary td {
-            padding: 2px 4px 2px 4px;
-         }
-         .summary-name {
-            background: #eeeeee;
-            text-align:left;
-         }
-         .summary-size {
-            background: #eeeeee;
-            text-align:center;
-         }
-         .summary-ratio {
-            background: #eeeeee;
-            text-align:center;
-         }
-         .summary-priority-all {
-            background: #dddddd;
-            text-align:center;
-         }
-         .summary-priority-1 {
-            background: red;
-            text-align:center;
-         }
-         .summary-priority-2 {
-            background: orange;
-            text-align:center;
-         }
-         .summary-priority-3 {
-            background: green;
-            text-align:center;
-         }
-         .summary-priority-4 {
-            background: blue;
-            text-align:center;
-         }
-         .ob {
-            border: 1px solid black;
-            margin: 10px;
-         }
-         .ob-t {
-            border-bottom: 1px solid #000000; font-size: 12pt; font-weight: bold;
-            background: #cccccc; margin: 0; padding: 0 5px 0 5px;
-         }
-         .t-h {
-            font-weight: normal;
-         }
-         .ib-1, .ib-2 {
-            margin: 0 0 0 10px;
-         }
-         .ib-1-t, .ib-2-t {
-            border-bottom: 1px solid #000000; border-left: 1px solid #000000;
-            margin: 0; padding: 0 5px 0 5px;
-            font-size: 12pt; font-weight: bold; background: #cccccc;
-         }
-         .bb {
-            border-bottom: 1px solid #000000; border-left: 1px solid #000000;
-         }
-         .b-1 {
-            background: red; height: 0.5em; width: 1em;
-            margin-right: 0.5em;
-         }
-         .b-2 {
-            background: orange; height: 0.5em; width: 1em;
-            margin-right: 0.5em;
-         }
-         .b-3 {
-            background: green; height: 0.5em; width: 1em;
-            margin-right: 0.5em;
-         }
-         .b-4 {
-            background: blue; height: 0.5em; width: 1em;
-            margin-right: 0.5em;
-         }
-         .b-t {
-         }
-         .b-r {
-            font-size: 10pt; font-weight: bold; padding: 0 0 0 60px;
-         }
-         .b-d {
-            font-weight: normal; background: #eeeee0;
-            padding: 0 5px 0 5px; margin: 0px;
-         }
-         .bug-placeholder {
-            top:140px;
-            border:1px solid black;
-            display:none;
-         }
-         .tip {
-            border:solid 1px #666666;
-            width:600px;
-            padding:3px;
-            position:absolute;
-            z-index:100;
-            visibility:hidden;
-            color:#333333;
-            top:20px;
-            left:90px;
-            background-color:#ffffcc;
-            layer-background-color:#ffffcc;
-         }
-
-
-      </style>
-   </head>
-   <body>
-   <div id='content'>
-      <h1>
-         FindBugs (<xsl:value-of select="/BugCollection/@version" />) 
-         Analysis for 
-         <xsl:choose>
-            <xsl:when test='string-length(/BugCollection/Project/@projectName)>0'><xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when>
-            <xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise>
-         </xsl:choose>
-      </h1>
-      <div id="menu">
-         <ul>
-            <li id='bug-summary-tab' class='menu-tab-selected'>
-               <xsl:attribute name="onclick">showmenu('bug-summary');return false;</xsl:attribute>
-               <a href='' onclick='return false;'>Bug Summary</a>
-            </li>
-            <li id='analysis-data-tab' class='menu-tab'>
-               <xsl:attribute name="onclick">showmenu('analysis-data');return false;</xsl:attribute>
-               <a href='' onclick='return false;'>Analysis Information</a>
-            </li>
-            <li id='list-by-category-tab' class='menu-tab'>
-               <xsl:attribute name="onclick">showmenu('list-by-category');return false;</xsl:attribute>
-               <a href='' onclick='return false;'>List bugs by bug category</a>
-            </li>
-            <li id='list-by-package-tab' class='menu-tab'>
-               <xsl:attribute name="onclick">showmenu('list-by-package');return false;</xsl:attribute>
-               <a href='' onclick='return false;'>List bugs by package</a>
-            </li>
-         </ul>
-      </div>
-      <xsl:call-template name="generateSummary" />
-      <xsl:call-template name="analysis-data" />
-      <xsl:call-template name="list-by-category" />
-      <xsl:call-template name="list-by-package" />
-
-
-      <!-- advanced tooltips -->
-      <xsl:for-each select="/BugCollection/BugPattern">
-         <xsl:variable name="b-t"><xsl:value-of select="@type" /></xsl:variable>
-         <div>
-            <xsl:attribute name="id">tip-<xsl:value-of select="$b-t" /></xsl:attribute>
-            <xsl:attribute name="class">tip</xsl:attribute>
-            <b><xsl:value-of select="@abbrev" /> / <xsl:value-of select="@type" /></b><br/>
-            <xsl:value-of select="/BugCollection/BugPattern[@type=$b-t]/Details" disable-output-escaping="yes" />
-         </div>
-      </xsl:for-each>
-
-      <!-- bug descriptions - hidden -->
-      <xsl:for-each select="/BugCollection/BugInstance[not(@last)]">
-            <div style="display:none;">
-               <xsl:attribute name="id">b-uid-<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" /></xsl:attribute>
-               <xsl:for-each select="*/Message">
-                   <xsl:choose>
-                    <xsl:when test="parent::SourceLine and $htmlsrcpath != '' ">
-                      <div class="b-r"><a>
-                        <xsl:attribute name="href"><xsl:value-of select="$htmlsrcpath"/><xsl:value-of select="../@sourcepath" />.html#<xsl:value-of select="../@start" /></xsl:attribute>
-                        <xsl:apply-templates />
-                      </a></div>
-                    </xsl:when>
-                    <xsl:otherwise>
-                      <div class="b-r"><xsl:apply-templates /></div>
-                    </xsl:otherwise>
-                   </xsl:choose>
-               </xsl:for-each>
-               <div class="b-d">
-                  <xsl:value-of select="LongMessage" disable-output-escaping="no" />
-               </div>
-            </div>
-      </xsl:for-each>
-   </div>
-   <div id='fixedbox'>
-      <div id='bug-placeholder'></div>
-   </div>
-   </body>
-</html>
-</xsl:template>
-
-<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
-<!-- generate summary report from stats -->
-<xsl:template name="generateSummary" >
-<div class='summary' id='bug-summary'>
-   <h2>FindBugs Analysis generated at: <xsl:value-of select="/BugCollection/FindBugsSummary/@timestamp" /></h2>
-   <table>
-      <tr>
-         <th>Package</th>
-         <th>Code Size</th>
-         <th>Bugs</th>
-         <th>Bugs p1</th>
-         <th>Bugs p2</th>
-         <th>Bugs p3</th>
-         <th>Bugs Exp.</th>
-         <th>Ratio</th>
-      </tr>
-      <tr>
-         <td class='summary-name'>
-            Overall
-            (<xsl:value-of select="/BugCollection/FindBugsSummary/@num_packages" /> packages),
-            (<xsl:value-of select="/BugCollection/FindBugsSummary/@total_classes" /> classes)
-         </td>
-         <td class='summary-size'><xsl:value-of select="/BugCollection/FindBugsSummary/@total_size" /></td>
-         <td class='summary-priority-all'><xsl:value-of select="/BugCollection/FindBugsSummary/@total_bugs" /></td>
-         <td class='summary-priority-1'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_1" /></td>
-         <td class='summary-priority-2'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_2" /></td>
-         <td class='summary-priority-3'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_3" /></td>
-         <td class='summary-priority-4'><xsl:value-of select="/BugCollection/FindBugsSummary/@priority_4" /></td>
-         <td class='summary-ratio'></td>
-      </tr>
-      <xsl:for-each select="/BugCollection/FindBugsSummary/PackageStats">
-         <xsl:sort select="@package" />
-         <xsl:if test="@total_bugs!='0'" >
-            <tr>
-               <td class='summary-name'><xsl:value-of select="@package" /></td>
-               <td class='summary-size'><xsl:value-of select="@total_size" /></td>
-               <td class='summary-priority-all'><xsl:value-of select="@total_bugs" /></td>
-               <td class='summary-priority-1'><xsl:value-of select="@priority_1" /></td>
-               <td class='summary-priority-2'><xsl:value-of select="@priority_2" /></td>
-               <td class='summary-priority-3'><xsl:value-of select="@priority_3" /></td>
-               <td class='summary-priority-4'><xsl:value-of select="@priority_4" /></td>
-               <td class='summary-ratio'></td>
-<!--
-               <xsl:for-each select="ClassStats">
-                  <xsl:if test="@bugs!='0'" >
-                  <li>
-                     <xsl:value-of select="@class" /> - total: <xsl:value-of select="@bugs" />
-                  </li>
-                  </xsl:if>
-               </xsl:for-each>
--->
-            </tr>
-         </xsl:if>
-      </xsl:for-each>
-   </table>
-</div>
-</xsl:template>
-
-<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
-<!-- display analysis info -->
-<xsl:template name="analysis-data">
-      <div id='analysis-data' style='display:none;'>
-         <div id='analyzed-files'>
-            <h3>Analyzed Files:</h3>
-            <ul>
-               <xsl:for-each select="/BugCollection/Project/Jar">
-                  <li><xsl:apply-templates /></li>
-               </xsl:for-each>
-            </ul>
-         </div>
-         <div id='used-libraries'>
-            <h3>Used Libraries:</h3>
-            <ul>
-               <xsl:for-each select="/BugCollection/Project/AuxClasspathEntry">
-                  <li><xsl:apply-templates /></li>
-               </xsl:for-each>
-               <xsl:if test="count(/BugCollection/Project/AuxClasspathEntry)=0" >
-                  <li>None</li>
-               </xsl:if>
-            </ul>
-         </div>
-         <div id='analysis-error'>
-            <h3>Analysis Errors:</h3>
-            <ul>
-               <xsl:variable name="error-count"
-                             select="count(/BugCollection/Errors/MissingClass)" />
-               <xsl:if test="$error-count=0" >
-                  <li>None</li>
-               </xsl:if>
-               <xsl:if test="$error-count>0" >
-                  <li>Missing ref classes for analysis:
-                     <ul>
-                        <xsl:for-each select="/BugCollection/Errors/MissingClass">
-                           <li><xsl:apply-templates /></li>
-                        </xsl:for-each>
-                     </ul>
-                  </li>
-               </xsl:if>
-            </ul>
-         </div>
-      </div>
-</xsl:template>
-
-<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
-<!-- show priorities helper -->
-<xsl:template name="helpPriorities">
-   <span>
-      <xsl:attribute name="class">b-1</xsl:attribute>
-      &#160;&#160;
-   </span> P1
-   <span>
-      <xsl:attribute name="class">b-2</xsl:attribute>
-      &#160;&#160;
-   </span> P2
-   <span>
-      <xsl:attribute name="class">b-3</xsl:attribute>
-      &#160;&#160;
-   </span> P3
-   <span>
-      <xsl:attribute name="class">b-4</xsl:attribute>
-      &#160;&#160;
-   </span> Exp.
-</xsl:template>
-
-<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
-<!-- display the details of a bug -->
-<xsl:template name="display-bug" >
-   <xsl:param name="b-t"    select="''" />
-   <xsl:param name="bug-id"      select="''" />
-   <xsl:param name="which-list"  select="''" />
-   <div class="bb">
-      <a>
-         <xsl:attribute name="href"></xsl:attribute>
-         <xsl:attribute name="onclick">showbug('b-uid-<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" />','<xsl:value-of select="$which-list" />');return false;</xsl:attribute>
-         <span>
-            <xsl:attribute name="class">b-<xsl:value-of select="@priority"/></xsl:attribute>
-            &#160;&#160;
-         </span>
-         <span class="b-t"><xsl:value-of select="@abbrev" />: </span> <xsl:value-of select="Class/Message" />
-      </a>
-      <div style="display:none;">
-         <xsl:attribute name="id">b-uid-<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" />-ph-<xsl:value-of select="$which-list" /></xsl:attribute>
-         loading...
-      </div>
-   </div>
-</xsl:template>
-
-<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
-<!-- main template for the list by category -->
-<xsl:template name="list-by-category" >
-   <div id='list-by-category' class='data-box' style='display:none;'>
-      <xsl:call-template name="helpPriorities" />
-      <xsl:variable name="unique-category" select="/BugCollection/BugCategory/@category"/>
-      <xsl:for-each select="$unique-category">
-         <xsl:sort select="." order="ascending" />
-            <xsl:call-template name="categories">
-               <xsl:with-param name="category" select="." />
-            </xsl:call-template>
-      </xsl:for-each>
-   </div>
-</xsl:template>
-
-<xsl:template name="categories" >
-   <xsl:param name="category" select="''" />
-   <xsl:variable name="category-count"
-                       select="count(/BugCollection/BugInstance[@category=$category and not(@last)])" />
-   <xsl:variable name="category-count-p1"
-                       select="count(/BugCollection/BugInstance[@category=$category and @priority='1' and not(@last)])" />
-   <xsl:variable name="category-count-p2"
-                       select="count(/BugCollection/BugInstance[@category=$category and @priority='2' and not(@last)])" />
-   <xsl:variable name="category-count-p3"
-                       select="count(/BugCollection/BugInstance[@category=$category and @priority='3' and not(@last)])" />
-   <xsl:variable name="category-count-p4"
-                       select="count(/BugCollection/BugInstance[@category=$category and @priority='4' and not(@last)])" />
-   <div class='ob'>
-      <div class='ob-t'>
-         <a>
-            <xsl:attribute name="href"></xsl:attribute>
-            <xsl:attribute name="onclick">toggle('category-<xsl:value-of select="$category" />');return false;</xsl:attribute>
-            <xsl:value-of select="/BugCollection/BugCategory[@category=$category]/Description" />
-            (<xsl:value-of select="$category-count" />:
-            <span class='t-h'><xsl:value-of select="$category-count-p1" />/<xsl:value-of select="$category-count-p2" />/<xsl:value-of select="$category-count-p3" />/<xsl:value-of select="$category-count-p4" /></span>)
-         </a>
-      </div>
-      <div style="display:none;">
-         <xsl:attribute name="id">category-<xsl:value-of select="$category" /></xsl:attribute>
-         <xsl:call-template name="list-by-category-and-code">
-            <xsl:with-param name="category" select="$category" />
-         </xsl:call-template>
-      </div>
-   </div>
-</xsl:template>
-
-<xsl:template name="list-by-category-and-code" >
-   <xsl:param name="category" select="''" />
-   <xsl:variable name="unique-code" select="/BugCollection/BugInstance[@category=$category and not(@last) and generate-id()= generate-id(key('lbc-code-key',concat(@category,@abbrev)))]/@abbrev" />
-   <xsl:for-each select="$unique-code">
-      <xsl:sort select="." order="ascending" />
-         <xsl:call-template name="codes">
-            <xsl:with-param name="category" select="$category" />
-            <xsl:with-param name="code" select="." />
-         </xsl:call-template>
-   </xsl:for-each>
-</xsl:template>
-
-<xsl:template name="codes" >
-   <xsl:param name="category" select="''" />
-   <xsl:param name="code"     select="''" />
-   <xsl:variable name="code-count"
-                       select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and not(@last)])" />
-   <xsl:variable name="code-count-p1"
-                       select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @priority='1' and not(@last)])" />
-   <xsl:variable name="code-count-p2"
-                       select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @priority='2' and not(@last)])" />
-   <xsl:variable name="code-count-p3"
-                       select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @priority='3' and not(@last)])" />
-   <xsl:variable name="code-count-p4"
-                       select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @priority='4' and not(@last)])" />
-   <div class='ib-1'>
-      <div class="ib-1-t">
-         <a>
-            <xsl:attribute name="href"></xsl:attribute>
-            <xsl:attribute name="onclick">toggle('category-<xsl:value-of select="$category" />-and-code-<xsl:value-of select="$code" />');return false;</xsl:attribute>
-            <xsl:value-of select="$code" />: <xsl:value-of select="/BugCollection/BugCode[@abbrev=$code]/Description" />
-            (<xsl:value-of select="$code-count" />:
-            <span class='t-h'><xsl:value-of select="$code-count-p1" />/<xsl:value-of select="$code-count-p2" />/<xsl:value-of select="$code-count-p3" />/<xsl:value-of select="$code-count-p4" /></span>)
-         </a>
-      </div>
-      <div style="display:none;">
-         <xsl:attribute name="id">category-<xsl:value-of select="$category" />-and-code-<xsl:value-of select="$code" /></xsl:attribute>
-         <xsl:call-template name="list-by-category-and-code-and-bug">
-            <xsl:with-param name="category" select="$category" />
-            <xsl:with-param name="code" select="$code" />
-         </xsl:call-template>
-      </div>
-   </div>
-</xsl:template>
-
-<xsl:template name="list-by-category-and-code-and-bug" >
-   <xsl:param name="category" select="''" />
-   <xsl:param name="code" select="''" />
-   <xsl:variable name="unique-bug" select="/BugCollection/BugInstance[@category=$category and not(@last) and @abbrev=$code and generate-id()= generate-id(key('lbc-bug-key',concat(@category,@abbrev,@type)))]/@type" />
-   <xsl:for-each select="$unique-bug">
-      <xsl:sort select="." order="ascending" />
-         <xsl:call-template name="bugs">
-            <xsl:with-param name="category" select="$category" />
-            <xsl:with-param name="code" select="$code" />
-            <xsl:with-param name="bug" select="." />
-         </xsl:call-template>
-   </xsl:for-each>
-</xsl:template>
-
-<xsl:template name="bugs" >
-   <xsl:param name="category" select="''" />
-   <xsl:param name="code"     select="''" />
-   <xsl:param name="bug"      select="''" />
-   <xsl:variable name="bug-count"
-                       select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @type=$bug and not(@last)])" />
-   <xsl:variable name="bug-count-p1"
-                       select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @type=$bug and @priority='1' and not(@last)])" />
-   <xsl:variable name="bug-count-p2"
-                       select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @type=$bug and @priority='2' and not(@last)])" />
-   <xsl:variable name="bug-count-p3"
-                       select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @type=$bug and @priority='3' and not(@last)])" />
-   <xsl:variable name="bug-count-p4"
-                       select="count(/BugCollection/BugInstance[@category=$category and @abbrev=$code and @type=$bug and @priority='4' and not(@last)])" />
-   <div class='ib-2'>
-      <div class='ib-2-t'>
-         <a>
-            <xsl:attribute name="href"></xsl:attribute>
-            <xsl:attribute name="onclick">toggle('category-<xsl:value-of select="$category" />-and-code-<xsl:value-of select="$code" />-and-bug-<xsl:value-of select="$bug" />');return false;</xsl:attribute>
-            <xsl:attribute name="onmouseout">popUp(event,'tip-<xsl:value-of select="$bug" />');</xsl:attribute>
-            <xsl:attribute name="onmouseover">popUp(event,'tip-<xsl:value-of select="$bug" />');</xsl:attribute>
-            <xsl:value-of select="/BugCollection/BugPattern[@category=$category and @abbrev=$code and @type=$bug]/ShortDescription" />&#160;&#160;
-            (<xsl:value-of select="$bug-count" />:
-            <span class='t-h'><xsl:value-of select="$bug-count-p1" />/<xsl:value-of select="$bug-count-p2" />/<xsl:value-of select="$bug-count-p3" />/<xsl:value-of select="$bug-count-p4" /></span>)
-         </a>
-      </div>
-      <div style="display:none;">
-         <xsl:attribute name="id">category-<xsl:value-of select="$category" />-and-code-<xsl:value-of select="$code" />-and-bug-<xsl:value-of select="$bug" /></xsl:attribute>
-         <xsl:variable name="cat-code-type">category-<xsl:value-of select="$category" />-and-code-<xsl:value-of select="$code" />-and-bug-<xsl:value-of select="$bug" /></xsl:variable>
-         <xsl:variable name="bug-id">b-uid-<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" /></xsl:variable>
-         <xsl:for-each select="/BugCollection/BugInstance[@category=$category and @abbrev=$code and @type=$bug and not(@last)]">
-            <xsl:call-template name="display-bug">
-               <xsl:with-param name="b-t"     select="@type" />
-               <xsl:with-param name="bug-id"       select="$bug-id" />
-               <xsl:with-param name="which-list"   select="'c'" />
-            </xsl:call-template>
-         </xsl:for-each>
-      </div>
-   </div>
-</xsl:template>
-
-<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
-<!-- main template for the list by package -->
-<xsl:template name="list-by-package" >
-   <div id='list-by-package' class='data-box' style='display:none;'>
-      <xsl:call-template name="helpPriorities" />
-      <xsl:for-each select="/BugCollection/FindBugsSummary/PackageStats[@total_bugs != '0']/@package">
-         <xsl:sort select="." order="ascending" />
-            <xsl:call-template name="packages">
-               <xsl:with-param name="package" select="." />
-            </xsl:call-template>
-      </xsl:for-each>
-   </div>
-</xsl:template>
-
-<xsl:template name="packages" >
-   <xsl:param name="package" select="''" />
-   <xsl:variable name="package-count-p1">
-      <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_1 != '')">0</xsl:if>
-      <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_1 != ''">
-         <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_1" />
-      </xsl:if>
-   </xsl:variable>
-   <xsl:variable name="package-count-p2">
-      <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_2 != '')">0</xsl:if>
-      <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_2 != ''">
-         <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_2" />
-      </xsl:if>
-   </xsl:variable>
-   <xsl:variable name="package-count-p3">
-      <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_3 != '')">0</xsl:if>
-      <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_3 != ''">
-         <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_3" />
-      </xsl:if>
-   </xsl:variable>
-   <xsl:variable name="package-count-p4">
-      <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_4 != '')">0</xsl:if>
-      <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_4 != ''">
-         <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@priority_4" />
-      </xsl:if>
-   </xsl:variable>
-
-   <div class='ob'>
-      <div class='ob-t'>
-         <a>
-            <xsl:attribute name="href"></xsl:attribute>
-            <xsl:attribute name="onclick">toggle('package-<xsl:value-of select="$package" />');return false;</xsl:attribute>
-            <xsl:value-of select="$package" />
-            (<xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/@total_bugs" />:
-            <span class='t-h'><xsl:value-of select="$package-count-p1" />/<xsl:value-of select="$package-count-p2" />/<xsl:value-of select="$package-count-p3" />/<xsl:value-of select="$package-count-p4" /></span>)
-         </a>
-      </div>
-      <div style="display:none;">
-         <xsl:attribute name="id">package-<xsl:value-of select="$package" /></xsl:attribute>
-         <xsl:call-template name="list-by-package-and-class">
-            <xsl:with-param name="package" select="$package" />
-         </xsl:call-template>
-      </div>
-   </div>
-</xsl:template>
-
-<xsl:template name="list-by-package-and-class" >
-   <xsl:param name="package" select="''" />
-   <xsl:for-each select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@bugs != '0']/@class">
-      <xsl:sort select="." order="ascending" />
-         <xsl:call-template name="classes">
-            <xsl:with-param name="package" select="$package" />
-            <xsl:with-param name="class" select="." />
-         </xsl:call-template>
-   </xsl:for-each>
-</xsl:template>
-
-<xsl:template name="classes" >
-   <xsl:param name="package" select="''" />
-   <xsl:param name="class"     select="''" />
-   <xsl:variable name="class-count"
-                       select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@bugs" />
-
-   <xsl:variable name="class-count-p1">
-      <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_1 != '')">0</xsl:if>
-      <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_1 != ''">
-         <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_1" />
-      </xsl:if>
-   </xsl:variable>
-   <xsl:variable name="class-count-p2">
-      <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_2 != '')">0</xsl:if>
-      <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_2 != ''">
-         <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_2" />
-      </xsl:if>
-   </xsl:variable>
-   <xsl:variable name="class-count-p3">
-      <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_3 != '')">0</xsl:if>
-      <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_3 != ''">
-         <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_3" />
-      </xsl:if>
-   </xsl:variable>
-   <xsl:variable name="class-count-p4">
-      <xsl:if test="not(/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_4 != '')">0</xsl:if>
-      <xsl:if test="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_4 != ''">
-         <xsl:value-of select="/BugCollection/FindBugsSummary/PackageStats[@package=$package]/ClassStats[@class=$class and @bugs != '0']/@priority_4" />
-      </xsl:if>
-   </xsl:variable>
-
-   <div class='ib-1'>
-      <div class="ib-1-t">
-         <a>
-            <xsl:attribute name="href"></xsl:attribute>
-            <xsl:attribute name="onclick">toggle('package-<xsl:value-of select="$package" />-and-class-<xsl:value-of select="$class" />');return false;</xsl:attribute>
-            <xsl:value-of select="$class" />  (<xsl:value-of select="$class-count" />:
-            <span class='t-h'><xsl:value-of select="$class-count-p1" />/<xsl:value-of select="$class-count-p2" />/<xsl:value-of select="$class-count-p3" />/<xsl:value-of select="$class-count-p4" /></span>)
-         </a>
-      </div>
-      <div style="display:none;">
-         <xsl:attribute name="id">package-<xsl:value-of select="$package" />-and-class-<xsl:value-of select="$class" /></xsl:attribute>
-         <xsl:call-template name="list-by-package-and-class-and-bug">
-            <xsl:with-param name="package" select="$package" />
-            <xsl:with-param name="class" select="$class" />
-         </xsl:call-template>
-      </div>
-   </div>
-</xsl:template>
-
-<xsl:template name="list-by-package-and-class-and-bug" >
-   <xsl:param name="package" select="''" />
-   <xsl:param name="class" select="''" />
-   <xsl:variable name="unique-class-bugs" select="/BugCollection/BugInstance[not(@last) and Class[position()=1 and @classname=$class] and generate-id() = generate-id(key('lbp-class-b-t',concat(Class/@classname,@type)))]/@type" />
-
-   <xsl:for-each select="$unique-class-bugs">
-      <xsl:sort select="." order="ascending" />
-         <xsl:call-template name="class-bugs">
-            <xsl:with-param name="package" select="$package" />
-            <xsl:with-param name="class" select="$class" />
-            <xsl:with-param name="type" select="." />
-         </xsl:call-template>
-   </xsl:for-each>
-</xsl:template>
-
-<xsl:template name="class-bugs" >
-   <xsl:param name="package" select="''" />
-   <xsl:param name="class"     select="''" />
-   <xsl:param name="type"      select="''" />
-   <xsl:variable name="bug-count"
-                       select="count(/BugCollection/BugInstance[@type=$type and not(@last) and Class[position()=1 and @classname=$class]])" />
-   <div class='ib-2'>
-      <div class='ib-2-t'>
-         <a>
-            <xsl:attribute name="href"></xsl:attribute>
-            <xsl:attribute name="onclick">toggle('package-<xsl:value-of select="$package" />-and-class-<xsl:value-of select="$class" />-and-type-<xsl:value-of select="$type" />');return false;</xsl:attribute>
-            <xsl:attribute name="onmouseout">popUp(event,'tip-<xsl:value-of select="$type" />')</xsl:attribute>
-            <xsl:attribute name="onmouseover">popUp(event,'tip-<xsl:value-of select="$type" />')</xsl:attribute>
-            <xsl:value-of select="/BugCollection/BugPattern[@type=$type]/ShortDescription" />&#160;&#160;
-            (<xsl:value-of select="$bug-count" />)
-         </a>
-      </div>
-      <div style="display:none;">
-         <xsl:attribute name="id">package-<xsl:value-of select="$package" />-and-class-<xsl:value-of select="$class" />-and-type-<xsl:value-of select="$type" /></xsl:attribute>
-         <xsl:variable name="package-class-type">package-<xsl:value-of select="$package" />-and-class-<xsl:value-of select="$class" />-and-type-<xsl:value-of select="$type" /></xsl:variable>
-         <xsl:variable name="bug-id">b-uid-<xsl:value-of select="@instanceHash" />-<xsl:value-of select="@instanceOccurrenceNum" /></xsl:variable>
-         <xsl:for-each select="/BugCollection/BugInstance[@type=$type and not(@last) and Class[position()=1 and @classname=$class]]">
-            <xsl:call-template name="display-bug">
-               <xsl:with-param name="b-t"     select="@type" />
-               <xsl:with-param name="bug-id"       select="$bug-id" />
-               <xsl:with-param name="which-list"   select="'p'" />
-            </xsl:call-template>
-         </xsl:for-each>
-      </div>
-   </div>
-</xsl:template>
-
-</xsl:transform>
diff --git a/lib/findbugs/xsl/plain.xsl b/lib/findbugs/xsl/plain.xsl
deleted file mode 100644
index 80fff8d..0000000
--- a/lib/findbugs/xsl/plain.xsl
+++ /dev/null
@@ -1,306 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  FindBugs - Find bugs in Java programs
-  Copyright (C) 2004,2005 University of Maryland
-  Copyright (C) 2005, Chris Nappin
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-  
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-  
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
--->
-<xsl:stylesheet version="1.0"
-	xmlns="http://www.w3.org/1999/xhtml"
-	xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-
-<xsl:output
-	method="xml"
-	omit-xml-declaration="yes"
-	standalone="yes"
-         doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
-         doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
-	indent="yes"
-	encoding="UTF-8"/>
-
-<xsl:variable name="bugTableHeader">
-	<tr class="tableheader">
-		<th align="left">Warning</th>
-		<th align="left">Priority</th>
-		<th align="left">Details</th>
-	</tr>
-</xsl:variable>
-
-<xsl:template match="/">
-	<html>
-	<head>
-		<title>FindBugs Report</title>
-		<style type="text/css">
-		.tablerow0 {
-			background: #EEEEEE;
-		}
-
-		.tablerow1 {
-			background: white;
-		}
-
-		.detailrow0 {
-			background: #EEEEEE;
-		}
-
-		.detailrow1 {
-			background: white;
-		}
-
-		.tableheader {
-			background: #b9b9fe;
-			font-size: larger;
-		}
-		</style>
-	</head>
-
-	<xsl:variable name="unique-catkey" select="/BugCollection/BugCategory/@category"/>
-
-	<body>
-
-	<h1>FindBugs Report</h1>
-		<p>Produced using <a href="http://findbugs.sourceforge.net">FindBugs</a> <xsl:value-of select="/BugCollection/@version"/>.</p>
-		<p>Project: 
-			<xsl:choose>
-				<xsl:when test='string-length(/BugCollection/Project/@projectName)>0'><xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when>
-				<xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise>
-			</xsl:choose>
-		</p>
-	<h2>Metrics</h2>
-	<xsl:apply-templates select="/BugCollection/FindBugsSummary"/>
-
-	<h2>Summary</h2>
-	<table width="500" cellpadding="5" cellspacing="2">
-	    <tr class="tableheader">
-			<th align="left">Warning Type</th>
-			<th align="right">Number</th>
-		</tr>
-
-	<xsl:for-each select="$unique-catkey">
-		<xsl:sort select="." order="ascending"/>
-		<xsl:variable name="catkey" select="."/>
-		<xsl:variable name="catdesc" select="/BugCollection/BugCategory[@category=$catkey]/Description"/>
-		<xsl:variable name="styleclass">
-			<xsl:choose><xsl:when test="position() mod 2 = 1">tablerow0</xsl:when>
-				<xsl:otherwise>tablerow1</xsl:otherwise>
-			</xsl:choose>
-		</xsl:variable>
-
-		<tr class="{$styleclass}">
-			<td><a href="#Warnings_{$catkey}"><xsl:value-of select="$catdesc"/> Warnings</a></td>
-			<td align="right"><xsl:value-of select="count(/BugCollection/BugInstance[(@category=$catkey) and (not(@last))])"/></td>
-		</tr>
-	</xsl:for-each>
-
-	<xsl:variable name="styleclass">
-		<xsl:choose><xsl:when test="count($unique-catkey) mod 2 = 0">tablerow0</xsl:when>
-			<xsl:otherwise>tablerow1</xsl:otherwise>
-		</xsl:choose>
-	</xsl:variable>
-		<tr class="{$styleclass}">
-		    <td><b>Total</b></td>
-		    <td align="right"><b><xsl:value-of select="count(/BugCollection/BugInstance[not(@last)])"/></b></td>
-		</tr>
-	</table>
-	<p><br/><br/></p>
-	
-	<h1>Warnings</h1>
-
-	<p>Click on each warning link to see a full description of the issue, and
-	    details of how to resolve it.</p>
-
-	<xsl:for-each select="$unique-catkey">
-		<xsl:sort select="." order="ascending"/>
-		<xsl:variable name="catkey" select="."/>
-		<xsl:variable name="catdesc" select="/BugCollection/BugCategory[@category=$catkey]/Description"/>
-
-		<xsl:call-template name="generateWarningTable">
-			<xsl:with-param name="warningSet" select="/BugCollection/BugInstance[(@category=$catkey) and (not(@last))]"/>
-			<xsl:with-param name="sectionTitle"><xsl:value-of select="$catdesc"/> Warnings</xsl:with-param>
-			<xsl:with-param name="sectionId">Warnings_<xsl:value-of select="$catkey"/></xsl:with-param>
-		</xsl:call-template>
-	</xsl:for-each>
-
-    <p><br/><br/></p>
-	<h1><a name="Details">Warning Types</a></h1>
-
-	<xsl:apply-templates select="/BugCollection/BugPattern">
-		<xsl:sort select="@abbrev"/>
-		<xsl:sort select="ShortDescription"/>
-	</xsl:apply-templates>
-
-	</body>
-	</html>
-</xsl:template>
-
-<xsl:template match="BugInstance[not(@last)]">
-	<xsl:variable name="warningId"><xsl:value-of select="generate-id()"/></xsl:variable>
-
-	<tr class="tablerow{position() mod 2}">
-		<td width="20%" valign="top">
-			<a href="#{@type}"><xsl:value-of select="ShortMessage"/></a>
-		</td>
-		<td width="10%" valign="top">
-			<xsl:choose>
-				<xsl:when test="@priority = 1">High</xsl:when>
-				<xsl:when test="@priority = 2">Medium</xsl:when>
-				<xsl:when test="@priority = 3">Low</xsl:when>
-				<xsl:otherwise>Unknown</xsl:otherwise>
-			</xsl:choose>
-		</td>
-		<td width="70%">
-		    <p><xsl:value-of select="LongMessage"/><br/><br/>
-		    
-		    	<!--  add source filename and line number(s), if any -->
-				<xsl:if test="SourceLine">
-					<br/>In file <xsl:value-of select="SourceLine/@sourcefile"/>,
-					<xsl:choose>
-						<xsl:when test="SourceLine/@start = SourceLine/@end">
-						line <xsl:value-of select="SourceLine/@start"/>
-						</xsl:when>
-						<xsl:otherwise>
-						lines <xsl:value-of select="SourceLine/@start"/>
-						    to <xsl:value-of select="SourceLine/@end"/>
-						</xsl:otherwise>
-					</xsl:choose>
-				</xsl:if>
-				
-				<xsl:for-each select="./*/Message">
-					<br/><xsl:value-of select="text()"/>
-				</xsl:for-each>
-		    </p>
-		</td>
-	</tr>
-</xsl:template>
-
-<xsl:template match="BugPattern">
-	<h2><a name="{@type}"><xsl:value-of select="ShortDescription"/></a></h2>
-	<xsl:value-of select="Details" disable-output-escaping="yes"/>
-	<p><br/><br/></p>
-</xsl:template>
-
-<xsl:template name="generateWarningTable">
-	<xsl:param name="warningSet"/>
-	<xsl:param name="sectionTitle"/>
-	<xsl:param name="sectionId"/>
-
-	<h2><a name="{$sectionId}"><xsl:value-of select="$sectionTitle"/></a></h2>
-	<table class="warningtable" width="100%" cellspacing="2" cellpadding="5">
-		<xsl:copy-of select="$bugTableHeader"/>
-		<xsl:choose>
-		    <xsl:when test="count($warningSet) &gt; 0">
-				<xsl:apply-templates select="$warningSet">
-					<xsl:sort select="@priority"/>
-					<xsl:sort select="@abbrev"/>
-					<xsl:sort select="Class/@classname"/>
-				</xsl:apply-templates>
-		    </xsl:when>
-		    <xsl:otherwise>
-		        <tr><td colspan="2"><p><i>None</i></p></td></tr>
-		    </xsl:otherwise>
-		</xsl:choose>
-	</table>
-	<p><br/><br/></p>
-</xsl:template>
-
-<xsl:template match="FindBugsSummary">
-    <xsl:variable name="kloc" select="@total_size div 1000.0"/>
-    <xsl:variable name="format" select="'#######0.00'"/>
-
-	<p><xsl:value-of select="@total_size"/> lines of code analyzed,
-	in <xsl:value-of select="@total_classes"/> classes, 
-	in <xsl:value-of select="@num_packages"/> packages.</p>
-	<table width="500" cellpadding="5" cellspacing="2">
-	    <tr class="tableheader">
-			<th align="left">Metric</th>
-			<th align="right">Total</th>
-			<th align="right">Density*</th>
-		</tr>
-		<tr class="tablerow0">
-			<td>High Priority Warnings</td>
-			<td align="right"><xsl:value-of select="@priority_1"/></td>
-			<td align="right">
-                <xsl:choose>
-                    <xsl:when test= "number($kloc) &gt; 0.0">
-       			        <xsl:value-of select="format-number(@priority_1 div $kloc, $format)"/>
-                    </xsl:when>
-                    <xsl:otherwise>
-      		            <xsl:value-of select="format-number(0.0, $format)"/>
-                    </xsl:otherwise>
-		        </xsl:choose>
-			</td>
-		</tr>
-		<tr class="tablerow1">
-			<td>Medium Priority Warnings</td>
-			<td align="right"><xsl:value-of select="@priority_2"/></td>
-			<td align="right">
-                <xsl:choose>
-                    <xsl:when test= "number($kloc) &gt; 0.0">
-       			        <xsl:value-of select="format-number(@priority_2 div $kloc, $format)"/>
-                    </xsl:when>
-                    <xsl:otherwise>
-      		            <xsl:value-of select="format-number(0.0, $format)"/>
-                    </xsl:otherwise>
-		        </xsl:choose>
-			</td>
-		</tr>
-
-    <xsl:choose>
-		<xsl:when test="@priority_3">
-			<tr class="tablerow1">
-				<td>Low Priority Warnings</td>
-				<td align="right"><xsl:value-of select="@priority_3"/></td>
-				<td align="right">
-	                <xsl:choose>
-	                    <xsl:when test= "number($kloc) &gt; 0.0">
-	       			        <xsl:value-of select="format-number(@priority_3 div $kloc, $format)"/>
-	                    </xsl:when>
-	                    <xsl:otherwise>
-	      		            <xsl:value-of select="format-number(0.0, $format)"/>
-	                    </xsl:otherwise>
-			        </xsl:choose>
-				</td>
-			</tr>
-			<xsl:variable name="totalClass" select="tablerow0"/>
-		</xsl:when>
-		<xsl:otherwise>
-		    <xsl:variable name="totalClass" select="tablerow1"/>
-		</xsl:otherwise>
-	</xsl:choose>
-
-		<tr class="$totalClass">
-			<td><b>Total Warnings</b></td>
-			<td align="right"><b><xsl:value-of select="@total_bugs"/></b></td>
-			<td align="right">
-				<b>
-                <xsl:choose>
-                    <xsl:when test= "number($kloc) &gt; 0.0">
-       			        <xsl:value-of select="format-number(@total_bugs div $kloc, $format)"/>
-                    </xsl:when>
-                    <xsl:otherwise>
-      		            <xsl:value-of select="format-number(0.0, $format)"/>
-                    </xsl:otherwise>
-		        </xsl:choose>
-				</b>
-			</td>
-		</tr>
-	</table>
-	<p><i>(* Defects per Thousand lines of non-commenting source statements)</i></p>
-	<p><br/><br/></p>
-
-</xsl:template>
-
-</xsl:stylesheet>
diff --git a/lib/findbugs/xsl/summary.xsl b/lib/findbugs/xsl/summary.xsl
deleted file mode 100644
index faf0131..0000000
--- a/lib/findbugs/xsl/summary.xsl
+++ /dev/null
@@ -1,252 +0,0 @@
-<?xml version="1.0"?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >
-
-<xsl:output
-         method="xml" indent="yes"
-         doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
-         doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
- 		encoding="UTF-8"/>
-
-<xsl:param name="PAGE.TITLE" select="'Findbugs Summary Statistics'" />
-<xsl:param name="PAGE.FONT" select="'Arial'" />
-<xsl:param name="SUMMARY.HEADER" select="'Findbugs Summary Report'" />
-<xsl:param name="SUMMARY.LABEL" select="'Summary Analysis Generated at: '" />
-<xsl:param name="PACKAGE.HEADER" select="'Bugs By Package'" />
-<xsl:param name="PACKAGE.SORT.LABEL" select="'Sorted by Total Bugs'" />
-<xsl:param name="PACKAGE.LABEL" select="'Analysis of Package: '" />
-<xsl:param name="DEFAULT.PACKAGE.NAME" select="'default package'" />
-<xsl:param name="PACKAGE.BUGCLASS.LABEL" select="'Most Buggy Class in Package with #1 $1:'" />
-<xsl:param name="TOTAL.PACKAGES.LABEL" select="'#1 $1 Analyzed'" />
-
-<xsl:param name="BUGS.SINGLE.LABEL" select="'Bug'" />
-<xsl:param name="BUGS.PULURAL.LABEL" select="'Bugs'" />
-<xsl:param name="PACKAGE.SINGLE.LABEL" select="'Package'" />
-<xsl:param name="PACKAGE.PULURAL.LABEL" select="'Packages'" />
-
-
-<xsl:param name="TABLE.HEADING.TYPE" select="'Type Checked'" />
-<xsl:param name="TABLE.HEADING.COUNT" select="'Count'" />
-<xsl:param name="TABLE.HEADING.BUGS" select="'Bugs'" />
-<xsl:param name="TABLE.HEADING.PERCENT" select="'Percentage'" />
-<xsl:param name="TABLE.ROW.OUTER" select="'Outer Classes'" />
-<xsl:param name="TABLE.ROW.INNER" select="'Inner Classes'" />
-<xsl:param name="TABLE.ROW.INTERFACE" select="'Interfaces'" />
-<xsl:param name="TABLE.ROW.TOTAL" select="'Total'" />
-<xsl:param name="TABLE.WIDTH" select="'90%'" />
-
-<xsl:param name="PERCENTAGE.FORMAT" select="'#0.00%'" />
-
-<!-- This template drives the rest of the output -->
-<xsl:template match="/" >
-  <html>
-   <!-- JEditorPane gets really angry if it sees this
-	WWP: Sorry, this needs to be explained better. Not a valid HTML document without a head.
-	 -->
-   <head><title><xsl:value-of select="$PAGE.TITLE" /></title></head>
-  <body>
-    <h1 align="center"><a href="http://findbugs.sourceforge.net"><xsl:value-of select="$SUMMARY.HEADER" /></a></h1>
-    <h2 align="center"> Analysis for 
-    <xsl:choose>
-      <xsl:when test='string-length(/BugCollection/Project/@projectName)>0'>
-          <xsl:value-of select="/BugCollection/Project/@projectName" /></xsl:when>
-      <xsl:otherwise><xsl:value-of select="/BugCollection/Project/@filename" /></xsl:otherwise>
-    </xsl:choose>
-      </h2>
-  <h2 align="center"><xsl:value-of select="$SUMMARY.LABEL" /> 
-      <i><xsl:value-of select="//FindBugsSummary/@timestamp" /></i></h2>
-  <xsl:apply-templates select="//FindBugsSummary" />
-  <br/>
-  <p align="center">
-  <font face="{$PAGE.FONT}" size="6"><xsl:value-of select="$PACKAGE.HEADER" /></font>
-    <br/><font face="{$PAGE.FONT}" size="4"><i>(<xsl:value-of select="$PACKAGE.SORT.LABEL"/>)</i></font>
-  </p>
-  <xsl:for-each select="//FindBugsSummary/PackageStats">
-  <xsl:sort select="@total_bugs" data-type="number" order="descending" />
-  <xsl:apply-templates select="." />
-  </xsl:for-each>
-  </body>
-  </html>
-</xsl:template>
-
-<xsl:template name="status_table_row" >
-  <xsl:param name="LABEL" select="''" />
-  <xsl:param name="COUNT" select="1" />
-  <xsl:param name="BUGS" select="0" />
-  <xsl:param name="FONT_SIZE" select="4" />
-  <tr>
-   <td align="left"><font face="{$PAGE.FONT}" size="{$FONT_SIZE}"><xsl:value-of select="$LABEL" /></font></td>
-   <td align="center"><font face="{$PAGE.FONT}" color="green" size="{$FONT_SIZE}"><xsl:value-of select="$COUNT" /></font></td>
-   <td align="center"><font face="{$PAGE.FONT}" color="red" size="{$FONT_SIZE}"><xsl:value-of select="$BUGS" /></font></td>
-   <td align="center"><font face="{$PAGE.FONT}" color="blue" size="{$FONT_SIZE}">
-      <xsl:choose>
-      <xsl:when test="$COUNT &gt; 0">
-       <xsl:value-of select="format-number(number($BUGS div $COUNT), $PERCENTAGE.FORMAT)"/>
-      </xsl:when>
-      <xsl:otherwise>
-       <xsl:value-of select="format-number(0, $PERCENTAGE.FORMAT)"/>
-      </xsl:otherwise>
-      </xsl:choose>
-     </font>
-   </td>
-  </tr>
-</xsl:template>
-
-<xsl:template name="table_header" >
-  <tr>
-  <th><font face="{$PAGE.FONT}" size="4"><xsl:value-of select="$TABLE.HEADING.TYPE"/></font></th>
-  <th><font face="{$PAGE.FONT}" size="4"><xsl:value-of select="$TABLE.HEADING.COUNT"/></font></th>
-  <th><font face="{$PAGE.FONT}" size="4"><xsl:value-of select="$TABLE.HEADING.BUGS"/></font></th>
-  <th><font face="{$PAGE.FONT}" size="4"><xsl:value-of select="$TABLE.HEADING.PERCENT"/></font></th>
-  </tr>
-</xsl:template>
-
-<xsl:template match="FindBugsSummary" >
-  <table width="{$TABLE.WIDTH}" border="1" align="center">
-   <xsl:call-template name="table_header" />
-
-   <xsl:call-template name="status_table_row">
-     <xsl:with-param name="LABEL" select="$TABLE.ROW.OUTER" />
-     <xsl:with-param name="COUNT" select="count(PackageStats/ClassStats[@interface='false' and substring-after(@class,'$')=''])" />
-     <xsl:with-param name="BUGS" select="sum(PackageStats/ClassStats[@interface='false' and substring-after(@class,'$')='']/@bugs)" />
-   </xsl:call-template>
-
-   <xsl:call-template name="status_table_row">
-     <xsl:with-param name="LABEL" select="$TABLE.ROW.INNER" />
-     <xsl:with-param name="COUNT" select="count(PackageStats/ClassStats[@interface='false' and substring-after(@class,'$')!=''])" />
-     <xsl:with-param name="BUGS" select="sum(PackageStats/ClassStats[@interface='false' and substring-after(@class,'$')!='']/@bugs)" />
-   </xsl:call-template>
-
-   <xsl:call-template name="status_table_row">
-     <xsl:with-param name="LABEL" select="$TABLE.ROW.INTERFACE" />
-     <xsl:with-param name="COUNT" select="count(PackageStats/ClassStats[@interface='true'])" />
-     <xsl:with-param name="BUGS" select="sum(PackageStats/ClassStats[@interface='true']/@bugs)" />
-   </xsl:call-template>
-
-   <xsl:call-template name="status_table_row">
-     <xsl:with-param name="LABEL" select="$TABLE.ROW.TOTAL" />
-     <xsl:with-param name="COUNT" select="@total_classes" />
-     <xsl:with-param name="BUGS" select="@total_bugs"/>
-     <xsl:with-param name="FONT_SIZE" select="5"/>
-   </xsl:call-template>
-   <xsl:variable name="num_packages" select="count(PackageStats)" />
-   <tr><td align="center" colspan="4"><font face="{$PAGE.FONT}" size="4">
-     <xsl:call-template name='string_format'>
-     <xsl:with-param name="COUNT" select="$num_packages"/>
-     <xsl:with-param name="STRING" select="$TOTAL.PACKAGES.LABEL"/>
-     <xsl:with-param name="SINGLE" select="$PACKAGE.SINGLE.LABEL"/>
-     <xsl:with-param name="PULURAL" select="$PACKAGE.PULURAL.LABEL"/>
-     </xsl:call-template>
-     </font></td>
-   </tr>
-  </table>
-</xsl:template>
-
-
-<xsl:template name='string_format'>
-  <xsl:param name="COUNT" select="1"/>
-  <xsl:param name="STRING" select="''"/>
-  <xsl:param name="SINGLE" select="''"/>
-  <xsl:param name="PULURAL" select="''"/>
-  <xsl:variable name="count_str" select="concat(substring-before($STRING,'#1'), $COUNT, substring-after($STRING,'#1'))" />
-
-  <xsl:choose>
-    <xsl:when test="$COUNT &gt; 1">
-      <xsl:value-of select="concat(substring-before($count_str,'$1'), $PULURAL, substring-after($count_str,'$1'))" />
-    </xsl:when>
-    <xsl:otherwise>
-    <xsl:value-of select="concat(substring-before($count_str,'$1'), $SINGLE, substring-after($count_str,'$1'))" />
-    </xsl:otherwise>
-  </xsl:choose>
-</xsl:template>
-
-
-<xsl:template match="PackageStats" >
-  <xsl:variable name="package-name">
-    <xsl:choose>
-      <xsl:when test="@package = ''">
-        <xsl:value-of select="$DEFAULT.PACKAGE.NAME"/>
-      </xsl:when>
-      <xsl:otherwise>
-        <xsl:value-of select="@package"/>
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:variable>
-  <xsl:variable name="package-prefix">
-    <xsl:choose>
-      <xsl:when test="@package = ''">
-        <xsl:text></xsl:text>
-      </xsl:when>
-      <xsl:otherwise>
-        <xsl:value-of select="concat(@package,'.')"/>
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:variable>
-  <h2 align="center"><xsl:value-of select="$PACKAGE.LABEL"/><i><font color='green'><xsl:value-of select="$package-name" /></font></i></h2>
-   <table width="{$TABLE.WIDTH}" border="1" align="center">
-   <xsl:call-template name="table_header" />
-
-   <xsl:call-template name="status_table_row">
-     <xsl:with-param name="LABEL" select="$TABLE.ROW.OUTER" />
-     <xsl:with-param name="COUNT" select="count(ClassStats[@interface='false' and substring-after(@class,'$')=''])" />
-     <xsl:with-param name="BUGS" select="sum(ClassStats[@interface='false' and substring-after(@class,'$')='']/@bugs)" />
-   </xsl:call-template>
-
-   <xsl:call-template name="status_table_row">
-     <xsl:with-param name="LABEL" select="$TABLE.ROW.INNER" />
-     <xsl:with-param name="COUNT" select="count(ClassStats[@interface='false' and substring-after(@class,'$')!=''])" />
-     <xsl:with-param name="BUGS" select="sum(ClassStats[@interface='false' and substring-after(@class,'$')!='']/@bugs)" />
-   </xsl:call-template>
-
-   <xsl:call-template name="status_table_row">
-     <xsl:with-param name="LABEL" select="$TABLE.ROW.INTERFACE" />
-     <xsl:with-param name="COUNT" select="count(ClassStats[@interface='true'])" />
-     <xsl:with-param name="BUGS" select="sum(ClassStats[@interface='true']/@bugs)" />
-   </xsl:call-template>
-
-   <xsl:call-template name="status_table_row">
-     <xsl:with-param name="LABEL" select="$TABLE.ROW.TOTAL" />
-     <xsl:with-param name="COUNT" select="@total_types" />
-     <xsl:with-param name="BUGS" select="@total_bugs" />
-     <xsl:with-param name="FONT_SIZE" select="5"/>
-   </xsl:call-template>
-
-  </table>
-  <xsl:if test="@total_bugs &gt; 0">
-  <table width="{$TABLE.WIDTH}" border="0" align="center">
-     <xsl:variable name="max_bugs">
-       <xsl:for-each select="ClassStats">
-         <xsl:sort select="@bugs" data-type="number" order="descending"/>
-         <xsl:if test="position()=1">
-           <xsl:value-of select="@bugs"/>
-         </xsl:if>
-       </xsl:for-each>
-     </xsl:variable>
-
-     <tr>
-       <td align="left" colspan="2">
-         <font face="{$PAGE.FONT}" size="4">
-     <xsl:call-template name='string_format'>
-     <xsl:with-param name="COUNT" select="$max_bugs"/>
-     <xsl:with-param name="STRING" select="$PACKAGE.BUGCLASS.LABEL"/>
-     <xsl:with-param name="SINGLE" select="$BUGS.SINGLE.LABEL"/>
-     <xsl:with-param name="PULURAL" select="$BUGS.PULURAL.LABEL"/>
-     </xsl:call-template>
-         </font>
-       </td>
-     </tr>
-
-     <xsl:for-each select="ClassStats">
-       <xsl:if test="@bugs = $max_bugs">
-       <tr>
-          <td>&#160;&#160;&#160;&#160;&#160;&#160;&#160;</td>
-          <td align="left"><font face="{$PAGE.FONT}" color="red" size="4"><i><xsl:value-of select="$package-prefix"/><xsl:value-of select="@class" /></i></font></td>
-       </tr>
-       </xsl:if>
-     </xsl:for-each>
-
-   </table>
-  </xsl:if>
-  <br/>
-</xsl:template>
-
-</xsl:stylesheet>
diff --git a/lib/jrat/bcel-326809.jar b/lib/jrat/bcel-326809.jar
deleted file mode 100644
index 9c8de92..0000000
Binary files a/lib/jrat/bcel-326809.jar and /dev/null differ
diff --git a/lib/jrat/jmxri.jar b/lib/jrat/jmxri.jar
deleted file mode 100644
index 5e519fd..0000000
Binary files a/lib/jrat/jmxri.jar and /dev/null differ
diff --git a/lib/jrat/shiftone-arbor.jar b/lib/jrat/shiftone-arbor.jar
deleted file mode 100644
index f16528e..0000000
Binary files a/lib/jrat/shiftone-arbor.jar and /dev/null differ
diff --git a/lib/jrat/shiftone-jrat.jar b/lib/jrat/shiftone-jrat.jar
deleted file mode 100644
index 3c1c5bf..0000000
Binary files a/lib/jrat/shiftone-jrat.jar and /dev/null differ
diff --git a/lib/junit/junit.jar b/lib/junit/junit.jar
deleted file mode 100644
index 717cd08..0000000
Binary files a/lib/junit/junit.jar and /dev/null differ
diff --git a/lib/log4j/log4j-1.2.13.jar b/lib/log4j/log4j-1.2.13.jar
deleted file mode 100644
index dde9972..0000000
Binary files a/lib/log4j/log4j-1.2.13.jar and /dev/null differ
diff --git a/lib/runtime/getopt/gnu.getopt.jar b/lib/runtime/getopt/gnu.getopt.jar
deleted file mode 100644
index 1aea24b..0000000
Binary files a/lib/runtime/getopt/gnu.getopt.jar and /dev/null differ
diff --git a/lib/svn/commons-lang-2.0.jar b/lib/svn/commons-lang-2.0.jar
deleted file mode 100644
index c8a2870..0000000
Binary files a/lib/svn/commons-lang-2.0.jar and /dev/null differ
diff --git a/lib/svn/jakarta-regexp-1.3.jar b/lib/svn/jakarta-regexp-1.3.jar
deleted file mode 100644
index d653a38..0000000
Binary files a/lib/svn/jakarta-regexp-1.3.jar and /dev/null differ
diff --git a/lib/svn/svnClientAdapter.jar b/lib/svn/svnClientAdapter.jar
deleted file mode 100644
index 502a53f..0000000
Binary files a/lib/svn/svnClientAdapter.jar and /dev/null differ
diff --git a/lib/svn/svnant.jar b/lib/svn/svnant.jar
deleted file mode 100644
index fc5e2b9..0000000
Binary files a/lib/svn/svnant.jar and /dev/null differ
diff --git a/lib/svn/svnjavahl.jar b/lib/svn/svnjavahl.jar
deleted file mode 100644
index 4208165..0000000
Binary files a/lib/svn/svnjavahl.jar and /dev/null differ
diff --git a/lib/vpp/commons-collections-3.1.jar b/lib/vpp/commons-collections-3.1.jar
deleted file mode 100644
index 41e230f..0000000
Binary files a/lib/vpp/commons-collections-3.1.jar and /dev/null differ
diff --git a/lib/vpp/foundrylogic-vpp-2.2.1-nodeps.jar b/lib/vpp/foundrylogic-vpp-2.2.1-nodeps.jar
deleted file mode 100644
index 3956a43..0000000
Binary files a/lib/vpp/foundrylogic-vpp-2.2.1-nodeps.jar and /dev/null differ
diff --git a/lib/vpp/velocity-1.4.jar b/lib/vpp/velocity-1.4.jar
deleted file mode 100644
index 04ec9d2..0000000
Binary files a/lib/vpp/velocity-1.4.jar and /dev/null differ
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..bb6ef10
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,124 @@
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>org.anarres</groupId>
+	<artifactId>cpp</artifactId>
+	<name>Anarres JCPP</name>
+	<url>http://www.anarres.org/projects/jcpp/</url>
+	<version>1.5.1-SNAPSHOT</version>
+	<packaging>jar</packaging>
+	<description></description>
+
+	<developers>
+		<developer>
+			<id>anarres.author</id>
+			<name>Anarres Author</name>
+			<email>contact@anarres.org</email>
+		</developer>
+	</developers>
+
+	<licenses>
+		<license>
+			<name>Apache 2.0</name>
+			<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
+			<distribution>repo</distribution>
+		</license>
+	</licenses>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.1</version>
+				<configuration>
+					<source>1.7</source>
+					<target>1.7</target>
+					<encoding>UTF-8</encoding>
+					<optimize>true</optimize>
+				</configuration>
+			</plugin>
+
+			<plugin>
+				<groupId>com.nativelibs4java</groupId>
+				<artifactId>maven-velocity-plugin</artifactId>
+				<version>0.8</version>
+				<executions>
+					<execution>
+						<phase>generate-sources</phase>
+						<goals>
+							<goal>generate</goal>
+						</goals>
+					</execution>
+				</executions>
+				<configuration>
+					<properties>
+						<version>${project.version}</version>
+						<project_version>${project.version}</project_version>
+						<project_name>${project.artifactId}</project_name>
+					</properties>
+				</configuration>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+				<version>2.4</version>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<version>2.16</version>
+				<configuration>
+					<redirectTestOutputToFile>true</redirectTestOutputToFile>
+				</configuration>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-assembly-plugin</artifactId>
+				<configuration>
+					<descriptorRefs>
+						<descriptorRef>jar-with-dependencies</descriptorRef>
+					</descriptorRefs>
+				</configuration>
+				<executions>
+					<execution>
+						<phase>package</phase>
+						<id>create-my-bundle</id>
+						<goals>
+							<goal>single</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.11</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.ant</groupId>
+			<artifactId>ant</artifactId>
+			<version>1.8.2</version>
+		</dependency>
+		<dependency>
+			<groupId>gnu.getopt</groupId>
+			<artifactId>java-getopt</artifactId>
+			<version>1.0.13</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sourceforge.findbugs</groupId>
+			<artifactId>jsr305</artifactId>
+			<version>1.3.2</version>
+		</dependency>
+	</dependencies>
+</project>
+
diff --git a/settings.gradle b/settings.gradle
deleted file mode 100644
index f22856c..0000000
--- a/settings.gradle
+++ /dev/null
@@ -1 +0,0 @@
-rootProject.name='jcpp'
diff --git a/src/main/java/org/anarres/cpp/CppTask.java b/src/main/java/org/anarres/cpp/CppTask.java
index 5e17786..55a8eff 100644
--- a/src/main/java/org/anarres/cpp/CppTask.java
+++ b/src/main/java/org/anarres/cpp/CppTask.java
@@ -34,7 +34,7 @@
  */
 public class CppTask extends Copy {
 
-    private class Listener extends PreprocessorListener {
+    private class Listener extends DefaultPreprocessorListener {
 
         @Override
         protected void print(String msg) {
diff --git a/src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java b/src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java
new file mode 100644
index 0000000..e6f122b
--- /dev/null
+++ b/src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java
@@ -0,0 +1,105 @@
+package org.anarres.cpp;
+
+/*
+ * Anarres C Preprocessor
+ * Copyright (c) 2007-2008, Shevek
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import javax.annotation.Nonnegative;
+
+/**
+ * A handler for preprocessor events, primarily errors and warnings.
+ *
+ * If no PreprocessorListener is installed in a Preprocessor, all
+ * error and warning events will throw an exception. Installing a
+ * listener allows more intelligent handling of these events.
+ */
+public class DefaultPreprocessorListener implements PreprocessorListener {
+
+    private int errors;
+    private int warnings;
+
+    public DefaultPreprocessorListener() {
+        clear();
+    }
+
+    public void clear() {
+        errors = 0;
+        warnings = 0;
+    }
+
+    @Nonnegative
+    public int getErrors() {
+        return errors;
+    }
+
+    @Nonnegative
+    public int getWarnings() {
+        return warnings;
+    }
+
+    protected void print(String msg) {
+        System.err.println(msg);
+    }
+
+    /**
+     * Handles a warning.
+     *
+     * The behaviour of this method is defined by the
+     * implementation. It may simply record the error message, or
+     * it may throw an exception.
+     */
+    public void handleWarning(Source source, int line, int column,
+            String msg)
+            throws LexerException {
+        warnings++;
+        print(source.getName() + ":" + line + ":" + column
+                + ": warning: " + msg);
+    }
+
+    /**
+     * Handles an error.
+     *
+     * The behaviour of this method is defined by the
+     * implementation. It may simply record the error message, or
+     * it may throw an exception.
+     */
+    public void handleError(Source source, int line, int column,
+            String msg)
+            throws LexerException {
+        errors++;
+        print(source.getName() + ":" + line + ":" + column
+                + ": error: " + msg);
+    }
+
+    public void handleSourceChange(Source source, String event) {
+    }
+
+    @Override
+    public boolean beforeInclude(String filePath, int line) {
+        return false;
+    }
+
+    public void handlePreprocesorDirective(Source source, PreprocessorDirective directive) {
+        System.err.println(directive.toString());
+    }
+
+    public void handleMacroExpansion(Source source, int line, int column, String macro,
+            String definitionFileName, int definitionLine, int definitionColumn) {
+        System.err.println(source.getName() + " : " + line + ":" + column + " macro: " + macro
+                + " definition: " + definitionFileName + ":" + definitionLine + ":"
+                + definitionColumn);
+    }
+
+}
diff --git a/src/main/java/org/anarres/cpp/FileLexerSource.java b/src/main/java/org/anarres/cpp/FileLexerSource.java
index 1505506..3f5a0d3 100644
--- a/src/main/java/org/anarres/cpp/FileLexerSource.java
+++ b/src/main/java/org/anarres/cpp/FileLexerSource.java
@@ -74,12 +74,12 @@ public File getFile() {
      * This is not necessarily the same as getFile().getPath() in case we are in a chroot.
      */
     @Override
-    /* pp */ String getPath() {
+    public String getPath() {
         return path;
     }
 
     @Override
-    /* pp */ String getName() {
+    public String getName() {
         return getPath();
     }
 
diff --git a/src/main/java/org/anarres/cpp/InputLexerSource.java b/src/main/java/org/anarres/cpp/InputLexerSource.java
index 3e1dcb3..5eb8f94 100644
--- a/src/main/java/org/anarres/cpp/InputLexerSource.java
+++ b/src/main/java/org/anarres/cpp/InputLexerSource.java
@@ -48,12 +48,12 @@ public InputLexerSource(InputStream input)
     }
 
     @Override
-    /* pp */ String getPath() {
+    public String getPath() {
         return "<standard-input>";
     }
 
     @Override
-    /* pp */ String getName() {
+    public String getName() {
         return "standard input";
     }
 
diff --git a/src/main/java/org/anarres/cpp/LexerSource.java b/src/main/java/org/anarres/cpp/LexerSource.java
index 5f1dac3..4f5362e 100644
--- a/src/main/java/org/anarres/cpp/LexerSource.java
+++ b/src/main/java/org/anarres/cpp/LexerSource.java
@@ -120,10 +120,10 @@ private void _error(String msg, boolean error)
     }
 
     /*
-     private boolean _isLineSeparator(int c) {
-     return Character.getType(c) == Character.LINE_SEPARATOR
-     || c == -1;
-     }
+     * private boolean _isLineSeparator(int c) {
+     * return Character.getType(c) == Character.LINE_SEPARATOR
+     * || c == -1;
+     * }
      */
 
     /* XXX Move to JoinReader and canonicalise newlines. */
@@ -197,14 +197,14 @@ private int read()
         }
 
         /*
-         if (isLineSeparator(c)) {
-         line++;
-         lastcolumn = column;
-         column = 0;
-         }
-         else {
-         column++;
-         }
+         * if (isLineSeparator(c)) {
+         * line++;
+         * lastcolumn = column;
+         * column = 0;
+         * }
+         * else {
+         * column++;
+         * }
          */
         return c;
     }
@@ -241,7 +241,7 @@ private void unread(int c)
 
     /* Consumes the rest of the current line into an invalid. */
     @Nonnull
-    private Token invalid(StringBuilder text, String reason)
+    private Token invalid(StringBuilder text, int expected, String reason)
             throws IOException,
             LexerException {
         int d = read();
@@ -250,25 +250,33 @@ private Token invalid(StringBuilder text, String reason)
             d = read();
         }
         unread(d);
-        return new Token(INVALID, text.toString(), reason);
+        return new Token(INVALID, expected, text.toString(), reason);
     }
 
     @Nonnull
     private Token ccomment()
             throws IOException,
             LexerException {
+
         StringBuilder text = new StringBuilder("/*");
         int d;
         do {
             do {
                 d = read();
-                text.append((char) d);
-            } while (d != '*');
+                if (d != -1) {
+                    text.append((char) d);
+                }
+            } while (d != '*' && d != -1);
             do {
                 d = read();
-                text.append((char) d);
+                if (d != -1) {
+                    text.append((char) d);
+                }
             } while (d == '*');
-        } while (d != '/');
+        } while (d != '/' && d != -1);
+        if (d == -1) {
+           return new Token(INVALID, CCOMMENT, text.toString(), "End of file in a multiline comment");
+        }
         return new Token(CCOMMENT, text.toString());
     }
 
@@ -375,15 +383,15 @@ private Token character()
             d = escape(text);
         } else if (isLineSeparator(d)) {
             unread(d);
-            return new Token(INVALID, text.toString(),
+            return new Token(INVALID, CHARACTER, text.toString(),
                     "Unterminated character literal");
         } else if (d == '\'') {
             text.append('\'');
-            return new Token(INVALID, text.toString(),
+            return new Token(INVALID, CHARACTER, text.toString(),
                     "Empty character literal");
         } else if (!Character.isDefined(d)) {
             text.append('?');
-            return invalid(text, "Illegal unicode character literal");
+            return invalid(text, CHARACTER, "Illegal unicode character literal");
         } else {
             text.append((char) d);
         }
@@ -402,7 +410,7 @@ private Token character()
                     break;
                 e = read();
             }
-            return new Token(INVALID, text.toString(),
+            return new Token(INVALID, CHARACTER, text.toString(),
                     "Illegal character constant " + text);
         }
         text.append('\'');
@@ -420,6 +428,26 @@ private Token string(char open, char close)
 
         StringBuilder buf = new StringBuilder();
 
+        final int expectedTokenType;
+        final String expectedTokenName;
+        switch (open) {
+            case '\"':
+                expectedTokenType = Token.STRING;
+                expectedTokenName = "string";
+                break;
+            case '\'':
+                expectedTokenType = Token.CHARACTER;
+                expectedTokenName = "character";
+                break;
+            case '>':
+                expectedTokenType = Token.HEADER;
+                expectedTokenName = "header";
+                break;
+            default:
+                expectedTokenType = 0;
+                expectedTokenName = "string";
+        }
+
         for (;;) {
             int c = read();
             if (c == close) {
@@ -433,13 +461,13 @@ private Token string(char open, char close)
             } else if (c == -1) {
                 unread(c);
                 // error("End of file in string literal after " + buf);
-                return new Token(INVALID, text.toString(),
-                        "End of file in string literal after " + buf);
+                return new Token(INVALID, expectedTokenType, text.toString(),
+                        "End of file in " + expectedTokenName + " literal after " + buf);
             } else if (isLineSeparator(c)) {
                 unread(c);
                 // error("Unterminated string literal after " + buf);
-                return new Token(INVALID, text.toString(),
-                        "Unterminated string literal after " + buf);
+                return new Token(INVALID, expectedTokenType, text.toString(),
+                        "Unterminated " + expectedTokenName + " literal after " + buf);
             } else {
                 text.append((char) c);
                 buf.append((char) c);
@@ -479,7 +507,7 @@ private Token _number_suffix(StringBuilder text, NumericValue value, int d)
                 d = read();
             } else if (d == 'L' || d == 'l') {
                 if ((flags & NumericValue.FF_SIZE) != 0)
-                    warning("Nultiple length suffixes after " + text);
+                    warning("Multiple length suffixes after " + text);
                 text.append((char) d);
                 int e = read();
                 if (e == d) {	// Case must match. Ll is Welsh.
@@ -492,19 +520,19 @@ private Token _number_suffix(StringBuilder text, NumericValue value, int d)
                 }
             } else if (d == 'I' || d == 'i') {
                 if ((flags & NumericValue.FF_SIZE) != 0)
-                    warning("Nultiple length suffixes after " + text);
+                    warning("Multiple length suffixes after " + text);
                 flags |= NumericValue.F_INT;
                 text.append((char) d);
                 d = read();
             } else if (d == 'F' || d == 'f') {
                 if ((flags & NumericValue.FF_SIZE) != 0)
-                    warning("Nultiple length suffixes after " + text);
+                    warning("Multiple length suffixes after " + text);
                 flags |= NumericValue.F_FLOAT;
                 text.append((char) d);
                 d = read();
             } else if (d == 'D' || d == 'd') {
                 if ((flags & NumericValue.FF_SIZE) != 0)
-                    warning("Nultiple length suffixes after " + text);
+                    warning("Multiple length suffixes after " + text);
                 flags |= NumericValue.F_DOUBLE;
                 text.append((char) d);
                 d = read();
@@ -512,7 +540,7 @@ private Token _number_suffix(StringBuilder text, NumericValue value, int d)
             else if (Character.isLetter(d) || d == '_') {
                 unread(d);
                 value.setFlags(flags);
-                return invalid(text,
+                return invalid(text, Token.NUMBER,
                         "Invalid suffix \"" + (char) d
                         + "\" on numeric constant");
             } else {
@@ -526,11 +554,16 @@ else if (Character.isLetter(d) || d == '_') {
 
     /* Either a decimal part, or a hex exponent. */
     @Nonnull
-    private String _number_part(StringBuilder text, int base)
+    private String _number_part(StringBuilder text, int base, boolean sign)
             throws IOException,
             LexerException {
         StringBuilder part = new StringBuilder();
         int d = read();
+        if (sign && d == '-') {
+            text.append((char) d);
+            part.append((char) d);
+            d = read();
+        }
         while (Character.digit(d, base) != -1) {
             text.append((char) d);
             part.append((char) d);
@@ -540,18 +573,6 @@ private String _number_part(StringBuilder text, int base)
         return part.toString();
     }
 
-    /* We already chewed a zero, so empty is fine. */
-    @Nonnull
-    private Token number_octal()
-            throws IOException,
-            LexerException {
-        StringBuilder text = new StringBuilder("0");
-        String integer = _number_part(text, 8);
-        int d = read();
-        NumericValue value = new NumericValue(8, integer);
-        return _number_suffix(text, value, d);
-    }
-
     /* We do not know whether know the first digit is valid. */
     @Nonnull
     private Token number_hex(char x)
@@ -559,23 +580,34 @@ private Token number_hex(char x)
             LexerException {
         StringBuilder text = new StringBuilder("0");
         text.append(x);
-        String integer = _number_part(text, 16);
+        String integer = _number_part(text, 16, false);
         NumericValue value = new NumericValue(16, integer);
         int d = read();
         if (d == '.') {
-            String fraction = _number_part(text, 16);
+            text.append((char) d);
+            String fraction = _number_part(text, 16, false);
             value.setFractionalPart(fraction);
             d = read();
         }
         if (d == 'P' || d == 'p') {
-            String exponent = _number_part(text, 10);
-            value.setExponent(exponent);
+            text.append((char) d);
+            String exponent = _number_part(text, 10, true);
+            value.setExponent(2, exponent);
             d = read();
         }
         // XXX Make sure it's got enough parts
         return _number_suffix(text, value, d);
     }
 
+    private static boolean is_octal(@Nonnull String text) {
+        if (!text.startsWith("0"))
+            return false;
+        for (int i = 0; i < text.length(); i++)
+            if (Character.digit(text.charAt(i), 8) == -1)
+                return false;
+        return true;
+    }
+
     /* We know we have at least one valid digit, but empty is not
      * fine. */
     @Nonnull
@@ -583,25 +615,95 @@ private Token number_decimal()
             throws IOException,
             LexerException {
         StringBuilder text = new StringBuilder();
-        String integer = _number_part(text, 10);
-        NumericValue value = new NumericValue(10, integer);
+        String integer = _number_part(text, 10, false);
+        String fraction = null;
+        String exponent = null;
         int d = read();
         if (d == '.') {
             text.append((char) d);
-            String fraction = _number_part(text, 10);
-            value.setFractionalPart(fraction);
+            fraction = _number_part(text, 10, false);
             d = read();
         }
         if (d == 'E' || d == 'e') {
             text.append((char) d);
-            String exponent = _number_part(text, 10);
-            value.setExponent(exponent);
+            exponent = _number_part(text, 10, true);
             d = read();
         }
+        int base = 10;
+        if (fraction == null && exponent == null && integer.startsWith("0")) {
+            if (!is_octal(integer))
+                warning("Decimal constant starts with 0, but not octal: " + integer);
+            else
+                base = 8;
+        }
+        NumericValue value = new NumericValue(base, integer);
+        if (fraction != null)
+            value.setFractionalPart(fraction);
+        if (exponent != null)
+            value.setExponent(10, exponent);
         // XXX Make sure it's got enough parts
         return _number_suffix(text, value, d);
     }
 
+    /**
+     * Section 6.4.4.1 of C99
+     * 
+     * (Not pasted here, but says that the initial negation is a separate token.)
+     * 
+     * Section 6.4.4.2 of C99
+     *
+     * A floating constant has a significand part that may be followed
+     * by an exponent part and a suffix that specifies its type. The
+     * components of the significand part may include a digit sequence
+     * representing the whole-number part, followed by a period (.),
+     * followed by a digit sequence representing the fraction part.
+     *
+     * The components of the exponent part are an e, E, p, or P
+     * followed by an exponent consisting of an optionally signed digit
+     * sequence. Either the whole-number part or the fraction part has to
+     * be present; for decimal floating constants, either the period or
+     * the exponent part has to be present.
+     *
+     * The significand part is interpreted as a (decimal or hexadecimal)
+     * rational number; the digit sequence in the exponent part is
+     * interpreted as a decimal integer. For decimal floating constants,
+     * the exponent indicates the power of 10 by which the significand
+     * part is to be scaled. For hexadecimal floating constants, the
+     * exponent indicates the power of 2 by which the significand part is
+     * to be scaled.
+     *
+     * For decimal floating constants, and also for hexadecimal
+     * floating constants when FLT_RADIX is not a power of 2, the result
+     * is either the nearest representable value, or the larger or smaller
+     * representable value immediately adjacent to the nearest representable
+     * value, chosen in an implementation-defined manner. For hexadecimal
+     * floating constants when FLT_RADIX is a power of 2, the result is
+     * correctly rounded.
+     */
+    @Nonnull
+    private Token number()
+            throws IOException,
+            LexerException {
+        Token tok;
+        int c = read();
+        if (c == '0') {
+            int d = read();
+            if (d == 'x' || d == 'X') {
+                tok = number_hex((char) d);
+            } else {
+                unread(d);
+                unread(c);
+                tok = number_decimal();
+            }
+        } else if (Character.isDigit(c) || c == '.') {
+            unread(c);
+            tok = number_decimal();
+        } else {
+            throw new LexerException("Asked to parse something as a number which isn't: " + (char) c);
+        }
+        return tok;
+    }
+
     @Nonnull
     private Token identifier(int c)
             throws IOException,
@@ -611,11 +713,13 @@ private Token identifier(int c)
         text.append((char) c);
         for (;;) {
             d = read();
-            if (Character.isIdentifierIgnorable(d))
-				; else if (Character.isJavaIdentifierPart(d))
+            if (Character.isIdentifierIgnorable(d)) {
+                ;
+            } else if (Character.isJavaIdentifierPart(d)) {
                 text.append((char) d);
-            else
+            } else {
                 break;
+            }
         }
         unread(d);
         return new Token(IDENTIFIER, text.toString());
@@ -839,26 +943,11 @@ else if (d == '=')
                     unread(d);
                 if (Character.isDigit(d)) {
                     unread('.');
-                    tok = number_decimal();
+                    tok = number();
                 }
                 /* XXX decimal fraction */
                 break;
 
-            case '0':
-                /* octal or hex */
-                d = read();
-                if (d == 'x' || d == 'X')
-                    tok = number_hex((char) d);
-                else if (d == '.') {
-                    unread(d);
-                    unread(c);
-                    tok = number_decimal();
-                } else {
-                    unread(d);
-                    tok = number_octal();
-                }
-                break;
-
             case '\'':
                 tok = string('\'', '\'');
                 break;
@@ -878,7 +967,7 @@ else if (d == '.') {
                 tok = whitespace(c);
             } else if (Character.isDigit(c)) {
                 unread(c);
-                tok = number_decimal();
+                tok = number();
             } else if (Character.isJavaIdentifierStart(c)) {
                 tok = identifier(c);
             } else {
@@ -904,6 +993,7 @@ else if (d == '.') {
         return tok;
     }
 
+    @Override
     public void close()
             throws IOException {
         if (reader != null) {
diff --git a/src/main/java/org/anarres/cpp/Macro.java b/src/main/java/org/anarres/cpp/Macro.java
index 534cb2b..c69b693 100644
--- a/src/main/java/org/anarres/cpp/Macro.java
+++ b/src/main/java/org/anarres/cpp/Macro.java
@@ -29,6 +29,11 @@
  * extra tokens {@link Token#M_ARG} and {@link Token#M_STRING}.
  */
 public class Macro {
+	/**
+	 * A value for indicating an unknown position of a macro name.
+	 */
+	public static final int UNKNOWN_POSITION_VALUE = -1;
+
 	private Source			source;
 	private String			name;
 	/* It's an explicit decision to keep these around here. We don't
@@ -39,12 +44,32 @@ public class Macro {
 	private boolean			variadic;
 	private List<Token>		tokens;
 
-	public Macro(Source source, String name) {
+	/**
+	 * Number of the line that the name of the macro in its definition starts
+	 * in. It is set to UNKNOWN_POSITION_VALUE if it is unknown, e.g. if the
+	 * macro does not come from any file.
+	 */
+	private final int nameStartLine;
+
+	/**
+	 * Number of the column that the name of the macro in its definition
+	 * starts in. It is set to UNKNOWN_POSITION_VALUE if it us unknown.
+	 */
+	private final int nameStartColumn;
+
+
+	public Macro(Source source, String name, int nameStartLine, int nameStartColumn) {
 		this.source = source;
 		this.name = name;
 		this.args = null;
 		this.variadic = false;
 		this.tokens = new ArrayList<Token>();
+		this.nameStartLine = nameStartLine;
+		this.nameStartColumn = nameStartColumn;
+	}
+
+	public Macro(Source source, String name) {
+		this(source, name, UNKNOWN_POSITION_VALUE, UNKNOWN_POSITION_VALUE);
 	}
 
 	public Macro(String name) {
@@ -96,6 +121,18 @@ public int getArgs() {
 		return args.size();
 	}
 
+	/**
+	 * @return The number of the line the name of the macro in its definition
+	 *         starts or <code>UNKNOWN_POSITION_VALUE</code> if it is unknown.
+	 */
+	public int getNameStartLine() { return nameStartLine; }
+
+	/**
+	 * @return The number of the column the name of the macro in its definition
+	 *         starts or <code>UNKNOWN_POSITION_VALUE</code> if it is unknown.
+	 */
+	public int getNameStartColumn() { return nameStartColumn; }
+
 	/**
 	 * Sets the variadic flag on this Macro.
 	 */
diff --git a/src/main/java/org/anarres/cpp/MacroTokenSource.java b/src/main/java/org/anarres/cpp/MacroTokenSource.java
index 516e4f2..6fa4970 100644
--- a/src/main/java/org/anarres/cpp/MacroTokenSource.java
+++ b/src/main/java/org/anarres/cpp/MacroTokenSource.java
@@ -17,6 +17,7 @@
 package org.anarres.cpp;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
@@ -32,12 +33,54 @@
     private final List<Argument> args;	/* { unexpanded, expanded } */
 
     private Iterator<Token> arg;	/* "current expansion" */
+    private boolean argumentPasted;  /* do tokens from 'arg' come from a paste? */
 
-    /* pp */ MacroTokenSource(Macro m, List<Argument> args) {
+    /**
+     * Token with the macro identifier that tokens from this source replace.
+     */
+    private final Token originalToken;
+
+    /* pp */ MacroTokenSource(Macro m, List<Argument> args, Token originalToken) {
         this.macro = m;
-        this.tokens = m.getTokens().iterator();
+
+        /* Clone all tokens from the macro definition. It is done to keep the
+           appropriate original tokens in those that are returned by
+           MacroTokenSource objects. Cloning tokens solves a problem with that
+           while nesting the same macro in itself, e.g. ADD(1, ADD(1, 2))
+           where ADD is defined as follows: #define ADD(x, y) x + y  */
+        final List<Token> clonedTokens = new ArrayList<>();
+        try {
+            for (Token token : m.getTokens()) {
+                clonedTokens.add((Token) token.clone());
+            }
+
+        } catch(CloneNotSupportedException e) {
+            /* This type of exception should never be thrown in the above code
+               because Token class implements 'clone' method and Cloneable
+               interface properly */
+            throw new RuntimeException("MacroTokenSource.<init>: CloneNotSupportedException"
+                + " caught\n" + e.getMessage());
+        }
+        this.tokens = clonedTokens.iterator();
+
         this.args = args;
         this.arg = null;
+        this.originalToken = originalToken;
+        this.argumentPasted = false;
+    }
+
+    @Override
+    MacroTokenSource getExpandingRoot() {
+        final Source parent = getParent();
+        if (parent == null || !parent.isExpanding()) {
+            return this;
+        }
+        return parent.getExpandingRoot();
+    }
+
+    @Override
+    boolean isExpanding() {
+        return true;
     }
 
     @Override
@@ -81,6 +124,31 @@ private void concat(StringBuilder buf, Argument arg) {
     }
 
     private Token stringify(Token pos, Argument arg) {
+        // Set the data for the position tracing
+        final MacroTokenSource expandingRoot = getExpandingRoot();
+        assert expandingRoot != null;
+        final Token expandingRootToken = expandingRoot.getOriginalToken();
+        Token origToken = null;  // original token to set in the result of this method
+        if (arg.size() > 0) {
+            final Token argFirstTok = arg.get(0);
+            final Token argFirstTokOrigTok = argFirstTok.getOriginalMacroToken();
+
+            if (expandingRoot.argumentContains(argFirstTok)) {
+                pos =   argFirstTokOrigTok != null
+                      ? argFirstTokOrigTok
+                      : argFirstTok;
+                origToken =   argFirstTokOrigTok != null
+                            ? argFirstTokOrigTok
+                            : null;
+            } else {
+                pos = expandingRootToken;
+                origToken = expandingRootToken;
+            }
+        } else {
+            pos = expandingRootToken;
+            origToken = expandingRootToken;
+        }
+
         StringBuilder buf = new StringBuilder();
         concat(buf, arg);
         // System.out.println("Concat: " + arg + " -> " + buf);
@@ -88,9 +156,15 @@ private Token stringify(Token pos, Argument arg) {
         escape(str, buf);
         str.append("\"");
         // System.out.println("Escape: " + buf + " -> " + str);
-        return new Token(STRING,
+
+        final Token result = new Token(STRING,
                 pos.getLine(), pos.getColumn(),
                 str.toString(), buf.toString());
+        result.setStringized(true);
+        if (origToken != null) {
+            result.setOriginalMacroToken(origToken);
+        }
+        return result;
     }
 
 
@@ -146,6 +220,7 @@ private void paste(Token ptok)
 
         /* XXX Check that concatenation produces a valid token. */
         arg = new SourceIterator(sl);
+        argumentPasted = true;
     }
 
     public Token token()
@@ -160,9 +235,10 @@ public Token token()
                     /* XXX PASTE -> INVALID. */
                     assert tok.getType() != M_PASTE :
                             "Unexpected paste token";
-                    return tok;
+                    return argumentPasted ? withOriginalToken(tok) : tok;
                 }
                 arg = null;
+                argumentPasted = false;
             }
 
             if (!tokens.hasNext())
@@ -185,12 +261,65 @@ public Token token()
                     paste(tok);
                     break;
                 default:
-                    return tok;
+                    return withOriginalToken(tok);
             }
         } /* for */
 
     }
 
+    /**
+     * Sets the original token of the given one to the original token from the
+     * source code (but not from a macro definition) that caused expansion of
+     * a macro that this object is result of.
+     *
+     * @param token Token whose original one is to be assigned.
+     * @return The given token.
+     */
+    private Token withOriginalToken(Token token) {
+        assert token != null;
+        token.setOriginalMacroToken(getExpandingRootToken());
+        return token;
+    }
+
+    /**
+     * @return Token with a macro identifier that caused the appearance of this
+     *         Source object.
+     */
+    Token getOriginalToken() {
+        return originalToken;
+    }
+
+    /**
+     * @return True if and only if the given token is a token from an argument
+     *         expansion or the actual argument of a macro use that this object
+     *         represents.
+     */
+    boolean argumentContains(Token tok) {
+        if (args == null) {
+            return false;
+        }
+
+        for (Argument arg : args) {
+            // Check if the token comes from an argument expansion
+            final Iterator<Token> argumentExpansion = arg.expansion();
+            while (argumentExpansion.hasNext()) {
+                if (argumentExpansion.next() == tok) {
+                    return true;
+                }
+            }
+
+            /* Check if the token comes from the original expression passed as
+               an argument (before its expansion) */
+            for (Token argTokBeforeExpansion : arg) {
+                if (argTokBeforeExpansion == tok) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
     @Override
     public String toString() {
         StringBuilder buf = new StringBuilder();
diff --git a/src/main/java/org/anarres/cpp/Main.java b/src/main/java/org/anarres/cpp/Main.java
index 1902798..4c50b70 100644
--- a/src/main/java/org/anarres/cpp/Main.java
+++ b/src/main/java/org/anarres/cpp/Main.java
@@ -92,7 +92,7 @@ public void run(String[] args) throws Exception {
         pp.addFeature(Feature.TRIGRAPHS);
         pp.addFeature(Feature.LINEMARKERS);
         pp.addWarning(Warning.IMPORT);
-        pp.setListener(new PreprocessorListener());
+        pp.setListener(new DefaultPreprocessorListener());
         pp.addMacro("__JCPP__");
         pp.getSystemIncludePath().add("/usr/local/include");
         pp.getSystemIncludePath().add("/usr/include");
diff --git a/src/main/java/org/anarres/cpp/NumericValue.java b/src/main/java/org/anarres/cpp/NumericValue.java
index 8d961c4..e38d28f 100644
--- a/src/main/java/org/anarres/cpp/NumericValue.java
+++ b/src/main/java/org/anarres/cpp/NumericValue.java
@@ -18,6 +18,10 @@
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import javax.annotation.CheckForNull;
+import javax.annotation.CheckForSigned;
+import javax.annotation.Nonnegative;
+import javax.annotation.Nonnull;
 
 public class NumericValue extends Number {
 
@@ -33,6 +37,7 @@ public class NumericValue extends Number {
     private final int base;
     private final String integer;
     private String fraction;
+    private int expbase = 0;
     private String exponent;
     private int flags;
 
@@ -41,14 +46,17 @@ public NumericValue(int base, String integer) {
         this.integer = integer;
     }
 
+    @Nonnegative
     public int getBase() {
         return base;
     }
 
+    @Nonnull
     public String getIntegerPart() {
         return integer;
     }
 
+    @CheckForNull
     public String getFractionalPart() {
         return fraction;
     }
@@ -57,11 +65,18 @@ public String getFractionalPart() {
         this.fraction = fraction;
     }
 
+    @CheckForSigned
+    public int getExponentBase() {
+        return expbase;
+    }
+
+    @CheckForNull
     public String getExponent() {
         return exponent;
     }
 
-    /* pp */ void setExponent(String exponent) {
+    /* pp */ void setExponent(int expbase, String exponent) {
+        this.expbase = expbase;
         this.exponent = exponent;
     }
 
@@ -78,6 +93,7 @@ public int getFlags() {
      * precision numbers is nontrivial, and this routine gets it wrong
      * in many important cases.
      */
+    @Nonnull
     public BigDecimal toBigDecimal() {
         int scale = 0;
         String text = getIntegerPart();
@@ -93,6 +109,7 @@ public BigDecimal toBigDecimal() {
         return new BigDecimal(unscaled, scale);
     }
 
+    @Nonnull
     public Number toJavaLangNumber() {
         int flags = getFlags();
         if ((flags & F_DOUBLE) != 0)
@@ -111,23 +128,41 @@ else if (getExponent() != null)
             return intValue();
     }
 
+    private int exponentValue() {
+        return Integer.parseInt(exponent, 10);
+    }
+
     @Override
     public int intValue() {
-        return Integer.parseInt(toString());
+        int v = integer.isEmpty() ? 0 : Integer.parseInt(integer, base);
+        if (expbase == 2)
+            v = v << exponentValue();
+        else if (expbase != 0)
+            v = (int) (v * Math.pow(expbase, exponentValue()));
+        return v;
     }
 
     @Override
     public long longValue() {
-        return Long.parseLong(toString());
+        long v = integer.isEmpty() ? 0 : Long.parseLong(integer, base);
+        if (expbase == 2)
+            v = v << exponentValue();
+        else if (expbase != 0)
+            v = (int) (v * Math.pow(expbase, exponentValue()));
+        return v;
     }
 
     @Override
     public float floatValue() {
+        if (getBase() != 10)
+            return longValue();
         return Float.parseFloat(toString());
     }
 
     @Override
     public double doubleValue() {
+        if (getBase() != 10)
+            return longValue();
         return Double.parseDouble(toString());
     }
 
diff --git a/src/main/java/org/anarres/cpp/Preprocessor.java b/src/main/java/org/anarres/cpp/Preprocessor.java
index e4ecdc1..9ba241e 100644
--- a/src/main/java/org/anarres/cpp/Preprocessor.java
+++ b/src/main/java/org/anarres/cpp/Preprocessor.java
@@ -47,31 +47,31 @@
  * {@link CppReader}, which does this.)
  */
 /*
- Source file name and line number information is conveyed by lines of the form
-
- # linenum filename flags
-
- These are called linemarkers. They are inserted as needed into
- the output (but never within a string or character constant). They
- mean that the following line originated in file filename at line
- linenum. filename will never contain any non-printing characters;
- they are replaced with octal escape sequences.
-
- After the file name comes zero or more flags, which are `1', `2',
- `3', or `4'. If there are multiple flags, spaces separate them. Here
- is what the flags mean:
-
- `1'
- This indicates the start of a new file.
- `2'
- This indicates returning to a file (after having included another
- file).
- `3'
- This indicates that the following text comes from a system header
- file, so certain warnings should be suppressed.
- `4'
- This indicates that the following text should be treated as being
- wrapped in an implicit extern "C" block.
+ * Source file name and line number information is conveyed by lines of the form
+ *
+ * # linenum filename flags
+ *
+ * These are called linemarkers. They are inserted as needed into
+ * the output (but never within a string or character constant). They
+ * mean that the following line originated in file filename at line
+ * linenum. filename will never contain any non-printing characters;
+ * they are replaced with octal escape sequences.
+ *
+ * After the file name comes zero or more flags, which are `1', `2',
+ * `3', or `4'. If there are multiple flags, spaces separate them. Here
+ * is what the flags mean:
+ *
+ * `1'
+ * This indicates the start of a new file.
+ * `2'
+ * This indicates returning to a file (after having included another
+ * file).
+ * `3'
+ * This indicates that the following text comes from a system header
+ * file, so certain warnings should be suppressed.
+ * `4'
+ * This indicates that the following text should be treated as being
+ * wrapped in an implicit extern "C" block.
  */
 public class Preprocessor implements Closeable {
 
@@ -292,7 +292,7 @@ public void addInput(@Nonnull File file)
      * If a PreprocessorListener is installed, it receives the
      * error. Otherwise, an exception is thrown.
      */
-    protected void error(int line, int column, String msg)
+    protected void error(int line, int column, @Nonnull String msg)
             throws LexerException {
         if (listener != null)
             listener.handleError(source, line, column, msg);
@@ -300,6 +300,43 @@ protected void error(int line, int column, String msg)
             throw new LexerException("Error at " + line + ":" + column + ": " + msg);
     }
 
+    /**
+     * Handles a preprocessor directive.
+     *
+     * If a PreprocessorListener is installed, it receives the
+     * directive. Otherwise, it is ignored.
+     */
+    protected void directive(PreprocessorDirective directive) {
+        if (listener != null) {
+            listener.handlePreprocesorDirective(getSource(), directive);
+        }
+    }
+
+    protected void macroExpansion(Macro macro, Token identifier, boolean inExpandingSources) {
+        if (listener != null && (inExpandingSources || !getSource().isExpanding())) {
+            // Source can be null
+            final String definitionFileName = macro.getSource() != null ? macro.getSource().getPath() : null;
+
+            listener.handleMacroExpansion(getSource(), identifier.getLine(),
+                    identifier.getColumn(), identifier.getText(), definitionFileName,
+                    macro.getNameStartLine(), macro.getNameStartColumn());
+        }
+    }
+
+    /**
+     * Marks all tokens that are part of macro definition. Therefore, when
+     * the macro is expanded and macro's tokens are returned by preprocessor,
+     * these tokens can be easily distinguished from tokens that comes from
+     * source file.
+     *
+     * @param m macro
+     */
+    protected void markTokens(Macro m) {
+        for (Token token : m.getTokens()) {
+            token.setExpanded(true);
+        }
+    }
+
     /**
      * Handles an error.
      *
@@ -308,7 +345,7 @@ protected void error(int line, int column, String msg)
      *
      * @see #error(int, int, String)
      */
-    protected void error(Token tok, String msg)
+    protected void error(@Nonnull Token tok, @Nonnull String msg)
             throws LexerException {
         error(tok.getLine(), tok.getColumn(), msg);
     }
@@ -319,7 +356,7 @@ protected void error(Token tok, String msg)
      * If a PreprocessorListener is installed, it receives the
      * warning. Otherwise, an exception is thrown.
      */
-    protected void warning(int line, int column, String msg)
+    protected void warning(int line, int column, @Nonnull String msg)
             throws LexerException {
         if (warnings.contains(Warning.ERROR))
             error(line, column, msg);
@@ -337,7 +374,7 @@ else if (listener != null)
      *
      * @see #warning(int, int, String)
      */
-    protected void warning(Token tok, String msg)
+    protected void warning(@Nonnull Token tok, @Nonnull String msg)
             throws LexerException {
         warning(tok.getLine(), tok.getColumn(), msg);
     }
@@ -348,12 +385,12 @@ protected void warning(Token tok, String msg)
      * The given {@link Macro} object encapsulates both the name
      * and the expansion.
      */
-    public void addMacro(Macro m) throws LexerException {
-        // System.out.println("Macro " + m);
+    public void addMacro(@Nonnull Macro m) throws LexerException {
         String name = m.getName();
         /* Already handled as a source error in macro(). */
         if ("defined".equals(name))
             throw new LexerException("Cannot redefine name 'defined'");
+        markTokens(m);
         macros.put(m.getName(), m);
     }
 
@@ -363,7 +400,7 @@ public void addMacro(Macro m) throws LexerException {
      * The String value is lexed into a token stream, which is
      * used as the macro expansion.
      */
-    public void addMacro(String name, String value)
+    public void addMacro(@Nonnull String name, @Nonnull String value)
             throws LexerException {
         try {
             Macro m = new Macro(name);
@@ -386,7 +423,7 @@ public void addMacro(String name, String value)
      * This is a convnience method, and is equivalent to
      * <code>addMacro(name, "1")</code>.
      */
-    public void addMacro(String name)
+    public void addMacro(@Nonnull String name)
             throws LexerException {
         addMacro(name, "1");
     }
@@ -395,7 +432,7 @@ public void addMacro(String name)
      * Sets the user include path used by this Preprocessor.
      */
     /* Note for future: Create an IncludeHandler? */
-    public void setQuoteIncludePath(List<String> path) {
+    public void setQuoteIncludePath(@Nonnull List<String> path) {
         this.quoteincludepath = path;
     }
 
@@ -404,6 +441,7 @@ public void setQuoteIncludePath(List<String> path) {
      *
      * This list may be freely modified by user code.
      */
+    @Nonnull
     public List<String> getQuoteIncludePath() {
         return quoteincludepath;
     }
@@ -412,7 +450,7 @@ public List<String> getQuoteIncludePath() {
      * Sets the system include path used by this Preprocessor.
      */
     /* Note for future: Create an IncludeHandler? */
-    public void setSystemIncludePath(List<String> path) {
+    public void setSystemIncludePath(@Nonnull List<String> path) {
         this.sysincludepath = path;
     }
 
@@ -421,6 +459,7 @@ public void setSystemIncludePath(List<String> path) {
      *
      * This list may be freely modified by user code.
      */
+    @Nonnull
     public List<String> getSystemIncludePath() {
         return sysincludepath;
     }
@@ -429,7 +468,7 @@ public List<String> getSystemIncludePath() {
      * Sets the Objective-C frameworks path used by this Preprocessor.
      */
     /* Note for future: Create an IncludeHandler? */
-    public void setFrameworksPath(List<String> path) {
+    public void setFrameworksPath(@Nonnull List<String> path) {
         this.frameworkspath = path;
     }
 
@@ -439,6 +478,7 @@ public void setFrameworksPath(List<String> path) {
      *
      * This list may be freely modified by user code.
      */
+    @Nonnull
     public List<String> getFrameworksPath() {
         return frameworkspath;
     }
@@ -447,6 +487,7 @@ public List<String> getFrameworksPath() {
      * Returns the Map of Macros parsed during the run of this
      * Preprocessor.
      */
+    @Nonnull
     public Map<String, Macro> getMacros() {
         return macros;
     }
@@ -457,6 +498,7 @@ public Map<String, Macro> getMacros() {
      * While you can modify the returned object, unexpected things
      * might happen if you do.
      */
+    @CheckForNull
     public Macro getMacro(String name) {
         return macros.get(name);
     }
@@ -765,8 +807,8 @@ private boolean macro(Macro m, Token orig)
                 }
 
                 /*
-                 for (Argument a : args)
-                 a.expand(this);
+                 * for (Argument a : args)
+                 * a.expand(this);
                  */
                 for (int i = 0; i < args.size(); i++) {
                     args.get(i).expand(this);
@@ -783,12 +825,14 @@ private boolean macro(Macro m, Token orig)
             args = null;
         }
 
+        macroExpansion(m, orig, false);
+
         if (m == __LINE__) {
             push_source(new FixedTokenSource(
                     new Token[]{new Token(NUMBER,
                                 orig.getLine(), orig.getColumn(),
-                                String.valueOf(orig.getLine()),
-                                new NumericValue(10, "" + orig.getLine()))}
+                                Integer.toString(orig.getLine()),
+                                new NumericValue(10, Integer.toString(orig.getLine())))}
             ), true);
         } else if (m == __FILE__) {
             StringBuilder buf = new StringBuilder("\"");
@@ -823,11 +867,11 @@ private boolean macro(Macro m, Token orig)
             push_source(new FixedTokenSource(
                     new Token[]{new Token(NUMBER,
                                 orig.getLine(), orig.getColumn(),
-                                String.valueOf(value),
-                                new NumericValue(10, "" + value))}
+                                Integer.toString(value),
+                                new NumericValue(10, Integer.toString(value)))}
             ), true);
         } else {
-            push_source(new MacroTokenSource(m, args), true);
+            push_source(new MacroTokenSource(m, args, orig), true);
         }
 
         return true;
@@ -875,10 +919,11 @@ private boolean macro(Macro m, Token orig)
     }
 
     /* processes a #define directive */
-    private Token define()
+    private Token define(@Nonnull PreprocessorDirective preprocessorDirective)
             throws IOException,
             LexerException {
         Token tok = source_token_nonwhite();
+        preprocessorDirective.addToken(tok);
         if (tok.getType() != IDENTIFIER) {
             error(tok, "Expected identifier");
             return source_skipline(false);
@@ -891,12 +936,14 @@ private Token define()
             return source_skipline(false);
         }
 
-        Macro m = new Macro(getSource(), name);
+        Macro m = new Macro(getSource(), name, tok.getLine(), tok.getColumn());
         List<String> args;
 
         tok = source_token();
         if (tok.getType() == '(') {
+            preprocessorDirective.addToken(tok);
             tok = source_token_nonwhite();
+            preprocessorDirective.addToken(tok);
             if (tok.getType() != ')') {
                 args = new ArrayList<String>();
                 ARGS:
@@ -924,6 +971,7 @@ private Token define()
                             return source_skipline(false);
                     }
                     tok = source_token_nonwhite();
+                    preprocessorDirective.addToken(tok);
                     switch (tok.getType()) {
                         case ',':
                             break;
@@ -950,6 +998,7 @@ private Token define()
                             return source_skipline(false);
                     }
                     tok = source_token_nonwhite();
+                    preprocessorDirective.addToken(tok);
                 }
             } else {
                 assert tok.getType() == ')' : "Expected ')'";
@@ -970,6 +1019,7 @@ private Token define()
 
         /* Ensure no space at start. */
         tok = source_token_nonwhite();
+        preprocessorDirective.addToken(tok);
         EXPANSION:
         for (;;) {
             switch (tok.getType()) {
@@ -1039,8 +1089,11 @@ private Token define()
                     break;
             }
             tok = source_token();
+            preprocessorDirective.addToken(tok);
         }
 
+        directive(preprocessorDirective);
+
         if (getFeature(Feature.DEBUG))
             System.err.println("Defined macro " + m);
         addMacro(m);
@@ -1050,21 +1103,23 @@ private Token define()
     }
 
     @Nonnull
-    private Token undef()
+    private Token undef(@Nonnull PreprocessorDirective preprocessorDirective)
             throws IOException,
             LexerException {
         Token tok = source_token_nonwhite();
+        preprocessorDirective.addToken(tok);
         if (tok.getType() != IDENTIFIER) {
             error(tok,
                     "Expected identifier, not " + tok.getText());
             if (tok.getType() == NL || tok.getType() == EOF)
                 return tok;
         } else {
-            Macro m = macros.get(tok.getText());
+            Macro m = getMacro(tok.getText());
             if (m != null) {
                 /* XXX error if predefined */
                 macros.remove(m.getName());
             }
+            directive(preprocessorDirective);
         }
         return source_skipline(true);
     }
@@ -1075,12 +1130,22 @@ private Token undef()
      * User code may override this method to implement a virtual
      * file system.
      */
-    protected boolean include(@Nonnull VirtualFile file)
+    protected boolean include(@Nonnull VirtualFile file, int line)
             throws IOException,
             LexerException {
         // System.out.println("Try to include " + ((File)file).getAbsolutePath());
         if (!file.isFile())
             return false;
+        if (listener != null) {
+            if (getFeature(Feature.DEBUG))
+                System.out.println("Trying to include " + file.getPath());
+            if (listener.beforeInclude(file.getPath(), line)) {
+                // push_source() omitted
+                if (getFeature(Feature.DEBUG))
+                    System.err.println("pp: skipping " + file);
+                return true;
+            }
+        }
         if (getFeature(Feature.DEBUG))
             System.err.println("pp: including " + file);
         push_source(file.getSource(), true);
@@ -1090,12 +1155,12 @@ protected boolean include(@Nonnull VirtualFile file)
     /**
      * Includes a file from an include path, by name.
      */
-    protected boolean include(@Nonnull Iterable<String> path, @Nonnull String name)
+    protected boolean include(@Nonnull Iterable<String> path, @Nonnull String name, int line)
             throws IOException,
             LexerException {
         for (String dir : path) {
             VirtualFile file = filesystem.getFile(dir, name);
-            if (include(file))
+            if (include(file, line))
                 return true;
         }
         return false;
@@ -1117,14 +1182,14 @@ private void include(
             }
             if (pdir != null) {
                 VirtualFile ifile = pdir.getChildFile(name);
-                if (include(ifile))
+                if (include(ifile, line))
                     return;
             }
-            if (include(quoteincludepath, name))
+            if (include(quoteincludepath, name, line))
                 return;
         }
 
-        if (include(sysincludepath, name))
+        if (include(sysincludepath, name, line))
             return;
 
         StringBuilder buf = new StringBuilder();
@@ -1141,13 +1206,14 @@ private void include(
     }
 
     @Nonnull
-    private Token include(boolean next)
+    private Token include(boolean next, @Nonnull PreprocessorDirective preprocessorDirective)
             throws IOException,
             LexerException {
         LexerSource lexer = (LexerSource) source;
         try {
             lexer.setInclude(true);
             Token tok = token_nonwhite();
+            preprocessorDirective.addToken(tok);
 
             String name;
             boolean quoted;
@@ -1159,6 +1225,7 @@ private Token include(boolean next)
                 HEADER:
                 for (;;) {
                     tok = token_nonwhite();
+                    preprocessorDirective.addToken(tok);
                     switch (tok.getType()) {
                         case STRING:
                             buf.append((String) tok.getValue());
@@ -1190,7 +1257,7 @@ private Token include(boolean next)
                         return source_skipline(false);
                 }
             }
-
+            directive(preprocessorDirective);
             /* Do the inclusion. */
             include(source.getPath(), tok.getLine(), name, quoted, next);
 
@@ -1228,7 +1295,7 @@ protected void pragma(@Nonnull Token name, @Nonnull List<Token> value)
     }
 
     @Nonnull
-    private Token pragma()
+    private Token pragma(@Nonnull PreprocessorDirective preprocessorDirective)
             throws IOException,
             LexerException {
         Token name;
@@ -1236,6 +1303,7 @@ private Token pragma()
         NAME:
         for (;;) {
             Token tok = token();
+            preprocessorDirective.addToken(tok);
             switch (tok.getType()) {
                 case EOF:
                     /* There ought to be a newline before EOF.
@@ -1266,6 +1334,7 @@ private Token pragma()
         VALUE:
         for (;;) {
             tok = token();
+            preprocessorDirective.addToken(tok);
             switch (tok.getType()) {
                 case EOF:
                     /* There ought to be a newline before EOF.
@@ -1289,6 +1358,7 @@ private Token pragma()
             }
         }
 
+        directive(preprocessorDirective);
         pragma(name, value);
 
         return tok;	/* The NL. */
@@ -1296,13 +1366,14 @@ private Token pragma()
     }
 
     /* For #error and #warning. */
-    private void error(@Nonnull Token pptok, boolean is_error)
+    private void error(@Nonnull Token pptok, boolean is_error, @Nonnull PreprocessorDirective preprocessorDirective)
             throws IOException,
             LexerException {
         StringBuilder buf = new StringBuilder();
         buf.append('#').append(pptok.getText()).append(' ');
         /* Peculiar construction to ditch first whitespace. */
         Token tok = source_token_nonwhite();
+        preprocessorDirective.addToken(tok);
         ERROR:
         for (;;) {
             switch (tok.getType()) {
@@ -1314,11 +1385,14 @@ private void error(@Nonnull Token pptok, boolean is_error)
                     break;
             }
             tok = source_token();
+            preprocessorDirective.addToken(tok);
         }
         if (is_error)
             error(pptok, buf.toString());
         else
             warning(pptok, buf.toString());
+
+        directive(preprocessorDirective);
     }
 
     /* This bypasses token() for #elif expressions.
@@ -1332,7 +1406,7 @@ private Token expanded_token()
             Token tok = source_token();
             // System.out.println("Source token is " + tok);
             if (tok.getType() == IDENTIFIER) {
-                Macro m = macros.get(tok.getText());
+                Macro m = getMacro(tok.getText());
                 if (m == null)
                     return tok;
                 if (source.isExpanding(m))
@@ -1474,9 +1548,9 @@ private long expr(int priority)
             throws IOException,
             LexerException {
         /*
-         System.out.flush();
-         (new Exception("expr(" + priority + ") called")).printStackTrace();
-         System.err.flush();
+         * System.out.flush();
+         * (new Exception("expr(" + priority + ") called")).printStackTrace();
+         * System.err.flush();
          */
 
         Token tok = expr_token();
@@ -1615,9 +1689,9 @@ private long expr(int priority)
         }
 
         /*
-         System.out.flush();
-         (new Exception("expr returning " + lhs)).printStackTrace();
-         System.err.flush();
+         * System.out.flush();
+         * (new Exception("expr returning " + lhs)).printStackTrace();
+         * System.err.flush();
          */
         // System.out.println("expr returning " + lhs);
         return lhs;
@@ -1675,6 +1749,9 @@ private Token _token()
                     source.setActive(false);
                     tok = source_token();
                 } finally {
+                    if (source == null) {
+                        throw new LexerException("Requested a token with a null Source");
+                    }
                     /* XXX Tell lexer to stop ignoring warnings. */
                     source.setActive(true);
                 }
@@ -1783,7 +1860,7 @@ private Token _token()
                     return tok;
 
                 case IDENTIFIER:
-                    Macro m = macros.get(tok.getText());
+                    Macro m = getMacro(tok.getText());
                     if (m == null)
                         return tok;
                     if (source.isExpanding(m))
@@ -1807,7 +1884,10 @@ private Token _token()
                 // break;
 
                 case HASH:
+                    PreprocessorDirective preprocessorDirective = new PreprocessorDirective();
+                    preprocessorDirective.addToken(tok);
                     tok = source_token_nonwhite();
+                    preprocessorDirective.addToken(tok);
                     // (new Exception("here")).printStackTrace();
                     switch (tok.getType()) {
                         case NL:
@@ -1828,6 +1908,7 @@ private Token _token()
                                 + tok.getText());
                         return source_skipline(false);
                     }
+                    preprocessorDirective.setCommand(ppcmd);
 
                     PP:
                     switch (ppcmd) {
@@ -1836,21 +1917,21 @@ private Token _token()
                             if (!isActive())
                                 return source_skipline(false);
                             else
-                                return define();
+                                return define(preprocessorDirective);
                         // break;
 
                         case PP_UNDEF:
                             if (!isActive())
                                 return source_skipline(false);
                             else
-                                return undef();
+                                return undef(preprocessorDirective);
                         // break;
 
                         case PP_INCLUDE:
                             if (!isActive())
                                 return source_skipline(false);
                             else
-                                return include(false);
+                                return include(false, preprocessorDirective);
                         // break;
                         case PP_INCLUDE_NEXT:
                             if (!isActive())
@@ -1861,7 +1942,7 @@ private Token _token()
                                 );
                                 return source_skipline(false);
                             }
-                            return include(true);
+                            return include(true, preprocessorDirective);
                         // break;
 
                         case PP_WARNING:
@@ -1869,7 +1950,7 @@ private Token _token()
                             if (!isActive())
                                 return source_skipline(false);
                             else
-                                error(tok, ppcmd == PP_ERROR);
+                                error(tok, ppcmd == PP_ERROR, preprocessorDirective);
                             break;
 
                         case PP_IF:
@@ -1880,6 +1961,9 @@ private Token _token()
                             expr_token = null;
                             states.peek().setActive(expr(0) != 0);
                             tok = expr_token();	/* unget */
+                            if (!states.peek().isActive())
+                                preprocessorDirective.setInactiveBlock();
+                            directive(preprocessorDirective);
 
                             if (tok.getType() == NL)
                                 return tok;
@@ -1899,6 +1983,8 @@ private Token _token()
                                 return source_skipline(false);
                             } else if (state.isActive()) {
                                 /* The 'if' part got executed. */
+                                preprocessorDirective.setInactiveBlock();
+                                directive(preprocessorDirective);
                                 state.setParentActive(false);
                                 /* This is like # else # if but with
                                  * only one # end. */
@@ -1907,6 +1993,9 @@ private Token _token()
                             } else {
                                 expr_token = null;
                                 state.setActive(expr(0) != 0);
+                                if (!state.isActive())
+                                    preprocessorDirective.setInactiveBlock();
+                                directive(preprocessorDirective);
                                 tok = expr_token();	/* unget */
 
                                 if (tok.getType() == NL)
@@ -1917,14 +2006,18 @@ private Token _token()
 
                         case PP_ELSE:
                             state = states.peek();
-                            if (false)
-								/* Check for 'if' */ ; else if (state.sawElse()) {
+                            if (false) {
+								/* Check for 'if' */ ;
+                            } else if (state.sawElse()) {
                                 error(tok,
                                         "#" + "else after #" + "else");
                                 return source_skipline(false);
                             } else {
                                 state.setSawElse();
                                 state.setActive(!state.isActive());
+                                if (!state.isActive())
+                                    preprocessorDirective.setInactiveBlock();
+                                directive(preprocessorDirective);
                                 return source_skipline(warnings.contains(Warning.ENDIF_LABELS));
                             }
                         // break;
@@ -1940,12 +2033,17 @@ private Token _token()
                                     error(tok,
                                             "Expected identifier, not "
                                             + tok.getText());
+                                    directive(preprocessorDirective);
                                     return source_skipline(false);
                                 } else {
+                                    preprocessorDirective.addToken(tok);
                                     String text = tok.getText();
                                     boolean exists
                                             = macros.containsKey(text);
                                     states.peek().setActive(exists);
+                                    if (!exists)
+                                        preprocessorDirective.setInactiveBlock();
+                                    directive(preprocessorDirective);
                                     return source_skipline(true);
                                 }
                             }
@@ -1961,12 +2059,17 @@ private Token _token()
                                     error(tok,
                                             "Expected identifier, not "
                                             + tok.getText());
+                                    directive(preprocessorDirective);
                                     return source_skipline(false);
                                 } else {
+                                    preprocessorDirective.addToken(tok);
                                     String text = tok.getText();
                                     boolean exists
                                             = macros.containsKey(text);
                                     states.peek().setActive(!exists);
+                                    if (exists)
+                                        preprocessorDirective.setInactiveBlock();
+                                    directive(preprocessorDirective);
                                     return source_skipline(true);
                                 }
                             }
@@ -1974,17 +2077,19 @@ private Token _token()
 
                         case PP_ENDIF:
                             pop_state();
+                            directive(preprocessorDirective);
                             return source_skipline(warnings.contains(Warning.ENDIF_LABELS));
                         // break;
 
                         case PP_LINE:
+                            directive(preprocessorDirective);
                             return source_skipline(false);
                         // break;
 
                         case PP_PRAGMA:
                             if (!isActive())
                                 return source_skipline(false);
-                            return pragma();
+                            return pragma(preprocessorDirective);
                         // break;
 
                         default:
@@ -2050,7 +2155,7 @@ public String toString() {
         Iterator<String> mt = keys.iterator();
         while (mt.hasNext()) {
             String key = mt.next();
-            Macro macro = macros.get(key);
+            Macro macro = getMacro(key);
             buf.append("#").append("macro ").append(macro).append("\n");
         }
 
diff --git a/src/main/java/org/anarres/cpp/PreprocessorDirective.java b/src/main/java/org/anarres/cpp/PreprocessorDirective.java
new file mode 100644
index 0000000..1bb0dea
--- /dev/null
+++ b/src/main/java/org/anarres/cpp/PreprocessorDirective.java
@@ -0,0 +1,57 @@
+package org.anarres.cpp;
+
+import javax.annotation.Nonnull;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents all the tokens that form a single preprocessor directive.
+ * Additionally informs if the block after
+ */
+public class PreprocessorDirective {
+    private final List<Token> directiveTokens = new ArrayList<>();
+    private boolean activeBlock = true;
+    private PreprocessorCommand command;
+
+    public PreprocessorDirective() {
+    }
+
+    public  void addToken(@Nonnull Token token) {
+        directiveTokens.add(token);
+    }
+
+    public void setCommand(PreprocessorCommand cmd) {
+        this.command = cmd;
+    }
+
+    public PreprocessorCommand getCommand() {
+        return this.command;
+    }
+
+    @Nonnull
+    public List<Token> getTokenList() { return this.directiveTokens; }
+
+    public boolean isActiveBlock() {
+        return this.activeBlock;
+    }
+
+    public void setInactiveBlock() {
+        this.activeBlock = false;
+    }
+
+    @Override
+    public String toString() {
+        String result = new String();
+        if (!activeBlock)
+            result += "inactive block ";
+        for (Token tok : directiveTokens) {
+            if (tok.getType() == Token.NL) {
+                result += " \\n";
+            } else {
+                result += " " + tok.getText();
+            }
+        }
+        return result;
+    }
+}
diff --git a/src/main/java/org/anarres/cpp/PreprocessorListener.java b/src/main/java/org/anarres/cpp/PreprocessorListener.java
index a5b4339..cf2757b 100644
--- a/src/main/java/org/anarres/cpp/PreprocessorListener.java
+++ b/src/main/java/org/anarres/cpp/PreprocessorListener.java
@@ -23,31 +23,7 @@
  * error and warning events will throw an exception. Installing a
  * listener allows more intelligent handling of these events.
  */
-public class PreprocessorListener {
-
-    private int errors;
-    private int warnings;
-
-    public PreprocessorListener() {
-        clear();
-    }
-
-    public void clear() {
-        errors = 0;
-        warnings = 0;
-    }
-
-    public int getErrors() {
-        return errors;
-    }
-
-    public int getWarnings() {
-        return warnings;
-    }
-
-    protected void print(String msg) {
-        System.err.println(msg);
-    }
+public interface PreprocessorListener {
 
     /**
      * Handles a warning.
@@ -58,11 +34,7 @@ protected void print(String msg) {
      */
     public void handleWarning(Source source, int line, int column,
             String msg)
-            throws LexerException {
-        warnings++;
-        print(source.getName() + ":" + line + ":" + column
-                + ": warning: " + msg);
-    }
+            throws LexerException;
 
     /**
      * Handles an error.
@@ -73,13 +45,30 @@ public void handleWarning(Source source, int line, int column,
      */
     public void handleError(Source source, int line, int column,
             String msg)
-            throws LexerException {
-        errors++;
-        print(source.getName() + ":" + line + ":" + column
-                + ": error: " + msg);
-    }
+            throws LexerException;
+
+    public void handleSourceChange(Source source, String event);
 
-    public void handleSourceChange(Source source, String event) {
-    }
+    /**
+     * Called when preprocessor is about to include file.
+     *
+     * @param filePath file path
+     * @param line     line of include directive
+     * @return <code>true</code> if specified file should be skipped,
+     * <code>false</code> otherwise
+     */
+    public boolean beforeInclude(String filePath, int line);
+
+    public void handlePreprocesorDirective(Source source, PreprocessorDirective directive);
+
+    /**
+     * @param definitionFileName Can be null in certain cases.
+     * @param definitionLine <code>Macro.UNKNOWN_POSITION_VALUE</code> if it is
+     *                       unknown, otherwise proper value
+     * @param definitionColumn <code>Macro.UNKNOWN_POSITION_VALUE</code> if it
+     *                         is unknown, otherwise proper value
+     */
+    public void handleMacroExpansion(Source source, int line, int column, String macro,
+            String definitionFileName, int definitionLine, int definitionColumn);
 
 }
diff --git a/src/main/java/org/anarres/cpp/Source.java b/src/main/java/org/anarres/cpp/Source.java
index ef20803..e6df101 100644
--- a/src/main/java/org/anarres/cpp/Source.java
+++ b/src/main/java/org/anarres/cpp/Source.java
@@ -20,6 +20,7 @@
 import java.io.IOException;
 import java.util.Iterator;
 import javax.annotation.CheckForNull;
+import javax.annotation.Nonnegative;
 import javax.annotation.Nonnull;
 import static org.anarres.cpp.Token.*;
 
@@ -129,7 +130,7 @@ public void setListener(PreprocessorListener pl) {
      * If no Source on the stack is a FileLexerSource, returns null.
      */
     @CheckForNull
-    /* pp */ String getPath() {
+    public String getPath() {
         Source parent = getParent();
         if (parent != null)
             return parent.getPath();
@@ -139,7 +140,8 @@ public void setListener(PreprocessorListener pl) {
     /**
      * Returns the human-readable name of the current Source.
      */
-    /* pp */ String getName() {
+    @CheckForNull
+    public String getName() {
         Source parent = getParent();
         if (parent != null)
             return parent.getName();
@@ -149,6 +151,7 @@ public void setListener(PreprocessorListener pl) {
     /**
      * Returns the current line number within this Source.
      */
+    @Nonnegative
     public int getLine() {
         Source parent = getParent();
         if (parent == null)
@@ -166,6 +169,42 @@ public int getColumn() {
         return parent.getColumn();
     }
 
+    /**
+     * @return Source object that represents the root of the macro expansion
+     *         if it is currently in progress. If no macro expansion is
+     *         currently in progress, returns null.
+     */
+    MacroTokenSource getExpandingRoot() {
+        final Source parent = getParent();
+        if (parent == null) {
+            return null;
+        }
+        return parent.getExpandingRoot();
+    }
+
+    /**
+     * @return Token with a macro identifier in the source code (not from
+     *         a macro definition) that caused appearance of this source.
+     *         If no macro is currently being expanded, null is returned.
+     */
+    final Token getExpandingRootToken() {
+        final MacroTokenSource expandingRoot = getExpandingRoot();
+        if (expandingRoot != null) {
+            return expandingRoot.getOriginalToken();
+        }
+        return null;
+    }
+
+    /***
+     * Returns true if this Source is expanding any macro.
+     */
+    boolean isExpanding() {
+        Source parent = getParent();
+        if (parent != null)
+            return parent.isExpanding();
+        return false;
+    }
+
     /**
      * Returns true if this Source is expanding the given macro.
      *
diff --git a/src/main/java/org/anarres/cpp/Token.java b/src/main/java/org/anarres/cpp/Token.java
index 3e6eb3e..5cdf229 100644
--- a/src/main/java/org/anarres/cpp/Token.java
+++ b/src/main/java/org/anarres/cpp/Token.java
@@ -21,22 +21,46 @@
  *
  * @see Preprocessor
  */
-public final class Token {
+public final class Token implements Cloneable {
 
     // public static final int	EOF        = -1;
     private final int type;
+    private final int expected_type;
     private int line;
     private int column;
     private final Object value;
     private final String text;
+    /**
+     * Indicates that token comes from macro expansion.
+     */
+    private boolean isExpanded;
+    /**
+     * Token that this one replaced (because of a macro expansion).
+     * It can be null.
+     */
+    private Token originalMacroToken;
+    /**
+     * True if and only if the token comes from a macro argument stringizing,
+     * e.g. as the result of use of a macro defined as follows:
+     *    #define STRINGIZE(x) #x
+     */
+    private boolean isStringized;
 
-    public Token(int type, int line, int column,
+    public Token(int type, int expected, int line, int column,
             String text, Object value) {
         this.type = type;
+        this.expected_type = expected;
         this.line = line;
         this.column = column;
         this.text = text;
         this.value = value;
+        this.isExpanded = false;
+        this.isStringized = false;
+    }
+
+    public Token(int type, int line, int column,
+                 String text, Object value) {
+        this(type, -1, line, column, text, value);
     }
 
     public Token(int type, int line, int column, String text) {
@@ -47,14 +71,26 @@ public Token(int type, int line, int column, String text) {
         this(type, -1, -1, text, value);
     }
 
+    Token(int type, int expected, String text, Object value) {
+        this(type, expected, -1, -1, text, value);
+    }
+
     /* pp */ Token(int type, String text) {
         this(type, text, null);
     }
 
+    Token(int type, int expected, String text) {
+        this(type, expected, text, null);
+    }
+
     /* pp */ Token(int type) {
         this(type, TokenType.getTokenText(type));
     }
 
+    Token(int type, int expected) {
+        this(type, expected, TokenType.getTokenText(type));
+    }
+
     /**
      * Returns the semantic type of this token.
      */
@@ -62,6 +98,13 @@ public int getType() {
         return type;
     }
 
+    /**
+     * If the token type is INVALID returns the expected type of this token.
+     */
+    public int getExpectedType() {
+        return expected_type;
+    }
+
     /* pp */ void setLocation(int line, int column) {
         this.line = line;
         this.column = column;
@@ -109,6 +152,65 @@ public Object getValue() {
         return value;
     }
 
+    /**
+     * Returns if token comes from macro expansion.
+     *
+     * @return <code>true</code> when macro comes from macro expansion
+     */
+    public boolean isExpanded() {
+        return isExpanded;
+    }
+
+    /**
+     * @return True if and only if the token comes from a use of operator '#'
+     *         in a macro definition.
+     */
+    public boolean isStringized() {
+        return isStringized;
+    }
+
+    /**
+     * @return Token that has been replaced by this one (and possibly some other
+     *         ones) because of macro expansion. It can be null even if a macro
+     *         expansion has happened.
+     *         If it is not null, it is never a token from a macro definition.
+     */
+    public Token getOriginalMacroToken() {
+        return originalMacroToken;
+    }
+
+    /* pp */ void setExpanded(boolean isExpanded) {
+        this.isExpanded = isExpanded;
+    }
+
+    /**
+     * Sets the <code>isStringized</code> flag to the given value.
+     *
+     * @param isStringized Value of the <code>isStringized</code> flag to set.
+     */
+    void setStringized(boolean isStringized) {
+        this.isStringized = isStringized;
+    }
+
+    /**
+     * Unconditionally sets the original macro token of this object to the given
+     * one.
+     *
+     * @param originalMacroToken Original macro token of this object. It can be null.
+     */
+    void setOriginalMacroToken(Token originalMacroToken) {
+        this.originalMacroToken = originalMacroToken;
+    }
+
+    /**
+     * @return Shallow copy of this token (all references in the returned object
+     *         are the same as in this one).
+     */
+    @Override
+    public Object clone() throws CloneNotSupportedException {
+        return super.clone();
+    }
+
     /**
      * Returns a description of this token, for debugging purposes.
      */
@@ -122,6 +224,8 @@ public String toString() {
             if (column != -1)
                 buf.append(',').append(column);
         }
+        if (isExpanded)
+            buf.append("(expanded)");
         buf.append("]:");
         if (text != null)
             buf.append('"').append(text).append('"');
diff --git a/src/test/java/org/anarres/cpp/ErrorTest.java b/src/test/java/org/anarres/cpp/ErrorTest.java
index 8777452..42240d4 100644
--- a/src/test/java/org/anarres/cpp/ErrorTest.java
+++ b/src/test/java/org/anarres/cpp/ErrorTest.java
@@ -22,7 +22,7 @@ private boolean testError(Preprocessor p)
 
     private void testError(String input) throws Exception {
         StringLexerSource sl;
-        PreprocessorListener pl;
+        DefaultPreprocessorListener pl;
         Preprocessor p;
 
         /* Without a PreprocessorListener, throws an exception. */
@@ -42,7 +42,7 @@ private void testError(String input) throws Exception {
         p = new Preprocessor();
         p.addFeature(Feature.CSYNTAX);
         p.addInput(sl);
-        pl = new PreprocessorListener();
+        pl = new DefaultPreprocessorListener();
         p.setListener(pl);
         assertNotNull("CPP has listener", p.getListener());
         assertTrue(testError(p));
diff --git a/src/test/java/org/anarres/cpp/IsExpandedFlagTest.java b/src/test/java/org/anarres/cpp/IsExpandedFlagTest.java
new file mode 100644
index 0000000..292e422
--- /dev/null
+++ b/src/test/java/org/anarres/cpp/IsExpandedFlagTest.java
@@ -0,0 +1,128 @@
+package org.anarres.cpp;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Grzegorz Kołakowski <gk291583@students.mimuw.edu.pl>
+ */
+public class IsExpandedFlagTest {
+
+    private Preprocessor preprocessor;
+
+    @Before
+    public void setUp() throws Exception {
+        preprocessor = new Preprocessor();
+    }
+
+    @Test
+    public void testSimpleExpansion() throws Exception {
+        final List<Token> tokens = getTokens("is_expanded_flag/simple_expansion.c");
+        System.out.println(tokens);
+
+        assertEquals(10, tokens.size());
+
+        for (int i = 0; i < 10; ++i) {
+            assertEquals(tokens.get(i).toString(), i == 7, tokens.get(i).isExpanded());
+        }
+    }
+
+    @Test
+    public void testPredefinedMacroExpansion() throws Exception {
+        preprocessor.addMacro("PREDEFINED", "123");
+        final List<Token> tokens = getTokens("is_expanded_flag/predefined_macro_expansion.c");
+        System.out.println(tokens);
+
+        assertEquals(9, tokens.size());
+
+        for (int i = 0; i < 9; ++i) {
+            assertEquals(tokens.get(i).toString(), i == 6, tokens.get(i).isExpanded());
+        }
+    }
+
+    @Test
+    public void testExpansionWithArgs() throws Exception {
+        final List<Token> tokens = getTokens("is_expanded_flag/expansion_with_args.c");
+        System.out.println(tokens);
+
+        assertEquals(26, tokens.size());
+
+        for (Token token : tokens) {
+            switch (token.getType()) {
+                case ':':
+                case '?':
+                case '>':
+                    assertTrue(token.toString(), token.isExpanded());
+                    break;
+                case Token.WHITESPACE:
+                case Token.NL:
+                case Token.EOF:
+                    // ignore whitespaces, eof
+                    break;
+                default:
+                    assertFalse(token.toString(), token.isExpanded());
+                    break;
+            }
+        }
+    }
+
+    @Test
+    public void testNestedExpansion() throws Exception {
+        final List<Token> tokens = getTokens("is_expanded_flag/nested_expansion.c");
+        System.out.println(tokens);
+
+        assertEquals(32, tokens.size());
+
+        for (Token token : tokens) {
+            final String text = token.getText();
+            switch (token.getType()) {
+                case '%':
+                case Token.EQ:
+                case Token.LAND:
+                    assertTrue(token.toString(), token.isExpanded());
+                    break;
+                case Token.WHITESPACE:
+                case Token.NL:
+                case Token.EOF:
+                    // ignore whitespaces, eof
+                    break;
+                case Token.NUMBER:
+                    if ("0".equals(text)) {
+                        assertTrue(token.toString(), token.isExpanded());
+                    } else if ("3423".equals(text)) {
+                        assertFalse(token.toString(), token.isExpanded());
+                    }
+                    break;
+                default:
+                    assertFalse(token.toString(), token.isExpanded());
+                    break;
+            }
+        }
+    }
+
+    private List<Token> getTokens(String resourcePath) throws IOException, LexerException {
+        final List<Token> result = new ArrayList<>();
+        final String filePath = Thread.currentThread()
+                .getContextClassLoader()
+                .getResource(resourcePath)
+                .getFile();
+        preprocessor.addInput(new File(filePath));
+
+        Token token = preprocessor.token();
+        while (token.getType() != Token.EOF) {
+            result.add(token);
+            token = preprocessor.token();
+        }
+        return result;
+    }
+
+}
diff --git a/src/test/java/org/anarres/cpp/LexerSourceTest.java b/src/test/java/org/anarres/cpp/LexerSourceTest.java
index f51b253..db90b31 100644
--- a/src/test/java/org/anarres/cpp/LexerSourceTest.java
+++ b/src/test/java/org/anarres/cpp/LexerSourceTest.java
@@ -70,6 +70,7 @@ public void testLexerSource()
         testLexerSource("/**/", true, CCOMMENT);
         testLexerSource("/* /**/ */", true, CCOMMENT, WHITESPACE, '*', '/');
         testLexerSource("/** ** **/", true, CCOMMENT);
+        testLexerSource("/*", true, INVALID);
         testLexerSource("//* ** **/", true, CPPCOMMENT);
         testLexerSource("'\\r' '\\xf' '\\xff' 'x' 'aa' ''", true,
                 CHARACTER, WHITESPACE,
@@ -98,5 +99,6 @@ public void testNumbers() throws Exception {
         testLexerSource("1e6", true, NUMBER);
         testLexerSource("1.45e6", true, NUMBER);
         testLexerSource(".45e6", true, NUMBER);
+        testLexerSource("-6", true, '-', NUMBER);
     }
 }
diff --git a/src/test/java/org/anarres/cpp/NumericValueTest.java b/src/test/java/org/anarres/cpp/NumericValueTest.java
new file mode 100644
index 0000000..5668452
--- /dev/null
+++ b/src/test/java/org/anarres/cpp/NumericValueTest.java
@@ -0,0 +1,97 @@
+package org.anarres.cpp;
+
+import java.io.IOException;
+import org.junit.Test;
+import static org.anarres.cpp.Token.*;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author shevek
+ */
+public class NumericValueTest {
+
+    private Token testNumericValue(String in) throws IOException, LexerException {
+        StringLexerSource s = new StringLexerSource(in);
+
+        Token tok = s.token();
+        System.out.println("Token is " + tok);
+        assertEquals(NUMBER, tok.getType());
+
+        Token eof = s.token();
+        assertEquals("Didn't get EOF, but " + tok, EOF, eof.getType());
+
+        return tok;
+    }
+
+    private void testNumericValue(String in, double out) throws IOException, LexerException {
+        System.out.println("Testing '" + in + "' -> " + out);
+        Token tok = testNumericValue(in);
+        assertEquals(in, tok.getText());
+        NumericValue value = (NumericValue) tok.getValue();
+        assertEquals("Double mismatch", out, value.doubleValue(), 0.01d);
+        assertEquals("Float mismatch", (float) out, value.floatValue(), 0.01f);
+        assertEquals("Long mismatch", (long) out, value.longValue());
+        assertEquals("Integer mismatch", (int) out, value.intValue());
+    }
+
+    @Test
+    public void testNumericValue() throws Exception {
+
+        // Zero
+        testNumericValue("0", 0);
+
+        // Decimal
+        testNumericValue("1", 1);
+        testNumericValue("1L", 1);
+        testNumericValue("12", 12);
+        testNumericValue("12L", 12);
+
+        // Hex
+        testNumericValue("0xf", 0xf);
+        testNumericValue("0xfL", 0xf);
+        testNumericValue("0x12", 0x12);
+        testNumericValue("0x12L", 0x12);
+
+        // Negative
+        // testNumericValue("-0", 0);
+        // testNumericValue("-1", -1);
+
+        // Negative hex
+        // testNumericValue("-0x56", -0x56);
+        // testNumericValue("-0x102", -0x102);
+
+        // Octal and negative octal
+        testNumericValue("0673", Integer.parseInt("673", 8));
+        // testNumericValue("-0673", Integer.parseInt("-673", 8));
+
+        // Floating point
+        testNumericValue(".0", 0);
+        testNumericValue(".00", 0);
+        testNumericValue("0.", 0);
+        testNumericValue("0.0", 0);
+        testNumericValue("00.0", 0);
+        testNumericValue("00.", 0);
+
+        // Sign on exponents
+        testNumericValue("1e1", 1e1);
+        // testNumericValue("-1e1", -1e1);
+        testNumericValue("1e-1", 1e-1);
+
+        // Hex numbers with decimal exponents
+        testNumericValue("0x12e3", 0x12e3);
+        testNumericValue("0x12p3", 0x12p3);
+
+        // Octal numbers with decimal exponents
+        testNumericValue("012e3", 012e3);    // Fails
+        testNumericValue("067e4", 067e4);    // Fails
+
+        // Issues a warning.
+        try {
+            testNumericValue("097", 97);
+            fail("No warning.");
+        } catch (LexerException e) {
+        }
+
+    }
+}
diff --git a/src/test/resources/is_expanded_flag/expansion_with_args.c b/src/test/resources/is_expanded_flag/expansion_with_args.c
new file mode 100644
index 0000000..f479c35
--- /dev/null
+++ b/src/test/resources/is_expanded_flag/expansion_with_args.c
@@ -0,0 +1,3 @@
+#define MAX(a, b) a > b ? a : b
+
+int i = MAX(123, 321) + 1;
diff --git a/src/test/resources/is_expanded_flag/nested_expansion.c b/src/test/resources/is_expanded_flag/nested_expansion.c
new file mode 100644
index 0000000..526314c
--- /dev/null
+++ b/src/test/resources/is_expanded_flag/nested_expansion.c
@@ -0,0 +1,5 @@
+#define DIVISIBLE2(n) n % 2 == 0
+#define DIVISIBLE3(n) n % 3 == 0
+#define DIVISIBLE6(n) DIVISIBLE2(n) && DIVISIBLE3(n)
+
+bool isDivisible = DIVISIBLE6(3423);
diff --git a/src/test/resources/is_expanded_flag/predefined_macro_expansion.c b/src/test/resources/is_expanded_flag/predefined_macro_expansion.c
new file mode 100644
index 0000000..dc50d96
--- /dev/null
+++ b/src/test/resources/is_expanded_flag/predefined_macro_expansion.c
@@ -0,0 +1 @@
+int i = PREDEFINED;
diff --git a/src/test/resources/is_expanded_flag/simple_expansion.c b/src/test/resources/is_expanded_flag/simple_expansion.c
new file mode 100644
index 0000000..489ef3e
--- /dev/null
+++ b/src/test/resources/is_expanded_flag/simple_expansion.c
@@ -0,0 +1,3 @@
+#define ONE_HUNDRED 100
+
+int i = ONE_HUNDRED;