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