Repository: prettier/prettier (JavaScript) — Feature

Issue:
Provide way to use single quotes in jsx
I read [this comment](https://github.com/prettier/prettier/issues/73#issuecomment-271953751) saying that "I've never seen anyone write `<div className='a' />`". Well, here's someone 👋 

The same way `trailingComma` accepts a string, we could let `singleQuote` do as well. 
- `'all'` would use single quotes in js as well as jsx
- `'js'` (or `true`) would use single quotes in js but not in jsx
- `'jsx'` would use single quotes in jsx but not in js


Discussion:
Here's someone else!
We currently use tslint with auto fixes which also changes all `"` in jsx to `'` so I guess people which use singlequotes and tslint is used to them in jsx too.
@Pajn Seems fitting that we're both from Sweden, the [land of single households](http://sverigesradio.se/sida/artikel.aspx?programid=2054&artikel=5722944) 🇸🇪 
Same here! I actually thought it was some sort of config mistake on my end when I saw it replace single quotes with double quotes.
We really, really don't want to add any more configuration options. Ideally when commas at the end of function parameter lists we can deprecate the options to trailing comma and just accept a single `--trailing-comma` option. The only reason we can't right now is because function arg trailing commas aren't valid JS, but people can use them with a babel transform.

I think the only option here is to decide if JSX should respect the quote option or not. This is the first I've heard someone complain about it which makes me think you're a small minority (sorry!). I think makes sense the way we currently do it since using double-quotes is a very strong style with HTML an that's why JSX applies the same practice.

It's worth having the discussion though. What do you think @rattrayalex and anyone else?
I understand and support the desire to keep configuration options down. I was actually surprised to see `singleQuote` as an option when I first started using the tool, I thought the majority had switched over to single quotes already.

I could see a solution where we just keep whatever quotes are used in jsx. I don't know how well that rhymes with the philosophy of prettier however. 
My impression is JSX style strongly encourages double-quotes; @trotzig I'm curious why you prefer single-quotes for JSX? Could double-quotes be acceptable?

EDIT: hello from [react-waypoint](https://github.com/brigade/react-waypoint/pull/152), by the way! 👋 
Hi @rattrayalex! 

Double quotes are definitely acceptable. It's a style thing we started doing a few years back, and I don't have strong feelings for or against it. I guess you could argue that single quotes makes it more obvious that we're not technically dealing with raw html (must use `className` instead of `class` etc). But yeah, we could fall into the mainstream here without much pain.
I always feel bad saying no but I think it's good for the long-term health of the project. Thanks for being open to changing your style! It would be really easy for our config to get really complicated if we catered to a lot of the existing styles. I think it's going to be really valuable for the JS community if a large portion of the styles are decided on.
Hm I know you just closed this, but I wanted to make a push for consistency - for the same reason that `--single-quote` is a flag, someone who uses single quotes as a stylistic choice would want to use that for JSX as well. (That's certainly the case for us - we just see JSX as a nice wrapper around `React.createElement`.)

Can we consider having the JSX behavior match non-JSX behavior?
@joshma I think most requests for options need a pretty strong use case at this point. Pure style preference usually isn't enough; part of the goal of the project is to rally the community around a single "style preference" (which, of course, nobody will be perfectly happy with – including the project maintainers). 

Would the status quo be usable for your team, or a blocker from using prettier?
@rattrayalex just to be clear, I'm not requesting another option, just that the JSX behavior matches the existing `--single-quote` option. (My claim is that most people are consistent between JSX and non-JSX code, although that could be wrong.)

It'd be a blocker somewhat, in the sense that I wouldn't switch our team over 😛 . I want to introduce prettier to reduce style discussions and encourage consistency, but in doing so we'd have to either convert our entire codebase (and in some sense create a lot of discussion) or accept inconsistency between "prettier" code and legacy code (which seems worse than what we have now).

FWIW, I totally accept that this project is allowed to make its own opinions on what's valuable for the JS community, but the value to my team is consistency in *some* style, not consistency in following a global style. And I think that's doable with the community at large also - you use whatever prettier config the codebase you're contributing to uses, and that's that.

Maybe we'll drift towards prettier's default config over time, but it seems better to gradually change things.
Hmm, interesting. Thanks for sharing @joshma !

> most people are consistent between JSX and non-JSX code, although that could be wrong.

that's not what I've seen – which is a strong majority using the recommended `"` in JSX, despite many using `'` elsewhere – but part of what makes this hard is that there isn't data anywhere, and everyone has different experiences 😕 
Interesting, it that just so it matches common HTML style?
It may also be because you can't escape a quote within JSX:
http://eslint.org/docs/rules/jsx-quotes

but, yes, I think the typical answer is that: https://github.com/airbnb/javascript/tree/master/react#quotes

>  Regular HTML attributes also typically use double quotes instead of single, so JSX attributes mirror this convention.

This question, like most others of similar import, is not without its controversy: https://github.com/airbnb/javascript/issues/269#issuecomment-134990455  and https://github.com/airbnb/javascript/issues/629
Totally agree maintainers can do what they think is best. 

I would just point out that @joshma is definitely not alone. This is also the reason my team uses single quote everywhere: consistency. In our case it's also simpler to tell new team members "single quote everywhere" rather than "single quote everywhere _**except**_ JSX". 
It's the simplest to tell new team members that they don't need to care about which quotes they type at all. prettier takes care of it ;)
Fair point @lydell 
I ran into this today, I thought it was a bug in prettier because I had set `singleQuote: true` and then arrived at this thread. I think it the comments for single quote in default settings should specific you only apply the option to `.js` and not `.jsx` if you are going to enforce this.

For me I can use prettier, and run `eslint assets --ext .jsx --fix` to convert all the double quotes prettier puts in back to single quotes, but I believe that either the docs or your idea is wrong in that

```
// If true, will use single instead of double quotes
"singleQuote": true,
```

should do what it says on the tin, and not have an undocumented exception for jsx

Perhaps
```
// If true, will use single instead of double quotes, except `.jsx` see https://github.com/prettier/prettier/issues/1080 for justification
"singleQuote": true,
```
@audiolion that makes sense! Care to submit a PR?
Sure, wont be till Monday with Easter tomorrow, cheers!
A big +1 for single quotes in JSX - or rather, a consistent application of the flag. It seems strange to me that people would prefer one in JSX and the other in JS.

FWIW, in Babel, the transformed code appears to result in single quotes regardless:

```
import React from 'react';
const foo = (<Foo prop1="double" prop2='single' />);
```

becomes

```
import React from 'react';
const foo = React.createElement(Foo, { prop1: 'double', prop2: 'single' });
```

;)
Oh man, I completely forgot about this! I will get this PR up today
@audiolion are you still planning a PR?
Hah, yes, I am so sorry this keeps slipping my mind, it is on my Trello board now
Where do we raise the voice for the `singleQuote` for all (js, jsx) or at least have that option #1084?! 
I think the discussion here indicates that they want to force a style on the entire community to get codebases mostly uniform, and less config options is better. I found that I can run prettier and then afterwards run `eslint <dir> --ext .jsx --fix` and my eslint rules will replace all double quotes that prettier added with single quotes. It isn't perfect but I think if you are in the minority and want this functionality, you need to have your own post-processor as Henrik's fantastic PR didn't make it in.
@audiolion See also [prettier-eslint](https://github.com/kentcdodds/prettier-eslint).
@lydell, @audiolion  `prettier-eslint` is unfortunately really slow if you want to run it every time you save a file. It would be great if it's supported directly by prettier. 
My suggestion is run it once before you commit your files so it passes linting
I also want to place a link to gaearon's (Redux creator) comment about single and double quotes in .jsx: https://github.com/airbnb/javascript/issues/269#issuecomment-134990455
Please reconsider allowing consistency.  Why?

- This issue has `21` 👍  and `0` 👎  reactions
- No new options are being proposed
- Consistency, JSX is written in JS
- The overwhelming majority of reactions to comments on all issues where this is discussed is to support single quotes and maintain JSX/JS consistency
- There are notable real world projects that use consistent JS/JSX quotes, like [Semantic UI React](https://github.com/Semantic-Org/Semantic-UI-React)
- There are other issues for this, such as #656
- It has confused many that `prettier` prints certain lines and columns of JS/JSX files differently with `--single-quote`: `<User bar="baz" rab={'zab?'} />`

Comments and support for this since have been largely dismissed as far back as https://github.com/prettier/prettier/issues/73#issuecomment-272014988, however, I see very few who agree that `--single-quote` should behave differently between JSX and JS.

Regarding:
>This is the first I've heard someone complain about it which makes me think you're a small minority (sorry!)

Though there were already 3 individuals in support when this comment was made, there are now within this issue alone:
- `@trotzig`
- `@Pajn`
- `@iansinnott`
- `@joshma`
- `@audiolion`
- `@jamesgpearce`
- `@shinzui`
- `@kshestakov`
- `@lipis`
- `@levithomason`

`@gaearon` is one of the most influential and respected in the React community.  Though he has spoken his peace and given up the bikeshedding, he had made good arguments for single quotes [here](https://github.com/airbnb/javascript/issues/269#issuecomment-134990455) and [here](https://github.com/airbnb/javascript/issues/269#issuecomment-135201861).  Again community reactions were 100% in favor, `18` total 👍 `0` 👎 .  He links several React issues supporting his statement:
>I always liked using single quotes in JSX precisely to highlight this isn't HTML.

***

My peace is spoken, would love to have more consistent and community accepted `--single-quote` behavior.  In either case, long live `prettier`.
FWIW, maybe this will help give some additional understanding on why people might use single quotes in JSX. In [office-ui-fabric-react](https://github.com/officedev/office-ui-fabric-react) we are using single quotes everywhere, and this has been an issue in consuming prettier. In our line of thinking, the context difference is not a good enough reason to special case usage.

This seems completely inconsistent. It's all JavaScript. We aren't in HTML. Why suddenly abandon conventions because we're in jsx? It's just confusing and adds more mental cycles.

```jsx
<div 
  className={ 'class name inside of curly brackets should be single quoted' } 
  bar="attribute value should be... double... unless you need to concat something, then switch back"
/>
```

We had a similar conversation about spaces in between curly brackets. Most of the community would accept this:

```ts
import { Foo } from 'bar';
const thing = { foo: 'bar' };
```

But then most JSX out there abandons the spacing for some reason, probably to reduce the line lengths:

```tsx
<div className={foo} />
```

Similar convention would be in back-tick strings:

```tsx
const name = `My name is ${displayName}.`;
```

So... why deviate in specific contexts? It makes the rules complicated and special cased. If you pick one or the other and stick with it, there are less special cases to explain. If you like shorter line lengths, no spaces inside curlies anywhere. 

Likewise, if you like single quotes, use them everywhere (assuming you're still in JavaScript and not writing JSON or HTML which changes the entire styling context.)

I love prettier because it can ensure whatever rule is picked is what is checked in. I don't really have an issue with adding config settings, as long as the default are generally what's accepted.

But the current design making the quotes configurable, while in the context of jsx not configurable, is an unpredictable halfway design that creates confusion and frustration. Pick single quotes or double quotes everywhere, or don't let it be configurable at all. Pick spaces or no spaces, or don't let it be configurable at all. 

Or, make everything configurable (like estlint / tslint / vscode formatting), complete with contextual scenarios (`jsxSingleQuotes`, `backTickSpacesInsideCurlies`), make the defaults echo the general community direction (path of least resistance becomes the default approach), and make everyone happy, even the odd person out that has some alternative insight on the problem space.

The :+1:/:-1: ratio here is compelling to me, along with the statements from `@gaearon` and others whose work I respect. There's also already a flag for quotes (we just need to add another option to it, which in this case would not be very expensive to implement). So I will reopen this issue and mark it as seeking PR's. 

I will leave it up to other maintainers (probably @vjeux ) to decide whether to merge a PR, and I hope that the community will understand if the choice is to not merge. 

If that occurs, I would urge you to either: 

1) Use `double` if you just want consistency between js and jsx.
2) Use eslint (eg; via https://github.com/prettier/prettier-eslint) to override prettier where you disagree with it.
3) Give in 😜 

There isn't much more to be said on the topic and it seems this is going in loops, so I will close this issue to comments. Feel free to message me privately if you think this is in error.
For reference, there's some more discussion on this in https://github.com/prettier/prettier/issues/3437
How about printing single quotes in JSX and JS if `singleQuote` is `true`, printing single quotes in JS but not JSX if `singleQuote` is `"js"`, printing single quotes in JSX but not JS if `singleQuote` is `"jsx"`, and not printing single quotes if `singleQuote` is `false` (strings containing single/double quotes will continue to avoid escapes)?
@j-f1 if we choose to extend that option for this (which is still somewhat up in the air), then that implementation sounds fine to me.

Also, for reference, @duailibe raises an important point here that could affect implementation details and/or decision(s): https://github.com/prettier/prettier/issues/3437#issuecomment-351209905
Should this issue be unlocked to allow people to 👍?
Unlocking 🔑 to allow people to 👍/👎.

**Please don’t comment unless you have something to add that hasn’t already been said, and please don’t comment** +1 **or** 👍 **and instead use the 👍 reaction button on [the original comment](https://github.com/prettier/prettier/issues/1080#issue-216355660) to indicate your support.**
If this proposal is accepted, I will gladly submit the patch. I already submitted a PR in the past and am more than willing to make whatever changes are necessary.
The [Rational](https://prettier.io/docs/en/rationale.html) clearly says:
> JSX always uses double quotes. JSX takes its roots from HTML, where the dominant use of quotes for attributes is double quotes. Browser developer tools also follow this convention by always displaying HTML with double quotes, even if the source code uses single quotes.

However, the (X)HTML/SGML standards, as long as I have been writing HTML (over 20 years) have been to allow both single and double quotes for attributes.

## HTML5
* https://www.w3.org/TR/2012/WD-html-markup-20120320/syntax.html#syntax-attributes
* https://www.w3.org/TR/2011/WD-html5-20110113/tokenization.html#attribute-value-double-quoted-state

## HTML 4
* https://www.w3.org/TR/html4/intro/sgmltut.html#attributes

## HTML 3.2
* https://www.w3.org/TR/2018/SPSD-html32-20180315/

The "convention" has *always* been to allow both. That someone *feels* that one is preferred over the other is completely arbitrary. There are reasons to use one over the other and *both* are valid.

The statement that "dominant use of quotes for attributes is double quotes" seems to be entirely untrue. There is no evidence at all to support that claim. From my own personal experience, I always use single quotes for strings unless there is a reason to use double quotes, this includes HTML attributes. I know that most of my peers also use the same convention. 

Clearly **actual** HTML standards should drive specification, not someone's **feeling** that something is "dominant" or "typical", and certainly when there is no evidence to support such a claim of dominance.

I am adding this comment because no one has mention that supporting both is the **actual HTML standard**.

Also, since someone asked this of another earlier, I would like to say that this seems to be a blocker for my team. We cannot use `prettier` because our convention is to use single quotes unless we are doing interpolation or when having to escape single quotes makes things not easily readable ([JavaScript Standard Style](https://github.com/standard/standard)). We use `standard` on save, and `prettier` and `eslint` on pre-commit. I will look into changing the flow from `eslint` -> `prettier` to `prettier` -> `eslint` on pre-commit, perhaps using [prettier-eslint](https://github.com/prettier/prettier-eslint). Thanks to @lydell, @audiolion, and @shinzui for your comments, I hope they prove helpful.
A dominant convention is a defacto standard.
bump.
i know there's a comment above saying not to +1, but the original comment has 62 👍 already and this issue has been stale for a month now
@smirea Feel free to open a PR! (Perhaps [my suggestion](https://github.com/prettier/prettier/issues/1080#issuecomment-378567278) would make a good starting point?)
sure thing! I thought there already was a PR for this but I guess I miss-remembered

@j-f1 [this is a working proof of concept based on your suggestion](https://github.com/smirea/prettier/commit/d1fa72e3a240d9e78e7e3e73c930e545bbbb0335), seems pretty straightforward but want to make sure I'm not overlooking something

```bash
cat <<CODE > /tmp/test-prettier.js && echo '------' && ./bin/prettier.js /tmp/test-prettier.js --single-quote=all
const a = "foo";
const jsx = <div style="color:red" this-should='stay the same'>some quotes "that should not" change</div>
CODE
```

if it looks good I can go ahead and write some tests and open a PR
That looks great!
@smirea There was! I submitted it a while back but eventually it withered on the vine. It'd need to be updated with the latest suggestions from @j-f1 and rebased as well. If it helps, you can find the work I did [here](https://github.com/prettier/prettier/pull/3839). I don't mind updating it if that's the route we want to go but it sounds like you're already doing quite well without it. Thanks for looking into this!

Edit: One final thing that I remembered... Not sure if @j-f1 still wants it or not, but he had suggested some changes regarding replacing `&apos;` which you can find in my PR in printer-estree.js:1640.
Thanks all, I submitted [a preliminary PR](https://github.com/prettier/prettier/pull/4798) if y'all can take a gander and give some feedback
Anyone here can review/approve that PR please?
Gentle ping to maintainers on this PR - can anyone take a look?
@konpikwastaken I opened this PR over a year ago and have since moved on to using double quotes. I have no desire to pick it up.
well we can't really approve this, but someone should.

If you are not drowning, it doesn't mean everyone else isn't.
I’m not a maintainer of this project, so even if I wanted to I couldn’t merge this. I’m going to close this, and I encourage discussion/work to continue elsewhere.

EDIT: apologies, I thought I was commenting on my pull request...

Resolving patch:
diff --git a/docs/options.md b/docs/options.md
index 2fedcbd58207..46b6b9b5de33 100644
--- a/docs/options.md
+++ b/docs/options.md
@@ -60,7 +60,7 @@ Use single quotes instead of double quotes.
 
 Notes:
 
-- Quotes in JSX will always be double and ignore this setting.
+- JSX quotes ignore this option – see [jsx-single-quote](#jsx-single-quote).
 - If the number of quotes outweighs the other quote, the quote which is less used will be used to format the string - Example: `"I'm double quoted"` results in `"I'm double quoted"` and `"This \"example\" is single quoted"` results in `'This "example" is single quoted'`.
 
 See the [strings rationale](rationale.md#strings) for more information.
@@ -69,6 +69,14 @@ See the [strings rationale](rationale.md#strings) for more information.
 | ------- | ---------------- | --------------------- |
 | `false` | `--single-quote` | `singleQuote: <bool>` |
 
+## JSX Quotes
+
+Use single quotes instead of double quotes in JSX.
+
+| Default | CLI Override         | API Override             |
+| ------- | -------------------- | ------------------------ |
+| `false` | `--jsx-single-quote` | `jsxSingleQuote: <bool>` |
+
 ## Trailing Commas
 
 Print trailing commas wherever possible when multi-line. (A single-line array, for example, never gets trailing commas.)
diff --git a/src/common/util.js b/src/common/util.js
index 7bea29ca574c..bea82d1707ac 100644
--- a/src/common/util.js
+++ b/src/common/util.js
@@ -430,7 +430,7 @@ function getIndentSize(value, tabWidth) {
   );
 }
 
-function printString(raw, options, isDirectiveLiteral) {
+function getPreferredQuote(raw, preferredQuote) {
   // `rawContent` is the string exactly like it appeared in the input source
   // code, without its enclosing quotes.
   const rawContent = raw.slice(1, -1);
@@ -438,17 +438,14 @@ function printString(raw, options, isDirectiveLiteral) {
   const double = { quote: '"', regex: /"/g };
   const single = { quote: "'", regex: /'/g };
 
-  const preferred = options.singleQuote ? single : double;
+  const preferred = preferredQuote === "'" ? single : double;
   const alternate = preferred === single ? double : single;
 
-  let shouldUseAlternateQuote = false;
-  let canChangeDirectiveQuotes = false;
+  let result = preferred.quote;
 
   // If `rawContent` contains at least one of the quote preferred for enclosing
   // the string, we might want to enclose with the alternate quote instead, to
   // minimize the number of escaped quotes.
-  // Also check for the alternate quote, to determine if we're allowed to swap
-  // the quotes on a DirectiveLiteral.
   if (
     rawContent.includes(preferred.quote) ||
     rawContent.includes(alternate.quote)
@@ -456,19 +453,31 @@ function printString(raw, options, isDirectiveLiteral) {
     const numPreferredQuotes = (rawContent.match(preferred.regex) || []).length;
     const numAlternateQuotes = (rawContent.match(alternate.regex) || []).length;
 
-    shouldUseAlternateQuote = numPreferredQuotes > numAlternateQuotes;
-  } else {
-    canChangeDirectiveQuotes = true;
+    result =
+      numPreferredQuotes > numAlternateQuotes
+        ? alternate.quote
+        : preferred.quote;
   }
 
+  return result;
+}
+
+function printString(raw, options, isDirectiveLiteral) {
+  // `rawContent` is the string exactly like it appeared in the input source
+  // code, without its enclosing quotes.
+  const rawContent = raw.slice(1, -1);
+
+  // Check for the alternate quote, to determine if we're allowed to swap
+  // the quotes on a DirectiveLiteral.
+  const canChangeDirectiveQuotes =
+    !rawContent.includes('"') && !rawContent.includes("'");
+
   const enclosingQuote =
     options.parser === "json"
-      ? double.quote
+      ? '"'
       : options.__isInHtmlAttribute
-        ? single.quote
-        : shouldUseAlternateQuote
-          ? alternate.quote
-          : preferred.quote;
+        ? "'"
+        : getPreferredQuote(raw, options.singleQuote ? "'" : '"');
 
   // Directives are exact code unit sequences, which means that you can't
   // change the escape sequences they use.
@@ -691,6 +700,7 @@ module.exports = {
   startsWithNoLookaheadToken,
   getAlignmentSize,
   getIndentSize,
+  getPreferredQuote,
   printString,
   printNumber,
   hasIgnoreComment,
diff --git a/src/language-js/options.js b/src/language-js/options.js
index 2635f7f1ecbf..a20e269f7118 100644
--- a/src/language-js/options.js
+++ b/src/language-js/options.js
@@ -41,6 +41,13 @@ module.exports = {
       "Do not print semicolons, except at the beginning of lines which may need them."
   },
   singleQuote: commonOptions.singleQuote,
+  jsxSingleQuote: {
+    since: "1.15.0",
+    category: CATEGORY_JAVASCRIPT,
+    type: "boolean",
+    default: false,
+    description: "Use single quotes in JSX."
+  },
   trailingComma: {
     since: "0.0.0",
     category: CATEGORY_JAVASCRIPT,
diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js
index 515eda801c97..27167a80938f 100644
--- a/src/language-js/printer-estree.js
+++ b/src/language-js/printer-estree.js
@@ -20,7 +20,8 @@ const {
   getPenultimate,
   startsWithNoLookaheadToken,
   getIndentSize,
-  matchAncestorTypes
+  matchAncestorTypes,
+  getPreferredQuote
 } = require("../common/util");
 const {
   isNextLineEmpty,
@@ -33,8 +34,8 @@ const clean = require("./clean");
 const insertPragma = require("./pragma").insertPragma;
 const handleComments = require("./comments");
 const pathNeedsParens = require("./needs-parens");
-const preprocess = require("./preprocess");
 const { printHtmlBinding } = require("./html-binding");
+const preprocess = require("./preprocess");
 const {
   hasNode,
   hasFlowAnnotationComment,
@@ -1948,8 +1949,16 @@ function printPathNoParens(path, options, print, args) {
       if (n.value) {
         let res;
         if (isStringLiteral(n.value)) {
-          const value = rawText(n.value);
-          res = '"' + value.slice(1, -1).replace(/"/g, "&quot;") + '"';
+          const raw = rawText(n.value);
+          // Unescape all quotes so we get an accurate preferred quote
+          let final = raw.replace(/&apos;/g, "'").replace(/&quot;/g, '"');
+          const quote = getPreferredQuote(
+            final,
+            options.jsxSingleQuote ? "'" : '"'
+          );
+          const escape = quote === "'" ? "&apos;" : "&quot;";
+          final = final.slice(1, -1).replace(new RegExp(quote, "g"), escape);
+          res = concat([quote, final, quote]);
         } else {
           res = path.call(print, "value");
         }
@@ -5257,7 +5266,7 @@ function printJSXElement(path, options, print) {
     containsMultipleAttributes ||
     containsMultipleExpressions;
 
-  const rawJsxWhitespace = options.singleQuote ? "{' '}" : '{" "}';
+  const rawJsxWhitespace = options.jsxSingleQuote ? "{' '}" : '{" "}';
   const jsxWhitespace = ifBreak(concat([rawJsxWhitespace, softline]), " ");
 
   const isFacebookTranslationTag =


Test patch:
diff --git a/tests/jsx/__snapshots__/jsfmt.spec.js.snap b/tests/jsx/__snapshots__/jsfmt.spec.js.snap
index f13e52886219..6554eb7076eb 100644
--- a/tests/jsx/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/jsx/__snapshots__/jsfmt.spec.js.snap
@@ -69,6 +69,213 @@ const TodoList = ({ todos }) => (
 
 `;
 
+exports[`array-iter.js - flow-verify 2`] = `
+const UsersList = ({ users }) => (
+  <section>
+    <h2>Users list</h2>
+    <ul>
+      {users.map(user => (
+        <li key={user.id}>{user.name}</li>
+      ))}
+    </ul>
+  </section>
+)
+
+const TodoList = ({ todos }) => (
+  <div className="TodoList">
+    <ul>{_.map(todos, (todo, i) => <TodoItem key={i} {...todo} />)}</ul>
+  </div>
+);
+
+<div className="search-filter-chips">
+    {scopes
+        .filter(scope => scope.value !== '')
+        .map((scope, i) => (
+            <FilterChip
+                query={this.props.query}
+                onFilterChosen={this.onSearchScopeClicked}
+                key={i}
+                value={scope.value}
+                name={scope.name}
+            />
+        ))}
+</div>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const UsersList = ({ users }) => (
+  <section>
+    <h2>Users list</h2>
+    <ul>
+      {users.map(user => (
+        <li key={user.id}>{user.name}</li>
+      ))}
+    </ul>
+  </section>
+);
+
+const TodoList = ({ todos }) => (
+  <div className='TodoList'>
+    <ul>
+      {_.map(todos, (todo, i) => (
+        <TodoItem key={i} {...todo} />
+      ))}
+    </ul>
+  </div>
+);
+
+<div className='search-filter-chips'>
+  {scopes
+    .filter(scope => scope.value !== "")
+    .map((scope, i) => (
+      <FilterChip
+        query={this.props.query}
+        onFilterChosen={this.onSearchScopeClicked}
+        key={i}
+        value={scope.value}
+        name={scope.name}
+      />
+    ))}
+</div>;
+
+`;
+
+exports[`array-iter.js - flow-verify 3`] = `
+const UsersList = ({ users }) => (
+  <section>
+    <h2>Users list</h2>
+    <ul>
+      {users.map(user => (
+        <li key={user.id}>{user.name}</li>
+      ))}
+    </ul>
+  </section>
+)
+
+const TodoList = ({ todos }) => (
+  <div className="TodoList">
+    <ul>{_.map(todos, (todo, i) => <TodoItem key={i} {...todo} />)}</ul>
+  </div>
+);
+
+<div className="search-filter-chips">
+    {scopes
+        .filter(scope => scope.value !== '')
+        .map((scope, i) => (
+            <FilterChip
+                query={this.props.query}
+                onFilterChosen={this.onSearchScopeClicked}
+                key={i}
+                value={scope.value}
+                name={scope.name}
+            />
+        ))}
+</div>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const UsersList = ({ users }) => (
+  <section>
+    <h2>Users list</h2>
+    <ul>
+      {users.map(user => (
+        <li key={user.id}>{user.name}</li>
+      ))}
+    </ul>
+  </section>
+);
+
+const TodoList = ({ todos }) => (
+  <div className="TodoList">
+    <ul>
+      {_.map(todos, (todo, i) => (
+        <TodoItem key={i} {...todo} />
+      ))}
+    </ul>
+  </div>
+);
+
+<div className="search-filter-chips">
+  {scopes
+    .filter(scope => scope.value !== '')
+    .map((scope, i) => (
+      <FilterChip
+        query={this.props.query}
+        onFilterChosen={this.onSearchScopeClicked}
+        key={i}
+        value={scope.value}
+        name={scope.name}
+      />
+    ))}
+</div>;
+
+`;
+
+exports[`array-iter.js - flow-verify 4`] = `
+const UsersList = ({ users }) => (
+  <section>
+    <h2>Users list</h2>
+    <ul>
+      {users.map(user => (
+        <li key={user.id}>{user.name}</li>
+      ))}
+    </ul>
+  </section>
+)
+
+const TodoList = ({ todos }) => (
+  <div className="TodoList">
+    <ul>{_.map(todos, (todo, i) => <TodoItem key={i} {...todo} />)}</ul>
+  </div>
+);
+
+<div className="search-filter-chips">
+    {scopes
+        .filter(scope => scope.value !== '')
+        .map((scope, i) => (
+            <FilterChip
+                query={this.props.query}
+                onFilterChosen={this.onSearchScopeClicked}
+                key={i}
+                value={scope.value}
+                name={scope.name}
+            />
+        ))}
+</div>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const UsersList = ({ users }) => (
+  <section>
+    <h2>Users list</h2>
+    <ul>
+      {users.map(user => (
+        <li key={user.id}>{user.name}</li>
+      ))}
+    </ul>
+  </section>
+);
+
+const TodoList = ({ todos }) => (
+  <div className='TodoList'>
+    <ul>
+      {_.map(todos, (todo, i) => (
+        <TodoItem key={i} {...todo} />
+      ))}
+    </ul>
+  </div>
+);
+
+<div className='search-filter-chips'>
+  {scopes
+    .filter(scope => scope.value !== '')
+    .map((scope, i) => (
+      <FilterChip
+        query={this.props.query}
+        onFilterChosen={this.onSearchScopeClicked}
+        key={i}
+        value={scope.value}
+        name={scope.name}
+      />
+    ))}
+</div>;
+
+`;
+
 exports[`attr-comments.js - flow-verify 1`] = `
 <Component
   propFn={
@@ -136,64 +343,265 @@ exports[`attr-comments.js - flow-verify 1`] = `
 
 `;
 
-exports[`conditional-expression.js - flow-verify 1`] = `
-// There are two ways to print ConditionalExpressions: "normal mode" and
-// "JSX mode". This is normal mode (when breaking):
-//
-//   test
-//     ? consequent
-//     : alternate;
-//
-// And this is JSX mode (when breaking):
-//
-//   test ? (
-//     consequent
-//   ) : (
-//     alternate
-//   );
-//
-// When non-breaking, they look the same:
-//
-//  test ? consequent : alternate;
-//
-// We only print a conditional expression in JSX mode if its test,
-// consequent, or alternate are JSXElements.
-// Otherwise, we print in normal mode.
-
-// This ConditionalExpression has no JSXElements so it prints in normal mode.
-// The line does not break.
-normalModeNonBreaking ? "a" : "b";
-
-// This ConditionalExpression has no JSXElements so it prints in normal mode.
-// Its consequent is very long, so it breaks out to multiple lines.
-normalModeBreaking
-  ? johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
-  : "c";
-
-// This ConditionalExpression prints in JSX mode because its test is a
-// JSXElement. It is non-breaking.
-// Note: I have never, ever seen someone use a JSXElement as the test in a
-// ConditionalExpression. But this test is included for completeness.
-<div /> ? jsxModeFromElementNonBreaking : "a";
-
-// This ConditionalExpression prints in JSX mode because its consequent is a
-// JSXElement. It is non-breaking.
-jsxModeFromElementNonBreaking ? <div /> : "a";
-
-// This ConditionalExpression prints in JSX mode because its alternate is a
-// JSXElement. It is non-breaking.
-jsxModeFromElementNonBreaking ? "a" : <div />;
-
-// This ConditionalExpression prints in JSX mode because its test is a
-// JSXElement. It is breaking.
-// Note: I have never, ever seen someone use a JSXElement as the test in a
-// ConditionalExpression. But this test is included for completeness.
-<div>
-  <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
-</div>  ? (
-  "jsx mode from element breaking"
-) : (
-  "a"
+exports[`attr-comments.js - flow-verify 2`] = `
+<Component
+  propFn={
+    // comment
+    function(arg) {
+      fn(arg);
+    }
+  }
+  propArrowFn={
+    // comment
+    arg => fn(arg)
+  }
+  propArrowWithBreak={
+    // comment
+    arg =>
+      fn({
+        makeItBreak
+      })
+  }
+  propArray={
+    // comment
+    [el1, el2]
+  }
+  propObj={
+    // comment
+    { key: val }
+  }
+  propTemplate={
+    // comment
+    \`text\`
+  }
+/>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<Component
+  propFn={
+    // comment
+    function(arg) {
+      fn(arg);
+    }
+  }
+  propArrowFn={
+    // comment
+    arg => fn(arg)
+  }
+  propArrowWithBreak={
+    // comment
+    arg =>
+      fn({
+        makeItBreak
+      })
+  }
+  propArray={
+    // comment
+    [el1, el2]
+  }
+  propObj={
+    // comment
+    { key: val }
+  }
+  propTemplate={
+    // comment
+    \`text\`
+  }
+/>;
+
+`;
+
+exports[`attr-comments.js - flow-verify 3`] = `
+<Component
+  propFn={
+    // comment
+    function(arg) {
+      fn(arg);
+    }
+  }
+  propArrowFn={
+    // comment
+    arg => fn(arg)
+  }
+  propArrowWithBreak={
+    // comment
+    arg =>
+      fn({
+        makeItBreak
+      })
+  }
+  propArray={
+    // comment
+    [el1, el2]
+  }
+  propObj={
+    // comment
+    { key: val }
+  }
+  propTemplate={
+    // comment
+    \`text\`
+  }
+/>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<Component
+  propFn={
+    // comment
+    function(arg) {
+      fn(arg);
+    }
+  }
+  propArrowFn={
+    // comment
+    arg => fn(arg)
+  }
+  propArrowWithBreak={
+    // comment
+    arg =>
+      fn({
+        makeItBreak
+      })
+  }
+  propArray={
+    // comment
+    [el1, el2]
+  }
+  propObj={
+    // comment
+    { key: val }
+  }
+  propTemplate={
+    // comment
+    \`text\`
+  }
+/>;
+
+`;
+
+exports[`attr-comments.js - flow-verify 4`] = `
+<Component
+  propFn={
+    // comment
+    function(arg) {
+      fn(arg);
+    }
+  }
+  propArrowFn={
+    // comment
+    arg => fn(arg)
+  }
+  propArrowWithBreak={
+    // comment
+    arg =>
+      fn({
+        makeItBreak
+      })
+  }
+  propArray={
+    // comment
+    [el1, el2]
+  }
+  propObj={
+    // comment
+    { key: val }
+  }
+  propTemplate={
+    // comment
+    \`text\`
+  }
+/>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<Component
+  propFn={
+    // comment
+    function(arg) {
+      fn(arg);
+    }
+  }
+  propArrowFn={
+    // comment
+    arg => fn(arg)
+  }
+  propArrowWithBreak={
+    // comment
+    arg =>
+      fn({
+        makeItBreak
+      })
+  }
+  propArray={
+    // comment
+    [el1, el2]
+  }
+  propObj={
+    // comment
+    { key: val }
+  }
+  propTemplate={
+    // comment
+    \`text\`
+  }
+/>;
+
+`;
+
+exports[`conditional-expression.js - flow-verify 1`] = `
+// There are two ways to print ConditionalExpressions: "normal mode" and
+// "JSX mode". This is normal mode (when breaking):
+//
+//   test
+//     ? consequent
+//     : alternate;
+//
+// And this is JSX mode (when breaking):
+//
+//   test ? (
+//     consequent
+//   ) : (
+//     alternate
+//   );
+//
+// When non-breaking, they look the same:
+//
+//  test ? consequent : alternate;
+//
+// We only print a conditional expression in JSX mode if its test,
+// consequent, or alternate are JSXElements.
+// Otherwise, we print in normal mode.
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// The line does not break.
+normalModeNonBreaking ? "a" : "b";
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// Its consequent is very long, so it breaks out to multiple lines.
+normalModeBreaking
+  ? johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
+  : "c";
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is non-breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div /> ? jsxModeFromElementNonBreaking : "a";
+
+// This ConditionalExpression prints in JSX mode because its consequent is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? <div /> : "a";
+
+// This ConditionalExpression prints in JSX mode because its alternate is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? "a" : <div />;
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div>
+  <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+</div>  ? (
+  "jsx mode from element breaking"
+) : (
+  "a"
 );
 
 // This ConditionalExpression prints in JSX mode because its consequent is a
@@ -415,540 +823,3523 @@ cable ? (
 
 `;
 
+exports[`conditional-expression.js - flow-verify 2`] = `
+// There are two ways to print ConditionalExpressions: "normal mode" and
+// "JSX mode". This is normal mode (when breaking):
+//
+//   test
+//     ? consequent
+//     : alternate;
+//
+// And this is JSX mode (when breaking):
+//
+//   test ? (
+//     consequent
+//   ) : (
+//     alternate
+//   );
+//
+// When non-breaking, they look the same:
+//
+//  test ? consequent : alternate;
+//
+// We only print a conditional expression in JSX mode if its test,
+// consequent, or alternate are JSXElements.
+// Otherwise, we print in normal mode.
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// The line does not break.
+normalModeNonBreaking ? "a" : "b";
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// Its consequent is very long, so it breaks out to multiple lines.
+normalModeBreaking
+  ? johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
+  : "c";
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is non-breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div /> ? jsxModeFromElementNonBreaking : "a";
+
+// This ConditionalExpression prints in JSX mode because its consequent is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? <div /> : "a";
+
+// This ConditionalExpression prints in JSX mode because its alternate is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? "a" : <div />;
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div>
+  <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+</div>  ? (
+  "jsx mode from element breaking"
+) : (
+  "a"
+);
+
+// This ConditionalExpression prints in JSX mode because its consequent is a
+// JSXElement. It is breaking.
+jsxModeFromElementBreaking ? (
+  <div>
+    <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+  </div>
+) : (
+  "a"
+);
+
+// This ConditionalExpression prints in JSX mode because its alternate is a
+// JSXElement. It is breaking.
+jsxModeFromElementBreaking ? (
+  "a"
+) : (
+  <div>
+    <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+  </div>
+);
+
+// This chain of ConditionalExpressions prints in JSX mode because the parent of
+// the outermost ConditionalExpression is a JSXExpressionContainer. It is
+// non-breaking.
+<div>
+  {a ? "a" : b ? "b" : "c"}
+</div>;
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain. It is non-breaking.
+cable ? "satellite" : public ? "affairs" : network ? <span id="c" /> : "dunno";
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain (in this case, at the end). It is
+// breaking; notice the consequents and alternates in the entire chain get
+// wrapped in parens.
+cable ? (
+  "satellite"
+) : public ? (
+  "affairs"
+) : network ? (
+  <div>
+    <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+  </div>
+) : "dunno";
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain (in this case, at the beginning). It is
+// breaking; notice the consequents and alternates in the entire chain get
+// wrapped in parens.
+cable ? (
+  <div>
+    <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+  </div>
+) : sateline ? (
+  "public"
+) : affairs ? (
+  "network"
+) : "dunno";
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain. It is breaking; notice the consequents
+// and alternates in the entire chain get wrapped in parens.
+<div>
+  {properties.length > 1 ||
+  (properties.length === 1 && properties[0].apps.size > 1) ? (
+    draggingApp == null || newPropertyName == null ? (
+      <MigrationPropertyListItem />
+    ) : (
+      <MigrationPropertyListItem apps={Immutable.List()} />
+    )
+  ) : null}
+</div>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// There are two ways to print ConditionalExpressions: "normal mode" and
+// "JSX mode". This is normal mode (when breaking):
+//
+//   test
+//     ? consequent
+//     : alternate;
+//
+// And this is JSX mode (when breaking):
+//
+//   test ? (
+//     consequent
+//   ) : (
+//     alternate
+//   );
+//
+// When non-breaking, they look the same:
+//
+//  test ? consequent : alternate;
+//
+// We only print a conditional expression in JSX mode if its test,
+// consequent, or alternate are JSXElements.
+// Otherwise, we print in normal mode.
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// The line does not break.
+normalModeNonBreaking ? "a" : "b";
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// Its consequent is very long, so it breaks out to multiple lines.
+normalModeBreaking
+  ? johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
+  : "c";
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is non-breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div /> ? jsxModeFromElementNonBreaking : "a";
+
+// This ConditionalExpression prints in JSX mode because its consequent is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? <div /> : "a";
+
+// This ConditionalExpression prints in JSX mode because its alternate is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? "a" : <div />;
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div>
+  <span>
+    thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+  </span>
+</div> ? (
+  "jsx mode from element breaking"
+) : (
+  "a"
+);
+
+// This ConditionalExpression prints in JSX mode because its consequent is a
+// JSXElement. It is breaking.
+jsxModeFromElementBreaking ? (
+  <div>
+    <span>
+      thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+    </span>
+  </div>
+) : (
+  "a"
+);
+
+// This ConditionalExpression prints in JSX mode because its alternate is a
+// JSXElement. It is breaking.
+jsxModeFromElementBreaking ? (
+  "a"
+) : (
+  <div>
+    <span>
+      thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+    </span>
+  </div>
+);
+
+// This chain of ConditionalExpressions prints in JSX mode because the parent of
+// the outermost ConditionalExpression is a JSXExpressionContainer. It is
+// non-breaking.
+<div>{a ? "a" : b ? "b" : "c"}</div>;
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain. It is non-breaking.
+cable ? "satellite" : public ? "affairs" : network ? <span id='c' /> : "dunno";
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain (in this case, at the end). It is
+// breaking; notice the consequents and alternates in the entire chain get
+// wrapped in parens.
+cable ? (
+  "satellite"
+) : public ? (
+  "affairs"
+) : network ? (
+  <div>
+    <span>
+      thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+    </span>
+  </div>
+) : (
+  "dunno"
+);
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain (in this case, at the beginning). It is
+// breaking; notice the consequents and alternates in the entire chain get
+// wrapped in parens.
+cable ? (
+  <div>
+    <span>
+      thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+    </span>
+  </div>
+) : sateline ? (
+  "public"
+) : affairs ? (
+  "network"
+) : (
+  "dunno"
+);
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain. It is breaking; notice the consequents
+// and alternates in the entire chain get wrapped in parens.
+<div>
+  {properties.length > 1 ||
+  (properties.length === 1 && properties[0].apps.size > 1) ? (
+    draggingApp == null || newPropertyName == null ? (
+      <MigrationPropertyListItem />
+    ) : (
+      <MigrationPropertyListItem apps={Immutable.List()} />
+    )
+  ) : null}
+</div>;
+
+`;
+
+exports[`conditional-expression.js - flow-verify 3`] = `
+// There are two ways to print ConditionalExpressions: "normal mode" and
+// "JSX mode". This is normal mode (when breaking):
+//
+//   test
+//     ? consequent
+//     : alternate;
+//
+// And this is JSX mode (when breaking):
+//
+//   test ? (
+//     consequent
+//   ) : (
+//     alternate
+//   );
+//
+// When non-breaking, they look the same:
+//
+//  test ? consequent : alternate;
+//
+// We only print a conditional expression in JSX mode if its test,
+// consequent, or alternate are JSXElements.
+// Otherwise, we print in normal mode.
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// The line does not break.
+normalModeNonBreaking ? "a" : "b";
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// Its consequent is very long, so it breaks out to multiple lines.
+normalModeBreaking
+  ? johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
+  : "c";
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is non-breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div /> ? jsxModeFromElementNonBreaking : "a";
+
+// This ConditionalExpression prints in JSX mode because its consequent is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? <div /> : "a";
+
+// This ConditionalExpression prints in JSX mode because its alternate is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? "a" : <div />;
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div>
+  <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+</div>  ? (
+  "jsx mode from element breaking"
+) : (
+  "a"
+);
+
+// This ConditionalExpression prints in JSX mode because its consequent is a
+// JSXElement. It is breaking.
+jsxModeFromElementBreaking ? (
+  <div>
+    <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+  </div>
+) : (
+  "a"
+);
+
+// This ConditionalExpression prints in JSX mode because its alternate is a
+// JSXElement. It is breaking.
+jsxModeFromElementBreaking ? (
+  "a"
+) : (
+  <div>
+    <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+  </div>
+);
+
+// This chain of ConditionalExpressions prints in JSX mode because the parent of
+// the outermost ConditionalExpression is a JSXExpressionContainer. It is
+// non-breaking.
+<div>
+  {a ? "a" : b ? "b" : "c"}
+</div>;
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain. It is non-breaking.
+cable ? "satellite" : public ? "affairs" : network ? <span id="c" /> : "dunno";
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain (in this case, at the end). It is
+// breaking; notice the consequents and alternates in the entire chain get
+// wrapped in parens.
+cable ? (
+  "satellite"
+) : public ? (
+  "affairs"
+) : network ? (
+  <div>
+    <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+  </div>
+) : "dunno";
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain (in this case, at the beginning). It is
+// breaking; notice the consequents and alternates in the entire chain get
+// wrapped in parens.
+cable ? (
+  <div>
+    <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+  </div>
+) : sateline ? (
+  "public"
+) : affairs ? (
+  "network"
+) : "dunno";
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain. It is breaking; notice the consequents
+// and alternates in the entire chain get wrapped in parens.
+<div>
+  {properties.length > 1 ||
+  (properties.length === 1 && properties[0].apps.size > 1) ? (
+    draggingApp == null || newPropertyName == null ? (
+      <MigrationPropertyListItem />
+    ) : (
+      <MigrationPropertyListItem apps={Immutable.List()} />
+    )
+  ) : null}
+</div>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// There are two ways to print ConditionalExpressions: "normal mode" and
+// "JSX mode". This is normal mode (when breaking):
+//
+//   test
+//     ? consequent
+//     : alternate;
+//
+// And this is JSX mode (when breaking):
+//
+//   test ? (
+//     consequent
+//   ) : (
+//     alternate
+//   );
+//
+// When non-breaking, they look the same:
+//
+//  test ? consequent : alternate;
+//
+// We only print a conditional expression in JSX mode if its test,
+// consequent, or alternate are JSXElements.
+// Otherwise, we print in normal mode.
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// The line does not break.
+normalModeNonBreaking ? 'a' : 'b';
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// Its consequent is very long, so it breaks out to multiple lines.
+normalModeBreaking
+  ? johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
+  : 'c';
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is non-breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div /> ? jsxModeFromElementNonBreaking : 'a';
+
+// This ConditionalExpression prints in JSX mode because its consequent is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? <div /> : 'a';
+
+// This ConditionalExpression prints in JSX mode because its alternate is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? 'a' : <div />;
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div>
+  <span>
+    thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+  </span>
+</div> ? (
+  'jsx mode from element breaking'
+) : (
+  'a'
+);
+
+// This ConditionalExpression prints in JSX mode because its consequent is a
+// JSXElement. It is breaking.
+jsxModeFromElementBreaking ? (
+  <div>
+    <span>
+      thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+    </span>
+  </div>
+) : (
+  'a'
+);
+
+// This ConditionalExpression prints in JSX mode because its alternate is a
+// JSXElement. It is breaking.
+jsxModeFromElementBreaking ? (
+  'a'
+) : (
+  <div>
+    <span>
+      thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+    </span>
+  </div>
+);
+
+// This chain of ConditionalExpressions prints in JSX mode because the parent of
+// the outermost ConditionalExpression is a JSXExpressionContainer. It is
+// non-breaking.
+<div>{a ? 'a' : b ? 'b' : 'c'}</div>;
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain. It is non-breaking.
+cable ? 'satellite' : public ? 'affairs' : network ? <span id="c" /> : 'dunno';
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain (in this case, at the end). It is
+// breaking; notice the consequents and alternates in the entire chain get
+// wrapped in parens.
+cable ? (
+  'satellite'
+) : public ? (
+  'affairs'
+) : network ? (
+  <div>
+    <span>
+      thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+    </span>
+  </div>
+) : (
+  'dunno'
+);
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain (in this case, at the beginning). It is
+// breaking; notice the consequents and alternates in the entire chain get
+// wrapped in parens.
+cable ? (
+  <div>
+    <span>
+      thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+    </span>
+  </div>
+) : sateline ? (
+  'public'
+) : affairs ? (
+  'network'
+) : (
+  'dunno'
+);
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain. It is breaking; notice the consequents
+// and alternates in the entire chain get wrapped in parens.
+<div>
+  {properties.length > 1 ||
+  (properties.length === 1 && properties[0].apps.size > 1) ? (
+    draggingApp == null || newPropertyName == null ? (
+      <MigrationPropertyListItem />
+    ) : (
+      <MigrationPropertyListItem apps={Immutable.List()} />
+    )
+  ) : null}
+</div>;
+
+`;
+
+exports[`conditional-expression.js - flow-verify 4`] = `
+// There are two ways to print ConditionalExpressions: "normal mode" and
+// "JSX mode". This is normal mode (when breaking):
+//
+//   test
+//     ? consequent
+//     : alternate;
+//
+// And this is JSX mode (when breaking):
+//
+//   test ? (
+//     consequent
+//   ) : (
+//     alternate
+//   );
+//
+// When non-breaking, they look the same:
+//
+//  test ? consequent : alternate;
+//
+// We only print a conditional expression in JSX mode if its test,
+// consequent, or alternate are JSXElements.
+// Otherwise, we print in normal mode.
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// The line does not break.
+normalModeNonBreaking ? "a" : "b";
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// Its consequent is very long, so it breaks out to multiple lines.
+normalModeBreaking
+  ? johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
+  : "c";
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is non-breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div /> ? jsxModeFromElementNonBreaking : "a";
+
+// This ConditionalExpression prints in JSX mode because its consequent is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? <div /> : "a";
+
+// This ConditionalExpression prints in JSX mode because its alternate is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? "a" : <div />;
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div>
+  <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+</div>  ? (
+  "jsx mode from element breaking"
+) : (
+  "a"
+);
+
+// This ConditionalExpression prints in JSX mode because its consequent is a
+// JSXElement. It is breaking.
+jsxModeFromElementBreaking ? (
+  <div>
+    <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+  </div>
+) : (
+  "a"
+);
+
+// This ConditionalExpression prints in JSX mode because its alternate is a
+// JSXElement. It is breaking.
+jsxModeFromElementBreaking ? (
+  "a"
+) : (
+  <div>
+    <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+  </div>
+);
+
+// This chain of ConditionalExpressions prints in JSX mode because the parent of
+// the outermost ConditionalExpression is a JSXExpressionContainer. It is
+// non-breaking.
+<div>
+  {a ? "a" : b ? "b" : "c"}
+</div>;
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain. It is non-breaking.
+cable ? "satellite" : public ? "affairs" : network ? <span id="c" /> : "dunno";
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain (in this case, at the end). It is
+// breaking; notice the consequents and alternates in the entire chain get
+// wrapped in parens.
+cable ? (
+  "satellite"
+) : public ? (
+  "affairs"
+) : network ? (
+  <div>
+    <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+  </div>
+) : "dunno";
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain (in this case, at the beginning). It is
+// breaking; notice the consequents and alternates in the entire chain get
+// wrapped in parens.
+cable ? (
+  <div>
+    <span>thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo</span>
+  </div>
+) : sateline ? (
+  "public"
+) : affairs ? (
+  "network"
+) : "dunno";
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain. It is breaking; notice the consequents
+// and alternates in the entire chain get wrapped in parens.
+<div>
+  {properties.length > 1 ||
+  (properties.length === 1 && properties[0].apps.size > 1) ? (
+    draggingApp == null || newPropertyName == null ? (
+      <MigrationPropertyListItem />
+    ) : (
+      <MigrationPropertyListItem apps={Immutable.List()} />
+    )
+  ) : null}
+</div>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// There are two ways to print ConditionalExpressions: "normal mode" and
+// "JSX mode". This is normal mode (when breaking):
+//
+//   test
+//     ? consequent
+//     : alternate;
+//
+// And this is JSX mode (when breaking):
+//
+//   test ? (
+//     consequent
+//   ) : (
+//     alternate
+//   );
+//
+// When non-breaking, they look the same:
+//
+//  test ? consequent : alternate;
+//
+// We only print a conditional expression in JSX mode if its test,
+// consequent, or alternate are JSXElements.
+// Otherwise, we print in normal mode.
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// The line does not break.
+normalModeNonBreaking ? 'a' : 'b';
+
+// This ConditionalExpression has no JSXElements so it prints in normal mode.
+// Its consequent is very long, so it breaks out to multiple lines.
+normalModeBreaking
+  ? johnJacobJingleHeimerSchmidtHisNameIsMyNameTooWheneverWeGoOutThePeopleAlwaysShoutThereGoesJohnJacobJingleHeimerSchmidtYaDaDaDaDaDaDa
+  : 'c';
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is non-breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div /> ? jsxModeFromElementNonBreaking : 'a';
+
+// This ConditionalExpression prints in JSX mode because its consequent is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? <div /> : 'a';
+
+// This ConditionalExpression prints in JSX mode because its alternate is a
+// JSXElement. It is non-breaking.
+jsxModeFromElementNonBreaking ? 'a' : <div />;
+
+// This ConditionalExpression prints in JSX mode because its test is a
+// JSXElement. It is breaking.
+// Note: I have never, ever seen someone use a JSXElement as the test in a
+// ConditionalExpression. But this test is included for completeness.
+<div>
+  <span>
+    thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+  </span>
+</div> ? (
+  'jsx mode from element breaking'
+) : (
+  'a'
+);
+
+// This ConditionalExpression prints in JSX mode because its consequent is a
+// JSXElement. It is breaking.
+jsxModeFromElementBreaking ? (
+  <div>
+    <span>
+      thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+    </span>
+  </div>
+) : (
+  'a'
+);
+
+// This ConditionalExpression prints in JSX mode because its alternate is a
+// JSXElement. It is breaking.
+jsxModeFromElementBreaking ? (
+  'a'
+) : (
+  <div>
+    <span>
+      thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+    </span>
+  </div>
+);
+
+// This chain of ConditionalExpressions prints in JSX mode because the parent of
+// the outermost ConditionalExpression is a JSXExpressionContainer. It is
+// non-breaking.
+<div>{a ? 'a' : b ? 'b' : 'c'}</div>;
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain. It is non-breaking.
+cable ? 'satellite' : public ? 'affairs' : network ? <span id='c' /> : 'dunno';
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain (in this case, at the end). It is
+// breaking; notice the consequents and alternates in the entire chain get
+// wrapped in parens.
+cable ? (
+  'satellite'
+) : public ? (
+  'affairs'
+) : network ? (
+  <div>
+    <span>
+      thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+    </span>
+  </div>
+) : (
+  'dunno'
+);
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain (in this case, at the beginning). It is
+// breaking; notice the consequents and alternates in the entire chain get
+// wrapped in parens.
+cable ? (
+  <div>
+    <span>
+      thisIsASongAboutYourPoorSickPenguinHeHasAFeverAndHisToesAreBlueButIfISingToYourPoorSickPenguinHeWillFeelBetterInADayOrTwo
+    </span>
+  </div>
+) : sateline ? (
+  'public'
+) : affairs ? (
+  'network'
+) : (
+  'dunno'
+);
+
+// This chain of ConditionalExpressions prints in JSX mode because there is a
+// JSX element somewhere in the chain. It is breaking; notice the consequents
+// and alternates in the entire chain get wrapped in parens.
+<div>
+  {properties.length > 1 ||
+  (properties.length === 1 && properties[0].apps.size > 1) ? (
+    draggingApp == null || newPropertyName == null ? (
+      <MigrationPropertyListItem />
+    ) : (
+      <MigrationPropertyListItem apps={Immutable.List()} />
+    )
+  ) : null}
+</div>;
+
+`;
+
 exports[`expression.js - flow-verify 1`] = `
 <View
-  style={
+  style={
+    {
+      someVeryLongStyle1: "true",
+      someVeryLongStyle2: "true",
+      someVeryLongStyle3: "true",
+      someVeryLongStyle4: "true"
+    }
+  }
+/>;
+
+<View
+  style={
+    [
+      {
+        someVeryLongStyle1: "true",
+        someVeryLongStyle2: "true",
+        someVeryLongStyle3: "true",
+        someVeryLongStyle4: "true"
+      }
+    ]
+  }
+/>;
+
+<Something>
+  {() => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  )}
+</Something>;
+
+<Something>
+  {items.map(item => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  ))}
+</Something>;
+
+<Something>
+  {function() {
+    return (
+      <SomethingElse>
+        <span />
+      </SomethingElse>
+    );
+  }}
+</Something>;
+
+<RadioListItem
+  key={option}
+  imageSource={this.props.veryBigItemImageSourceFunc &&
+    this.props.veryBigItemImageSourceFunc(option)}
+  imageSize={this.props.veryBigItemImageSize}
+  imageView={this.props.veryBigItemImageViewFunc &&
+    this.props.veryBigItemImageViewFunc(option)}
+  heading={this.props.displayTextFunc(option)}
+  value={option}
+/>;
+
+<ParentComponent prop={
+  <Child>
+    test
+  </Child>
+}/>;
+
+<BookingIntroPanel
+  prop="long_string_make_to_force_break"
+  logClick={data => doLogClick("short", "short", data)}
+/>;
+
+<BookingIntroPanel
+  logClick={data =>
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }
+/>;
+
+<BookingIntroPanel
+  logClick={data => {
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }}
+/>;
+
+<Component
+  onChange={(
+    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
+    value: string | Immutable.List<string>,
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+/>;
+
+<BookingIntroPanel>
+  {data => doLogClick("short", "short", data)}
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data =>
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data => {
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }}
+</BookingIntroPanel>;
+
+<Component>
+  {(
+    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
+    value: string | Immutable.List<string>,
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+</Component>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<View
+  style={{
+    someVeryLongStyle1: "true",
+    someVeryLongStyle2: "true",
+    someVeryLongStyle3: "true",
+    someVeryLongStyle4: "true"
+  }}
+/>;
+
+<View
+  style={[
+    {
+      someVeryLongStyle1: "true",
+      someVeryLongStyle2: "true",
+      someVeryLongStyle3: "true",
+      someVeryLongStyle4: "true"
+    }
+  ]}
+/>;
+
+<Something>
+  {() => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  )}
+</Something>;
+
+<Something>
+  {items.map(item => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  ))}
+</Something>;
+
+<Something>
+  {function() {
+    return (
+      <SomethingElse>
+        <span />
+      </SomethingElse>
+    );
+  }}
+</Something>;
+
+<RadioListItem
+  key={option}
+  imageSource={
+    this.props.veryBigItemImageSourceFunc &&
+    this.props.veryBigItemImageSourceFunc(option)
+  }
+  imageSize={this.props.veryBigItemImageSize}
+  imageView={
+    this.props.veryBigItemImageViewFunc &&
+    this.props.veryBigItemImageViewFunc(option)
+  }
+  heading={this.props.displayTextFunc(option)}
+  value={option}
+/>;
+
+<ParentComponent prop={<Child>test</Child>} />;
+
+<BookingIntroPanel
+  prop="long_string_make_to_force_break"
+  logClick={data => doLogClick("short", "short", data)}
+/>;
+
+<BookingIntroPanel
+  logClick={data =>
+    doLogClick(
+      "long_name_long_name_long_name",
+      "long_name_long_name_long_name",
+      data
+    )
+  }
+/>;
+
+<BookingIntroPanel
+  logClick={data => {
+    doLogClick(
+      "long_name_long_name_long_name",
+      "long_name_long_name_long_name",
+      data
+    );
+  }}
+/>;
+
+<Component
+  onChange={(
+    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
+    value: string | Immutable.List<string>
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+/>;
+
+<BookingIntroPanel>
+  {data => doLogClick("short", "short", data)}
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data =>
+    doLogClick(
+      "long_name_long_name_long_name",
+      "long_name_long_name_long_name",
+      data
+    )
+  }
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data => {
+    doLogClick(
+      "long_name_long_name_long_name",
+      "long_name_long_name_long_name",
+      data
+    );
+  }}
+</BookingIntroPanel>;
+
+<Component>
+  {(
+    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
+    value: string | Immutable.List<string>
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+</Component>;
+
+`;
+
+exports[`expression.js - flow-verify 2`] = `
+<View
+  style={
+    {
+      someVeryLongStyle1: "true",
+      someVeryLongStyle2: "true",
+      someVeryLongStyle3: "true",
+      someVeryLongStyle4: "true"
+    }
+  }
+/>;
+
+<View
+  style={
+    [
+      {
+        someVeryLongStyle1: "true",
+        someVeryLongStyle2: "true",
+        someVeryLongStyle3: "true",
+        someVeryLongStyle4: "true"
+      }
+    ]
+  }
+/>;
+
+<Something>
+  {() => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  )}
+</Something>;
+
+<Something>
+  {items.map(item => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  ))}
+</Something>;
+
+<Something>
+  {function() {
+    return (
+      <SomethingElse>
+        <span />
+      </SomethingElse>
+    );
+  }}
+</Something>;
+
+<RadioListItem
+  key={option}
+  imageSource={this.props.veryBigItemImageSourceFunc &&
+    this.props.veryBigItemImageSourceFunc(option)}
+  imageSize={this.props.veryBigItemImageSize}
+  imageView={this.props.veryBigItemImageViewFunc &&
+    this.props.veryBigItemImageViewFunc(option)}
+  heading={this.props.displayTextFunc(option)}
+  value={option}
+/>;
+
+<ParentComponent prop={
+  <Child>
+    test
+  </Child>
+}/>;
+
+<BookingIntroPanel
+  prop="long_string_make_to_force_break"
+  logClick={data => doLogClick("short", "short", data)}
+/>;
+
+<BookingIntroPanel
+  logClick={data =>
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }
+/>;
+
+<BookingIntroPanel
+  logClick={data => {
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }}
+/>;
+
+<Component
+  onChange={(
+    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
+    value: string | Immutable.List<string>,
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+/>;
+
+<BookingIntroPanel>
+  {data => doLogClick("short", "short", data)}
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data =>
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data => {
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }}
+</BookingIntroPanel>;
+
+<Component>
+  {(
+    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
+    value: string | Immutable.List<string>,
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+</Component>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<View
+  style={{
+    someVeryLongStyle1: "true",
+    someVeryLongStyle2: "true",
+    someVeryLongStyle3: "true",
+    someVeryLongStyle4: "true"
+  }}
+/>;
+
+<View
+  style={[
+    {
+      someVeryLongStyle1: "true",
+      someVeryLongStyle2: "true",
+      someVeryLongStyle3: "true",
+      someVeryLongStyle4: "true"
+    }
+  ]}
+/>;
+
+<Something>
+  {() => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  )}
+</Something>;
+
+<Something>
+  {items.map(item => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  ))}
+</Something>;
+
+<Something>
+  {function() {
+    return (
+      <SomethingElse>
+        <span />
+      </SomethingElse>
+    );
+  }}
+</Something>;
+
+<RadioListItem
+  key={option}
+  imageSource={
+    this.props.veryBigItemImageSourceFunc &&
+    this.props.veryBigItemImageSourceFunc(option)
+  }
+  imageSize={this.props.veryBigItemImageSize}
+  imageView={
+    this.props.veryBigItemImageViewFunc &&
+    this.props.veryBigItemImageViewFunc(option)
+  }
+  heading={this.props.displayTextFunc(option)}
+  value={option}
+/>;
+
+<ParentComponent prop={<Child>test</Child>} />;
+
+<BookingIntroPanel
+  prop='long_string_make_to_force_break'
+  logClick={data => doLogClick("short", "short", data)}
+/>;
+
+<BookingIntroPanel
+  logClick={data =>
+    doLogClick(
+      "long_name_long_name_long_name",
+      "long_name_long_name_long_name",
+      data
+    )
+  }
+/>;
+
+<BookingIntroPanel
+  logClick={data => {
+    doLogClick(
+      "long_name_long_name_long_name",
+      "long_name_long_name_long_name",
+      data
+    );
+  }}
+/>;
+
+<Component
+  onChange={(
+    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
+    value: string | Immutable.List<string>
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+/>;
+
+<BookingIntroPanel>
+  {data => doLogClick("short", "short", data)}
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data =>
+    doLogClick(
+      "long_name_long_name_long_name",
+      "long_name_long_name_long_name",
+      data
+    )
+  }
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data => {
+    doLogClick(
+      "long_name_long_name_long_name",
+      "long_name_long_name_long_name",
+      data
+    );
+  }}
+</BookingIntroPanel>;
+
+<Component>
+  {(
+    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
+    value: string | Immutable.List<string>
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+</Component>;
+
+`;
+
+exports[`expression.js - flow-verify 3`] = `
+<View
+  style={
+    {
+      someVeryLongStyle1: "true",
+      someVeryLongStyle2: "true",
+      someVeryLongStyle3: "true",
+      someVeryLongStyle4: "true"
+    }
+  }
+/>;
+
+<View
+  style={
+    [
+      {
+        someVeryLongStyle1: "true",
+        someVeryLongStyle2: "true",
+        someVeryLongStyle3: "true",
+        someVeryLongStyle4: "true"
+      }
+    ]
+  }
+/>;
+
+<Something>
+  {() => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  )}
+</Something>;
+
+<Something>
+  {items.map(item => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  ))}
+</Something>;
+
+<Something>
+  {function() {
+    return (
+      <SomethingElse>
+        <span />
+      </SomethingElse>
+    );
+  }}
+</Something>;
+
+<RadioListItem
+  key={option}
+  imageSource={this.props.veryBigItemImageSourceFunc &&
+    this.props.veryBigItemImageSourceFunc(option)}
+  imageSize={this.props.veryBigItemImageSize}
+  imageView={this.props.veryBigItemImageViewFunc &&
+    this.props.veryBigItemImageViewFunc(option)}
+  heading={this.props.displayTextFunc(option)}
+  value={option}
+/>;
+
+<ParentComponent prop={
+  <Child>
+    test
+  </Child>
+}/>;
+
+<BookingIntroPanel
+  prop="long_string_make_to_force_break"
+  logClick={data => doLogClick("short", "short", data)}
+/>;
+
+<BookingIntroPanel
+  logClick={data =>
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }
+/>;
+
+<BookingIntroPanel
+  logClick={data => {
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }}
+/>;
+
+<Component
+  onChange={(
+    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
+    value: string | Immutable.List<string>,
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+/>;
+
+<BookingIntroPanel>
+  {data => doLogClick("short", "short", data)}
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data =>
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data => {
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }}
+</BookingIntroPanel>;
+
+<Component>
+  {(
+    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
+    value: string | Immutable.List<string>,
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+</Component>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<View
+  style={{
+    someVeryLongStyle1: 'true',
+    someVeryLongStyle2: 'true',
+    someVeryLongStyle3: 'true',
+    someVeryLongStyle4: 'true'
+  }}
+/>;
+
+<View
+  style={[
+    {
+      someVeryLongStyle1: 'true',
+      someVeryLongStyle2: 'true',
+      someVeryLongStyle3: 'true',
+      someVeryLongStyle4: 'true'
+    }
+  ]}
+/>;
+
+<Something>
+  {() => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  )}
+</Something>;
+
+<Something>
+  {items.map(item => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  ))}
+</Something>;
+
+<Something>
+  {function() {
+    return (
+      <SomethingElse>
+        <span />
+      </SomethingElse>
+    );
+  }}
+</Something>;
+
+<RadioListItem
+  key={option}
+  imageSource={
+    this.props.veryBigItemImageSourceFunc &&
+    this.props.veryBigItemImageSourceFunc(option)
+  }
+  imageSize={this.props.veryBigItemImageSize}
+  imageView={
+    this.props.veryBigItemImageViewFunc &&
+    this.props.veryBigItemImageViewFunc(option)
+  }
+  heading={this.props.displayTextFunc(option)}
+  value={option}
+/>;
+
+<ParentComponent prop={<Child>test</Child>} />;
+
+<BookingIntroPanel
+  prop="long_string_make_to_force_break"
+  logClick={data => doLogClick('short', 'short', data)}
+/>;
+
+<BookingIntroPanel
+  logClick={data =>
+    doLogClick(
+      'long_name_long_name_long_name',
+      'long_name_long_name_long_name',
+      data
+    )
+  }
+/>;
+
+<BookingIntroPanel
+  logClick={data => {
+    doLogClick(
+      'long_name_long_name_long_name',
+      'long_name_long_name_long_name',
+      data
+    );
+  }}
+/>;
+
+<Component
+  onChange={(
+    key: 'possible_key_1' | 'possible_key_2' | 'possible_key_3',
+    value: string | Immutable.List<string>
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+/>;
+
+<BookingIntroPanel>
+  {data => doLogClick('short', 'short', data)}
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data =>
+    doLogClick(
+      'long_name_long_name_long_name',
+      'long_name_long_name_long_name',
+      data
+    )
+  }
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data => {
+    doLogClick(
+      'long_name_long_name_long_name',
+      'long_name_long_name_long_name',
+      data
+    );
+  }}
+</BookingIntroPanel>;
+
+<Component>
+  {(
+    key: 'possible_key_1' | 'possible_key_2' | 'possible_key_3',
+    value: string | Immutable.List<string>
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+</Component>;
+
+`;
+
+exports[`expression.js - flow-verify 4`] = `
+<View
+  style={
+    {
+      someVeryLongStyle1: "true",
+      someVeryLongStyle2: "true",
+      someVeryLongStyle3: "true",
+      someVeryLongStyle4: "true"
+    }
+  }
+/>;
+
+<View
+  style={
+    [
+      {
+        someVeryLongStyle1: "true",
+        someVeryLongStyle2: "true",
+        someVeryLongStyle3: "true",
+        someVeryLongStyle4: "true"
+      }
+    ]
+  }
+/>;
+
+<Something>
+  {() => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  )}
+</Something>;
+
+<Something>
+  {items.map(item => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  ))}
+</Something>;
+
+<Something>
+  {function() {
+    return (
+      <SomethingElse>
+        <span />
+      </SomethingElse>
+    );
+  }}
+</Something>;
+
+<RadioListItem
+  key={option}
+  imageSource={this.props.veryBigItemImageSourceFunc &&
+    this.props.veryBigItemImageSourceFunc(option)}
+  imageSize={this.props.veryBigItemImageSize}
+  imageView={this.props.veryBigItemImageViewFunc &&
+    this.props.veryBigItemImageViewFunc(option)}
+  heading={this.props.displayTextFunc(option)}
+  value={option}
+/>;
+
+<ParentComponent prop={
+  <Child>
+    test
+  </Child>
+}/>;
+
+<BookingIntroPanel
+  prop="long_string_make_to_force_break"
+  logClick={data => doLogClick("short", "short", data)}
+/>;
+
+<BookingIntroPanel
+  logClick={data =>
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }
+/>;
+
+<BookingIntroPanel
+  logClick={data => {
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }}
+/>;
+
+<Component
+  onChange={(
+    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
+    value: string | Immutable.List<string>,
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+/>;
+
+<BookingIntroPanel>
+  {data => doLogClick("short", "short", data)}
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data =>
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data => {
+    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
+  }}
+</BookingIntroPanel>;
+
+<Component>
+  {(
+    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
+    value: string | Immutable.List<string>,
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+</Component>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<View
+  style={{
+    someVeryLongStyle1: 'true',
+    someVeryLongStyle2: 'true',
+    someVeryLongStyle3: 'true',
+    someVeryLongStyle4: 'true'
+  }}
+/>;
+
+<View
+  style={[
     {
-      someVeryLongStyle1: "true",
-      someVeryLongStyle2: "true",
-      someVeryLongStyle3: "true",
-      someVeryLongStyle4: "true"
+      someVeryLongStyle1: 'true',
+      someVeryLongStyle2: 'true',
+      someVeryLongStyle3: 'true',
+      someVeryLongStyle4: 'true'
     }
+  ]}
+/>;
+
+<Something>
+  {() => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  )}
+</Something>;
+
+<Something>
+  {items.map(item => (
+    <SomethingElse>
+      <span />
+    </SomethingElse>
+  ))}
+</Something>;
+
+<Something>
+  {function() {
+    return (
+      <SomethingElse>
+        <span />
+      </SomethingElse>
+    );
+  }}
+</Something>;
+
+<RadioListItem
+  key={option}
+  imageSource={
+    this.props.veryBigItemImageSourceFunc &&
+    this.props.veryBigItemImageSourceFunc(option)
+  }
+  imageSize={this.props.veryBigItemImageSize}
+  imageView={
+    this.props.veryBigItemImageViewFunc &&
+    this.props.veryBigItemImageViewFunc(option)
+  }
+  heading={this.props.displayTextFunc(option)}
+  value={option}
+/>;
+
+<ParentComponent prop={<Child>test</Child>} />;
+
+<BookingIntroPanel
+  prop='long_string_make_to_force_break'
+  logClick={data => doLogClick('short', 'short', data)}
+/>;
+
+<BookingIntroPanel
+  logClick={data =>
+    doLogClick(
+      'long_name_long_name_long_name',
+      'long_name_long_name_long_name',
+      data
+    )
+  }
+/>;
+
+<BookingIntroPanel
+  logClick={data => {
+    doLogClick(
+      'long_name_long_name_long_name',
+      'long_name_long_name_long_name',
+      data
+    );
+  }}
+/>;
+
+<Component
+  onChange={(
+    key: 'possible_key_1' | 'possible_key_2' | 'possible_key_3',
+    value: string | Immutable.List<string>
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+/>;
+
+<BookingIntroPanel>
+  {data => doLogClick('short', 'short', data)}
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data =>
+    doLogClick(
+      'long_name_long_name_long_name',
+      'long_name_long_name_long_name',
+      data
+    )
+  }
+</BookingIntroPanel>;
+
+<BookingIntroPanel>
+  {data => {
+    doLogClick(
+      'long_name_long_name_long_name',
+      'long_name_long_name_long_name',
+      data
+    );
+  }}
+</BookingIntroPanel>;
+
+<Component>
+  {(
+    key: 'possible_key_1' | 'possible_key_2' | 'possible_key_3',
+    value: string | Immutable.List<string>
+  ) => {
+    this.setState({
+      updatedTask: this.state.updatedTask.set(key, value)
+    });
+  }}
+</Component>;
+
+`;
+
+exports[`flow_fix_me.js - flow-verify 1`] = `
+const aDiv = (
+  /* $FlowFixMe */
+  <div className="foo">
+    Foo bar
+  </div>
+);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const aDiv = (
+  /* $FlowFixMe */
+  <div className="foo">Foo bar</div>
+);
+
+`;
+
+exports[`flow_fix_me.js - flow-verify 2`] = `
+const aDiv = (
+  /* $FlowFixMe */
+  <div className="foo">
+    Foo bar
+  </div>
+);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const aDiv = (
+  /* $FlowFixMe */
+  <div className='foo'>Foo bar</div>
+);
+
+`;
+
+exports[`flow_fix_me.js - flow-verify 3`] = `
+const aDiv = (
+  /* $FlowFixMe */
+  <div className="foo">
+    Foo bar
+  </div>
+);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const aDiv = (
+  /* $FlowFixMe */
+  <div className="foo">Foo bar</div>
+);
+
+`;
+
+exports[`flow_fix_me.js - flow-verify 4`] = `
+const aDiv = (
+  /* $FlowFixMe */
+  <div className="foo">
+    Foo bar
+  </div>
+);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const aDiv = (
+  /* $FlowFixMe */
+  <div className='foo'>Foo bar</div>
+);
+
+`;
+
+exports[`html_escape.js - flow-verify 1`] = `
+export default () => <a href="https://foo.bar?q1=foo&q2=bar" />;
+
+() => <img src="https://bar.foo?param1=1&param2=2" />;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+export default () => <a href="https://foo.bar?q1=foo&q2=bar" />;
+
+() => <img src="https://bar.foo?param1=1&param2=2" />;
+
+`;
+
+exports[`html_escape.js - flow-verify 2`] = `
+export default () => <a href="https://foo.bar?q1=foo&q2=bar" />;
+
+() => <img src="https://bar.foo?param1=1&param2=2" />;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+export default () => <a href='https://foo.bar?q1=foo&q2=bar' />;
+
+() => <img src='https://bar.foo?param1=1&param2=2' />;
+
+`;
+
+exports[`html_escape.js - flow-verify 3`] = `
+export default () => <a href="https://foo.bar?q1=foo&q2=bar" />;
+
+() => <img src="https://bar.foo?param1=1&param2=2" />;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+export default () => <a href="https://foo.bar?q1=foo&q2=bar" />;
+
+() => <img src="https://bar.foo?param1=1&param2=2" />;
+
+`;
+
+exports[`html_escape.js - flow-verify 4`] = `
+export default () => <a href="https://foo.bar?q1=foo&q2=bar" />;
+
+() => <img src="https://bar.foo?param1=1&param2=2" />;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+export default () => <a href='https://foo.bar?q1=foo&q2=bar' />;
+
+() => <img src='https://bar.foo?param1=1&param2=2' />;
+
+`;
+
+exports[`hug.js - flow-verify 1`] = `
+<div>
+  {__DEV__
+    ? this.renderDevApp()
+    : <div>
+      {routes.map(route => (
+        <MatchAsync
+          key={\`\${route.to}-async\`}
+          pattern={route.to}
+          exactly={route.to === "/"}
+          getComponent={routeES6Modules[route.value]}
+        />
+      ))}
+    </div>}
+</div>;
+
+<div>
+  {__DEV__ && <div>
+    {routes.map(route => (
+      <MatchAsync
+        key={\`\${route.to}-async\`}
+        pattern={route.to}
+        exactly={route.to === "/"}
+        getComponent={routeES6Modules[route.value]}
+      />
+    ))}
+    </div>}
+</div>;
+
+<div>
+  {member.memberName.memberSomething +
+    (member.memberDef.memberSomething.signatures ? '()' : '')}
+</div>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<div>
+  {__DEV__ ? (
+    this.renderDevApp()
+  ) : (
+    <div>
+      {routes.map(route => (
+        <MatchAsync
+          key={\`\${route.to}-async\`}
+          pattern={route.to}
+          exactly={route.to === "/"}
+          getComponent={routeES6Modules[route.value]}
+        />
+      ))}
+    </div>
+  )}
+</div>;
+
+<div>
+  {__DEV__ && (
+    <div>
+      {routes.map(route => (
+        <MatchAsync
+          key={\`\${route.to}-async\`}
+          pattern={route.to}
+          exactly={route.to === "/"}
+          getComponent={routeES6Modules[route.value]}
+        />
+      ))}
+    </div>
+  )}
+</div>;
+
+<div>
+  {member.memberName.memberSomething +
+    (member.memberDef.memberSomething.signatures ? "()" : "")}
+</div>;
+
+`;
+
+exports[`hug.js - flow-verify 2`] = `
+<div>
+  {__DEV__
+    ? this.renderDevApp()
+    : <div>
+      {routes.map(route => (
+        <MatchAsync
+          key={\`\${route.to}-async\`}
+          pattern={route.to}
+          exactly={route.to === "/"}
+          getComponent={routeES6Modules[route.value]}
+        />
+      ))}
+    </div>}
+</div>;
+
+<div>
+  {__DEV__ && <div>
+    {routes.map(route => (
+      <MatchAsync
+        key={\`\${route.to}-async\`}
+        pattern={route.to}
+        exactly={route.to === "/"}
+        getComponent={routeES6Modules[route.value]}
+      />
+    ))}
+    </div>}
+</div>;
+
+<div>
+  {member.memberName.memberSomething +
+    (member.memberDef.memberSomething.signatures ? '()' : '')}
+</div>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<div>
+  {__DEV__ ? (
+    this.renderDevApp()
+  ) : (
+    <div>
+      {routes.map(route => (
+        <MatchAsync
+          key={\`\${route.to}-async\`}
+          pattern={route.to}
+          exactly={route.to === "/"}
+          getComponent={routeES6Modules[route.value]}
+        />
+      ))}
+    </div>
+  )}
+</div>;
+
+<div>
+  {__DEV__ && (
+    <div>
+      {routes.map(route => (
+        <MatchAsync
+          key={\`\${route.to}-async\`}
+          pattern={route.to}
+          exactly={route.to === "/"}
+          getComponent={routeES6Modules[route.value]}
+        />
+      ))}
+    </div>
+  )}
+</div>;
+
+<div>
+  {member.memberName.memberSomething +
+    (member.memberDef.memberSomething.signatures ? "()" : "")}
+</div>;
+
+`;
+
+exports[`hug.js - flow-verify 3`] = `
+<div>
+  {__DEV__
+    ? this.renderDevApp()
+    : <div>
+      {routes.map(route => (
+        <MatchAsync
+          key={\`\${route.to}-async\`}
+          pattern={route.to}
+          exactly={route.to === "/"}
+          getComponent={routeES6Modules[route.value]}
+        />
+      ))}
+    </div>}
+</div>;
+
+<div>
+  {__DEV__ && <div>
+    {routes.map(route => (
+      <MatchAsync
+        key={\`\${route.to}-async\`}
+        pattern={route.to}
+        exactly={route.to === "/"}
+        getComponent={routeES6Modules[route.value]}
+      />
+    ))}
+    </div>}
+</div>;
+
+<div>
+  {member.memberName.memberSomething +
+    (member.memberDef.memberSomething.signatures ? '()' : '')}
+</div>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<div>
+  {__DEV__ ? (
+    this.renderDevApp()
+  ) : (
+    <div>
+      {routes.map(route => (
+        <MatchAsync
+          key={\`\${route.to}-async\`}
+          pattern={route.to}
+          exactly={route.to === '/'}
+          getComponent={routeES6Modules[route.value]}
+        />
+      ))}
+    </div>
+  )}
+</div>;
+
+<div>
+  {__DEV__ && (
+    <div>
+      {routes.map(route => (
+        <MatchAsync
+          key={\`\${route.to}-async\`}
+          pattern={route.to}
+          exactly={route.to === '/'}
+          getComponent={routeES6Modules[route.value]}
+        />
+      ))}
+    </div>
+  )}
+</div>;
+
+<div>
+  {member.memberName.memberSomething +
+    (member.memberDef.memberSomething.signatures ? '()' : '')}
+</div>;
+
+`;
+
+exports[`hug.js - flow-verify 4`] = `
+<div>
+  {__DEV__
+    ? this.renderDevApp()
+    : <div>
+      {routes.map(route => (
+        <MatchAsync
+          key={\`\${route.to}-async\`}
+          pattern={route.to}
+          exactly={route.to === "/"}
+          getComponent={routeES6Modules[route.value]}
+        />
+      ))}
+    </div>}
+</div>;
+
+<div>
+  {__DEV__ && <div>
+    {routes.map(route => (
+      <MatchAsync
+        key={\`\${route.to}-async\`}
+        pattern={route.to}
+        exactly={route.to === "/"}
+        getComponent={routeES6Modules[route.value]}
+      />
+    ))}
+    </div>}
+</div>;
+
+<div>
+  {member.memberName.memberSomething +
+    (member.memberDef.memberSomething.signatures ? '()' : '')}
+</div>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<div>
+  {__DEV__ ? (
+    this.renderDevApp()
+  ) : (
+    <div>
+      {routes.map(route => (
+        <MatchAsync
+          key={\`\${route.to}-async\`}
+          pattern={route.to}
+          exactly={route.to === '/'}
+          getComponent={routeES6Modules[route.value]}
+        />
+      ))}
+    </div>
+  )}
+</div>;
+
+<div>
+  {__DEV__ && (
+    <div>
+      {routes.map(route => (
+        <MatchAsync
+          key={\`\${route.to}-async\`}
+          pattern={route.to}
+          exactly={route.to === '/'}
+          getComponent={routeES6Modules[route.value]}
+        />
+      ))}
+    </div>
+  )}
+</div>;
+
+<div>
+  {member.memberName.memberSomething +
+    (member.memberDef.memberSomething.signatures ? '()' : '')}
+</div>;
+
+`;
+
+exports[`logical-expression.js - flow-verify 1`] = `
+<div>
+  {a || "b"}
+</div>;
+
+<div>
+  {a && "b"}
+</div>;
+
+<div>
+  {a || <span></span>}
+</div>;
+
+<div>
+  {a && <span></span>}
+</div>;
+
+<div>
+  {a && <span>make this text just so long enough to break this to the next line</span>}
+</div>;
+
+<div>
+  {a && b && <span>make this text just so long enough to break this to the next line</span>}
+</div>;
+
+<div>
+  {a && <span>
+    <div>
+      <div></div>
+    </div>
+  </span>}
+</div>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<div>{a || "b"}</div>;
+
+<div>{a && "b"}</div>;
+
+<div>{a || <span />}</div>;
+
+<div>{a && <span />}</div>;
+
+<div>
+  {a && (
+    <span>
+      make this text just so long enough to break this to the next line
+    </span>
+  )}
+</div>;
+
+<div>
+  {a && b && (
+    <span>
+      make this text just so long enough to break this to the next line
+    </span>
+  )}
+</div>;
+
+<div>
+  {a && (
+    <span>
+      <div>
+        <div />
+      </div>
+    </span>
+  )}
+</div>;
+
+`;
+
+exports[`logical-expression.js - flow-verify 2`] = `
+<div>
+  {a || "b"}
+</div>;
+
+<div>
+  {a && "b"}
+</div>;
+
+<div>
+  {a || <span></span>}
+</div>;
+
+<div>
+  {a && <span></span>}
+</div>;
+
+<div>
+  {a && <span>make this text just so long enough to break this to the next line</span>}
+</div>;
+
+<div>
+  {a && b && <span>make this text just so long enough to break this to the next line</span>}
+</div>;
+
+<div>
+  {a && <span>
+    <div>
+      <div></div>
+    </div>
+  </span>}
+</div>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<div>{a || "b"}</div>;
+
+<div>{a && "b"}</div>;
+
+<div>{a || <span />}</div>;
+
+<div>{a && <span />}</div>;
+
+<div>
+  {a && (
+    <span>
+      make this text just so long enough to break this to the next line
+    </span>
+  )}
+</div>;
+
+<div>
+  {a && b && (
+    <span>
+      make this text just so long enough to break this to the next line
+    </span>
+  )}
+</div>;
+
+<div>
+  {a && (
+    <span>
+      <div>
+        <div />
+      </div>
+    </span>
+  )}
+</div>;
+
+`;
+
+exports[`logical-expression.js - flow-verify 3`] = `
+<div>
+  {a || "b"}
+</div>;
+
+<div>
+  {a && "b"}
+</div>;
+
+<div>
+  {a || <span></span>}
+</div>;
+
+<div>
+  {a && <span></span>}
+</div>;
+
+<div>
+  {a && <span>make this text just so long enough to break this to the next line</span>}
+</div>;
+
+<div>
+  {a && b && <span>make this text just so long enough to break this to the next line</span>}
+</div>;
+
+<div>
+  {a && <span>
+    <div>
+      <div></div>
+    </div>
+  </span>}
+</div>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<div>{a || 'b'}</div>;
+
+<div>{a && 'b'}</div>;
+
+<div>{a || <span />}</div>;
+
+<div>{a && <span />}</div>;
+
+<div>
+  {a && (
+    <span>
+      make this text just so long enough to break this to the next line
+    </span>
+  )}
+</div>;
+
+<div>
+  {a && b && (
+    <span>
+      make this text just so long enough to break this to the next line
+    </span>
+  )}
+</div>;
+
+<div>
+  {a && (
+    <span>
+      <div>
+        <div />
+      </div>
+    </span>
+  )}
+</div>;
+
+`;
+
+exports[`logical-expression.js - flow-verify 4`] = `
+<div>
+  {a || "b"}
+</div>;
+
+<div>
+  {a && "b"}
+</div>;
+
+<div>
+  {a || <span></span>}
+</div>;
+
+<div>
+  {a && <span></span>}
+</div>;
+
+<div>
+  {a && <span>make this text just so long enough to break this to the next line</span>}
+</div>;
+
+<div>
+  {a && b && <span>make this text just so long enough to break this to the next line</span>}
+</div>;
+
+<div>
+  {a && <span>
+    <div>
+      <div></div>
+    </div>
+  </span>}
+</div>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<div>{a || 'b'}</div>;
+
+<div>{a && 'b'}</div>;
+
+<div>{a || <span />}</div>;
+
+<div>{a && <span />}</div>;
+
+<div>
+  {a && (
+    <span>
+      make this text just so long enough to break this to the next line
+    </span>
+  )}
+</div>;
+
+<div>
+  {a && b && (
+    <span>
+      make this text just so long enough to break this to the next line
+    </span>
+  )}
+</div>;
+
+<div>
+  {a && (
+    <span>
+      <div>
+        <div />
+      </div>
+    </span>
+  )}
+</div>;
+
+`;
+
+exports[`object-property.js - flow-verify 1`] = `
+const tabs = [
+  {
+    title: "General Info",
+    content: (
+      <GeneralForm
+        long-attribute="i-need-long-value-here"
+        onSave={ onSave }
+        onCancel={ onCancel }
+        countries={ countries }
+      />
+    )
   }
-/>;
+];
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const tabs = [
+  {
+    title: "General Info",
+    content: (
+      <GeneralForm
+        long-attribute="i-need-long-value-here"
+        onSave={onSave}
+        onCancel={onCancel}
+        countries={countries}
+      />
+    )
+  }
+];
+
+`;
+
+exports[`object-property.js - flow-verify 2`] = `
+const tabs = [
+  {
+    title: "General Info",
+    content: (
+      <GeneralForm
+        long-attribute="i-need-long-value-here"
+        onSave={ onSave }
+        onCancel={ onCancel }
+        countries={ countries }
+      />
+    )
+  }
+];
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const tabs = [
+  {
+    title: "General Info",
+    content: (
+      <GeneralForm
+        long-attribute='i-need-long-value-here'
+        onSave={onSave}
+        onCancel={onCancel}
+        countries={countries}
+      />
+    )
+  }
+];
+
+`;
+
+exports[`object-property.js - flow-verify 3`] = `
+const tabs = [
+  {
+    title: "General Info",
+    content: (
+      <GeneralForm
+        long-attribute="i-need-long-value-here"
+        onSave={ onSave }
+        onCancel={ onCancel }
+        countries={ countries }
+      />
+    )
+  }
+];
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const tabs = [
+  {
+    title: 'General Info',
+    content: (
+      <GeneralForm
+        long-attribute="i-need-long-value-here"
+        onSave={onSave}
+        onCancel={onCancel}
+        countries={countries}
+      />
+    )
+  }
+];
+
+`;
+
+exports[`object-property.js - flow-verify 4`] = `
+const tabs = [
+  {
+    title: "General Info",
+    content: (
+      <GeneralForm
+        long-attribute="i-need-long-value-here"
+        onSave={ onSave }
+        onCancel={ onCancel }
+        countries={ countries }
+      />
+    )
+  }
+];
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const tabs = [
+  {
+    title: 'General Info',
+    content: (
+      <GeneralForm
+        long-attribute='i-need-long-value-here'
+        onSave={onSave}
+        onCancel={onCancel}
+        countries={countries}
+      />
+    )
+  }
+];
+
+`;
+
+exports[`open-break.js - flow-verify 1`] = `
+<td
+onClick={() => {
+  a
+}}>{header}{showSort}</td>;
+
+<td
+onClick={() => {
+  a
+}}>{header}<showSort attr="long long long long long long long long long long long"/></td>;
+
+<Foo>{\`    a    very    long    text    that    does    not    break    \`}</Foo>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<td
+  onClick={() => {
+    a;
+  }}
+>
+  {header}
+  {showSort}
+</td>;
+
+<td
+  onClick={() => {
+    a;
+  }}
+>
+  {header}
+  <showSort attr="long long long long long long long long long long long" />
+</td>;
+
+<Foo>{\`    a    very    long    text    that    does    not    break    \`}</Foo>;
+
+`;
+
+exports[`open-break.js - flow-verify 2`] = `
+<td
+onClick={() => {
+  a
+}}>{header}{showSort}</td>;
+
+<td
+onClick={() => {
+  a
+}}>{header}<showSort attr="long long long long long long long long long long long"/></td>;
+
+<Foo>{\`    a    very    long    text    that    does    not    break    \`}</Foo>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<td
+  onClick={() => {
+    a;
+  }}
+>
+  {header}
+  {showSort}
+</td>;
 
-<View
-  style={
-    [
-      {
-        someVeryLongStyle1: "true",
-        someVeryLongStyle2: "true",
-        someVeryLongStyle3: "true",
-        someVeryLongStyle4: "true"
-      }
-    ]
-  }
-/>;
+<td
+  onClick={() => {
+    a;
+  }}
+>
+  {header}
+  <showSort attr='long long long long long long long long long long long' />
+</td>;
 
-<Something>
-  {() => (
-    <SomethingElse>
-      <span />
-    </SomethingElse>
-  )}
-</Something>;
+<Foo>{\`    a    very    long    text    that    does    not    break    \`}</Foo>;
 
-<Something>
-  {items.map(item => (
-    <SomethingElse>
-      <span />
-    </SomethingElse>
-  ))}
-</Something>;
+`;
 
-<Something>
-  {function() {
-    return (
-      <SomethingElse>
-        <span />
-      </SomethingElse>
-    );
+exports[`open-break.js - flow-verify 3`] = `
+<td
+onClick={() => {
+  a
+}}>{header}{showSort}</td>;
+
+<td
+onClick={() => {
+  a
+}}>{header}<showSort attr="long long long long long long long long long long long"/></td>;
+
+<Foo>{\`    a    very    long    text    that    does    not    break    \`}</Foo>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<td
+  onClick={() => {
+    a;
   }}
-</Something>;
+>
+  {header}
+  {showSort}
+</td>;
 
-<RadioListItem
-  key={option}
-  imageSource={this.props.veryBigItemImageSourceFunc &&
-    this.props.veryBigItemImageSourceFunc(option)}
-  imageSize={this.props.veryBigItemImageSize}
-  imageView={this.props.veryBigItemImageViewFunc &&
-    this.props.veryBigItemImageViewFunc(option)}
-  heading={this.props.displayTextFunc(option)}
-  value={option}
+<td
+  onClick={() => {
+    a;
+  }}
+>
+  {header}
+  <showSort attr="long long long long long long long long long long long" />
+</td>;
+
+<Foo>{\`    a    very    long    text    that    does    not    break    \`}</Foo>;
+
+`;
+
+exports[`open-break.js - flow-verify 4`] = `
+<td
+onClick={() => {
+  a
+}}>{header}{showSort}</td>;
+
+<td
+onClick={() => {
+  a
+}}>{header}<showSort attr="long long long long long long long long long long long"/></td>;
+
+<Foo>{\`    a    very    long    text    that    does    not    break    \`}</Foo>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<td
+  onClick={() => {
+    a;
+  }}
+>
+  {header}
+  {showSort}
+</td>;
+
+<td
+  onClick={() => {
+    a;
+  }}
+>
+  {header}
+  <showSort attr='long long long long long long long long long long long' />
+</td>;
+
+<Foo>{\`    a    very    long    text    that    does    not    break    \`}</Foo>;
+
+`;
+
+exports[`parens.js - flow-verify 1`] = `
+a = [
+  <path
+    key='0'
+    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
+  />,
+  <path
+    key='1'
+    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
+  />,
+];
+
+<div {...((foo || foo === null) ? {foo} : null)} />
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+a = [
+  <path
+    key="0"
+    d="M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,"
+  />,
+  <path
+    key="1"
+    d="M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,"
+  />
+];
+
+<div {...(foo || foo === null ? { foo } : null)} />;
+
+`;
+
+exports[`parens.js - flow-verify 2`] = `
+a = [
+  <path
+    key='0'
+    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
+  />,
+  <path
+    key='1'
+    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
+  />,
+];
+
+<div {...((foo || foo === null) ? {foo} : null)} />
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+a = [
+  <path
+    key='0'
+    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
+  />,
+  <path
+    key='1'
+    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
+  />
+];
+
+<div {...(foo || foo === null ? { foo } : null)} />;
+
+`;
+
+exports[`parens.js - flow-verify 3`] = `
+a = [
+  <path
+    key='0'
+    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
+  />,
+  <path
+    key='1'
+    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
+  />,
+];
+
+<div {...((foo || foo === null) ? {foo} : null)} />
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+a = [
+  <path
+    key="0"
+    d="M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,"
+  />,
+  <path
+    key="1"
+    d="M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,"
+  />
+];
+
+<div {...(foo || foo === null ? { foo } : null)} />;
+
+`;
+
+exports[`parens.js - flow-verify 4`] = `
+a = [
+  <path
+    key='0'
+    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
+  />,
+  <path
+    key='1'
+    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
+  />,
+];
+
+<div {...((foo || foo === null) ? {foo} : null)} />
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+a = [
+  <path
+    key='0'
+    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
+  />,
+  <path
+    key='1'
+    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
+  />
+];
+
+<div {...(foo || foo === null ? { foo } : null)} />;
+
+`;
+
+exports[`quotes.js - flow-verify 1`] = `
+<div id="&quot;'<>&amp;quot;" />;
+<div id='"&#39;<>&amp;quot;' />;
+<div id={'\\'"&quot;<>&amp;quot;'} />;
+<div id='123' />;
+<div id='&#39;&quot;' />;
+<div id={'\\'\\"\\\\\\''} />;
+<div
+  single='foo'
+  single2={'foo'}
+
+  double="bar"
+  double2={"bar"}
+
+  singleDouble='"'
+  singleDouble2={'"'}
+
+  doubleSingle="'"
+  doubleSingle2={"'"}
+
+  singleEscaped={'\\''}
+  singleEscaped2='&apos;'
+
+  doubleEscaped={"\\""}
+  doubleEscaped2="&quot;"
+
+  singleBothEscaped={'\\'"'}
+  singleBothEscaped2='&apos;"'
+
+  singleBoth='&apos; "'
+  singleBoth2={'\\' "'}
+  singleBoth3='&apos; &apos; "'
+
+  doubleBoth="&quot; '"
+  doubleBoth2={"\\" '"}
+  doubleBoth3="&quot; &apos; '"
+/>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<div id="&quot;'<>&amp;quot;" />;
+<div id='"&#39;<>&amp;quot;' />;
+<div id={"'\\"&quot;<>&amp;quot;"} />;
+<div id="123" />;
+<div id='&#39;"' />;
+<div id={"'\\"\\\\'"} />;
+<div
+  single="foo"
+  single2={"foo"}
+  double="bar"
+  double2={"bar"}
+  singleDouble='"'
+  singleDouble2={'"'}
+  doubleSingle="'"
+  doubleSingle2={"'"}
+  singleEscaped={"'"}
+  singleEscaped2="'"
+  doubleEscaped={'"'}
+  doubleEscaped2='"'
+  singleBothEscaped={"'\\""}
+  singleBothEscaped2="'&quot;"
+  singleBoth="' &quot;"
+  singleBoth2={"' \\""}
+  singleBoth3="' ' &quot;"
+  doubleBoth="&quot; '"
+  doubleBoth2={"\\" '"}
+  doubleBoth3="&quot; ' '"
 />;
 
-<ParentComponent prop={
-  <Child>
-    test
-  </Child>
-}/>;
+`;
+
+exports[`quotes.js - flow-verify 2`] = `
+<div id="&quot;'<>&amp;quot;" />;
+<div id='"&#39;<>&amp;quot;' />;
+<div id={'\\'"&quot;<>&amp;quot;'} />;
+<div id='123' />;
+<div id='&#39;&quot;' />;
+<div id={'\\'\\"\\\\\\''} />;
+<div
+  single='foo'
+  single2={'foo'}
 
-<BookingIntroPanel
-  prop="long_string_make_to_force_break"
-  logClick={data => doLogClick("short", "short", data)}
-/>;
+  double="bar"
+  double2={"bar"}
 
-<BookingIntroPanel
-  logClick={data =>
-    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
-  }
-/>;
+  singleDouble='"'
+  singleDouble2={'"'}
 
-<BookingIntroPanel
-  logClick={data => {
-    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
-  }}
-/>;
+  doubleSingle="'"
+  doubleSingle2={"'"}
 
-<Component
-  onChange={(
-    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
-    value: string | Immutable.List<string>,
-  ) => {
-    this.setState({
-      updatedTask: this.state.updatedTask.set(key, value)
-    });
-  }}
-/>;
+  singleEscaped={'\\''}
+  singleEscaped2='&apos;'
 
-<BookingIntroPanel>
-  {data => doLogClick("short", "short", data)}
-</BookingIntroPanel>;
+  doubleEscaped={"\\""}
+  doubleEscaped2="&quot;"
 
-<BookingIntroPanel>
-  {data =>
-    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
-  }
-</BookingIntroPanel>;
+  singleBothEscaped={'\\'"'}
+  singleBothEscaped2='&apos;"'
 
-<BookingIntroPanel>
-  {data => {
-    doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data)
-  }}
-</BookingIntroPanel>;
+  singleBoth='&apos; "'
+  singleBoth2={'\\' "'}
+  singleBoth3='&apos; &apos; "'
 
-<Component>
-  {(
-    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
-    value: string | Immutable.List<string>,
-  ) => {
-    this.setState({
-      updatedTask: this.state.updatedTask.set(key, value)
-    });
-  }}
-</Component>;
+  doubleBoth="&quot; '"
+  doubleBoth2={"\\" '"}
+  doubleBoth3="&quot; &apos; '"
+/>;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<View
-  style={{
-    someVeryLongStyle1: "true",
-    someVeryLongStyle2: "true",
-    someVeryLongStyle3: "true",
-    someVeryLongStyle4: "true"
-  }}
+<div id='"&apos;<>&amp;quot;' />;
+<div id='"&#39;<>&amp;quot;' />;
+<div id={"'\\"&quot;<>&amp;quot;"} />;
+<div id='123' />;
+<div id='&#39;"' />;
+<div id={"'\\"\\\\'"} />;
+<div
+  single='foo'
+  single2={"foo"}
+  double='bar'
+  double2={"bar"}
+  singleDouble='"'
+  singleDouble2={'"'}
+  doubleSingle="'"
+  doubleSingle2={"'"}
+  singleEscaped={"'"}
+  singleEscaped2="'"
+  doubleEscaped={'"'}
+  doubleEscaped2='"'
+  singleBothEscaped={"'\\""}
+  singleBothEscaped2='&apos;"'
+  singleBoth='&apos; "'
+  singleBoth2={"' \\""}
+  singleBoth3="' ' &quot;"
+  doubleBoth='" &apos;'
+  doubleBoth2={"\\" '"}
+  doubleBoth3="&quot; ' '"
 />;
 
-<View
-  style={[
-    {
-      someVeryLongStyle1: "true",
-      someVeryLongStyle2: "true",
-      someVeryLongStyle3: "true",
-      someVeryLongStyle4: "true"
-    }
-  ]}
-/>;
+`;
 
-<Something>
-  {() => (
-    <SomethingElse>
-      <span />
-    </SomethingElse>
-  )}
-</Something>;
+exports[`quotes.js - flow-verify 3`] = `
+<div id="&quot;'<>&amp;quot;" />;
+<div id='"&#39;<>&amp;quot;' />;
+<div id={'\\'"&quot;<>&amp;quot;'} />;
+<div id='123' />;
+<div id='&#39;&quot;' />;
+<div id={'\\'\\"\\\\\\''} />;
+<div
+  single='foo'
+  single2={'foo'}
 
-<Something>
-  {items.map(item => (
-    <SomethingElse>
-      <span />
-    </SomethingElse>
-  ))}
-</Something>;
+  double="bar"
+  double2={"bar"}
 
-<Something>
-  {function() {
-    return (
-      <SomethingElse>
-        <span />
-      </SomethingElse>
-    );
-  }}
-</Something>;
+  singleDouble='"'
+  singleDouble2={'"'}
 
-<RadioListItem
-  key={option}
-  imageSource={
-    this.props.veryBigItemImageSourceFunc &&
-    this.props.veryBigItemImageSourceFunc(option)
-  }
-  imageSize={this.props.veryBigItemImageSize}
-  imageView={
-    this.props.veryBigItemImageViewFunc &&
-    this.props.veryBigItemImageViewFunc(option)
-  }
-  heading={this.props.displayTextFunc(option)}
-  value={option}
-/>;
+  doubleSingle="'"
+  doubleSingle2={"'"}
 
-<ParentComponent prop={<Child>test</Child>} />;
+  singleEscaped={'\\''}
+  singleEscaped2='&apos;'
 
-<BookingIntroPanel
-  prop="long_string_make_to_force_break"
-  logClick={data => doLogClick("short", "short", data)}
-/>;
+  doubleEscaped={"\\""}
+  doubleEscaped2="&quot;"
 
-<BookingIntroPanel
-  logClick={data =>
-    doLogClick(
-      "long_name_long_name_long_name",
-      "long_name_long_name_long_name",
-      data
-    )
-  }
-/>;
+  singleBothEscaped={'\\'"'}
+  singleBothEscaped2='&apos;"'
 
-<BookingIntroPanel
-  logClick={data => {
-    doLogClick(
-      "long_name_long_name_long_name",
-      "long_name_long_name_long_name",
-      data
-    );
-  }}
-/>;
+  singleBoth='&apos; "'
+  singleBoth2={'\\' "'}
+  singleBoth3='&apos; &apos; "'
 
-<Component
-  onChange={(
-    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
-    value: string | Immutable.List<string>
-  ) => {
-    this.setState({
-      updatedTask: this.state.updatedTask.set(key, value)
-    });
-  }}
+  doubleBoth="&quot; '"
+  doubleBoth2={"\\" '"}
+  doubleBoth3="&quot; &apos; '"
+/>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<div id="&quot;'<>&amp;quot;" />;
+<div id='"&#39;<>&amp;quot;' />;
+<div id={'\\'"&quot;<>&amp;quot;'} />;
+<div id="123" />;
+<div id='&#39;"' />;
+<div id={"'\\"\\\\'"} />;
+<div
+  single="foo"
+  single2={'foo'}
+  double="bar"
+  double2={'bar'}
+  singleDouble='"'
+  singleDouble2={'"'}
+  doubleSingle="'"
+  doubleSingle2={"'"}
+  singleEscaped={"'"}
+  singleEscaped2="'"
+  doubleEscaped={'"'}
+  doubleEscaped2='"'
+  singleBothEscaped={'\\'"'}
+  singleBothEscaped2="'&quot;"
+  singleBoth="' &quot;"
+  singleBoth2={'\\' "'}
+  singleBoth3="' ' &quot;"
+  doubleBoth="&quot; '"
+  doubleBoth2={'" \\''}
+  doubleBoth3="&quot; ' '"
 />;
 
-<BookingIntroPanel>
-  {data => doLogClick("short", "short", data)}
-</BookingIntroPanel>;
+`;
 
-<BookingIntroPanel>
-  {data =>
-    doLogClick(
-      "long_name_long_name_long_name",
-      "long_name_long_name_long_name",
-      data
-    )
-  }
-</BookingIntroPanel>;
+exports[`quotes.js - flow-verify 4`] = `
+<div id="&quot;'<>&amp;quot;" />;
+<div id='"&#39;<>&amp;quot;' />;
+<div id={'\\'"&quot;<>&amp;quot;'} />;
+<div id='123' />;
+<div id='&#39;&quot;' />;
+<div id={'\\'\\"\\\\\\''} />;
+<div
+  single='foo'
+  single2={'foo'}
 
-<BookingIntroPanel>
-  {data => {
-    doLogClick(
-      "long_name_long_name_long_name",
-      "long_name_long_name_long_name",
-      data
-    );
-  }}
-</BookingIntroPanel>;
+  double="bar"
+  double2={"bar"}
 
-<Component>
-  {(
-    key: "possible_key_1" | "possible_key_2" | "possible_key_3",
-    value: string | Immutable.List<string>
-  ) => {
-    this.setState({
-      updatedTask: this.state.updatedTask.set(key, value)
-    });
-  }}
-</Component>;
+  singleDouble='"'
+  singleDouble2={'"'}
 
-`;
+  doubleSingle="'"
+  doubleSingle2={"'"}
 
-exports[`flow_fix_me.js - flow-verify 1`] = `
-const aDiv = (
-  /* $FlowFixMe */
-  <div className="foo">
-    Foo bar
-  </div>
-);
+  singleEscaped={'\\''}
+  singleEscaped2='&apos;'
+
+  doubleEscaped={"\\""}
+  doubleEscaped2="&quot;"
+
+  singleBothEscaped={'\\'"'}
+  singleBothEscaped2='&apos;"'
+
+  singleBoth='&apos; "'
+  singleBoth2={'\\' "'}
+  singleBoth3='&apos; &apos; "'
+
+  doubleBoth="&quot; '"
+  doubleBoth2={"\\" '"}
+  doubleBoth3="&quot; &apos; '"
+/>;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-const aDiv = (
-  /* $FlowFixMe */
-  <div className="foo">Foo bar</div>
-);
+<div id='"&apos;<>&amp;quot;' />;
+<div id='"&#39;<>&amp;quot;' />;
+<div id={'\\'"&quot;<>&amp;quot;'} />;
+<div id='123' />;
+<div id='&#39;"' />;
+<div id={"'\\"\\\\'"} />;
+<div
+  single='foo'
+  single2={'foo'}
+  double='bar'
+  double2={'bar'}
+  singleDouble='"'
+  singleDouble2={'"'}
+  doubleSingle="'"
+  doubleSingle2={"'"}
+  singleEscaped={"'"}
+  singleEscaped2="'"
+  doubleEscaped={'"'}
+  doubleEscaped2='"'
+  singleBothEscaped={'\\'"'}
+  singleBothEscaped2='&apos;"'
+  singleBoth='&apos; "'
+  singleBoth2={'\\' "'}
+  singleBoth3="' ' &quot;"
+  doubleBoth='" &apos;'
+  doubleBoth2={'" \\''}
+  doubleBoth3="&quot; ' '"
+/>;
 
 `;
 
-exports[`html_escape.js - flow-verify 1`] = `
-export default () => <a href="https://foo.bar?q1=foo&q2=bar" />;
+exports[`return-statement.js - flow-verify 1`] = `
+const NonBreakingArrowExpression = () => <div />;
 
-() => <img src="https://bar.foo?param1=1&param2=2" />;
+const BreakingArrowExpression = () => <div>
+  <div>
+    bla bla bla
+  </div>
+</div>;
+
+const NonBreakingArrowExpressionWBody = () => {
+  return (
+    <div />
+  );
+};
+
+const BreakingArrowExpressionWBody = () => {
+  return <div>
+    <div>
+      bla bla bla
+    </div>
+  </div>
+};
+
+const NonBreakingFunction = function() {
+  return (
+    <div />
+  );
+};
+
+const BreakingFunction = function() {
+  return <div>
+    <div>
+      bla bla bla
+    </div>
+  </div>
+};
+
+class NonBreakingClass extends React.component {
+  render() {
+    return (
+      <div />
+    );
+  }
+}
+
+class BreakingClass extends React.component {
+  render() {
+    return <div>
+      <div>
+        bla bla bla
+      </div>
+    </div>;
+  }
+}
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-export default () => <a href="https://foo.bar?q1=foo&q2=bar" />;
-
-() => <img src="https://bar.foo?param1=1&param2=2" />;
-
-`;
+const NonBreakingArrowExpression = () => <div />;
 
-exports[`hug.js - flow-verify 1`] = `
-<div>
-  {__DEV__
-    ? this.renderDevApp()
-    : <div>
-      {routes.map(route => (
-        <MatchAsync
-          key={\`\${route.to}-async\`}
-          pattern={route.to}
-          exactly={route.to === "/"}
-          getComponent={routeES6Modules[route.value]}
-        />
-      ))}
-    </div>}
-</div>;
+const BreakingArrowExpression = () => (
+  <div>
+    <div>bla bla bla</div>
+  </div>
+);
 
-<div>
-  {__DEV__ && <div>
-    {routes.map(route => (
-      <MatchAsync
-        key={\`\${route.to}-async\`}
-        pattern={route.to}
-        exactly={route.to === "/"}
-        getComponent={routeES6Modules[route.value]}
-      />
-    ))}
-    </div>}
-</div>;
+const NonBreakingArrowExpressionWBody = () => {
+  return <div />;
+};
 
-<div>
-  {member.memberName.memberSomething +
-    (member.memberDef.memberSomething.signatures ? '()' : '')}
-</div>
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<div>
-  {__DEV__ ? (
-    this.renderDevApp()
-  ) : (
+const BreakingArrowExpressionWBody = () => {
+  return (
     <div>
-      {routes.map(route => (
-        <MatchAsync
-          key={\`\${route.to}-async\`}
-          pattern={route.to}
-          exactly={route.to === "/"}
-          getComponent={routeES6Modules[route.value]}
-        />
-      ))}
+      <div>bla bla bla</div>
     </div>
-  )}
-</div>;
+  );
+};
 
-<div>
-  {__DEV__ && (
+const NonBreakingFunction = function() {
+  return <div />;
+};
+
+const BreakingFunction = function() {
+  return (
     <div>
-      {routes.map(route => (
-        <MatchAsync
-          key={\`\${route.to}-async\`}
-          pattern={route.to}
-          exactly={route.to === "/"}
-          getComponent={routeES6Modules[route.value]}
-        />
-      ))}
+      <div>bla bla bla</div>
     </div>
-  )}
-</div>;
+  );
+};
 
-<div>
-  {member.memberName.memberSomething +
-    (member.memberDef.memberSomething.signatures ? "()" : "")}
-</div>;
+class NonBreakingClass extends React.component {
+  render() {
+    return <div />;
+  }
+}
 
-`;
+class BreakingClass extends React.component {
+  render() {
+    return (
+      <div>
+        <div>bla bla bla</div>
+      </div>
+    );
+  }
+}
 
-exports[`logical-expression.js - flow-verify 1`] = `
-<div>
-  {a || "b"}
-</div>;
+`;
 
-<div>
-  {a && "b"}
-</div>;
+exports[`return-statement.js - flow-verify 2`] = `
+const NonBreakingArrowExpression = () => <div />;
 
-<div>
-  {a || <span></span>}
+const BreakingArrowExpression = () => <div>
+  <div>
+    bla bla bla
+  </div>
 </div>;
 
-<div>
-  {a && <span></span>}
-</div>;
+const NonBreakingArrowExpressionWBody = () => {
+  return (
+    <div />
+  );
+};
 
-<div>
-  {a && <span>make this text just so long enough to break this to the next line</span>}
-</div>;
+const BreakingArrowExpressionWBody = () => {
+  return <div>
+    <div>
+      bla bla bla
+    </div>
+  </div>
+};
 
-<div>
-  {a && b && <span>make this text just so long enough to break this to the next line</span>}
-</div>;
+const NonBreakingFunction = function() {
+  return (
+    <div />
+  );
+};
 
-<div>
-  {a && <span>
+const BreakingFunction = function() {
+  return <div>
     <div>
-      <div></div>
+      bla bla bla
     </div>
-  </span>}
-</div>;
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<div>{a || "b"}</div>;
+  </div>
+};
 
-<div>{a && "b"}</div>;
+class NonBreakingClass extends React.component {
+  render() {
+    return (
+      <div />
+    );
+  }
+}
 
-<div>{a || <span />}</div>;
+class BreakingClass extends React.component {
+  render() {
+    return <div>
+      <div>
+        bla bla bla
+      </div>
+    </div>;
+  }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const NonBreakingArrowExpression = () => <div />;
 
-<div>{a && <span />}</div>;
+const BreakingArrowExpression = () => (
+  <div>
+    <div>bla bla bla</div>
+  </div>
+);
 
-<div>
-  {a && (
-    <span>
-      make this text just so long enough to break this to the next line
-    </span>
-  )}
-</div>;
+const NonBreakingArrowExpressionWBody = () => {
+  return <div />;
+};
 
-<div>
-  {a && b && (
-    <span>
-      make this text just so long enough to break this to the next line
-    </span>
-  )}
-</div>;
+const BreakingArrowExpressionWBody = () => {
+  return (
+    <div>
+      <div>bla bla bla</div>
+    </div>
+  );
+};
 
-<div>
-  {a && (
-    <span>
-      <div>
-        <div />
-      </div>
-    </span>
-  )}
-</div>;
+const NonBreakingFunction = function() {
+  return <div />;
+};
 
-`;
+const BreakingFunction = function() {
+  return (
+    <div>
+      <div>bla bla bla</div>
+    </div>
+  );
+};
 
-exports[`object-property.js - flow-verify 1`] = `
-const tabs = [
-  {
-    title: "General Info",
-    content: (
-      <GeneralForm
-        long-attribute="i-need-long-value-here"
-        onSave={ onSave }
-        onCancel={ onCancel }
-        countries={ countries }
-      />
-    )
-  }
-];
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-const tabs = [
-  {
-    title: "General Info",
-    content: (
-      <GeneralForm
-        long-attribute="i-need-long-value-here"
-        onSave={onSave}
-        onCancel={onCancel}
-        countries={countries}
-      />
-    )
+class NonBreakingClass extends React.component {
+  render() {
+    return <div />;
   }
-];
+}
+
+class BreakingClass extends React.component {
+  render() {
+    return (
+      <div>
+        <div>bla bla bla</div>
+      </div>
+    );
+  }
+}
 
 `;
 
-exports[`open-break.js - flow-verify 1`] = `
-<td
-onClick={() => {
-  a
-}}>{header}{showSort}</td>;
+exports[`return-statement.js - flow-verify 3`] = `
+const NonBreakingArrowExpression = () => <div />;
 
-<td
-onClick={() => {
-  a
-}}>{header}<showSort attr="long long long long long long long long long long long"/></td>;
+const BreakingArrowExpression = () => <div>
+  <div>
+    bla bla bla
+  </div>
+</div>;
 
-<Foo>{\`    a    very    long    text    that    does    not    break    \`}</Foo>;
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<td
-  onClick={() => {
-    a;
-  }}
->
-  {header}
-  {showSort}
-</td>;
+const NonBreakingArrowExpressionWBody = () => {
+  return (
+    <div />
+  );
+};
 
-<td
-  onClick={() => {
-    a;
-  }}
->
-  {header}
-  <showSort attr="long long long long long long long long long long long" />
-</td>;
+const BreakingArrowExpressionWBody = () => {
+  return <div>
+    <div>
+      bla bla bla
+    </div>
+  </div>
+};
 
-<Foo>{\`    a    very    long    text    that    does    not    break    \`}</Foo>;
+const NonBreakingFunction = function() {
+  return (
+    <div />
+  );
+};
 
-`;
+const BreakingFunction = function() {
+  return <div>
+    <div>
+      bla bla bla
+    </div>
+  </div>
+};
 
-exports[`parens.js - flow-verify 1`] = `
-a = [
-  <path
-    key='0'
-    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
-  />,
-  <path
-    key='1'
-    d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
-  />,
-];
+class NonBreakingClass extends React.component {
+  render() {
+    return (
+      <div />
+    );
+  }
+}
 
-<div {...((foo || foo === null) ? {foo} : null)} />
+class BreakingClass extends React.component {
+  render() {
+    return <div>
+      <div>
+        bla bla bla
+      </div>
+    </div>;
+  }
+}
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-a = [
-  <path
-    key="0"
-    d="M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,"
-  />,
-  <path
-    key="1"
-    d="M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,"
-  />
-];
+const NonBreakingArrowExpression = () => <div />;
 
-<div {...(foo || foo === null ? { foo } : null)} />;
+const BreakingArrowExpression = () => (
+  <div>
+    <div>bla bla bla</div>
+  </div>
+);
 
-`;
+const NonBreakingArrowExpressionWBody = () => {
+  return <div />;
+};
 
-exports[`quotes.js - flow-verify 1`] = `
-<div id="&quot;'<>&amp;quot;" />;
-<div id='"&#39;<>&amp;quot;' />;
-<div id={'\\'"&quot;<>&amp;quot;'} />;
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<div id="&quot;'<>&amp;quot;" />;
-<div id="&quot;&#39;<>&amp;quot;" />;
-<div id={"'\\"&quot;<>&amp;quot;"} />;
+const BreakingArrowExpressionWBody = () => {
+  return (
+    <div>
+      <div>bla bla bla</div>
+    </div>
+  );
+};
+
+const NonBreakingFunction = function() {
+  return <div />;
+};
+
+const BreakingFunction = function() {
+  return (
+    <div>
+      <div>bla bla bla</div>
+    </div>
+  );
+};
+
+class NonBreakingClass extends React.component {
+  render() {
+    return <div />;
+  }
+}
+
+class BreakingClass extends React.component {
+  render() {
+    return (
+      <div>
+        <div>bla bla bla</div>
+      </div>
+    );
+  }
+}
 
 `;
 
-exports[`return-statement.js - flow-verify 1`] = `
+exports[`return-statement.js - flow-verify 4`] = `
 const NonBreakingArrowExpression = () => <div />;
 
 const BreakingArrowExpression = () => <div>
@@ -1083,3 +4474,96 @@ const Labels = {
 };
 
 `;
+
+exports[`spacing.js - flow-verify 2`] = `
+const Labels = {
+  label1: (
+    <fbt>
+      Label 1
+    </fbt>
+  ),
+
+  label2: (
+    <fbt>
+      Label 2
+    </fbt>
+  ),
+
+  label3: (
+    <fbt>
+      Label 3
+    </fbt>
+  ),
+};
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const Labels = {
+  label1: <fbt>Label 1</fbt>,
+
+  label2: <fbt>Label 2</fbt>,
+
+  label3: <fbt>Label 3</fbt>
+};
+
+`;
+
+exports[`spacing.js - flow-verify 3`] = `
+const Labels = {
+  label1: (
+    <fbt>
+      Label 1
+    </fbt>
+  ),
+
+  label2: (
+    <fbt>
+      Label 2
+    </fbt>
+  ),
+
+  label3: (
+    <fbt>
+      Label 3
+    </fbt>
+  ),
+};
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const Labels = {
+  label1: <fbt>Label 1</fbt>,
+
+  label2: <fbt>Label 2</fbt>,
+
+  label3: <fbt>Label 3</fbt>
+};
+
+`;
+
+exports[`spacing.js - flow-verify 4`] = `
+const Labels = {
+  label1: (
+    <fbt>
+      Label 1
+    </fbt>
+  ),
+
+  label2: (
+    <fbt>
+      Label 2
+    </fbt>
+  ),
+
+  label3: (
+    <fbt>
+      Label 3
+    </fbt>
+  ),
+};
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const Labels = {
+  label1: <fbt>Label 1</fbt>,
+
+  label2: <fbt>Label 2</fbt>,
+
+  label3: <fbt>Label 3</fbt>
+};
+
+`;
diff --git a/tests/jsx/jsfmt.spec.js b/tests/jsx/jsfmt.spec.js
index aeb016da0388..687ad179cdcb 100644
--- a/tests/jsx/jsfmt.spec.js
+++ b/tests/jsx/jsfmt.spec.js
@@ -1,1 +1,16 @@
-run_spec(__dirname, ["flow", "babylon", "typescript"]);
+run_spec(__dirname, ["flow", "babylon", "typescript"], {
+  singleQuote: false,
+  jsxSingleQuote: false
+});
+run_spec(__dirname, ["flow", "babylon", "typescript"], {
+  singleQuote: false,
+  jsxSingleQuote: true
+});
+run_spec(__dirname, ["flow", "babylon", "typescript"], {
+  singleQuote: true,
+  jsxSingleQuote: false
+});
+run_spec(__dirname, ["flow", "babylon", "typescript"], {
+  singleQuote: true,
+  jsxSingleQuote: true
+});
diff --git a/tests/jsx/quotes.js b/tests/jsx/quotes.js
index 304e72c982c0..6982466fe0e1 100644
--- a/tests/jsx/quotes.js
+++ b/tests/jsx/quotes.js
@@ -1,3 +1,36 @@
 <div id="&quot;'<>&amp;quot;" />;
 <div id='"&#39;<>&amp;quot;' />;
 <div id={'\'"&quot;<>&amp;quot;'} />;
+<div id='123' />;
+<div id='&#39;&quot;' />;
+<div id={'\'\"\\\''} />;
+<div
+  single='foo'
+  single2={'foo'}
+
+  double="bar"
+  double2={"bar"}
+
+  singleDouble='"'
+  singleDouble2={'"'}
+
+  doubleSingle="'"
+  doubleSingle2={"'"}
+
+  singleEscaped={'\''}
+  singleEscaped2='&apos;'
+
+  doubleEscaped={"\""}
+  doubleEscaped2="&quot;"
+
+  singleBothEscaped={'\'"'}
+  singleBothEscaped2='&apos;"'
+
+  singleBoth='&apos; "'
+  singleBoth2={'\' "'}
+  singleBoth3='&apos; &apos; "'
+
+  doubleBoth="&quot; '"
+  doubleBoth2={"\" '"}
+  doubleBoth3="&quot; &apos; '"
+/>;
diff --git a/tests_integration/__tests__/__snapshots__/early-exit.js.snap b/tests_integration/__tests__/__snapshots__/early-exit.js.snap
index 4e2e3af446ec..572f147af08b 100644
--- a/tests_integration/__tests__/__snapshots__/early-exit.js.snap
+++ b/tests_integration/__tests__/__snapshots__/early-exit.js.snap
@@ -65,6 +65,8 @@ Format options:
                            Defaults to css.
   --jsx-bracket-same-line  Put > on the last line instead of at a new line.
                            Defaults to false.
+  --jsx-single-quote       Use single quotes in JSX.
+                           Defaults to false.
   --parser <flow|babylon|typescript|css|less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|html|angular>
                            Which parser to use.
   --print-width <int>      The line length where Prettier will try wrap.
@@ -206,6 +208,8 @@ Format options:
                            Defaults to css.
   --jsx-bracket-same-line  Put > on the last line instead of at a new line.
                            Defaults to false.
+  --jsx-single-quote       Use single quotes in JSX.
+                           Defaults to false.
   --parser <flow|babylon|typescript|css|less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|html|angular>
                            Which parser to use.
   --print-width <int>      The line length where Prettier will try wrap.
diff --git a/tests_integration/__tests__/__snapshots__/help-options.js.snap b/tests_integration/__tests__/__snapshots__/help-options.js.snap
index 8f7ac365d77c..e45689f1076c 100644
--- a/tests_integration/__tests__/__snapshots__/help-options.js.snap
+++ b/tests_integration/__tests__/__snapshots__/help-options.js.snap
@@ -196,6 +196,19 @@ Default: false
 
 exports[`show detailed usage with --help jsx-bracket-same-line (write) 1`] = `Array []`;
 
+exports[`show detailed usage with --help jsx-single-quote (stderr) 1`] = `""`;
+
+exports[`show detailed usage with --help jsx-single-quote (stdout) 1`] = `
+"--jsx-single-quote
+
+  Use single quotes in JSX.
+
+Default: false
+"
+`;
+
+exports[`show detailed usage with --help jsx-single-quote (write) 1`] = `Array []`;
+
 exports[`show detailed usage with --help list-different (stderr) 1`] = `""`;
 
 exports[`show detailed usage with --help list-different (stdout) 1`] = `
diff --git a/tests_integration/__tests__/__snapshots__/schema.js.snap b/tests_integration/__tests__/__snapshots__/schema.js.snap
index 33b0b7aa8124..b2afcf6a6c2c 100644
--- a/tests_integration/__tests__/__snapshots__/schema.js.snap
+++ b/tests_integration/__tests__/__snapshots__/schema.js.snap
@@ -82,6 +82,11 @@ This option cannot be used with --range-start and --range-end.",
           "description": "Put > on the last line instead of at a new line.",
           "type": "boolean",
         },
+        "jsxSingleQuote": Object {
+          "default": false,
+          "description": "Use single quotes in JSX.",
+          "type": "boolean",
+        },
         "parser": Object {
           "default": undefined,
           "description": "Which parser to use.",
diff --git a/tests_integration/__tests__/__snapshots__/support-info.js.snap b/tests_integration/__tests__/__snapshots__/support-info.js.snap
index 30c6bfc091b4..125e06ccc6c5 100644
--- a/tests_integration/__tests__/__snapshots__/support-info.js.snap
+++ b/tests_integration/__tests__/__snapshots__/support-info.js.snap
@@ -489,7 +489,7 @@ exports[`API getSupportInfo() with version 1.8.2 -> undefined 1`] = `
         \\"type\\": \\"boolean\\",
       },
       \\"cursorOffset\\": Object {
-@@ -56,10 +85,19 @@
+@@ -56,33 +85,61 @@
       },
       \\"filepath\\": Object {
         \\"default\\": undefined,
@@ -509,7 +509,17 @@ exports[`API getSupportInfo() with version 1.8.2 -> undefined 1`] = `
         \\"type\\": \\"boolean\\",
       },
       \\"jsxBracketSameLine\\": Object {
-@@ -73,16 +111,31 @@
+        \\"default\\": false,
+        \\"type\\": \\"boolean\\",
+      },
++     \\"jsxSingleQuote\\": Object {
++       \\"default\\": false,
++       \\"type\\": \\"boolean\\",
++     },
+      \\"parser\\": Object {
+        \\"choices\\": Array [
+          \\"flow\\",
+          \\"babylon\\",
           \\"typescript\\",
           \\"css\\",
           \\"less\\",
@@ -542,7 +552,7 @@ exports[`API getSupportInfo() with version 1.8.2 -> undefined 1`] = `
         \\"range\\": Object {
           \\"end\\": Infinity,
           \\"start\\": 0,
-@@ -90,14 +143,15 @@
+@@ -90,14 +147,15 @@
         },
         \\"type\\": \\"int\\",
       },
@@ -1019,6 +1029,15 @@ exports[`CLI --support-info (stdout) 1`] = `
       \\"since\\": \\"0.17.0\\",
       \\"type\\": \\"boolean\\"
     },
+    {
+      \\"category\\": \\"JavaScript\\",
+      \\"default\\": false,
+      \\"description\\": \\"Use single quotes in JSX.\\",
+      \\"name\\": \\"jsxSingleQuote\\",
+      \\"pluginDefaults\\": {},
+      \\"since\\": \\"1.15.0\\",
+      \\"type\\": \\"boolean\\"
+    },
     {
       \\"category\\": \\"Global\\",
       \\"choices\\": [