text: var reactDocs = require('react-docgen');
  var fs = require('fs');
  
  const componentInfo = {};
  
  function generateType(type) {
    if (type.name === 'union') {
      const types = [];
      for (let i = 0, ii = type.value.length; i < ii; ++i) {
        types.push(generateType(type.value[i])[0]);
      }
      return types;
    } else if (type.name === 'arrayOf') {
      return [type.name + '(' + type.value.name + ')'];
    } else {
      return [type.name];
    }
  }
  
  function getSubprops(prop) {
    if (prop.type && prop.type.name === 'shape') {
      const subProps = [];
      for (let key in prop.type.value) {
        const member = prop.type.value[key];
        subProps.push({
          name: key,
          description: member.description,
          optional: !member.required,
          type: {names: [member.name]}
        });
      }
      return subProps;
    }
  }
  
  exports.handlers = {
      fileBegin: function(e) {
        const filename = e.filename;
        if (filename.indexOf('component') !== -1) {
          filename.substr(filename.indexOf('src/')+4, filename.indexOf('.js')-(filename.indexOf('src/')+4));
          const start = filename.indexOf('src/') + 4;
          const end = filename.indexOf('.js') - start;
          const module = `module:${e.filename.substr(start, end)}`;
          componentInfo[module] = reactDocs.parse(fs.readFileSync(e.filename), reactDocs.resolver.findAllComponentDefinitions);
        }
      },
      newDoclet: function(e) {
        if (e.doclet ){
          const doclet = e.doclet;
          const info = componentInfo[doclet.longname];
          if (info) {
            doclet.properties = [];
            for (let i = 0, ii = info.length; i < ii; ++i) {
              if (info[i].composes) {
                const parentClass = info[i].composes[0].replace('./', 'module:components/');
                const parentInfo = componentInfo[parentClass];
                for (let p = 0, pp = parentInfo.length; p < pp; ++p) {
                  if (parentInfo[p].props) {
                    info[i].props = Object.assign(info[i].props || {}, parentInfo[p].props);
                  }
                }
              }
              if (info[i].props) {
                for (let key in info[i].props) {
                  const prop = info[i].props[key];
                  let defaultValue;
                  if (prop.defaultValue) {
                    defaultValue = prop.defaultValue.value;
                    if (defaultValue.indexOf('class') === 0) {
                      defaultValue = defaultValue.substring(defaultValue.indexOf('class ') + 6, defaultValue.indexOf('extends'));
                    }
                  }
                  if (prop.description && prop.description.indexOf('@ignore') === -1) {
                    doclet.properties.push({
                      name: key,
                      optional: !prop.required,
                      description: prop.description,
                      defaultvalue: defaultValue,
                      type: {names: prop.type ? generateType(prop.type) : undefined},
                      subprops: getSubprops(prop),
                    });
                  }
                }
              }
            }
          }
        }
      }
  };
  