text: // Generated by CoffeeScript 1.7.1
  var async, baseTypes, ensureBaseType, ensureImplicitNestedTypes, inspect, isArray, isObject, resolveImplicitNestedTypes, resolveImplicitType, resolveInheritedType, resolveType, resolveTypes, simplifyNestedTypes, simplifyTypeSpecification,
    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
  
  async = require('async');
  
  inspect = require('./inspect');
  
  baseTypes = ['boolean', 'string', 'number', 'array', 'enum', 'object'];
  
  ensureBaseType = function(type, cb) {
    if (__indexOf.call(baseTypes, type) < 0) {
      return cb(new Error("Unable to resolve type: " + type));
    } else {
      return cb(null);
    }
  };
  
  simplifyNestedTypes = function(typeSpec, cb) {
    var name, nested, _ref;
    if (((typeSpec != null ? (_ref = typeSpec.nestedTypes) != null ? _ref.length : void 0 : void 0) || 0) < 1) {
      return cb(null, []);
    }
    name = inspect.findTypeName(typeSpec);
    if (name !== 'array' && name !== 'enum') {
      return cb(new Error("Nested types are allowed only for array and enum types."));
    }
    nested = typeSpec.nestedTypes;
    return async.map(nested, ensureBaseType, function(err) {
      if (err) {
        return cb(err);
      }
      return cb(null, nested);
    });
  };
  
  simplifyTypeSpecification = function(typeSpec, cb) {
    var name;
    name = inspect.findTypeName(typeSpec);
    if (!name) {
      return cb(null, null);
    }
    return ensureBaseType(name, function(err) {
      if (err) {
        return cb(err);
      }
      return simplifyNestedTypes(typeSpec, function(err, nested) {
        return cb(err, (!err ? {
          name: name,
          nested: nested
        } : void 0));
      });
    });
  };
  
  isArray = function(elementNode) {
    return inspect.hasMultipleValues(elementNode);
  };
  
  isObject = function(elementNode) {
    return inspect.hasAnyMemberSections(elementNode);
  };
  
  resolveImplicitNestedTypes = function(typeName, elementNode, cb) {
    if ((typeName === 'array' || typeName === 'enum') && (inspect.listValues(elementNode)).length) {
      return cb(null, ['string']);
    } else {
      return cb(null, []);
    }
  };
  
  resolveImplicitType = function(elementNode, cb) {
    var isArr, isObj, name;
    isArr = isArray(elementNode);
    isObj = isObject(elementNode);
    if (isObj && isArr) {
      return cb(new Error("Unable to resolve type. Ambiguous implicit type (seems to be both object and inline array)."));
    } else {
      name = (isArr ? 'array' : void 0) || (isObj ? 'object' : void 0) || 'string';
      return resolveImplicitNestedTypes(name, elementNode, function(err, nested) {
        return cb(err, (!err ? {
          name: name,
          nested: nested
        } : void 0));
      });
    }
  };
  
  resolveInheritedType = function(elementNode, inheritedTypeName, cb) {
    return cb(null, {
      name: inheritedTypeName,
      nested: []
    });
  };
  
  ensureImplicitNestedTypes = function(elementNode, simpleTypeSpec, cb) {
    var name, _ref;
    if ((_ref = simpleTypeSpec.nested) != null ? _ref.length : void 0) {
      return cb(null, simpleTypeSpec);
    } else {
      name = simpleTypeSpec.name;
      return resolveImplicitNestedTypes(name, elementNode, function(err, nested) {
        return cb(err, (!err ? {
          name: name,
          nested: nested
        } : void 0));
      });
    }
  };
  
  resolveType = function(elementNode, inheritedTypeName, cb) {
    var typeSpec;
    if (inheritedTypeName) {
      if (typeof inheritedTypeName === 'function') {
        cb = inheritedTypeName;
      } else {
        return resolveInheritedType(elementNode, inheritedTypeName, cb);
      }
    }
    typeSpec = inspect.findTypeSpecification(elementNode);
    return simplifyTypeSpecification(typeSpec, function(err, simpleTypeSpec) {
      if (err) {
        return cb(err);
      }
      if (!simpleTypeSpec) {
        return resolveImplicitType(elementNode, cb);
      }
      return ensureImplicitNestedTypes(elementNode, simpleTypeSpec, cb);
    });
  };
  
  resolveTypes = function(elementNodes, inheritedTypeName, cb) {
    return async.map(elementNodes, function(elementNode, next) {
      return resolveType(elementNode, inheritedTypeName, next);
    }, cb);
  };
  
  module.exports = {
    resolveType: resolveType,
    resolveTypes: resolveTypes
  };
  