docs: function traverse(schema, p, group) {
  	var params = {};
  
  	// Case: apiSuccess returns an array
  	/*if (!p && schema.type === 'array'){
  		params['data'] = '{array} data';
  		p = 'data[]';
  	}*/
  
  	p = p || '';
  
  
  	var properties = {};
  	//schema = mergeAllOf(schema);
  	if (isType(schema.type, 'object')){
  		properties = schema.properties;
  	} else if (isType(schema.type, 'array') && !schema.items) { // catch errors
  	  throw SyntaxError('ERROR: schema array missing items');
  	} else if (isType(schema.type, 'array') && schema.items.type === 'object') {
  		//schema.items = mergeAllOf(schema.items);
  		properties = schema.items.properties;
  	}
  
  	//console.log('properties',properties);
  
  	for(var key in properties) {
  		if (!properties.hasOwnProperty(key)) { continue; }
  		var param = properties[key];
  		//console.log('param',param);
  		if (!param) { continue; }
  
  		var type = makeType(param);
  		var size = makeSize(param);
  		var allowedValues = makeAllowedValues(param);
  
  		var description = param.description || '';
  		if (param.type === 'array') {
  			description += ' '+ (param.items.description || '');
  		}
  
  		// make field
  		var parent = p ? p + '.':'';
  		var field = parent + key;
  
  		if (exists(Object.keys(param),'default')) {
  			if (typeof param.default === 'object') {
  				field += '=\''+JSON.stringify(param.default)+'\'';
  			} else {
  				field += '='+param.default;
  			}
  		}
  
  		if ( !isRequired(schema, key) ) {
  			field = '['+field+']';
  		}
  
  		if (p) key = p + '.' + key;
  		var g = group ? '('+group+') ' : '';
  		// make group
  		params[key] = g+'{'+type+size+allowedValues+'} '+field+' '+description;
  		//console.log(parent+key, params[parent + key])
  		var subs = {};
  		//var subgroup = p ? p+'.' : ''; // TODO apidoc - groups cannot have `.` in them
  		if (isType(param.type, 'array') && param.items.type === 'object') {
  			subs = traverse(param.items, key, group); // subgroup+
  		} else if (isType(param.type, 'object')) {
  			subs = traverse(param, key, group); // subgroup+
  		}
  		for(var subKey in subs) {
  			if (!subs.hasOwnProperty(subKey)) { continue; }
  			params[key+'.'+subKey] = subs[subKey];
  		}
  	}
  
  	return params;
  }