Merged rel/2 into default
M .classpath +70 -16
@@ 1,35 1,89 @@ 
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry including="**/*.java" kind="src" output="target/classes" path="src">
+	<classpathentry excluding="main/resources/" including="**/*.java" kind="src" output="target/classes" path="src">
 		<attributes>
 			<attribute name="optional" value="true"/>
-			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="maven.pomderived" value="false"/>
 		</attributes>
 	</classpathentry>
 	<classpathentry kind="src" output="target/test-classes" path="test">
 		<attributes>
 			<attribute name="optional" value="true"/>
-			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="maven.pomderived" value="false"/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="lib" path="target/dependency/spark-core-2.5.5.jar"/>
-	<classpathentry kind="lib" path="target/dependency/slf4j-simple-1.7.21.jar"/>
-	<classpathentry kind="lib" path="target/dependency/slf4j-api-1.7.21.jar"/>
+	<classpathentry kind="src" path="src/main/resources"/>
+	<classpathentry kind="lib" path="target/dependency/aws-java-sdk-core-1.11.192.jar"/>
+	<classpathentry kind="lib" path="target/dependency/aws-java-sdk-kms-1.11.192.jar"/>
+	<classpathentry kind="lib" path="target/dependency/aws-java-sdk-s3-1.11.192.jar"/>
+	<classpathentry kind="lib" path="target/dependency/backport-util-concurrent-3.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/classworlds-1.1-alpha-2.jar"/>
+	<classpathentry kind="lib" path="target/dependency/collections-generic-4.01.jar"/>
+	<classpathentry kind="lib" path="target/dependency/commons-beanutils-1.8.0.jar"/>
+	<classpathentry kind="lib" path="target/dependency/commons-codec-1.6.jar"/>
+	<classpathentry kind="lib" path="target/dependency/commons-collections-3.2.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/commons-exec-1.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/commons-io-2.5.jar"/>
+	<classpathentry kind="lib" path="target/dependency/commons-lang-2.5.jar"/>
+	<classpathentry kind="lib" path="target/dependency/commons-lang3-3.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/commons-logging-1.1.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/debian-maven-plugin-1.0.5.jar"/>
+	<classpathentry kind="lib" path="target/dependency/ezmorph-1.0.6.jar"/>
+	<classpathentry kind="lib" path="target/dependency/guava-21.0.jar"/>
+	<classpathentry kind="lib" path="target/dependency/hamcrest-core-1.3.jar"/>
+	<classpathentry kind="lib" path="target/dependency/httpclient-4.5.2.jar"/>
+	<classpathentry kind="lib" path="target/dependency/httpcore-4.4.4.jar"/>
+	<classpathentry kind="lib" path="target/dependency/ini4j-0.5.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/ion-java-1.0.2.jar"/>
+	<classpathentry kind="lib" path="target/dependency/jackson-annotations-2.6.0.jar"/>
+	<classpathentry kind="lib" path="target/dependency/jackson-core-2.6.7.jar"/>
+	<classpathentry kind="lib" path="target/dependency/jackson-databind-2.6.7.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/jackson-dataformat-cbor-2.6.7.jar"/>
+	<classpathentry kind="lib" path="target/dependency/javassist-3.21.0-GA.jar"/>
 	<classpathentry kind="lib" path="target/dependency/javax.servlet-api-3.1.0.jar"/>
-	<classpathentry kind="lib" path="target/dependency/jetty-server-9.3.6.v20151106.jar"/>
-	<classpathentry kind="lib" path="target/dependency/jetty-util-9.3.6.v20151106.jar"/>
 	<classpathentry kind="lib" path="target/dependency/jetty-http-9.3.6.v20151106.jar"/>
 	<classpathentry kind="lib" path="target/dependency/jetty-io-9.3.6.v20151106.jar"/>
-	<classpathentry kind="lib" path="target/dependency/websocket-server-9.3.6.v20151106.jar"/>
-	<classpathentry kind="lib" path="target/dependency/commons-io-2.5.jar"/>
+	<classpathentry kind="lib" path="target/dependency/jetty-security-9.3.6.v20151106.jar"/>
+	<classpathentry kind="lib" path="target/dependency/jetty-server-9.3.6.v20151106.jar"/>
+	<classpathentry kind="lib" path="target/dependency/jetty-servlet-9.3.6.v20151106.jar"/>
+	<classpathentry kind="lib" path="target/dependency/jetty-util-9.3.6.v20151106.jar"/>
+	<classpathentry kind="lib" path="target/dependency/jetty-webapp-9.3.6.v20151106.jar"/>
+	<classpathentry kind="lib" path="target/dependency/jetty-xml-9.3.6.v20151106.jar"/>
+	<classpathentry kind="lib" path="target/dependency/jmespath-java-1.11.192.jar"/>
+	<classpathentry kind="lib" path="target/dependency/joda-time-2.8.1.jar"/>
 	<classpathentry kind="lib" path="target/dependency/json-lib-2.4-jdk15.jar"/>
-	<classpathentry kind="lib" path="target/dependency/commons-lang-2.5.jar"/>
-	<classpathentry kind="lib" path="target/dependency/ezmorph-1.0.6.jar"/>
-	<classpathentry kind="lib" path="target/dependency/commons-collections-3.2.1.jar"/>
-	<classpathentry kind="lib" path="target/dependency/commons-beanutils-1.8.0.jar"/>
+	<classpathentry kind="lib" path="target/dependency/junit-4.11.jar"/>
+	<classpathentry kind="lib" path="target/dependency/log4j-api-2.8.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/log4j-core-2.8.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/maven-artifact-2.2.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/maven-artifact-manager-2.2.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/maven-model-2.2.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/maven-plugin-api-2.0.jar"/>
+	<classpathentry kind="lib" path="target/dependency/maven-plugin-registry-2.2.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/maven-profile-2.2.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/maven-project-2.2.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/maven-repository-metadata-2.2.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/maven-settings-2.2.1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/mysql-connector-java-5.1.6.jar"/>
+	<classpathentry kind="lib" path="target/dependency/plexus-container-default-1.0-alpha-9-stable-1.jar"/>
+	<classpathentry kind="lib" path="target/dependency/plexus-interpolation-1.11.jar"/>
+	<classpathentry kind="lib" path="target/dependency/plexus-utils-1.5.15.jar"/>
+	<classpathentry kind="lib" path="target/dependency/reflections-0.9.11.jar"/>
+	<classpathentry kind="lib" path="target/dependency/slf4j-api-1.7.21.jar"/>
+	<classpathentry kind="lib" path="target/dependency/slf4j-simple-1.7.21.jar"/>
+	<classpathentry kind="lib" path="target/dependency/spark-core-2.5.5.jar"/>
+	<classpathentry kind="lib" path="target/dependency/spring-aop-4.3.6.RELEASE.jar"/>
+	<classpathentry kind="lib" path="target/dependency/spring-beans-4.3.6.RELEASE.jar"/>
+	<classpathentry kind="lib" path="target/dependency/spring-context-4.3.6.RELEASE.jar"/>
+	<classpathentry kind="lib" path="target/dependency/spring-core-4.3.6.RELEASE.jar"/>
+	<classpathentry kind="lib" path="target/dependency/spring-expression-4.3.6.RELEASE.jar"/>
 	<classpathentry kind="lib" path="target/dependency/sqlite-jdbc-3.7.2.jar"/>
-	<classpathentry kind="lib" path="target/dependency/reflections-0.9.11.jar"/>
-	<classpathentry kind="lib" path="target/dependency/guava-21.0.jar"/>
+	<classpathentry kind="lib" path="target/dependency/wagon-provider-api-1.0-beta-6.jar"/>
+	<classpathentry kind="lib" path="target/dependency/websocket-api-9.3.6.v20151106.jar"/>
+	<classpathentry kind="lib" path="target/dependency/websocket-client-9.3.6.v20151106.jar"/>
+	<classpathentry kind="lib" path="target/dependency/websocket-common-9.3.6.v20151106.jar"/>
+	<classpathentry kind="lib" path="target/dependency/websocket-server-9.3.6.v20151106.jar"/>
+	<classpathentry kind="lib" path="target/dependency/websocket-servlet-9.3.6.v20151106.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
 	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
 		<attributes>

          
M .hgignore +1 -0
@@ 1,3 1,4 @@ 
 syntax: glob
 bin
 target
+src/main/resources/overhamj.ini

          
M .hgtags +1 -0
@@ 5,3 5,4 @@ c0c24679da5d95c2acaa16834f992fda3f7309b7
 5599cb9be9c7095f8cbe8198d24afc35d82b3df9 overhamj-2.0.3
 e74846bca1f47b75378c693964d6ccce4ec232a2 overhamj-2.0.4
 5285b3f9453ecb72805267854e511e26814e5fb4 overhamj-2.1.0
+1ee39494b7936b9fe96c689ace9b1cc78d99a778 overhamj-2.1.1

          
M .project +2 -2
@@ 11,13 11,13 @@ 
 			</arguments>
 		</buildCommand>
 		<buildCommand>
-			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
 			<arguments>
 			</arguments>
 		</buildCommand>
 	</buildSpec>
 	<natures>
-		<nature>org.eclipse.m2e.core.maven2Nature</nature>
 		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
 	</natures>
 </projectDescription>

          
M bitbucket-pipelines.yml +3 -6
@@ 1,12 1,9 @@ 
-# This is a sample build configuration for Maven.
 # Check our guides at https://confluence.atlassian.com/x/VYk8Lw for more examples.
 # Only use spaces to indent your .yml configuration.
-# -----
-# You can specify a custom docker image from Docker Hub as your build environment.
-image: maven:3.3.3
 
+image: java:8
 pipelines:
   default:
     - step:
-        script: # Modify the commands below to build your repository.
-          - mvn -q clean install
+        script:
+          - bash ./gradlew build

          
A => build.gradle +168 -0
@@ 0,0 1,168 @@ 
+apply plugin: 'java'
+apply plugin: 'maven'
+apply plugin: 'eclipse'
+
+// Coverage reporting: https://github.com/bmuschko/gradle-clover-plugin
+apply plugin: 'com.bmuschko.clover'
+
+group = 'org.overchat.overham'
+version = '2.1.1'
+
+description = """overhamj"""
+
+sourceCompatibility = 1.8
+targetCompatibility = 1.8
+
+repositories {
+	maven { url "http://repo.maven.apache.org/maven2" }
+}
+
+sourceSets {
+	main {
+		java {
+			srcDir "${project.projectDir}/src/org/overchat"
+		}
+	}
+
+	test {
+		java {
+			srcDir "${project.projectDir}/test/org/overchat"
+		}
+
+		resources {
+			srcDir "${project.projectDir}/test/main/resources"
+		}
+	}
+}
+
+buildscript {
+	repositories {
+		jcenter()
+	}
+
+	dependencies {
+		classpath 'com.bmuschko:gradle-clover-plugin:2.1.2'
+	}
+}
+
+// In this section you declare where to find the dependencies of your project
+repositories {
+	// Use jcenter for resolving your dependencies.
+	jcenter()
+
+	// We'll use Maven but not the default, we might as well use the UK mirror.
+	maven {
+		url 'http://uk.maven.org/maven2'
+	}
+}
+
+dependencies {
+	compile group: 'org.slf4j', name: 'slf4j-simple', version:'1.7.21'
+	compile group: 'org.springframework', name: 'spring-context', version:'4.3.6.RELEASE'
+	compile group: 'com.amazonaws', name: 'aws-java-sdk-s3', version:'1.11.192'
+	compile group: 'org.ini4j', name: 'ini4j', version:'0.5.1'
+	compile group: 'commons-io', name: 'commons-io', version:'2.5'
+	compile group: 'org.xerial', name: 'sqlite-jdbc', version:'3.7.2'
+	compile group: 'net.sf.debian-maven', name: 'debian-maven-plugin', version:'1.0.5'
+	compile group: 'net.sf.json-lib', name: 'json-lib', version:'2.4', classifier:'jdk15'
+	compile group: 'com.sparkjava', name: 'spark-core', version:'2.5.5'
+	compile group: 'org.reflections', name: 'reflections', version:'0.9.11'
+	compile group: 'com.google.guava', name: 'guava', version:'21.0'
+	compile group: 'mysql', name: 'mysql-connector-java', version:'5.1.18'
+
+	runtime group: 'org.slf4j', name: 'slf4j-simple', version:'1.7.21'
+	runtime group: 'org.springframework', name: 'spring-context', version:'4.3.6.RELEASE'
+	runtime group: 'com.amazonaws', name: 'aws-java-sdk-s3', version:'1.11.192'
+	runtime group: 'org.ini4j', name: 'ini4j', version:'0.5.1'
+	runtime group: 'commons-io', name: 'commons-io', version:'2.5'
+	runtime group: 'org.xerial', name: 'sqlite-jdbc', version:'3.7.2'
+	runtime group: 'net.sf.debian-maven', name: 'debian-maven-plugin', version:'1.0.5'
+	runtime group: 'net.sf.json-lib', name: 'json-lib', version:'2.4', classifier:'jdk15'
+	runtime group: 'com.sparkjava', name: 'spark-core', version:'2.5.5'
+	runtime group: 'org.reflections', name: 'reflections', version:'0.9.11'
+	runtime group: 'com.google.guava', name: 'guava', version:'21.0'
+	runtime group: 'mysql', name: 'mysql-connector-java', version:'5.1.18'
+
+	// Use JUnit test framework
+	testImplementation 'junit:junit:4.12'
+	testCompile group: 'junit', name: 'junit', version:'4.11'
+
+	clover 'org.openclover:clover:4.2.0'
+}
+
+task junitTest(type: Test) {
+	maxParallelForks 4
+
+	reports {
+		junitXml {
+			enabled = true
+			destination = file("${project.projectDir}/reports")
+		}
+
+		html {
+			enabled = true
+			destination = file("${project.projectDir}/reports")
+		}
+	}
+
+	// This test should run on demand, in case of intermittent errors.
+	outputs.upToDateWhen { false }
+}
+
+/*
+ * Note that this report won't get you a coverage report, on local machines run:
+ * ./gradlew cloverGenerateReport
+ */
+test { // Extend the test to point to our custom settings
+	dependsOn junitTest
+}
+
+// When gradlew is called via the debian/rules, we need to know which version is required.
+task wrapper(type: Wrapper) {
+        gradleVersion = '4.0.2'
+}
+
+// Our deb contains not just our own jar, but all of the libs we depend on at runtime, in a lib/ subdirectory.
+// This is called from the jar task
+task copyToLib(type: Copy) {
+	into "$buildDir/output/lib"
+	from configurations.default
+}
+
+// Extend the jar task and add additional dependencies.
+jar {
+	// When we build the jar, also copy in api dependencies
+	dependsOn copyToLib
+
+	manifest {
+		attributes(
+			'Main-Class': 'org.overchat.overham.Main',
+			'Class-Path': '/etc/overham/ ' + configurations.runtime.files.collect { '/usr/lib/overham/' + it.name }.join(' ')
+		)
+	}
+
+	// Make a well known name for the application jar
+	doLast {
+		exec {
+			commandLine "ln", "-sf", "${rootProject.name}-${version}.jar", "${buildDir}/libs/${rootProject.name}.jar"
+		}
+	}
+}
+
+// Settings for the Clover coverage report -- not a task; See cloverGenerateReport
+clover {
+	def env = System.getenv()
+	def useClover = env['CLOVER']
+	useClover = (useClover != null && useClover == '1') ? true : false
+
+	enabled = useClover
+
+	report {
+		html = true
+		xml  = true
+
+		// Support capturing test results from JUnix XML report
+		testResultsInclude = 'TEST-*.xml'
+		testResultsDir = project.tasks.getByName('junitTest').reports.junitXml.destination
+	}
+}

          
M debian/changelog +33 -0
@@ 1,3 1,36 @@ 
+overhamj (2.1.1) stable; urgency=low
+
+  * Headline changes:
+  * Merged Gradle support
+  * Resolved issues with config file packaging as part of Gradle migration
+  * Main page had wrong MIME type and visitors saw HTML! Sorry about that!
+  * Ranges no longer necessary for search criteria
+
+  * The following is an abridged changelog of important differences from 2.1.0:
+  * d9475f068896: Sack off pom.xml (Maven)
+  * 055055f84c4f: Trying to access config without absolute path
+  * 9d88cf338953: Use absolute path to ini
+  * 3eec7ced6816: Update mysql-connector-java to 5.1.18
+  * 5aa3b40e39c9: Added &autoReconnect=true (HamDatabase)
+  * 9b6e1b1270d8: Write makeConnectionString to dump connection string
+  * f5ab4d314d7a: Don't install dummy config
+  * 35844a6be45a: Move redacted config under test hierarchy
+  * 46a8b2c49957: Try to fix the bitbucket pipeline
+  * ac4a34463910: Implement bad range detection on 'when' to search
+  * 0d21cc113234: Added missing classpathentry to .classpath (Eclipse) for AWS and init4j
+  * b81bbae667c4: Migrate to org.eclipse.buildship.core.gradleprojectbuilder
+  * 6f077787e07b: Attempt to remove test which triggers a bug
+  * e64e14744e29: Refresh dependencies for Eclipse
+  * 3913aa7e779d: FIXME about integer has been addressed
+  * 11d1cd858202: Fix src/main/resources/ in Eclipse.
+  * 146f4b9e2c9b: Handle situation where recording is missing from the bucket
+  * 0c170be9c4d4: Debug the SQL
+  * 418c4a06d2f9: Handle single values for hzFreq
+  * 8312eb6adca4: Support single agument when
+  * 7c5f184a30bc: Fix index wrong MIME type
+
+ -- Duncan Ross Palmer <palmer@overchat.org>  Sun, 08 Oct 2017 16:20:21 +0100
+
 overhamj (2.1.0) stable; urgency=low
 
   * 294b356fd859: Merged in f/201705-qcode-dump (pull request #16)

          
M debian/control +1 -0
@@ 8,6 8,7 @@ Build-Depends: debhelper (>= 9),
  javahelper,
  cdbs,
  sqlite3,
+ maven-repo-helper,
 Standards-Version: 3.7.3
 Homepage: https://www.facebook.com/groups/overham/
 

          
M debian/install +2 -2
@@ 1,2 1,2 @@ 
-target/*.jar usr/bin/
-target/dependency/*.jar usr/lib/overham/
+build/libs/*.jar usr/bin
+build/output/lib/*.jar usr/lib/overham

          
M debian/rules +31 -6
@@ 1,11 1,36 @@ 
 #!/usr/bin/make -f
-
-include /usr/share/cdbs/1/rules/debhelper.mk
-include /usr/share/cdbs/1/class/javahelper.mk
+# TODO: On Debian Stretch, we may be able to use the following construct
+#%:
+#	dh $@ --buildsystem=gradle
 
 export DH_VERBOSE=0
 export JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:/bin/javac::")
 
-%:
-	$(SHELL) scripts/make-databases.sh
-	mvn -q clean install -Dmaven.repo.local=/tmp/.m2
+include /usr/share/cdbs/1/rules/debhelper.mk
+
+binary:
+	export GRADLE_USER_HOME=$(CURDIR); \
+	echo "Using $$GRADLE_USER_HOME for home directory during gradlew execution" && \
+	$(SHELL) ./gradlew jar
+
+install:
+	export GRADLE_USER_HOME=$(CURDIR); \
+	echo "Using $$GRADLE_USER_HOME for home directory during gradlew execution" && \
+	$(SHELL) ./gradlew assemble
+
+override_dh_clean:
+	export GRADLE_USER_HOME=$(CURDIR); \
+	echo "Using $$GRADLE_USER_HOME for home directory during gradlew execution" && \
+	$(SHELL) ./gradlew clean
+
+build: build-arch build-indep
+
+build-arch:
+	@echo Nothing to do
+
+build-indep:
+	export GRADLE_USER_HOME=$(CURDIR); \
+	echo "Using $$GRADLE_USER_HOME for home directory during gradlew execution" && \
+	$(SHELL) ./gradlew build test cloverGenerateReport
+
+.PHONY: binary install override_dh_clean build build-arch build-indep

          
A => gradle/wrapper/gradle-wrapper.properties +6 -0
@@ 0,0 1,6 @@ 
+#Sun Oct 01 21:03:27 BST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.0.2-bin.zip

          
A => gradlew +172 -0
@@ 0,0 1,172 @@ 
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# 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\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# 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
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+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" -a "$nonstop" = "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"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # 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
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"

          
A => gradlew.bat +84 -0
@@ 0,0 1,84 @@ 
+@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
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@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=
+
+@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 Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_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=%*
+
+: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

          
R pom.xml =>  +0 -155
@@ 1,155 0,0 @@ 
-<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.overchat.overham</groupId>
-	<artifactId>overhamj</artifactId>
-	<packaging>jar</packaging>
-	<version>2.1.0</version>
-	<name>overhamj</name>
-	<url>http://maven.apache.org</url>
-	<dependencies>
-		<dependency>
-			<groupId>junit</groupId>
-			<artifactId>junit</artifactId>
-			<version>4.11</version>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.slf4j</groupId>
-			<artifactId>slf4j-simple</artifactId>
-			<version>1.7.21</version>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework</groupId>
-			<artifactId>spring-context</artifactId>
-			<version>4.3.6.RELEASE</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3 -->
-		<dependency>
-			<groupId>com.amazonaws</groupId>
-			<artifactId>aws-java-sdk-s3</artifactId>
-			<version>1.11.192</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/org.ini4j/ini4j -->
-		<dependency>
-			<groupId>org.ini4j</groupId>
-			<artifactId>ini4j</artifactId>
-			<version>0.5.1</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
-		<dependency>
-			<groupId>commons-io</groupId>
-			<artifactId>commons-io</artifactId>
-			<version>2.5</version>
-		</dependency>
-		<dependency>
-			<groupId>org.xerial</groupId>
-			<artifactId>sqlite-jdbc</artifactId>
-			<version>3.7.2</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/net.sf.debian-maven/debian-maven-plugin -->
-		<dependency>
-			<groupId>net.sf.debian-maven</groupId>
-			<artifactId>debian-maven-plugin</artifactId>
-			<version>1.0.5</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/net.sf.json-lib/json-lib -->
-		<dependency>
-			<groupId>net.sf.json-lib</groupId>
-			<artifactId>json-lib</artifactId>
-			<version>2.4</version>
-			<classifier>jdk15</classifier>
-		</dependency>
-		<dependency>
-			<groupId>com.sparkjava</groupId>
-			<artifactId>spark-core</artifactId>
-			<version>2.5.5</version>
-		</dependency>
-		<dependency>
-			<groupId>org.reflections</groupId>
-			<artifactId>reflections</artifactId>
-			<version>0.9.11</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
-		<dependency>
-			<groupId>com.google.guava</groupId>
-			<artifactId>guava</artifactId>
-			<version>21.0</version>
-		</dependency>
-		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
-		<dependency>
-			<groupId>mysql</groupId>
-			<artifactId>mysql-connector-java</artifactId>
-			<version>5.1.6</version>
-		</dependency>
-	</dependencies>
-	<build>
-		<sourceDirectory>src</sourceDirectory>
-		<testSourceDirectory>test</testSourceDirectory>
-		<plugins>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-resources-plugin</artifactId>
-				<version>3.0.2</version>
-			</plugin>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-compiler-plugin</artifactId>
-				<version>3.6.1</version>
-				<configuration>
-					<source>1.8</source>
-					<target>1.8</target>
-				</configuration>
-			</plugin>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-jar-plugin</artifactId>
-				<version>2.4</version>
-				<configuration>
-					<archive>
-						<manifest>
-							<classpathPrefix>/usr/lib/overham</classpathPrefix>
-							<addClasspath>true</addClasspath>
-							<mainClass>org.overchat.overham.Main</mainClass>
-						</manifest>
-					</archive>
-				</configuration>
-			</plugin>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-dependency-plugin</artifactId>
-				<version>2.4</version>
-				<executions>
-					<execution>
-						<id>copy-dependencies</id>
-						<phase>package</phase>
-						<goals><goal>copy-dependencies</goal></goals>
-					</execution>
-				</executions>
-			</plugin>
-			<plugin>
-				<groupId>net.sf.debian-maven</groupId>
-				<artifactId>debian-maven-plugin</artifactId>
-				<version>2.1.0</version>
-				<configuration>
-					<options>
-						<version>2.1.0</version>
-						<maintainer>${env.DEBFULLNAME} &lt;${env.DEBEMAIL}&gt;</maintainer>
-						<homepage>https://www.facebook.com/groups/overham/</homepage>
-						<description>Amateur Radio Library</description>
-						<installDir>/usr/bin/overham</installDir>
-						<targetDir>build</targetDir>
-						<files>*.jar ../config/setup.ini </files>
-						<architecture>amd64</architecture>
-					</options>
-					<dependencyOverrides>
-						<dependencyOverride>
-							<name>org.hibernate.hibernate.*</name>
-							<value>hibernate_1.99-1.1</value>
-						</dependencyOverride>
-					</dependencyOverrides>
-				</configuration>
-			</plugin>
-		</plugins>
-	</build>
-</project>

          
A => settings.gradle +1 -0
@@ 0,0 1,1 @@ 
+rootProject.name = 'overhamj'

          
M src/org/overchat/overham/Server.java +1 -1
@@ 79,7 79,7 @@ public class Server {
 		Thread.currentThread().setContextClassLoader(classLoader);
 		this.startTime = java.lang.System.currentTimeMillis();
 		this.config = new Configuration();
-		this.s3Client = new AmazonS3Client(new ProfileCredentialsProvider("src/main/resources/overhamj.ini", "s3"));
+		this.s3Client = new AmazonS3Client(new ProfileCredentialsProvider("/etc/overham/overhamj.ini", "s3"));
 		this.hamDatabase = new HamDatabase(config);
 	}
 

          
M src/org/overchat/overham/db/HamDatabase.java +20 -7
@@ 107,18 107,30 @@ public class HamDatabase {
 		if (null == this.dynamicConnection) {
 			Section section = config.getSection("db");
 
-			this.dynamicConnection = DriverManager.getConnection(String.format(
-				"jdbc:mysql://%s/%s?user=%s&password=%s",
-				section.get("host"),
-				section.get("name"),
-				section.get("user"),
-				section.get("password")
-			));
+			this.makeConnectionString(section, false); // Log a redacted connection string
+			final String realConnectionString = this.makeConnectionString(section, true);
+			this.dynamicConnection = DriverManager.getConnection(realConnectionString);
 		}
 
 		return this.dynamicConnection;
 	}
 
+	private final String makeConnectionString(Section section, final Boolean real) {
+		final String connectionString = String.format(
+			"jdbc:mysql://%s/%s?user=%s&password=%s&autoReconnect=true",
+			section.get("host"),
+			section.get("name"),
+			section.get("user"),
+			((real) ? (section.get("password")) : ("<REDACTED>"))
+		);
+
+		if (!real) {
+			java.lang.System.out.println(connectionString);
+		}
+
+		return connectionString;
+	}
+
 	/**
 	 * Warning! This is public for now, but direct queries will be
 	 * withdrawn in a later version, meaning you will need to subclass

          
@@ 135,6 147,7 @@ public class HamDatabase {
 		do {
 			try {
 				if (statement == null) {
+					java.lang.System.out.println(query);
 					if (dynamic) {
 						statement = this.connectDynamic().prepareStatement(query);
 					} else {

          
M src/org/overchat/overham/module/Base.java +2 -1
@@ 45,6 45,7 @@ import java.util.UUID;
 
 import org.overchat.overham.Response;
 import org.overchat.overham.Server;
+import org.overchat.overham.module.CallStyle;
 
 import net.sf.json.JSONObject;
 

          
@@ 144,7 145,7 @@ public abstract class Base {
 
 	protected void registerUserMethod(final String methodName, final String mimeType, final CallStyle callStyle) {
 		final String defaultMimeType = "application/json";
-		this.userMethodMap.put(methodName, null);
+		this.userMethodMap.put(methodName, 0);
 		this.userMethodMimeMap.put(methodName, mimeType == null ? defaultMimeType : mimeType);
 		this.userMethodCallStyleMap.put(methodName, callStyle);
 	}

          
M src/org/overchat/overham/modules/Index.java +1 -1
@@ 102,7 102,7 @@ public class Index extends Base implemen
 	public void init(Server server) {
 		super.init(server);
 		this.registerUserMethod("routes", null, CallStyle.LEGACY);
-		this.registerUserMethod("", null, CallStyle.LEGACY); // Special entry for '/index' itself
+		this.registerUserMethod("", "text/html", CallStyle.LEGACY); // Special entry for '/index' itself
 	}
 
 	private String readIndex() {

          
M src/org/overchat/overham/modules/Recordings.java +58 -31
@@ 49,6 49,7 @@ import org.overchat.overham.module.ExitC
 import org.overchat.overham.module.ReturnData;
 import org.overchat.overham.module.interfaces.Module;
 
+import com.amazonaws.services.s3.model.AmazonS3Exception;
 import com.amazonaws.services.s3.model.GetObjectRequest;
 import com.amazonaws.services.s3.model.S3Object;
 import com.amazonaws.services.s3.model.S3ObjectInputStream;

          
@@ 123,9 124,14 @@ public class Recordings extends Base imp
 					return new ReturnData(null, null, new HTTPStatus(501, ExitCodes.TRY_LATER));
 				} else {
 					final String bucketName = "19ece944-89d6-11e7-a14b-a413fd9bf184";
+					S3Object s3Object;
 
 					java.lang.System.out.println("Fetching recording \"" + id + "\"");
-					S3Object s3Object = this.owner.getS3Client().getObject(new GetObjectRequest(bucketName, id));
+					try {
+						s3Object = this.owner.getS3Client().getObject(new GetObjectRequest(bucketName, id));
+					} catch (AmazonS3Exception e) {
+						return new ReturnData(null, null, new HTTPStatus(e.getStatusCode(), ExitCodes.NOT_FOUND));
+					}
 					java.lang.System.out.println(s3Object);
 					objectStream = s3Object.getObjectContent();
 

          
@@ 205,7 211,6 @@ public class Recordings extends Base imp
 		return new ReturnData(output);
 	}
 
-	// FIXME: Need to ensure all criteria are integer, for security
 	public ReturnData userSearch(JSONObject output, Map<String, String> methodParams) {
 		List<String> implemented = new ArrayList<String>(2);
 		List<Object> boundParams = new ArrayList<Object>();

          
@@ 230,28 235,34 @@ public class Recordings extends Base imp
 
 		if (hzFreq != null) { // Optional
 			int dashSep = hzFreq.indexOf("-");
-			if (dashSep == -1) { // Oops, you didn't put a hyphen for the frequency lower-upper
-				return new ReturnData(
-					this.buildErrorForUser(output, ExitCodes.MALFORMED_ARGUMENT),
-					new HTTPStatus(400, ExitCodes.MALFORMED_ARGUMENT)
-				);
-			}
-			String lowestStr = hzFreq.substring(0, dashSep);
-			String highestStr = hzFreq.substring(dashSep + 1, hzFreq.length());
+			String lowestStr;
+			Integer lowest;
+
+			if (dashSep == -1) { // You didn't put a hyphen for the frequency lower-upper, must a specific frequency
+				lowestStr = hzFreq;
+
+				lowest = Integer.valueOf(lowestStr);
+
+				q.append("hzFreq = ? ");
+				boundParams.add(lowest);
+			} else {
+				lowestStr = hzFreq.substring(0, dashSep);
+				String highestStr = hzFreq.substring(dashSep + 1, hzFreq.length());
 
-			Integer lowest = Integer.valueOf(lowestStr);
-			Integer highest = Integer.valueOf(highestStr);
+				lowest = Integer.valueOf(lowestStr);
+				Integer highest = Integer.valueOf(highestStr);
 
-			if (highest < lowest) {
-				return new ReturnData(
-					this.buildErrorForUser(output, ExitCodes.RANGE),
-					new HTTPStatus(400, ExitCodes.RANGE)
-				);
+				if (highest < lowest) {
+					return new ReturnData(
+						this.buildErrorForUser(output, ExitCodes.RANGE),
+						new HTTPStatus(400, ExitCodes.RANGE)
+					);
+				}
+
+				q.append("hzFreq BETWEEN ? AND ? ");
+				boundParams.add(lowest);
+				boundParams.add(highest);
 			}
-
-			q.append("hzFreq BETWEEN ? AND ? ");
-			boundParams.add(lowest);
-			boundParams.add(highest);
 		}
 
 		if (boundParams.size() > 0) {

          
@@ 259,18 270,34 @@ public class Recordings extends Base imp
 		}
 
 		if (when != null) { // Optional
+			String earliestStr;
+			Integer earliest;
+
 			int dashSep = when.indexOf("-");
-			if (dashSep == -1) { // Oops
-				return new ReturnData(
-					this.buildErrorForUser(output, ExitCodes.MALFORMED_ARGUMENT),
-					new HTTPStatus(400, ExitCodes.MALFORMED_ARGUMENT)
-				);
+			if (dashSep == -1) { // No hyphen? Must not be a range but a specific time
+				earliestStr = when;
+				earliest = Integer.valueOf(earliestStr);
+
+				q.append("(UNIX_TIMESTAMP(whenStart) = ?) ");
+				boundParams.add(earliest);
+			} else {
+				earliestStr = when.substring(0, dashSep);
+				String latestStr = when.substring(dashSep + 1, when.length());
+
+				earliest = Integer.valueOf(earliestStr);
+				Integer latest = Integer.valueOf(latestStr);
+
+				if (latest < earliest) {
+					return new ReturnData(
+						this.buildErrorForUser(output, ExitCodes.RANGE),
+						new HTTPStatus(400, ExitCodes.RANGE)
+					);
+				}
+
+				q.append("(UNIX_TIMESTAMP(whenStart) >= ? AND UNIX_TIMESTAMP(whenStart) <= ?) ");
+				boundParams.add(earliest);
+				boundParams.add(latest);
 			}
-			String earliest = when.substring(0, dashSep);
-			String latest = when.substring(dashSep + 1, when.length());
-			q.append("(UNIX_TIMESTAMP(whenStart) >= ? AND UNIX_TIMESTAMP(whenStart) <= ?) ");
-			boundParams.add(earliest);
-			boundParams.add(latest);
 		}
 
 		q.append("ORDER BY whenStart LIMIT 1000");

          
A => test/main/resources/overhamj.ini +10 -0
@@ 0,0 1,10 @@ 
+
+[db]
+name=redacted
+host=redacted
+user=redacted
+password=redacted
+
+[s3]
+aws_access_key_id=redacted
+aws_secret_access_key=redacted

          
R test/org/overchat/overham/modules/QCodeTest.java =>  +0 -118
@@ 1,118 0,0 @@ 
-/*
- * OverHam; An object-orientated ham radio math and tool library
- * Copyright (c) 2015-2017, Duncan Ross Palmer (2E0EOL),
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *     * Redistributions of source code must retain the above copyright notice,
- *       this list of conditions and the following disclaimer.
- *
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *
- *     * Neither the name of the Daybo Logic nor the names of its contributors
- *       may be used to endorse or promote products derived from this software
- *       without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.overchat.overham.modules;
-
-import static org.junit.Assert.*;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.overchat.overham.modules.qcode.Authority;
-
-/**
- * @author duncan.palmer
- *
- */
-public class QCodeTest extends QCode {
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@BeforeClass
-	public static void setUpBeforeClass() throws Exception {
-	}
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@AfterClass
-	public static void tearDownAfterClass() throws Exception {
-	}
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testDetaintAndResolve() {
-		assertEquals("SL", detaintAndResolve("QSL")); // Typical
-		assertEquals("SL", detaintAndResolve("SL")); // Already done
-		assertEquals("SL", detaintAndResolve("qsl")); // Lowercase
-		assertEquals("SL", detaintAndResolve("sl")); // LC Already done
-		assertEquals("RX", detaintAndResolve("QrX")); // Mixed case
-		assertEquals("", detaintAndResolve(null)); // null abuse
-		assertEquals("", detaintAndResolve("")); // Empty string
-		assertEquals("", detaintAndResolve(" ")); // Spacing Guild
-		assertEquals("", detaintAndResolve("xxx")); // LC not Q
-		assertEquals("", detaintAndResolve("xxxx")); // LC Too long, not Q
-		assertEquals("", detaintAndResolve("XXX")); // Not Q
-		assertEquals("", detaintAndResolve("XXXX")); // Too long, not Q
-		assertEquals("", detaintAndResolve("QSLX")); // Too long
-		assertEquals("", detaintAndResolve("qslx")); // LC Too long
-	}
-
-	@Test
-	public void testFindCodeAuthority() {
-		assertEquals(Authority.ITU, findCodeAuthority("SL"));
-		assertEquals(Authority.ICAO, findCodeAuthority("NH"));
-		assertEquals(Authority.Unallocated, findCodeAuthority("VA"));
-		assertEquals(Authority.Unallocated, findCodeAuthority("ZZ"));
-		assertEquals(Authority.ITU, findCodeAuthority("RZ"));
-		assertEquals(Authority.ITU, findCodeAuthority("SB"));
-		assertEquals(Authority.ITU, findCodeAuthority("RM"));
-		assertEquals(Authority.Maritime, findCodeAuthority("OC"));
-		assertEquals(Authority.Maritime, findCodeAuthority("OK"));
-		assertEquals(Authority.Maritime, findCodeAuthority("OA"));
-		assertEquals(Authority.Maritime, findCodeAuthority("OI"));
-		assertEquals(Authority.ICAO, findCodeAuthority("KH"));
-		assertEquals(Authority.ICAO, findCodeAuthority("BF"));
-		assertNull(findCodeAuthority("XXX"));
-		assertNull(findCodeAuthority("X"));
-		assertNull(findCodeAuthority("oc"));
-		assertNull(findCodeAuthority(""));
-		assertNull(findCodeAuthority(null));
-	}
-
-}