diff --git a/devtools/batchbuild.py b/devtools/batchbuild.py
new file mode 100644
index 0000000..5da74db
--- /dev/null
+++ b/devtools/batchbuild.py
@@ -0,0 +1,280 @@
+import collections
+import itertools
+import json
+import os
+import os.path
+import re
+import shutil
+import string
+import subprocess
+import sys
+import cgi
+
+class BuildDesc:
+    def __init__(self, prepend_envs=None, variables=None, build_type=None, generator=None):
+        self.prepend_envs = prepend_envs or [] # [ { "var": "value" } ]
+        self.variables = variables or []
+        self.build_type = build_type
+        self.generator = generator
+
+    def merged_with( self, build_desc ):
+        """Returns a new BuildDesc by merging field content.
+           Prefer build_desc fields to self fields for single valued field.
+        """
+        return BuildDesc( self.prepend_envs + build_desc.prepend_envs,
+                          self.variables + build_desc.variables,
+                          build_desc.build_type or self.build_type,
+                          build_desc.generator or self.generator )
+
+    def env( self ):
+        environ = os.environ.copy()
+        for values_by_name in self.prepend_envs:
+            for var, value in values_by_name.items():
+                var = var.upper()
+                if type(value) is unicode:
+                    value = value.encode( sys.getdefaultencoding() )
+                if var in environ:
+                    environ[var] = value + os.pathsep + environ[var]
+                else:
+                    environ[var] = value
+        return environ
+
+    def cmake_args( self ):
+        args = ["-D%s" % var for var in self.variables]
+        # skip build type for Visual Studio solution as it cause warning
+        if self.build_type and 'Visual' not in self.generator:
+            args.append( "-DCMAKE_BUILD_TYPE=%s" % self.build_type )
+        if self.generator:
+            args.extend( ['-G', self.generator] )
+        return args
+
+    def __repr__( self ):
+        return "BuildDesc( %s, build_type=%s )" %  (" ".join( self.cmake_args()), self.build_type)
+
+class BuildData:
+    def __init__( self, desc, work_dir, source_dir ):
+        self.desc = desc
+        self.work_dir = work_dir
+        self.source_dir = source_dir
+        self.cmake_log_path = os.path.join( work_dir, 'batchbuild_cmake.log' )
+        self.build_log_path = os.path.join( work_dir, 'batchbuild_build.log' )
+        self.cmake_succeeded = False
+        self.build_succeeded = False
+
+    def execute_build(self):
+        print 'Build %s' % self.desc
+        self._make_new_work_dir( )
+        self.cmake_succeeded = self._generate_makefiles( )
+        if self.cmake_succeeded:
+            self.build_succeeded = self._build_using_makefiles( )
+        return self.build_succeeded
+
+    def _generate_makefiles(self):
+        print '  Generating makefiles: ',
+        cmd = ['cmake'] + self.desc.cmake_args( ) + [os.path.abspath( self.source_dir )]
+        succeeded = self._execute_build_subprocess( cmd, self.desc.env(), self.cmake_log_path )
+        print 'done' if succeeded else 'FAILED'
+        return succeeded
+
+    def _build_using_makefiles(self):
+        print '  Building:',
+        cmd = ['cmake', '--build', self.work_dir]
+        if self.desc.build_type:
+            cmd += ['--config', self.desc.build_type]
+        succeeded = self._execute_build_subprocess( cmd, self.desc.env(), self.build_log_path )
+        print 'done' if succeeded else 'FAILED'
+        return succeeded
+
+    def _execute_build_subprocess(self, cmd, env, log_path):
+        process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self.work_dir,
+                                    env=env )
+        stdout, _ = process.communicate( )
+        succeeded = (process.returncode == 0)
+        with open( log_path, 'wb' ) as flog:
+            log = ' '.join( cmd ) + '\n' + stdout + '\nExit code: %r\n' % process.returncode
+            flog.write( fix_eol( log ) )
+        return succeeded
+
+    def _make_new_work_dir(self):
+        if os.path.isdir( self.work_dir ):
+            print '  Removing work directory', self.work_dir
+            shutil.rmtree( self.work_dir, ignore_errors=True )
+        if not os.path.isdir( self.work_dir ):
+            os.makedirs( self.work_dir )
+
+def fix_eol( stdout ):
+    """Fixes wrong EOL produced by cmake --build on Windows (\r\r\n instead of \r\n).
+    """
+    return re.sub( '\r*\n', os.linesep, stdout )
+
+def load_build_variants_from_config( config_path ):
+    with open( config_path, 'rb' ) as fconfig:
+        data = json.load( fconfig )
+    variants = data[ 'cmake_variants' ]
+    build_descs_by_axis = collections.defaultdict( list )
+    for axis in variants:
+        axis_name = axis["name"]
+        build_descs = []
+        if "generators" in axis:
+            for generator_data in axis["generators"]:
+                for generator in generator_data["generator"]:
+                    build_desc = BuildDesc( generator=generator,
+                                            prepend_envs=generator_data.get("env_prepend") )
+                    build_descs.append( build_desc )
+        elif "variables" in axis:
+            for variables in axis["variables"]:
+                build_desc = BuildDesc( variables=variables )
+                build_descs.append( build_desc )
+        elif "build_types" in axis:
+            for build_type in axis["build_types"]:
+                build_desc = BuildDesc( build_type=build_type )
+                build_descs.append( build_desc )
+        build_descs_by_axis[axis_name].extend( build_descs )
+    return build_descs_by_axis
+
+def generate_build_variants( build_descs_by_axis ):
+    """Returns a list of BuildDesc generated for the partial BuildDesc for each axis."""
+    axis_names = build_descs_by_axis.keys()
+    build_descs = []
+    for axis_name, axis_build_descs in build_descs_by_axis.items():
+        if len(build_descs):
+            # for each existing build_desc and each axis build desc, create a new build_desc
+            new_build_descs = []
+            for prototype_build_desc, axis_build_desc in itertools.product( build_descs, axis_build_descs):
+                new_build_descs.append( prototype_build_desc.merged_with( axis_build_desc ) )
+            build_descs = new_build_descs
+        else:
+            build_descs = axis_build_descs
+    return build_descs
+
+HTML_TEMPLATE = string.Template('''<html>
+<head>
+    <title>$title</title>
+    <style type="text/css">
+    td.failed {background-color:#f08080;}
+    td.ok {background-color:#c0eec0;}
+    </style>
+</head>
+<body>
+<table border="1">
+<thead>
+    <tr>
+        <th>Variables</th>
+        $th_vars
+    </tr>
+    <tr>
+        <th>Build type</th>
+        $th_build_types
+    </tr>
+</thead>
+<tbody>
+$tr_builds
+</tbody>
+</table>
+</body></html>''')
+
+def generate_html_report( html_report_path, builds ):
+    report_dir = os.path.dirname( html_report_path )
+    # Vertical axis: generator
+    # Horizontal: variables, then build_type
+    builds_by_generator = collections.defaultdict( list )
+    variables = set()
+    build_types_by_variable = collections.defaultdict( set )
+    build_by_pos_key = {} # { (generator, var_key, build_type): build }
+    for build in builds:
+        builds_by_generator[build.desc.generator].append( build )
+        var_key = tuple(sorted(build.desc.variables))
+        variables.add( var_key )
+        build_types_by_variable[var_key].add( build.desc.build_type )
+        pos_key = (build.desc.generator, var_key, build.desc.build_type)
+        build_by_pos_key[pos_key] = build
+    variables = sorted( variables )
+    th_vars = []
+    th_build_types = []
+    for variable in variables:
+        build_types = sorted( build_types_by_variable[variable] )
+        nb_build_type = len(build_types_by_variable[variable])
+        th_vars.append( '<th colspan="%d">%s</th>' % (nb_build_type, cgi.escape( ' '.join( variable ) ) ) )
+        for build_type in build_types:
+            th_build_types.append( '<th>%s</th>' % cgi.escape(build_type) )
+    tr_builds = []
+    for generator in sorted( builds_by_generator ):
+        tds = [ '<td>%s</td>\n' % cgi.escape( generator ) ]
+        for variable in variables:
+            build_types = sorted( build_types_by_variable[variable] )
+            for build_type in build_types:
+                pos_key = (generator, variable, build_type)
+                build = build_by_pos_key.get(pos_key)
+                if build:
+                    cmake_status = 'ok' if build.cmake_succeeded else 'FAILED'
+                    build_status = 'ok' if build.build_succeeded else 'FAILED'
+                    cmake_log_url = os.path.relpath( build.cmake_log_path, report_dir )
+                    build_log_url = os.path.relpath( build.build_log_path, report_dir )
+                    td = '<td class="%s"><a href="%s" class="%s">CMake: %s</a>' % (
+                        build_status.lower(), cmake_log_url, cmake_status.lower(), cmake_status)
+                    if build.cmake_succeeded:
+                        td += '<br><a href="%s" class="%s">Build: %s</a>' % (
+                            build_log_url, build_status.lower(), build_status)
+                    td += '</td>'
+                else:
+                    td = '<td></td>'
+                tds.append( td )
+        tr_builds.append( '<tr>%s</tr>' % '\n'.join( tds ) )
+    html = HTML_TEMPLATE.substitute(
+        title='Batch build report',
+        th_vars=' '.join(th_vars),
+        th_build_types=' '.join( th_build_types),
+        tr_builds='\n'.join( tr_builds ) )
+    with open( html_report_path, 'wt' ) as fhtml:
+        fhtml.write( html )
+    print 'HTML report generated in:', html_report_path
+
+def main():
+    usage = r"""%prog WORK_DIR SOURCE_DIR CONFIG_JSON_PATH [CONFIG2_JSON_PATH...]
+Build a given CMake based project located in SOURCE_DIR with multiple generators/options.dry_run
+as described in CONFIG_JSON_PATH building in WORK_DIR.
+
+Example of call:
+python devtools\batchbuild.py e:\buildbots\jsoncpp\build . devtools\agent_vmw7.json
+"""
+    from optparse import OptionParser
+    parser = OptionParser(usage=usage)
+    parser.allow_interspersed_args = True
+#    parser.add_option('-v', '--verbose', dest="verbose", action='store_true',
+#        help="""Be verbose.""")
+    parser.enable_interspersed_args()
+    options, args = parser.parse_args()
+    if len(args) < 3:
+        parser.error( "Missing one of WORK_DIR SOURCE_DIR CONFIG_JSON_PATH." )
+    work_dir = args[0]
+    source_dir = args[1].rstrip('/\\')
+    config_paths = args[2:]
+    for config_path in config_paths:
+        if not os.path.isfile( config_path ):
+            parser.error( "Can not read: %r" % config_path )
+
+    # generate build variants
+    build_descs = []
+    for config_path in config_paths:
+        build_descs_by_axis = load_build_variants_from_config( config_path )
+        build_descs.extend( generate_build_variants( build_descs_by_axis ) )
+    print 'Build variants (%d):' % len(build_descs)
+    # assign build directory for each variant
+    if not os.path.isdir( work_dir ):
+        os.makedirs( work_dir )
+    builds = []
+    with open( os.path.join( work_dir, 'matrix-dir-map.txt' ), 'wt' ) as fmatrixmap:
+        for index, build_desc in enumerate( build_descs ):
+            build_desc_work_dir = os.path.join( work_dir, '%03d' % (index+1) )
+            builds.append( BuildData( build_desc, build_desc_work_dir, source_dir ) )
+            fmatrixmap.write( '%s: %s\n' % (build_desc_work_dir, build_desc) )
+    for build in builds:
+        build.execute_build()
+    html_report_path = os.path.join( work_dir, 'batchbuild-report.html' )
+    generate_html_report( html_report_path, builds )
+    print 'Done'
+        
+
+if __name__ == '__main__':
+    main()
+
