text: module.exports = function (fork) {
      fork.use(require("./es7"));
  
      var types = fork.use(require("../lib/types"));
      var def = types.Type.def;
      var or = types.Type.or;
      var defaults = fork.use(require("../lib/shared")).defaults;
  
      def("JSXAttribute")
        .bases("Node")
        .build("name", "value")
        .field("name", or(def("JSXIdentifier"), def("JSXNamespacedName")))
        .field("value", or(
          def("Literal"), // attr="value"
          def("JSXExpressionContainer"), // attr={value}
          null // attr= or just attr
        ), defaults["null"]);
  
      def("JSXIdentifier")
        .bases("Identifier")
        .build("name")
        .field("name", String);
  
      def("JSXNamespacedName")
        .bases("Node")
        .build("namespace", "name")
        .field("namespace", def("JSXIdentifier"))
        .field("name", def("JSXIdentifier"));
  
      def("JSXMemberExpression")
        .bases("MemberExpression")
        .build("object", "property")
        .field("object", or(def("JSXIdentifier"), def("JSXMemberExpression")))
        .field("property", def("JSXIdentifier"))
        .field("computed", Boolean, defaults.false);
  
      var JSXElementName = or(
        def("JSXIdentifier"),
        def("JSXNamespacedName"),
        def("JSXMemberExpression")
      );
  
      def("JSXSpreadAttribute")
        .bases("Node")
        .build("argument")
        .field("argument", def("Expression"));
  
      var JSXAttributes = [or(
        def("JSXAttribute"),
        def("JSXSpreadAttribute")
      )];
  
      def("JSXExpressionContainer")
        .bases("Expression")
        .build("expression")
        .field("expression", def("Expression"));
  
      def("JSXElement")
        .bases("Expression")
        .build("openingElement", "closingElement", "children")
        .field("openingElement", def("JSXOpeningElement"))
        .field("closingElement", or(def("JSXClosingElement"), null), defaults["null"])
        .field("children", [or(
          def("JSXElement"),
          def("JSXExpressionContainer"),
          def("JSXText"),
          def("Literal") // TODO Esprima should return JSXText instead.
        )], defaults.emptyArray)
        .field("name", JSXElementName, function () {
            // Little-known fact: the `this` object inside a default function
            // is none other than the partially-built object itself, and any
            // fields initialized directly from builder function arguments
            // (like openingElement, closingElement, and children) are
            // guaranteed to be available.
            return this.openingElement.name;
        }, true) // hidden from traversal
        .field("selfClosing", Boolean, function () {
            return this.openingElement.selfClosing;
        }, true) // hidden from traversal
        .field("attributes", JSXAttributes, function () {
            return this.openingElement.attributes;
        }, true); // hidden from traversal
  
      def("JSXOpeningElement")
        .bases("Node") // TODO Does this make sense? Can't really be an JSXElement.
        .build("name", "attributes", "selfClosing")
        .field("name", JSXElementName)
        .field("attributes", JSXAttributes, defaults.emptyArray)
        .field("selfClosing", Boolean, defaults["false"]);
  
      def("JSXClosingElement")
        .bases("Node") // TODO Same concern.
        .build("name")
        .field("name", JSXElementName);
  
      def("JSXText")
        .bases("Literal")
        .build("value")
        .field("value", String);
  
      def("JSXEmptyExpression").bases("Expression").build();
  
  };