Persist Binding across DynamicParser script execs

Don't create a new Binding for every match/execution of the
DynamicParser script. This allows the script to add new variables to the
Binding and have them persist across all matches. Variables can be added
to the Binding within a script by omitting a type [1]. The Binding can
be checked for the presence of global variables with something like [2]:
binding.variables.containsKey("bindingVar"). Also add a reference to the
falsePositive Warning object. The motivation for these changes is to
enable scripts to keep a reference to the current working directory that
can be used to resolve relative paths in warning messages.

1. http://groovy.codehaus.org/Scoping+and+the+Semantics+of+%22def%22
2. http://www.justinleegrant.com/?p=129

An example script that makes use of this feature to keep track of the
current working directory follows:

  // This script is designed to operate on Windows paths in a Unix
  // environment. Since java.nio.file only appears to support local
  // filesystems supported by the JVM, the Windows path separators need
  // to be changed manually and some of the Path methods don't function
  // correctly (like isAbsolute()).

  // Associated regular expression:
  // ^((.+?):(\d+):(?:(\d+):)? (warning|.*error): (.*))|
  //  (Waf: Entering directory\s*\`(.*)\')$

  import hudson.plugins.warnings.parser.Warning
  import hudson.plugins.analysis.util.model.Priority
  import java.nio.file.Path
  import java.nio.file.Paths

  // If it matched a directory
  if(matcher.group(7) != null) {
      // Save the directory in the Binding as a Path object
      directory = Paths.get(matcher.group(8).replace("\\", "/"))
      return falsePositive
  }

  String fileName = matcher.group(2).replace("\\", "/")
  int lineNumber = Integer.parseInt(matcher.group(3))
  int column = Integer.parseInt(matcher.group(4))
  String message = matcher.group(6)

  Priority priority
  String category

  if (matcher.group(5).contains("error")) {
      priority = Priority.HIGH
      category = "Error"
  }
  else {
      priority = Priority.NORMAL
      category = "Warning"
  }

  // If the fileName is not absolute and we
  // have a directory variable in the Binding,
  if(!fileName.contains(":") &&
     binding.variables.containsKey("directory")) {
      // then append the filename to the directory and normalize
      // the path to remove redundant components
      fileName = directory.resolve(fileName).normalize().toString()
  }

  Warning warning = new Warning(fileName, lineNumber,
                                "Relative GCC Parser", category,
                                message, priority)
  warning.setColumnPosition(column)
  return warning