docs: function explore(o1, o2){
        if (typeof o2 === 'undefined') { // ignore undefined values
          grunt.verbose.writeln('Base value');
          return o1;
        }
        else if (o2 === null) { // null values overwrite the base value
          grunt.verbose.writeln('Null');
          return null;
        }
        else if (Array.isArray(o2)){ // Array overwrite base value
          grunt.verbose.writeln('Array');
          return o2;
        }
        else if (typeof o2 === 'object' && o1 != null){ // Object is completed
          var res = {}, keys = Object.keys(o1), keys2 = Object.keys(o2);
          for (var i = 0; i < keys.length; i++){
            var key = keys[i];
            grunt.verbose.write(key + ': ');
            res[key] = explore(o1[key], o2[key]);
          }
  
          // loop target config for keys that do not exist in base config
          for (var j = 0; j < keys2.length; j++){
            var key = keys2[j];
            if (typeof o1[key] === 'undefined'){
              grunt.verbose.write(key + ': ');
              res[key] = explore(null, o2[key]);
            }
          }
          return res;
        }
        else {
          // primitive values overwrite base value
          // also applied to objects when base key is undefined
          grunt.verbose.writeln(o2);
          return o2;
        }
      }