docs: function getES5ReactComponents(ast) {
    const output = {
      name: '',
      state: {},
      props: {},
      methods: [],
      children: [],
    };
    let iter = [];
    let topJsxComponent;
    let outside;
    const checker = {};
    esrecurse.visit(ast, {
      VariableDeclarator(node) {
        topJsxComponent = node.id.name;
        this.visitChildren(node);
      },
      MemberExpression(node) {
        if (node.property && node.property.name === 'createClass') {
          output.name = topJsxComponent;
        }
        this.visitChildren(node);
      },
      ObjectExpression(node) {
        node.properties.forEach(prop => {
          if (reactMethods.indexOf(prop.key.name) < 0
            && prop.value.type === 'FunctionExpression') {
            output.methods.push(prop.key.name);
          }
        });
        this.visitChildren(node);
      },
      JSXElement(node) {
        output.children = getChildJSXElements(node, output.name);
        output.props = getReactProps(node, output.name);
        if (htmlElements.indexOf(node.openingElement.name.name) < 0) {
          outside = {
            name: node.openingElement.name.name,
            children: getChildJSXElements(node, output.name),
            props: getReactProps(node, output.name),
            state: {},
            methods: [],
          };
        }
      },
    });
  
    const forIn = esquery(ast, 'ForInStatement').filter(ele => {
      const searched = bfs(ele).filter(n => {
        return n.type === 'JSXElement';
      });
      return searched.length > 0;
    });
    if (forIn.length > 0) iter = iter.concat(forInFinder(forIn, output.name));
  
    const forLoop = esquery(ast, 'ForStatement').filter(ele => {
      const searched = bfs(ele).filter(n => {
        return n.type === 'JSXElement';
      });
      return searched.length > 0;
    });
    if (forLoop.length > 0) iter = iter.concat(forLoopFinder(forLoop, output.name));
  
    const higherOrderFunc = esquery(ast, 'CallExpression').filter(ele => {
      let higherOrderChecker = false;
      const searched = bfs(ele).filter(n => {
        return n.type === 'JSXElement';
      });
      if (ele.callee.property && ele.callee.property.name.match(/(map|forEach|filter|reduce)/)) {
        higherOrderChecker = ele.callee.property.name.match(/(map|forEach|filter|reduce)/);
      }
      return searched.length > 0 && higherOrderChecker;
    });
    if (higherOrderFunc.length > 0) {
      iter = iter.concat(higherOrderFunctionFinder(higherOrderFunc, output.name));
    }
    if (outside) output.children.push(outside);
    output.children.forEach((ele, i) => {
      checker[ele.name] = i;
    });
  
    for (let i = 0; i < iter.length; i++) {
      if (checker.hasOwnProperty(iter[i].jsx.name)) {
        output.children[checker[iter[i].jsx.name]] = iter[i].jsx;
      }
    }
  
    return output;
  }