YETUS-749. change findbugs to spotbugs

Signed-off-by: Allen Wittenauer <aw@apache.org>
diff --git a/Jenkinsfile b/Jenkinsfile
index f568cd3..2392586 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -148,7 +148,7 @@
                 YETUS_ARGS+=(--proclimit=2000)
 
                 # rsync these files back into the archive dir
-                YETUS_ARGS+=("--archive-list=checkstyle-errors.xml,findbugsXml.xml")
+                YETUS_ARGS+=("--archive-list=checkstyle-errors.xml,spotbugsXml.xml")
 
                 # URL for user-side presentation in reports and such to our artifacts
                 # (needs to match the archive bits below)
diff --git a/asf-site-src/source/documentation/in-progress/precommit-basic.md b/asf-site-src/source/documentation/in-progress/precommit-basic.md
index bf882ea..5a6522a 100644
--- a/asf-site-src/source/documentation/in-progress/precommit-basic.md
+++ b/asf-site-src/source/documentation/in-progress/precommit-basic.md
@@ -101,7 +101,9 @@
 * [Apache Creadur Rat](http://creadur.apache.org/rat/) entries in build system
 * [checkstyle](http://checkstyle.sourceforge.net/) entries in build system (ant and maven only)
 * [FindBugs](http://findbugs.sourceforge.net/) entries in build system and 3.x executables
-   (NOTE: FindBugs executables are required even if the build system is using [Spotbugs](https://spotbugs.github.io/))
+  - NOTE: only one of FindBugs or SpotBugs may be used at a time.
+* [SpotBugs](https://spotbugs.github.io/)) entries in build system and 3.x executables
+  - NOTE: only one of FindBugs or SpotBugs may be used at a time.
 * [jshint](https://jshint.com) installed
 * [hadolint](https://github.com/hadolint/hadolint) installed
 * [Perl::Critic](http://perlcritic.com/) installed
diff --git a/audience-annotations-component/audience-annotations/src/main/java/org/apache/yetus/audience/tools/StabilityOptions.java b/audience-annotations-component/audience-annotations/src/main/java/org/apache/yetus/audience/tools/StabilityOptions.java
index 8e7a93e..26c1459 100644
--- a/audience-annotations-component/audience-annotations/src/main/java/org/apache/yetus/audience/tools/StabilityOptions.java
+++ b/audience-annotations-component/audience-annotations/src/main/java/org/apache/yetus/audience/tools/StabilityOptions.java
@@ -50,6 +50,8 @@
         case STABLE_OPTION:
           RootDocProcessor.stability = STABLE_OPTION;
           break;
+        default:
+          break;
       }
     }
   }
diff --git a/pom.xml b/pom.xml
index 5bbf662..19f262f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -73,7 +73,7 @@
     <jython-shaded.version>2.7.1</jython-shaded.version>
     <maven-checkstyle-plugin.version>3.0.0</maven-checkstyle-plugin.version>
     <maven-project-info-reports-plugin.version>3.0.0</maven-project-info-reports-plugin.version>
-    <spotbugs-maven-plugin.version>3.1.7</spotbugs-maven-plugin.version>
+    <spotbugs-maven-plugin.version>3.1.11</spotbugs-maven-plugin.version>
 
      <sourceReleaseAssemblyDescriptor>source-release-tar</sourceReleaseAssemblyDescriptor>
 
diff --git a/precommit/src/main/shell/core.d/01-common.sh b/precommit/src/main/shell/core.d/01-common.sh
index d5e5c32..ffd1e67 100755
--- a/precommit/src/main/shell/core.d/01-common.sh
+++ b/precommit/src/main/shell/core.d/01-common.sh
@@ -317,12 +317,11 @@
   declare strip
   declare stridx
 
-  yetus_debug "Testing if $1 has been enabled by user"
+  yetus_debug "Testing if ${toadd} has been enabled by user"
 
   bar=""
   for idx in ${ENABLED_PLUGINS}; do
     stridx=${idx// }
-    yetus_debug "verify_plugin_enabled: processing ${stridx}"
     case ${stridx} in
       all)
         bar=${toadd}
@@ -343,7 +342,9 @@
   done
 
   if [[ -n ${bar} ]]; then
-    yetus_debug "Post-parsing: checking ${bar} = ${toadd}"
+    if [[ "${bar}" = "${toadd}" ]]; then
+      yetus_debug "Post-parsing: ${toadd} enabled"
+    fi
   fi
   [[ ${bar} = "${toadd}" ]]
 }
@@ -418,6 +419,22 @@
   yetus_del_array_element TESTTYPES "${1}"
 }
 
+## @description  Add the given test type
+## @audience     public
+## @stability    stable
+## @replaceable  yes
+## @param        plugin
+function replace_test_type
+{
+  if verify_plugin_enabled "${1}" && verify_plugin_enabled "${2}"; then
+    ENABLED_PLUGINS=${ENABLED_PLUGINS%$2}
+    delete_test_type "$2"
+    delete_test "$2"
+    return 0
+  fi
+  return 1
+}
+
 ## @description  Add the given bugsystem type
 ## @audience     public
 ## @stability    stable
@@ -536,6 +553,12 @@
     fi
   done
 
+  for i in "${TESTTYPES[@]}"; do
+    if declare -f "${i}_deprecate_test_type" >/dev/null; then
+      "${i}_deprecate_test_type"
+    fi
+  done
+
   if [[ ${ROBOT} == true ]]; then
     if declare -f "${ROBOTTYPE}"_set_plugin_defaults >/dev/null; then
       "${ROBOTTYPE}"_set_plugin_defaults
diff --git a/precommit/src/main/shell/it/it-tp.sh b/precommit/src/main/shell/it/it-tp.sh
index 0e275f4..149d708 100755
--- a/precommit/src/main/shell/it/it-tp.sh
+++ b/precommit/src/main/shell/it/it-tp.sh
@@ -58,7 +58,7 @@
 # our 'default' args, in (mostly) alphabetical order
 
 # rsync these files back into the archive dir
-YETUS_ARGS+=("--archive-list=checkstyle-errors.xml,findbugsXml.xml")
+YETUS_ARGS+=("--archive-list=checkstyle-errors.xml,spotbugsXml.xml")
 
 # where the source is located
 YETUS_ARGS+=("--basedir=${BASEDIR}")
diff --git a/precommit/src/main/shell/personality/bigtop.sh b/precommit/src/main/shell/personality/bigtop.sh
index 6e84416..0a423ab 100755
--- a/precommit/src/main/shell/personality/bigtop.sh
+++ b/precommit/src/main/shell/personality/bigtop.sh
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-personality_plugins "all,-checkstyle,-findbugs"
+personality_plugins "all,-checkstyle,-findbugs,-spotbugs"
 
 ## @description  Globals specific to this personality
 ## @audience     private
diff --git a/precommit/src/main/shell/personality/jmeter.sh b/precommit/src/main/shell/personality/jmeter.sh
index f2a6056..b4f524c 100755
--- a/precommit/src/main/shell/personality/jmeter.sh
+++ b/precommit/src/main/shell/personality/jmeter.sh
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-personality_plugins "all,-javadoc,-findbugs,-asflicense"
+personality_plugins "all,-javadoc,-findbugs,-asflicense,-spotbugs"
 
 ## @description  Globals specific to this personality
 ## @audience     private
diff --git a/precommit/src/main/shell/personality/orc.sh b/precommit/src/main/shell/personality/orc.sh
index 95868ba..6fb5796 100755
--- a/precommit/src/main/shell/personality/orc.sh
+++ b/precommit/src/main/shell/personality/orc.sh
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-personality_plugins "all,-checkstyle,-findbugs"
+personality_plugins "all,-checkstyle,-findbugs,-spotbugs"
 
 ## @description  Globals specific to this personality
 ## @audience     private
diff --git a/precommit/src/main/shell/test-patch-docker/Dockerfile b/precommit/src/main/shell/test-patch-docker/Dockerfile
index e8552fb..7fe612f 100644
--- a/precommit/src/main/shell/test-patch-docker/Dockerfile
+++ b/precommit/src/main/shell/test-patch-docker/Dockerfile
@@ -121,6 +121,18 @@
     && rm -rf /var/lib/apt/lists/*
 ENV FINDBUGS_HOME /usr
 
+#####
+# Install SpotBugs
+#####
+RUN curl -fsSL http://repo.maven.apache.org/maven2/com/github/spotbugs/spotbugs/3.1.12/spotbugs-3.1.12.tgz -o spotbugs.tgz \
+    && curl -fsSL http://repo.maven.apache.org/maven2/com/github/spotbugs/spotbugs/3.1.12/spotbugs-3.1.12.tgz.sha1 -o spotbugs.tgz.sha1 \
+    && echo -n "  spotbugs.tgz" >> spotbugs.tgz.sha1 \
+    && shasum -c spotbugs.tgz.sha1 \
+    && mkdir -p /opt/spotbugs \
+    && tar -C /opt/spotbugs --strip-components 1  -xpf spotbugs.tgz \
+    && rm spotbugs.tgz spotbugs.tgz.sha1
+ENV SPOTBUGS_HOME /opt/spotbugs
+
 ####
 # Install GNU C/C++
 ####
diff --git a/precommit/src/main/shell/test-patch.d/ant.sh b/precommit/src/main/shell/test-patch.d/ant.sh
index 31a5e66..7171d26 100755
--- a/precommit/src/main/shell/test-patch.d/ant.sh
+++ b/precommit/src/main/shell/test-patch.d/ant.sh
@@ -120,6 +120,9 @@
     javadoc)
       modules_workers "${repostatus}" javadoc clean javadoc
     ;;
+    spotbugs)
+      modules_workers "${repostatus}" spotbugs spotbugs
+    ;;
     unit)
       modules_workers "${repostatus}" unit
     ;;
@@ -209,6 +212,7 @@
   fi
 
   if [[ ${filename} =~ \.java$ ]]; then
+    add_test spotbugs
     add_test findbugs
   fi
 }
diff --git a/precommit/src/main/shell/test-patch.d/findbugs.sh b/precommit/src/main/shell/test-patch.d/findbugs.sh
deleted file mode 100755
index 606fb93..0000000
--- a/precommit/src/main/shell/test-patch.d/findbugs.sh
+++ /dev/null
@@ -1,463 +0,0 @@
-#!/usr/bin/env bash
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-# SHELLDOC-IGNORE
-
-FINDBUGS_HOME=${FINDBUGS_HOME:-}
-FINDBUGS_WARNINGS_FAIL_PRECHECK=false
-
-add_test_type findbugs
-
-function findbugs_usage
-{
-  yetus_add_option "--findbugs-home=<path>" "Findbugs home directory (default \${FINDBUGS_HOME})"
-  yetus_add_option "--findbugs-strict-precheck" "If there are Findbugs warnings during precheck, fail"
-}
-
-function findbugs_parse_args
-{
-  declare i
-
-  for i in "$@"; do
-    case ${i} in
-    --findbugs-home=*)
-      FINDBUGS_HOME=${i#*=}
-    ;;
-    --findbugs-strict-precheck)
-      FINDBUGS_WARNINGS_FAIL_PRECHECK=true
-    ;;
-    esac
-  done
-}
-
-## @description  initialize the findbugs plug-in
-## @audience     private
-## @stability    evolving
-## @replaceable  no
-function findbugs_initialize
-{
-  if declare -f maven_add_install >/dev/null 2>&1; then
-    maven_add_install findbugs
-  fi
-}
-
-function findbugs_filefilter
-{
-  declare filename=$1
-
-  if [[ ${BUILDTOOL} == maven
-    || ${BUILDTOOL} == ant ]]; then
-    if [[ ${filename} =~ \.java$
-      || ${filename} =~ (^|/)findbugs-exclude.xml$ ]]; then
-      add_test findbugs
-    fi
-  fi
-}
-
-function findbugs_precheck
-{
-  declare exec
-  declare status=0
-
-  if [[ -z ${FINDBUGS_HOME} ]]; then
-    yetus_error "FINDBUGS_HOME was not specified."
-    status=1
-  else
-    for exec in computeBugHistory \
-                convertXmlToText \
-                filterBugs \
-                setBugDatabaseInfo\
-                unionBugs; do
-      if ! verify_command "${exec}" "${FINDBUGS_HOME}/bin/${exec}"; then
-        status=1
-      fi
-    done
-  fi
-  if [[ ${status} == 1 ]]; then
-    add_vote_table 0 findbugs "Findbugs executables are not available."
-    delete_test findbugs
-  fi
-}
-
-## @description  Run the maven findbugs plugin and record found issues in a bug database
-## @audience     private
-## @stability    evolving
-## @replaceable  no
-## @return       0 on success
-## @return       1 on failure
-## @param        repostatus
-function findbugs_runner
-{
-  declare name=$1
-  declare module
-  declare result=0
-  declare fn
-  declare warnings_file
-  declare i=0
-  declare savestop
-  declare retval
-
-
-  personality_modules "${name}" findbugs
-
-  "${BUILDTOOL}_modules_worker" "${name}" findbugs
-
-  if [[ ${UNSUPPORTED_TEST} = true ]]; then
-    return 0
-  fi
-
-  #shellcheck disable=SC2153
-  until [[ ${i} -eq ${#MODULE[@]} ]]; do
-    if [[ ${MODULE_STATUS[${i}]} == -1 ]]; then
-      ((result=result+1))
-      ((i=i+1))
-      continue
-    fi
-    start_clock
-    offset_clock "${MODULE_STATUS_TIMER[${i}]}"
-    module="${MODULE[${i}]}"
-    fn=$(module_file_fragment "${module}")
-
-    if [[ "${module}" == . ]]; then
-      module=root
-    fi
-
-    case ${BUILDTOOL} in
-      maven)
-        targetfile="findbugsXml.xml"
-      ;;
-      ant)
-        targetfile="${ANT_FINDBUGSXML}"
-      ;;
-    esac
-
-    while read -r line; do
-      files+=("${line}")
-    done < <(find . -name "${targetfile}")
-
-    if [[ "${#files[@]}" -lt 1 ]]; then
-      module_status ${i} 0 "" "${name}/${module} no findbugs output file (${targetfile})"
-      ((i=i+1))
-      continue
-    fi
-
-    warnings_file="${PATCH_DIR}/${name}-findbugs-${fn}-warnings"
-
-    "${FINDBUGS_HOME}/bin/unionBugs" -withMessages -output "${warnings_file}.xml" "${files[@]}"
-
-    if [[ ${name} == branch ]]; then
-      "${FINDBUGS_HOME}/bin/setBugDatabaseInfo" -name "${PATCH_BRANCH}" \
-          "${warnings_file}.xml" "${warnings_file}.xml"
-      retval=$?
-    else
-      "${FINDBUGS_HOME}/bin/setBugDatabaseInfo" -name patch \
-          "${warnings_file}.xml" "${warnings_file}.xml"
-      retval=$?
-    fi
-
-    if [[ ${retval} != 0 ]]; then
-      savestop=$(stop_clock)
-      MODULE_STATUS_TIMER[${i}]=${savestop}
-      module_status ${i} -1 "" "${name}/${module} cannot run setBugDatabaseInfo from findbugs"
-      ((result=result+1))
-      ((i=i+1))
-      continue
-    fi
-
-    if ! "${FINDBUGS_HOME}/bin/convertXmlToText" -html \
-      "${warnings_file}.xml" \
-      "${warnings_file}.html"; then
-      savestop=$(stop_clock)
-      MODULE_STATUS_TIMER[${i}]=${savestop}
-      module_status ${i} -1 "" "${name}/${module} cannot run convertXmlToText from findbugs"
-      ((result=result+1))
-    fi
-
-    if [[ -z ${FINDBUGS_VERSION}
-        && ${name} == branch ]]; then
-      FINDBUGS_VERSION=$(${GREP} -i "BugCollection version=" "${warnings_file}.xml" \
-        | cut -f2 -d\" \
-        | cut -f1 -d\" )
-      if [[ -n ${FINDBUGS_VERSION} ]]; then
-        add_footer_table findbugs "v${FINDBUGS_VERSION}"
-      fi
-    fi
-
-    ((i=i+1))
-  done
-  return ${result}
-}
-
-## @description  Track pre-existing findbugs warnings
-## @audience     private
-## @stability    evolving
-## @replaceable  no
-## @return       0 on success
-## @return       1 on failure
-function findbugs_preapply
-{
-  declare fn
-  declare module
-  declare modindex=0
-  declare warnings_file
-  declare module_findbugs_warnings
-  declare result=0
-  declare msg
-
-  if ! verify_needed_test findbugs; then
-    return 0
-  fi
-
-  big_console_header "findbugs detection: ${PATCH_BRANCH}"
-
-  findbugs_runner branch
-  result=$?
-
-  if [[ ${UNSUPPORTED_TEST} = true ]]; then
-    return 0
-  fi
-
-  until [[ ${modindex} -eq ${#MODULE[@]} ]]; do
-    if [[ ${MODULE_STATUS[${modindex}]} == -1 ]]; then
-      ((result=result+1))
-      ((modindex=modindex+1))
-      continue
-    fi
-
-    module=${MODULE[${modindex}]}
-    start_clock
-    offset_clock "${MODULE_STATUS_TIMER[${modindex}]}"
-    fn=$(module_file_fragment "${module}")
-
-    if [[ "${module}" == . ]]; then
-      module=root
-    fi
-
-    warnings_file="${PATCH_DIR}/branch-findbugs-${fn}-warnings"
-    # shellcheck disable=SC2016
-    module_findbugs_warnings=$("${FINDBUGS_HOME}/bin/filterBugs" -first \
-        "${PATCH_BRANCH}" \
-        "${warnings_file}.xml" \
-        "${warnings_file}.xml" \
-        | ${AWK} '{print $1}')
-
-    if [[ ${module_findbugs_warnings} -gt 0 ]] ; then
-      msg="${module} in ${PATCH_BRANCH} has ${module_findbugs_warnings} extant Findbugs warnings."
-      if [[ "${FINDBUGS_WARNINGS_FAIL_PRECHECK}" = "true" ]]; then
-        module_status ${modindex} -1 "branch-findbugs-${fn}-warnings.html" "${msg}"
-        ((result=result+1))
-      elif [[ "${BUILDMODE}" = full ]]; then
-        module_status ${modindex} -1 "branch-findbugs-${fn}-warnings.html" "${msg}"
-        ((result=result+1))
-        populate_test_table FindBugs "module:${module}"
-        #shellcheck disable=SC2162
-        while read line; do
-          firstpart=$(echo "${line}" | cut -f2 -d:)
-          secondpart=$(echo "${line}" | cut -f9- -d' ')
-          add_test_table "" "${firstpart}:${secondpart}"
-        done < <("${FINDBUGS_HOME}/bin/convertXmlToText" "${warnings_file}.xml")
-      else
-        module_status ${modindex} 0 "branch-findbugs-${fn}-warnings.html" "${msg}"
-      fi
-    fi
-
-    savestop=$(stop_clock)
-    MODULE_STATUS_TIMER[${modindex}]=${savestop}
-    ((modindex=modindex+1))
-  done
-  modules_messages branch findbugs true
-
-  if [[ ${result} != 0 ]]; then
-    return 1
-  fi
-  return 0
-}
-
-## @description  Verify patch does not trigger any findbugs warnings
-## @audience     private
-## @stability    evolving
-## @replaceable  no
-## @return       0 on success
-## @return       1 on failure
-function findbugs_postinstall
-{
-  declare module
-  declare fn
-  declare combined_xml
-  declare branchxml
-  declare patchxml
-  declare newbugsbase
-  declare fixedbugsbase
-  declare branch_warnings
-  declare patch_warnings
-  declare fixed_warnings
-  declare line
-  declare firstpart
-  declare secondpart
-  declare i=0
-  declare result=0
-  declare savestop
-  declare summarize=true
-  declare statstring
-
-  if ! verify_needed_test findbugs; then
-    return 0
-  fi
-
-  big_console_header "findbugs detection: ${BUILDMODE}"
-
-  findbugs_runner patch
-
-  if [[ ${UNSUPPORTED_TEST} = true ]]; then
-    return 0
-  fi
-
-  until [[ $i -eq ${#MODULE[@]} ]]; do
-    if [[ ${MODULE_STATUS[${i}]} == -1 ]]; then
-      ((result=result+1))
-      ((i=i+1))
-      continue
-    fi
-
-    start_clock
-    offset_clock "${MODULE_STATUS_TIMER[${i}]}"
-    module="${MODULE[${i}]}"
-
-    buildtool_cwd "${i}"
-
-    fn=$(module_file_fragment "${module}")
-
-    if [[ "${module}" == . ]]; then
-      module=root
-    fi
-
-    combined_xml="${PATCH_DIR}/combined-findbugs-${fn}.xml"
-    branchxml="${PATCH_DIR}/branch-findbugs-${fn}-warnings.xml"
-    patchxml="${PATCH_DIR}/patch-findbugs-${fn}-warnings.xml"
-
-    if [[ -f "${branchxml}" ]]; then
-      # shellcheck disable=SC2016
-      branch_warnings=$("${FINDBUGS_HOME}/bin/filterBugs" -first \
-          "${PATCH_BRANCH}" \
-          "${branchxml}" \
-          "${branchxml}" \
-          | ${AWK} '{print $1}')
-    else
-      branchxml=${patchxml}
-    fi
-
-    newbugsbase="${PATCH_DIR}/new-findbugs-${fn}"
-    fixedbugsbase="${PATCH_DIR}/fixed-findbugs-${fn}"
-
-    if ! "${FINDBUGS_HOME}/bin/computeBugHistory" -useAnalysisTimes -withMessages \
-            -output "${combined_xml}" \
-            "${branchxml}" \
-            "${patchxml}"; then
-      module_status ${i} -1 "" "${module} cannot run computeBugHistory from findbugs"
-      ((result=result+1))
-      savestop=$(stop_clock)
-      MODULE_STATUS_TIMER[${i}]=${savestop}
-      ((i=i+1))
-      popd >/dev/null || return 1
-      continue
-    fi
-
-    # shellcheck disable=SC2016
-    patch_warnings=$("${FINDBUGS_HOME}/bin/filterBugs" -first \
-        "patch" \
-        "${patchxml}" \
-        "${patchxml}" \
-        | ${AWK} '{print $1}')
-
-    #shellcheck disable=SC2016
-    add_warnings=$("${FINDBUGS_HOME}/bin/filterBugs" -first patch \
-        "${combined_xml}" "${newbugsbase}.xml" | ${AWK} '{print $1}')
-    retval=$?
-    if [[ ${retval} != 0 ]]; then
-      module_status ${i} -1 "" "${module} cannot run filterBugs (#1) from findbugs"
-      ((result=result+1))
-      savestop=$(stop_clock)
-      MODULE_STATUS_TIMER[${i}]=${savestop}
-      ((i=i+1))
-      popd >/dev/null || return 1
-      continue
-    fi
-
-    #shellcheck disable=SC2016
-    fixed_warnings=$("${FINDBUGS_HOME}/bin/filterBugs" -fixed patch \
-        "${combined_xml}" "${fixedbugsbase}.xml" | ${AWK} '{print $1}')
-    retval=$?
-    if [[ ${retval} != 0 ]]; then
-      module_status ${i} -1 "" "${module} cannot run filterBugs (#2) from findbugs"
-      ((result=result+1))
-      savestop=$(stop_clock)
-      MODULE_STATUS_TIMER[${i}]=${savestop}
-      ((i=i+1))
-      popd >/dev/null || return 1
-      continue
-    fi
-
-    statstring=$(generic_calcdiff_status "${branch_warnings}" "${patch_warnings}" "${add_warnings}")
-
-    if ! "${FINDBUGS_HOME}/bin/convertXmlToText" -html "${newbugsbase}.xml" \
-        "${newbugsbase}.html"; then
-      module_status ${i} -1 "" "${module} cannot run convertXmlToText from findbugs"
-      ((result=result+1))
-      savestop=$(stop_clock)
-      MODULE_STATUS_TIMER[${i}]=${savestop}
-      ((i=i+1))
-      popd >/dev/null || return 1
-      continue
-    fi
-
-    if [[ ${add_warnings} -gt 0 ]] ; then
-      populate_test_table FindBugs "module:${module}"
-      #shellcheck disable=SC2162
-      while read line; do
-        firstpart=$(echo "${line}" | cut -f2 -d:)
-        secondpart=$(echo "${line}" | cut -f9- -d' ')
-        add_test_table "" "${firstpart}:${secondpart}"
-      done < <("${FINDBUGS_HOME}/bin/convertXmlToText" "${newbugsbase}.xml")
-
-      module_status ${i} -1 "new-findbugs-${fn}.html" "${module} ${statstring}"
-      ((result=result+1))
-    elif [[ ${fixed_warnings} -gt 0 ]]; then
-      module_status ${i} +1 "" "${module} ${statstring}"
-      summarize=false
-    fi
-    savestop=$(stop_clock)
-    MODULE_STATUS_TIMER[${i}]=${savestop}
-    popd >/dev/null || return 1
-    ((i=i+1))
-  done
-
-  modules_messages patch findbugs "${summarize}"
-  if [[ ${result} != 0 ]]; then
-    return 1
-  fi
-  return 0
-}
-
-function findbugs_rebuild
-{
-  declare repostatus=$1
-
-  if [[ "${repostatus}" = branch || "${BUILDMODE}" = full ]]; then
-    findbugs_preapply
-  else
-    findbugs_postinstall
-  fi
-}
diff --git a/precommit/src/main/shell/test-patch.d/gradle.sh b/precommit/src/main/shell/test-patch.d/gradle.sh
index 64e9714..6e2382c 100755
--- a/precommit/src/main/shell/test-patch.d/gradle.sh
+++ b/precommit/src/main/shell/test-patch.d/gradle.sh
@@ -284,6 +284,7 @@
   fi
 
   if [[ ${filename} =~ \.java$ ]]; then
+    add_test spotbugs
     add_test findbugs
   fi
 }
diff --git a/precommit/src/main/shell/test-patch.d/maven.sh b/precommit/src/main/shell/test-patch.d/maven.sh
index 64fbcc2..5b2d9ab 100755
--- a/precommit/src/main/shell/test-patch.d/maven.sh
+++ b/precommit/src/main/shell/test-patch.d/maven.sh
@@ -326,6 +326,9 @@
     scaladoc)
       modules_workers "${repostatus}" scaladoc clean scala:doc -DskipTests=true
     ;;
+    spotbugs)
+      modules_workers "${repostatus}" spotbugs test-compile spotbugs:spotbugs -DskipTests=true
+    ;;
     unit)
       if [[ -n "${maven_unit_test_filter}" ]]; then
         modules_workers "${repostatus}" unit clean test -fae "${maven_unit_test_filter}"
@@ -525,6 +528,7 @@
   fi
 
   if [[ ${filename} =~ \.java$ ]]; then
+    add_test spotbugs
     add_test findbugs
   fi
 }
@@ -629,7 +633,8 @@
   modules_workers "${repostatus}" mvninstall -fae \
     clean install \
     -DskipTests=true -Dmaven.javadoc.skip=true \
-    -Dcheckstyle.skip=true -Dfindbugs.skip=true
+    -Dcheckstyle.skip=true -Dfindbugs.skip=true \
+    -Dspotbugs.skip=true
   result=$?
   modules_messages "${repostatus}" mvninstall true
   if [[ ${result} != 0 ]]; then
diff --git a/precommit/src/main/shell/test-patch.d/spotbugs.sh b/precommit/src/main/shell/test-patch.d/spotbugs.sh
new file mode 100755
index 0000000..57c5815
--- /dev/null
+++ b/precommit/src/main/shell/test-patch.d/spotbugs.sh
@@ -0,0 +1,583 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+# SHELLDOC-IGNORE
+
+SPOTBUGS_HOME=${SPOTBUGS_HOME:-}
+ANT_SPOTBUGSXML=${ANT_SPOTBUGSXML:-}
+SPOTBUGS_WARNINGS_FAIL_PRECHECK=false
+SPOTBUGS_TABLE_DUPE=false
+
+if [[ -z "${SPOTBUGS_HOME}" && -n "${FINDBUGS_HOME}" ]]; then
+  SPOTBUGS_MODE=findbugs
+else
+  SPOTBUGS_MODE=spotbugs
+fi
+
+add_test_type spotbugs
+
+function spotbugs_deprecate_test_type
+{
+  if [[ "${SPOTBUGS_MODE}" == spotbugs ]]; then
+    if replace_test_type spotbugs findbugs; then
+      yetus_error "WARNING: Found both spotbugs and findbugs. Disabling findbugs."
+      SPOTBUGS_TABLE_DUPE=true
+    fi
+  else
+    if replace_test_type findbugs spotbugs; then
+      yetus_error "WARNING: spotbugs has deprecated findbugs, but only found findbugs."
+    fi
+  fi
+}
+
+function spotbugs_usage
+{
+  yetus_add_option "--spotbugs-home=<path>" "SpotBugs home directory (default \${SPOTBUGS_HOME})"
+  yetus_add_option "--spotbugs-strict-precheck" "If there are SpotBugs warnings during precheck, fail"
+}
+
+function spotbugs_parse_args
+{
+  declare i
+
+  for i in "$@"; do
+    case ${i} in
+    --spotbugs-home=*)
+      SPOTBUGS_HOME=${i#*=}
+    ;;
+    --spotbugs-strict-precheck)
+      SPOTBUGS_WARNINGS_FAIL_PRECHECK=true
+    ;;
+    esac
+  done
+}
+
+## @description  initialize the spotbugs plug-in
+## @audience     private
+## @stability    evolving
+## @replaceable  no
+function spotbugs_initialize
+{
+  if [[ "${SPOTBUGS_MODE}" == findbugs ]]; then
+    FINDBUGS_HOME=${SPOTBUGS_HOME:-${FINDBUGS_HOME}}
+  fi
+
+  if declare -f maven_add_install >/dev/null 2>&1; then
+    maven_add_install "${SPOTBUGS_MODE}"
+  fi
+}
+
+function spotbugs_filefilter
+{
+  declare filename=$1
+
+  if [[ ${BUILDTOOL} == maven
+    || ${BUILDTOOL} == ant ]]; then
+    if [[ ${filename} =~ \.java$
+      || ${filename} =~ (^|/)${SPOTBUGS_MODE}-exclude.xml$ ]]; then
+      add_test "${SPOTBUGS_MODE}"
+    fi
+  fi
+}
+
+function spotbugs_precheck
+{
+  declare exec
+  declare status=0
+
+  if [[ -z ${SPOTBUGS_HOME} ]]; then
+    yetus_error "SPOTBUGS_HOME (or FINDBUGS_HOME) was not specified."
+    status=1
+  else
+    for exec in computeBugHistory \
+                convertXmlToText \
+                filterBugs \
+                setBugDatabaseInfo\
+                unionBugs; do
+      if ! verify_command "${exec}" "${SPOTBUGS_HOME}/bin/${exec}"; then
+        status=1
+      fi
+    done
+  fi
+  if [[ ${status} == 1 ]]; then
+    add_vote_table 0 "${SPOTBUGS_MODE}" "${SPOTBUGS_MODE} executables are not available."
+    delete_test "${SPOTBUGS_MODE}"
+  fi
+}
+
+## @description  Run the maven spotbugs plugin and record found issues in a bug database
+## @audience     private
+## @stability    evolving
+## @replaceable  no
+## @return       0 on success
+## @return       1 on failure
+## @param        repostatus
+function spotbugs_runner
+{
+  declare name=$1
+  declare module
+  declare result=0
+  declare fn
+  declare warnings_file
+  declare i=0
+  declare savestop
+  declare retval
+
+
+  personality_modules "${name}" "${SPOTBUGS_MODE}"
+
+  "${BUILDTOOL}_modules_worker" "${name}" "${SPOTBUGS_MODE}"
+
+  if [[ ${UNSUPPORTED_TEST} = true ]]; then
+    return 0
+  fi
+
+  echo ""
+  echo "Building ${SPOTBUGS_MODE} database(s) using ${SPOTBUGS_HOME} for executables."
+  echo ""
+
+  if [[ "${SPOTBUGS_TABLE_DUPE}" == true ]] && [[ "${name}" == branch ]]; then
+    add_vote_table 0 spotbugs "Both FindBugs and SpotBugs are enabled, using SpotBugs."
+  fi
+
+  #shellcheck disable=SC2153
+  until [[ ${i} -eq ${#MODULE[@]} ]]; do
+    if [[ ${MODULE_STATUS[${i}]} == -1 ]]; then
+      ((result=result+1))
+      ((i=i+1))
+      continue
+    fi
+    start_clock
+    offset_clock "${MODULE_STATUS_TIMER[${i}]}"
+    module="${MODULE[${i}]}"
+    fn=$(module_file_fragment "${module}")
+
+    if [[ "${module}" == . ]]; then
+      module=root
+    fi
+
+    case ${BUILDTOOL} in
+      maven)
+        targetfile="${SPOTBUGS_MODE}Xml.xml"
+      ;;
+      ant)
+        targetfile="${ANT_SPOTBUGSXML}"
+      ;;
+    esac
+
+    buildtool_cwd "${i}"
+
+    files=()
+    while read -r line; do
+      files+=("${line}")
+    done < <(find . -name "${targetfile}")
+
+    warnings_file="${PATCH_DIR}/${name}-${SPOTBUGS_MODE}-${fn}-warnings"
+
+    if [[ "${#files[@]}" -lt 1 ]]; then
+      module_status ${i} 0 "" "${name}/${module} no ${SPOTBUGS_MODE} output file (${targetfile})"
+      ((i=i+1))
+      popd >/dev/null || return 1
+      continue
+    elif [[ "${#files[@]}" -eq 1 ]]; then
+      cp -p "${files[0]}" "${warnings_file}.xml"
+    else
+      "${SPOTBUGS_HOME}/bin/unionBugs" -withMessages -output "${warnings_file}.xml" "${files[@]}"
+    fi
+
+    popd >/dev/null || return 1
+
+    if [[ ${name} == branch ]]; then
+      "${SPOTBUGS_HOME}/bin/setBugDatabaseInfo" -name "${PATCH_BRANCH}" \
+          "${warnings_file}.xml" "${warnings_file}.xml"
+      retval=$?
+    else
+      "${SPOTBUGS_HOME}/bin/setBugDatabaseInfo" -name patch \
+          "${warnings_file}.xml" "${warnings_file}.xml"
+      retval=$?
+    fi
+
+    if [[ ${retval} != 0 ]]; then
+      savestop=$(stop_clock)
+      MODULE_STATUS_TIMER[${i}]=${savestop}
+      module_status ${i} -1 "" "${name}/${module} cannot run setBugDatabaseInfo from ${SPOTBUGS_MODE}"
+      ((result=result+1))
+      ((i=i+1))
+      continue
+    fi
+
+    if [[ ! -f "${warnings_file}.xml" ]]; then
+      module_status ${i} 0 "" "${name}/${module} no data in SpotBugs/FindBugs output file (${targetfile})"
+      ((i=i+1))
+      popd >/dev/null || return 1
+      continue
+    fi
+
+    if ! "${SPOTBUGS_HOME}/bin/convertXmlToText" -html \
+      "${warnings_file}.xml" \
+      "${warnings_file}.html"; then
+      savestop=$(stop_clock)
+      MODULE_STATUS_TIMER[${i}]=${savestop}
+      module_status ${i} -1 "" "${name}/${module} cannot run convertXmlToText from ${SPOTBUGS_MODE}"
+      ((result=result+1))
+    fi
+
+    if [[ -z ${SPOTBUGS_VERSION}
+        && ${name} == branch ]]; then
+      SPOTBUGS_VERSION=$("${GREP}" -i "BugCollection version=" "${warnings_file}.xml" \
+        | cut -f2 -d\" \
+        | cut -f1 -d\" )
+      if [[ -n ${SPOTBUGS_VERSION} ]]; then
+        add_footer_table "${SPOTBUGS_MODE}" "v${SPOTBUGS_VERSION}"
+      fi
+    fi
+
+    ((i=i+1))
+  done
+
+  return ${result}
+}
+
+## @description  Track pre-existing spotbugs warnings
+## @audience     private
+## @stability    evolving
+## @replaceable  no
+## @return       0 on success
+## @return       1 on failure
+function spotbugs_preapply
+{
+  declare fn
+  declare module
+  declare modindex=0
+  declare warnings_file
+  declare module_spotbugs_warnings
+  declare result=0
+  declare msg
+
+  if ! verify_needed_test "${SPOTBUGS_MODE}"; then
+    return 0
+  fi
+
+  big_console_header "${SPOTBUGS_MODE} detection: ${PATCH_BRANCH}"
+
+  spotbugs_runner branch
+  result=$?
+
+  if [[ ${UNSUPPORTED_TEST} = true ]]; then
+    return 0
+  fi
+
+  if [[ "${SPOTBUGS_MODE}" == findbugs ]]; then
+    add_vote_table 0 spotbugs "Used deprecated FindBugs config; considering switching to SpotBugs."
+  fi
+
+  until [[ ${modindex} -eq ${#MODULE[@]} ]]; do
+    if [[ ${MODULE_STATUS[${modindex}]} == -1 ]]; then
+      ((result=result+1))
+      ((modindex=modindex+1))
+      continue
+    fi
+
+    module=${MODULE[${modindex}]}
+    start_clock
+    offset_clock "${MODULE_STATUS_TIMER[${modindex}]}"
+    fn=$(module_file_fragment "${module}")
+
+    if [[ "${module}" == . ]]; then
+      module=root
+    fi
+
+    warnings_file="${PATCH_DIR}/branch-${SPOTBUGS_MODE}-${fn}-warnings"
+    if [[ ! -f "${warnings_file}.xml" ]]; then
+      savestop=$(stop_clock)
+      MODULE_STATUS_TIMER[${modindex}]=${savestop}
+      ((modindex=modindex+1))
+      continue
+    fi
+
+    # shellcheck disable=SC2016
+    module_spotbugs_warnings=$("${SPOTBUGS_HOME}/bin/filterBugs" -first \
+        "${PATCH_BRANCH}" \
+        "${warnings_file}.xml" \
+        "${warnings_file}.xml" \
+        | "${AWK}" '{print $1}')
+
+    if [[ ${module_spotbugs_warnings} -gt 0 ]] ; then
+      msg="${module} in ${PATCH_BRANCH} has ${module_spotbugs_warnings} extant ${SPOTBUGS_MODE} warnings."
+      if [[ "${SPOTBUGS_WARNINGS_FAIL_PRECHECK}" = "true" ]]; then
+        module_status ${modindex} -1 "branch-${SPOTBUGS_MODE}-${fn}-warnings.html" "${msg}"
+        ((result=result+1))
+      elif [[ "${BUILDMODE}" = full ]]; then
+        module_status ${modindex} -1 "branch-${SPOTBUGS_MODE}-${fn}-warnings.html" "${msg}"
+        ((result=result+1))
+        populate_test_table "${SPOTBUGS_MODE}" "module:${module}"
+        #shellcheck disable=SC2162
+        while read line; do
+          firstpart=$(echo "${line}" | cut -f2 -d:)
+          secondpart=$(echo "${line}" | cut -f9- -d' ')
+          add_test_table "" "${firstpart}:${secondpart}"
+        done < <("${SPOTBUGS_HOME}/bin/convertXmlToText" "${warnings_file}.xml")
+      else
+        module_status ${modindex} 0 "branch-${SPOTBUGS_MODE}-${fn}-warnings.html" "${msg}"
+      fi
+    fi
+
+    savestop=$(stop_clock)
+    MODULE_STATUS_TIMER[${modindex}]=${savestop}
+    ((modindex=modindex+1))
+  done
+  modules_messages branch "${SPOTBUGS_MODE}" true
+
+  if [[ ${result} != 0 ]]; then
+    return 1
+  fi
+  return 0
+}
+
+## @description  Verify patch does not trigger any spotbugs warnings
+## @audience     private
+## @stability    evolving
+## @replaceable  no
+## @return       0 on success
+## @return       1 on failure
+function spotbugs_postinstall
+{
+  declare module
+  declare fn
+  declare combined_xml
+  declare branchxml
+  declare patchxml
+  declare newbugsbase
+  declare fixedbugsbase
+  declare branch_warnings
+  declare patch_warnings
+  declare fixed_warnings
+  declare line
+  declare firstpart
+  declare secondpart
+  declare i=0
+  declare result=0
+  declare savestop
+  declare summarize=true
+  declare statstring
+
+  if ! verify_needed_test "${SPOTBUGS_MODE}"; then
+    return 0
+  fi
+
+  big_console_header "${SPOTBUGS_MODE} detection: ${BUILDMODE}"
+
+  spotbugs_runner patch
+
+  if [[ ${UNSUPPORTED_TEST} = true ]]; then
+    return 0
+  fi
+
+  until [[ $i -eq ${#MODULE[@]} ]]; do
+    if [[ ${MODULE_STATUS[${i}]} == -1 ]]; then
+      ((result=result+1))
+      ((i=i+1))
+      continue
+    fi
+
+    start_clock
+    offset_clock "${MODULE_STATUS_TIMER[${i}]}"
+    module="${MODULE[${i}]}"
+
+    buildtool_cwd "${i}"
+
+    fn=$(module_file_fragment "${module}")
+
+    if [[ "${module}" == . ]]; then
+      module=root
+    fi
+
+    combined_xml="${PATCH_DIR}/combined-${SPOTBUGS_MODE}-${fn}.xml"
+    branchxml="${PATCH_DIR}/branch-${SPOTBUGS_MODE}-${fn}-warnings.xml"
+    patchxml="${PATCH_DIR}/patch-${SPOTBUGS_MODE}-${fn}-warnings.xml"
+
+    if [[ -f "${branchxml}" ]]; then
+      # shellcheck disable=SC2016
+      branch_warnings=$("${SPOTBUGS_HOME}/bin/filterBugs" -first \
+          "${PATCH_BRANCH}" \
+          "${branchxml}" \
+          "${branchxml}" \
+          | ${AWK} '{print $1}')
+    else
+      branchxml=${patchxml}
+    fi
+
+    newbugsbase="${PATCH_DIR}/new-${SPOTBUGS_MODE}-${fn}"
+    fixedbugsbase="${PATCH_DIR}/fixed-${SPOTBUGS_MODE}-${fn}"
+
+    if [[ ! -f "${branchxml}" ]] && [[ ! -f "${patchxml}" ]]; then
+      module_status ${i} 0 "" "${module} has no data from ${SPOTBUGS_MODE}"
+      ((result=result+1))
+      savestop=$(stop_clock)
+      MODULE_STATUS_TIMER[${i}]=${savestop}
+      ((i=i+1))
+      popd >/dev/null || return 1
+      continue
+    fi
+
+    echo ""
+
+    if ! "${SPOTBUGS_HOME}/bin/computeBugHistory" -useAnalysisTimes -withMessages \
+            -output "${combined_xml}" \
+            "${branchxml}" \
+            "${patchxml}"; then
+      module_status ${i} -1 "" "${module} cannot run computeBugHistory from ${SPOTBUGS_MODE}"
+      ((result=result+1))
+      savestop=$(stop_clock)
+      MODULE_STATUS_TIMER[${i}]=${savestop}
+      ((i=i+1))
+      popd >/dev/null || return 1
+      continue
+    fi
+
+    # shellcheck disable=SC2016
+    patch_warnings=$("${SPOTBUGS_HOME}/bin/filterBugs" -first \
+        "patch" \
+        "${patchxml}" \
+        "${patchxml}" \
+        | ${AWK} '{print $1}')
+
+    #shellcheck disable=SC2016
+    add_warnings=$("${SPOTBUGS_HOME}/bin/filterBugs" -first patch \
+        "${combined_xml}" "${newbugsbase}.xml" | ${AWK} '{print $1}')
+    retval=$?
+    if [[ ${retval} != 0 ]]; then
+      module_status ${i} -1 "" "${module} cannot run filterBugs (#1) from ${SPOTBUGS_MODE}"
+      ((result=result+1))
+      savestop=$(stop_clock)
+      MODULE_STATUS_TIMER[${i}]=${savestop}
+      ((i=i+1))
+      popd >/dev/null || return 1
+      continue
+    fi
+
+    #shellcheck disable=SC2016
+    fixed_warnings=$("${SPOTBUGS_HOME}/bin/filterBugs" -fixed patch \
+        "${combined_xml}" "${fixedbugsbase}.xml" | ${AWK} '{print $1}')
+    retval=$?
+    if [[ ${retval} != 0 ]]; then
+      module_status ${i} -1 "" "${module} cannot run filterBugs (#2) from ${SPOTBUGS_MODE}"
+      ((result=result+1))
+      savestop=$(stop_clock)
+      MODULE_STATUS_TIMER[${i}]=${savestop}
+      ((i=i+1))
+      popd >/dev/null || return 1
+      continue
+    fi
+
+    statstring=$(generic_calcdiff_status "${branch_warnings}" "${patch_warnings}" "${add_warnings}")
+
+    if ! "${SPOTBUGS_HOME}/bin/convertXmlToText" -html "${newbugsbase}.xml" \
+        "${newbugsbase}.html"; then
+      module_status ${i} -1 "" "${module} cannot run convertXmlToText from ${SPOTBUGS_MODE}"
+      ((result=result+1))
+      savestop=$(stop_clock)
+      MODULE_STATUS_TIMER[${i}]=${savestop}
+      ((i=i+1))
+      popd >/dev/null || return 1
+      continue
+    fi
+
+    if [[ ${add_warnings} -gt 0 ]] ; then
+      populate_test_table FindBugs "module:${module}"
+      #shellcheck disable=SC2162
+      while read line; do
+        firstpart=$(echo "${line}" | cut -f2 -d:)
+        secondpart=$(echo "${line}" | cut -f9- -d' ')
+        add_test_table "" "${firstpart}:${secondpart}"
+      done < <("${SPOTBUGS_HOME}/bin/convertXmlToText" "${newbugsbase}.xml")
+
+      module_status ${i} -1 "new-${SPOTBUGS_MODE}-${fn}.html" "${module} ${statstring}"
+      ((result=result+1))
+    elif [[ ${fixed_warnings} -gt 0 ]]; then
+      module_status ${i} +1 "" "${module} ${statstring}"
+      summarize=false
+    fi
+    savestop=$(stop_clock)
+    MODULE_STATUS_TIMER[${i}]=${savestop}
+    popd >/dev/null || return 1
+    ((i=i+1))
+  done
+
+  modules_messages patch ${SPOTBUGS_MODE} "${summarize}"
+  if [[ ${result} != 0 ]]; then
+    return 1
+  fi
+  return 0
+}
+
+function spotbugs_rebuild
+{
+  declare repostatus=$1
+
+  if [[ "${repostatus}" = branch || "${BUILDMODE}" = full ]]; then
+    spotbugs_preapply
+  else
+    spotbugs_postinstall
+  fi
+}
+
+
+##
+## To be removed:  FindBugs instead of SpotBugs
+##
+
+add_test_type findbugs
+
+function findbugs_usage
+{
+  yetus_add_option "--findbugs-home=<path>" "Findbugs home directory (default \${FINDBUGS_HOME})"
+  yetus_add_option "--findbugs-strict-precheck" "If there are Findbugs warnings during precheck, fail"
+}
+
+function findbugs_parse_args
+{
+  declare i
+
+  for i in "$@"; do
+    case ${i} in
+    --findbugs-home=*)
+      SPOTBUGS_HOME=${i#*=}
+    ;;
+    --findbugs-strict-precheck)
+      SPOTBUGS_WARNINGS_FAIL_PRECHECK=true
+    ;;
+    esac
+  done
+}
+
+function findbugs_initialize
+{
+  SPOTBUGS_MODE="findbugs"
+  ANT_SPOTBUGSXML=${ANT_FINDBUGSXML}
+  SPOTBUGS_HOME=${FINDBUGS_HOME}
+  spotbugs_initialize "$@"
+}
+
+function findbugs_filefilter
+{
+  spotbugs_initialize "$@"
+}
+
+function findbugs_rebuild
+{
+  spotbugs_rebuild "$@"
+}
\ No newline at end of file