<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">I get what you’re looking for, I really do.  Existing switch has a lot of warts, some of which could be avoided with a new expression switch construct.  Avoiding warts seems like a good idea, and fall through is _even wartier_ with expression switches than statement switches.  (Not sure how you quantify wartiness.  Frogs per KLoC?)  <div class=""><br class=""></div><div class="">But, the problem is that if we make an expression switch construct, now we have two switch constructs.  They’re similar, and you will frequently want to refactor between them, but they’re subtly different.  And let’s not assume that the new construct will not have warts, so now that’s two different sets of warts the user has to keep in their head.  Users who arrive at Java will ask, “why are there two subtly different ways to do basically the same thing?”  I don’t think that’s necessarily doing anyone a favor.  If the warts were fatal, sure, that’s what we’d do, but they’re not.  Mostly, it’s annoying that we’re stuck with them for another 20 years. </div><div class=""><br class=""></div><div class="">While of course I may be too close to it, I think there’s a very nice balance in the current proposal.  In addition to control flow working exactly the same across the two forms, which I think does reduce the complexity of the language, the shorthand for “case X -> e” protects users from the most warty aspects almost all the time: </div><div class=""> - the at-least-at-first weirdness of “break value”;</div><div class=""> - the need to say break at all;</div><div class=""> - the risk of accidental fall through.</div><div class=""><br class=""></div><div class="">But if you need either explicit break or fall-through, they’re there, and they work just like the break you’ve always known, for better or worse.  Just “break” the glass.  </div><div class=""><br class=""></div><div class="">You’re saying “it wouldn’t be that bad if switch expressions had no fall through and only could take single expressions on the RHS, no statements.”  Well, if you restrict yourself to the -> syntactic form, you get exactly that!  So the only difference is that the escape hatch exists, if you’re willing to use it.  But if you’re not willing to use it, they you get exactly what you asked for. </div><div class=""><br class=""></div><div class=""><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 13, 2018, at 8:43 PM, Kevin Bourrillion <<a href="mailto:kevinb@google.com" class="">kevinb@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="gmail_quote"><div class="">Sorry for 5,000 inline replies.</div><div class=""><br class=""></div><div class=""><br class=""></div><div dir="ltr" class="">On Tue, Mar 13, 2018 at 1:18 PM Brian Goetz <<a href="mailto:brian.goetz@oracle.com" class="">brian.goetz@oracle.com</a>> wrote:<br class=""></div><div dir="ltr" class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div text="#000000" bgcolor="#FFFFFF" class="">
    <tt class="">Thanks for the detailed analysis.  I'm glad to see that a larger
      percentage could be converted to expression switch given
      sufficient effort;</tt></div></blockquote><div class=""><br class=""></div><div class="">Just to be clear: the sample was only from the 19% already identified as convertible, so in <i class="">this</i> discussion that number is only going down. However, the important point is that we should separately investigate the 81% to see whether a few simple heuristics make them recognizable as e-switches too.</div><div class=""><br class=""></div><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF" class=""><tt class=""> I'm also not surprised to see that a lot had
      accidental reasons that kept them off the happy path.  And, your
      analysis comports with expectations in another way: that some
      required more significant intervention than others to lever them
      into compliance.  For example, the ones with side-effecting
      activities or logging, while good candidates for "strongly
      dissuade", happen in the real world, and not all codebases have
      the level of discipline or willingness to refactor that yours
      does.  So I'm not sure I'm ready to toss either of the size-7
      sub-buckets aside so quick; not everyone is as sanguine as "well,
      go refactor then" as you are.</tt></div></blockquote><div class=""><br class=""></div><div class="">Okay, I want to clarify a few things about this style of research, which is how we have been evaluating API decisions for Guava and our other libraries for a long time, but which I skipped really explaining.</div><div class=""><br class=""></div><div class="">First, we are using "existing code could refactor to" as a proxy for "what might they probably write anew today if they could". It's a conceit, but a useful one since the corpus of existing code has the benefit of being visible and analyzable. :-) So, arguments that we make don't necessarily rest on whether actual users <i class="">will actually refactor</i>. (Also, I mean, if they aren't willing to refactor <i class="">at all</i>, then they wouldn't be changing to expression switch at all so they'd be irrelevant to us anyway, but this is not the real point.)</div><div class=""><br class=""></div><div class="">Second, we believe that the <i class="">most</i> useful (not <i class="">only</i>)<i class=""> </i>way to judge the value of a feature lies in comparing the <i class="">best code</i> users can write without that feature to the <i class="">best code</i> they can write with it. Then we look at two factors: (a) how much better did the feature make this code, and (b) how commonly do we think this case comes up in real life. Roughly speaking we multiply (a) and (b) together (for which I have with questionable taste attempted to coin the phrase "utility times ubiquity") and that gives about how much we care about making the change. This type of analysis has driven most decisions about the shape of Guava's API.</div><div class=""><br class=""></div><div class="">It's not the only kind of argument that can be made. One can also add "it might not make a large amount of 'great' code 'greater', but people who write mediocre code will be more likely to write decent code!" I just think that we should put less stock in such arguments than the other kind, because this sounds like a problem better addressed with static analysis tools, education, evangelism, and whatnot.</div><div class=""><br class=""></div><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF" class=""><tt class="">Which is to say, adjusting the data brings the simple bucket from
      86% (which seemed low) to 93-95%, which is "most of the time" but
      not "all of the time".  So most of the time, the code will not
      need whatever escape mechanism (break or block), but it will often
      enough that having some escape hatch is needed.  <br class=""></tt></div></blockquote><div class=""><br class=""></div><div class="">We think the ability to stick with procedural switch is that escape hatch already.</div><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF" class=""><tt class="">
      You didn't mention fallthrough, but because that's everyone's
      favorite punching bag here, I'll add: most of the time,
      fallthrough is not needed in expression switches, but having
      reviewed a number of low-level switches in the JDK, it is
      sometimes desirable even for switches that can be converted to
      expressions.  One of the motivations for refining break in this
      way is so that when fallthrough is needed, the existing idiom just
      works as everyone understands it to.</tt></div></blockquote><div class=""><br class=""></div><div class="">My assumption is that that code can just keep doing what it's already doing. My claim is that there is only value to changing to expression switch if we are getting the benefit of how much more simple and constrained it is.</div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF" class=""><tt class="">
      <blockquote type="cite" class="">
        <div class="">imho, early signs suggest that the grossness of `break x`
          is not <i class="">nearly</i> justified by the actual observed
          positive value of supporting multi-statement cases in
          expression switch. Are we open to killing that, or would we be
          if I produced more and clearer evidence?</div>
      </blockquote>
      <br class="">
      That's one valid interpretation of the data, but not the only. 
      Whether making break behave more like return (takes a value in
      non-void context, doesn't take one in void context) is gross or
      natural is subjective.  Here's my subjective interpretation:
      "great, most of the time, you don't have to use the escape hatch,
      but when you do, it has control flow just like the break we know,
      extended to take a value in non-void contexts, so will be fairly
      familiar."</tt></div></blockquote><div class=""><br class=""></div><div class="">I think that there are features that make sense on their own, and there are features that <i class="">totally make lots of sense</i> assuming that you have heard the expert group's passionate explanation of why they make sense. (It reminds me of a certain Pied Piper focus group near the end of Silicon Valley season 2, but moving on.) I am concerned that "breaking a value" is of the second kind.</div><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF" class=""><tt class="">But setting aside subjective reactions, are there better
      alternatives?  Let's review what has been considered already, and
      why they've been passed over: <br class="">
      <br class="">
       - Do nothing; only allow single expressions.  Non-starter.<br class=""></tt></div></blockquote><div class=""><br class=""></div><div class="">We're just saying the feature seems to be at least 90% as applicable without it. Roughly. Why is it a non-starter for the other 10% to stick with the switch they've always had? I'm sure there are good answers to that, I'm not doubting there are, but I think we should explore them instead of just declaring something a non-starter by fiat.</div><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF" class="">
    <tt class=""><tt class="">    case 1 -> 1;<br class="">
            case 2 -> { println("two"); break 2; }<br class="">
        <br class="">
        But that is pretty similar to what we have now, just with
        braces.  If the concern is that we're stretching `break` too
        far, then this is just as bad.  <br class="">
        <br class="">
        Worse, it has two significant additional downsides: <br class="">
        <br class="">
        1.  You can't fall through at all.  (Yes, I know some people
        think this is an upside.)</tt></tt></div></blockquote><div class=""><br class=""></div><div class="">Yes! That! That's what we want. No fall-through.</div><div class=""><br class=""></div><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF" class=""><tt class=""><tt class="">But real code does use fallthrough,
        and this leaves them without any alternative; it also widens the
        asymmetry of expression switch vs statement switch.</tt></tt></div></blockquote><div class=""><br class=""></div><div class="">Well, the other thread I started today is me literally <i class="">asking</i> for asymmetry between this and statement switch. If we stop using the `switch` keyword, so much the better.</div><div class=""><br class=""></div><div class="">What are the motivating use cases for fall-through in expression switch? These must be exclusively examples featuring side-effects, right? Or is there a way for a case to access the result produced by the previous one and build on it?</div><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF" class=""><tt class=""><tt class="">  (Combine
        this with other suggestions that widen the asymmetry between
        pattern and non-pattern switch, and you have four switch
        constructs.  Oops.)  <br class=""></tt></tt></div></blockquote><div class=""><br class=""></div><div class="">(Not familiar with that stuff yet.)</div><div class=""><br class=""></div><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF" class=""><tt class=""><tt class="">There might be other alternatives, but I don't see a better one,
        other than deprecating switch and designing a whole new
        mechanism.</tt></tt></div></blockquote><div class=""><br class=""></div><div class="">I'm confused. `switch` has worked the same way for 20+ years; what could possibly motivate us to deprecate it?</div><div class=""><br class=""></div><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF" class=""><tt class=""><tt class="">And, to defend what we've proposed: it's exactly the switch we
        all know, warts and all.  Very little new; very little in the
        way of asymmetry between void/value and pattern/constant.</tt></tt></div></blockquote><div class=""><br class=""></div><div class="">(My response to this is already teed up in the other thread. Basically, it says that if we don't make expression switch suitably constrained then I have so far failed to grasp what its value is at all.)</div><div class=""><br class=""></div><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF" class=""><tt class=""><tt class="">  The
        cost is that we have to accept the existing warts, primarily the
        weird block expression (blocks of statements with break not
        surrounded by braces), the weird scoping, and fallthrough.  <br class="">
        <br class="">
        This choice reminds me of the old Yiddish proverb of the Tree of
        Sorrows.  (<a class="m_-6988986355588270801moz-txt-link-freetext" href="https://www.inspirationalstories.com/0/69.html" target="_blank">https://www.inspirationalstories.com/0/69.html</a>).  <br class=""></tt></tt></div></blockquote><div class=""><br class=""></div><div class="">Tangent, but I think that story actually advocates that we stick with exactly the switch statement we already have today.</div><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF" class=""><tt class=""><tt class="">
        <br class="">
        If you've got something better ...  <br class="">
        <br class="">
        <br class="">
        <br class="">
      </tt></tt>
    <div class="m_-6988986355588270801moz-cite-prefix">On 3/13/2018 3:32 PM, Kevin Bourrillion
      wrote:<br class="">
    </div>
    <blockquote type="cite" class="">
      <div dir="ltr" class="">
        <div class="gmail_extra">
          <div class="gmail_quote">On Fri, Mar 9, 2018 at 3:21 PM, Louis
            Wasserman <span dir="ltr" class=""><<a href="mailto:lowasser@google.com" target="_blank" class="">lowasser@google.com</a>></span>
            wrote:</div>
          <div class="gmail_quote"><br class="">
            <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
              <div dir="ltr" class="">Simplifying: let's call normal cases in a
                switch simple if they're a single statement or a no-op
                fallthrough, and let's call a default simple if it's a
                single statement or it's not there at all.
                <div class=""><br class="">
                </div>
                <div class="">Among switches apparently convertible to expression
                  switches,<br class="">
                  <div class="">
                    <ul class="">
                      <li class=""><font size="2" class="">81% had all simple normal cases
                          and a simple default.</font></li>
                      <li class=""><font size="2" class="">5% had all simple normal cases
                          and a nonsimple default.</font></li>
                      <li class=""><font size="2" class="">12% had a nonsimple normal case
                          and a simple default.</font></li>
                      <li class=""><font size="2" class="">2% had a nonsimple normal case
                          and a nonsimple default.</font></li>
                    </ul>
                  </div>
                </div>
              </div>
            </blockquote>
            <div class="">I was surprised it was as high as 19%, so I grabbed a
              random sample of these 45 occurrences from Google's
              codebase and reviewed them. My goal was to find evidence
              that multi-statement cases in expression switches are
              important and common. Spoiler: I found said evidence
              underwhelming.</div>
            <div class=""><br class="">
            </div>
            <div class="">There were 3 that I would call false matches (e.g. two
              that simply used a void `return` instead of `break` after
              every case without reason).</div>
            <div class=""><br class="">
            </div>
            <div class="">There were fully 20 out of the remaining 42 that I
              quickly concluded should be refactored regardless of
              anything else, and where that refactoring happens to leave
              them with only simple cases and simple/no default. These
              refactorings were varied (hoist out code common to all
              non-exception cases; simplify unreachable code; change to
              `if` if only 1-2 cases; extract a method (needing only 1-2
              parameters) for a case that is much bigger than the
              others; switch from loop to Streams; change `if/else` to
              ?:; move a precondition check to a more appropriate
              location; and a few other varied cleanups).</div>
            <div class=""><br class="">
            </div>
            <div class="">Next there were 7 examples where the non-simple cases
              included side-effecting code, like setting fields or
              calling void methods. In Google Style I expect that we
              will probably forbid (or at least strongly dissuade) side
              effects in expression switch. I should probably bring this
              up separately, but I am pretty convinced by now that users
              should see expression switch and procedural switch as two
              completely different things, and by convention should
              always keep the former purely functional.<br class="">
            </div>
            <div class=""><br class="">
            </div>
            <div class="">
              <div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial" class="">Next
                there were 7 examples where a case was "non-simple" only
                because it was using the "log, then return a null object
                (or null), instead of throwing an exception"
                anti-pattern. I was surprised this was that popular. and
                another 2 that used the "log-and-also-throw"
                anti-pattern.</div>
              <div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial" class=""><br class="">
              </div>
              2 examples had a use-once local variable that saved a <i class="">little</i> bit
              of nesting. I wouldn't normally refactor these, but if
              expression switch had no mechanism for multi-statement
              cases, I wouldn't think twice about it.</div>
            <div class=""><br class="">
            </div>
            <div class=""><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline" class="">1
                example had cases that looked nearly identical, 3
                statements each, that could all be hoisted out of the
                switch, except that the types that differed across the
                three didn't implement a common interface (as they
                clearly should have). Slightly compelling.</span><br class="">
            </div>
            <div class=""><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline" class=""><br class="">
              </span></div>
            <div class="">1 example had all simple cases except that one also
              wanted to check an assertion. Okay, slightly compelling.<br class="">
            </div>
            <div class=""><br class="">
            </div>
            <div class="">Finally, the cases that were the most compelling to me:
              3 examples had one or more large cases, where factoring
              them out into helper methods would imho be ugly because
              >=3 parameters would be required. If expression switch
              didn't permit multi-statement cases, I would just keep
              them as procedural switches. It's only 3 out of 42.</div>
            <div class=""><br class="">
            </div>
            <div class="">Summary:</div>
            <div class=""><br class="">
            </div>
            <div class="">imho, early signs suggest that the grossness of `break
              x` is not <i class="">nearly</i> justified by the actual observed
              positive value of supporting multi-statement cases in
              expression switch. Are we open to killing that, or would
              we be if I produced more and clearer evidence?</div>
            <div class=""><br class="">
            </div>
            <div class=""><br class="">
            </div>
            <div class=""><br class="">
            </div>
            <div class=""><br class="">
            </div>
            <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
              <div dir="ltr" class=""><br class="">
              </div>
              <div class="m_-6988986355588270801HOEnZb">
                <div class="m_-6988986355588270801h5"><br class="">
                  <div class="gmail_quote">
                    <div dir="ltr" class="">On Fri, Mar 9, 2018 at 2:56 PM Brian
                      Goetz <<a href="mailto:brian.goetz@oracle.com" target="_blank" class="">brian.goetz@oracle.com</a>>
                      wrote:<br class="">
                    </div>
                    <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
                      <div text="#000000" bgcolor="#FFFFFF" class=""> <tt class="">Did
                          you happen to calculate what percentage was
                          _not_ the "default" case?  I would expect that
                          to be a considerable fraction.  </tt><br class="">
                      </div>
                      <div text="#000000" bgcolor="#FFFFFF" class=""> <br class="">
                        <div class="m_-6988986355588270801m_417813047818011507m_6613500527998856350moz-cite-prefix">On
                          3/9/2018 5:49 PM, Kevin Bourrillion wrote:<br class="">
                        </div>
                        <blockquote type="cite" class="">
                          <div dir="ltr" class="">
                            <div class="gmail_extra">
                              <div class="gmail_quote">On Fri, Mar 9,
                                2018 at 1:19 PM, Remi Forax <span dir="ltr" class=""><<a href="mailto:forax@univ-mlv.fr" target="_blank" class="">forax@univ-mlv.fr</a>></span>
                                wrote:</div>
                              <div class="gmail_quote"><br class="">
                                <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">When i asked
                                  what we should do instead, the answer
                                  is either:<br class="">
                                    1/ we should not allow block of
                                  codes in the expression switch but
                                  only expression<br class="">
                                    2/ that we should use the lambda
                                  syntax with return, even if the
                                  semantics is different from the lambda
                                  semantics.<br class="">
                                  <br class="">
                                  I do not like (1) because i think the
                                  expression switch will become useless</blockquote>
                                <div class=""><br class="">
                                </div>
                                <div class="">In our (large) codebase, +Louis
                                  determined that, among switch
                                  statements that appear translatable to
                                  expression switch, 13.8% of them seem
                                  to require at least one
                                  multi-statement case.</div>
                                <div class=""><br class="">
                                </div>
                              </div>
                            </div>
                          </div>
                        </blockquote>
                        <br class="">
                      </div>
                    </blockquote>
                  </div>
                </div>
              </div>
            </blockquote>
          </div>
          <br class="">
          <br clear="all" class="">
          <div class=""><br class="">
          </div>
          -- <br class="">
          <div class="m_-6988986355588270801gmail_signature" data-smartmail="gmail_signature">
            <div dir="ltr" class="">
              <div class="">
                <div dir="ltr" class="">
                  <div class="">
                    <div dir="ltr" class="">
                      <div style="line-height:1.5em;padding-top:10px;margin-top:10px;color:rgb(85,85,85);font-family:sans-serif" class=""><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(213,15,37);padding-top:2px;margin-top:2px" class="">Kevin
                          Bourrillion |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(51,105,232);padding-top:2px;margin-top:2px" class=""> Java
                          Librarian |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(0,153,57);padding-top:2px;margin-top:2px" class=""> Google,
                          Inc. |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(238,178,17);padding-top:2px;margin-top:2px" class=""> <a href="mailto:kevinb@google.com" target="_blank" class="">kevinb@google.com</a></span></div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <br class="">
  </div>

</blockquote></div><br clear="all" class=""><div class=""><br class=""></div>-- <br class=""><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr" class=""><div class=""><div dir="ltr" class=""><div class=""><div dir="ltr" class=""><div style="line-height:1.5em;padding-top:10px;margin-top:10px;color:rgb(85,85,85);font-family:sans-serif" class=""><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(213,15,37);padding-top:2px;margin-top:2px" class="">Kevin Bourrillion |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(51,105,232);padding-top:2px;margin-top:2px" class=""> Java Librarian |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(0,153,57);padding-top:2px;margin-top:2px" class=""> Google, Inc. |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(238,178,17);padding-top:2px;margin-top:2px" class=""> <a href="mailto:kevinb@google.com" target="_blank" class="">kevinb@google.com</a></span></div></div></div></div></div></div></div></div>
</div></blockquote></div><br class=""></div></div></body></html>