<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>163225</bug_id>
          
          <creation_ts>2016-10-10 11:08:42 -0700</creation_ts>
          <short_desc>StringView.split() should use an iterator design pattern instead of allocating a Vector</short_desc>
          <delta_ts>2017-01-24 09:46:24 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>Web Template Framework</component>
          <version>Other</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>Unspecified</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Alex Christensen">achristensen</reporter>
          <assigned_to name="Daniel Bates">dbates</assigned_to>
          <cc>benjamin</cc>
    
    <cc>cdumez</cc>
    
    <cc>cmarcelo</cc>
    
    <cc>commit-queue</cc>
    
    <cc>darin</cc>
    
    <cc>dbates</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1238391</commentid>
    <comment_count>0</comment_count>
    <who name="Alex Christensen">achristensen</who>
    <bug_when>2016-10-10 11:08:42 -0700</bug_when>
    <thetext>See feedback from https://bugs.webkit.org/show_bug.cgi?id=161920
Maybe we should do the same with String.split.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1265599</commentid>
    <comment_count>1</comment_count>
      <attachid>298528</attachid>
    <who name="Daniel Bates">dbates</who>
    <bug_when>2017-01-10 17:20:00 -0800</bug_when>
    <thetext>Created attachment 298528
Patch and unit tests</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1265600</commentid>
    <comment_count>2</comment_count>
    <who name="WebKit Commit Bot">commit-queue</who>
    <bug_when>2017-01-10 17:20:51 -0800</bug_when>
    <thetext>Attachment 298528 did not pass style-queue:


ERROR: Source/WTF/wtf/text/StringView.cpp:104:  Code inside a namespace should not be indented.  [whitespace/indent] [4]
Total errors found: 1 in 7 files


If any of these errors are false positives, please file a bug against check-webkit-style.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1265692</commentid>
    <comment_count>3</comment_count>
      <attachid>298528</attachid>
    <who name="Darin Adler">darin</who>
    <bug_when>2017-01-10 23:39:01 -0800</bug_when>
    <thetext>Comment on attachment 298528
Patch and unit tests

View in context: https://bugs.webkit.org/attachment.cgi?id=298528&amp;action=review

Some of these new functions should be inlined, I think. I mentioned some specific ones, but maybe even more of them. I’m not 100% sure how to figure out the right level of inlining.

&gt; Source/WTF/wtf/text/StringView.cpp:117
&gt; +auto StringView::Fields::end() const -&gt; Iterator
&gt; +{
&gt; +    return Iterator { *this, m_stringView.length() };
&gt; +}

Might want to make an even more efficient implementation of this that uses a different constructor, although we might have to pull some trick since there’s no trivial way to have two constructors that both have no arguments (the enum trick perhaps). There is no reason to call StringView::find when initializing. Could call something that sticks the length into both m_beginPosition and m_endPosition.

&gt; Source/WTF/wtf/text/StringView.cpp:125
&gt; +    unsigned length = fields.m_stringView.length();
&gt; +    if (m_beginPosition &gt; length)
&gt; +        m_beginPosition = length;

I would have used std::min for this, but I suggest removing this code entirely, since I don’t see the need to support startOffset.

&gt; Source/WTF/wtf/text/StringView.cpp:129
&gt; +void StringView::Fields::Iterator::findNextField()

This function should be named findNextSubstring; I am not sure that the things we get when splitting are &quot;fields&quot;.

&gt; Source/WTF/wtf/text/StringView.cpp:131
&gt; +    const StringView&amp; stringView = m_fields.m_stringView;

Since the stringView is only used twice, I am not sure we should bother with the local variable. Or if you want to keep it, I would use auto:

    auto&amp; string = m_fields.m_string;

&gt; Source/WTF/wtf/text/StringView.cpp:137
&gt; +    while ((m_endPosition = stringView.find(m_fields.m_separator, m_beginPosition)) != notFound) {
&gt; +        if (m_endPosition != m_beginPosition)
&gt; +            return;
&gt; +        m_beginPosition = m_endPosition + 1;
&gt; +    }
&gt; +    m_endPosition = stringView.length();

If we change m_endPosition to be unsigned then we can’t have it directly get the result of find, but I think that might be better anyway, writing it more like this. However, in this version the for line is so long, so maybe that’s a reason to not do this version.

    for (size_t separatorPosition; (separatorPosition = m_fields.m_string.find(m_fields.separator, m_beginPosition)) != notFound, ++m_beginPosition) {
        if (separatorPosition &gt; m_beginPosition) {
            m_endPosition = separatorPosition;
            return;
        }
    }
    m_endPosition = m_fields.m_string.length();

&gt; Source/WTF/wtf/text/StringView.cpp:142
&gt; +    return m_fields.m_stringView.substring(m_beginPosition, m_endPosition - m_beginPosition);

This returns the empty string when at the end. But I think it would be even better to assert. We would just add this:

    ASSERT(m_beginPosition &lt; m_endPosition);
    ASSERT(m_endPosition &lt; m_fields.m_string.length());

Seems like we should consider inlining this function since boils down to a single function call.

&gt; Source/WTF/wtf/text/StringView.cpp:152
&gt; +    unsigned length = m_fields.m_stringView.length();
&gt; +    m_beginPosition = m_endPosition + 1;
&gt; +    if (m_beginPosition &gt; length)
&gt; +        m_beginPosition = length;
&gt; +    findNextField();
&gt; +    return *this;

I suggest this alternate implementation:

    ASSERT(m_beginPosition &lt; m_endPosition);
    if (m_endPosition == m_fields.m_stringView.length()) {
        m_beginPosition = m_endPosition;
        return *this;
    }
    m_beginPosition = m_endPosition + 1;
    findNextField();
    return *this;

The assertion is the one we would hit if we erroneously call ++ after reaching the end. Could also add this internal consistency check assertion:

    ASSERT(m_endPosition &lt;= m_fields.m_string.length());

&gt; Source/WTF/wtf/text/StringView.cpp:159
&gt; +    return m_beginPosition == other.m_beginPosition &amp;&amp; m_endPosition == other.m_endPosition
&gt; +        &amp;&amp; &amp;m_fields.m_stringView == &amp;other.m_fields.m_stringView
&gt; +        &amp;&amp; m_fields.m_separator == other.m_fields.m_separator;

If I was writing this, I would assert that the iterators are from the same call to split, rather than returning false in such cases. There is no valid reason to compare iterators from two different calls to split.

There is some confused code here. The last two comparisons do the same thing as this:

    &amp;m_fields == &amp;other.m_fields

Since m_stringView is a StringView, and not a const StringView&amp;, and should be, its address is just an internal pointer inside the Fields structure. So it will only be equal if we have two references to the same Fields structure. And also, each substring is uniquely identified by the begin position and the end position. So we don’t need to compare both. This implementation would work well, the assertion would catch you if you used == on iterators from two different calls to split.

    ASSERT(&amp;m_fields == &amp;other.m_fields);
    return m_beginPosition == other.m_beginPosition;

Once we write it this way, it becomes clear that is a great candidate for inlining since the non-assert part of the function is a single super-simple expression.

Here are five other internal consistency check assertions we could include if we like:

    ASSERT((m_beginPosition == other.m_beginPosition) == (m_endPosition == other.m_endPosition));
    ASSERT(m_beginPosition &lt;= m_endPosition);
    ASSERT(m_endPosition &lt;= m_fields.m_string.length());
    ASSERT(other.m_beginPosition &lt;= other.m_endPosition);
    ASSERT(other.m_endPosition &lt;= other.m_fields.m_string.length());

&gt; Source/WTF/wtf/text/StringView.h:121
&gt; +    class Fields;

I don’t think Fields is a great name for this class. I would call this SplitResult or SplitSubstrings.

Later we might need different names for variations because we might need different flavors of split. Split based on a character, a string, and maybe even a regular expression. Split returning the appropriate number of empty substrings, alongside this kind of split that skips all empty substrings.

&gt; Source/WTF/wtf/text/StringView.h:122
&gt; +    WTF_EXPORT_STRING_API Fields split(UChar, unsigned startOffset = 0) const;

It’s easy to use substring on a StringView to start at an arbitrary location, and it is efficient and does not memory allocation, so the startOffset seems like an unneeded feature and I suggest omitting it. These were needed in the String class because substrings there are expensive and to be avoided. If one was going to call string.split(&apos;/&apos;, 1) one could call string.subview(1).split(&apos;/&apos;) instead.

&gt; Source/WTF/wtf/text/StringView.h:620
&gt; +    explicit Fields(const StringView&amp;, UChar separator, unsigned startOffset);

The type of the argument here should be StringView, not const StringView&amp;, because StringView is efficient to pass by value so there is no reason to use a reference here.

&gt; Source/WTF/wtf/text/StringView.h:627
&gt; +    StringView m_stringView;

In the context of this class, which is a member of StringView, I think we can just name this m_string since there is no ambiguity about the fact that this is a string view. But roughly speaking, a string.

&gt; Source/WTF/wtf/text/StringView.h:673
&gt; +    Iterator&amp; operator++(int) = delete;

I believe this is unneeded. If you define operator++() and don’t define operator++(int), it automatically will give an error if you try to post-increment. An explicit delete is not necessary.

&gt; Source/WTF/wtf/text/StringView.h:683
&gt; +    friend Fields;

Why does this work? I’ve always seen this written as friend class Fields before. Is this preferred syntax?

&gt; Source/WTF/wtf/text/StringView.h:685
&gt; +    const Fields&amp; m_fields;

I would probably rename this m_result after changing the type name from Fields to SplitResult or m_substrings if we use the name SplitSubstrings.

(Hard extra credit project: Would be nice if we could figure out a way to make the iterator assert at runtime if we accidentally used this after the Fields object was destroyed. I wouldn’t want to greatly complicate these classes just to check that, but it would be a bad bug if we kept an iterator around after m_fields was gone.)

&gt; Source/WTF/wtf/text/StringView.h:687
&gt; +    size_t m_beginPosition;
&gt; +    size_t m_endPosition;

These should be unsigned, not size_t. Positions within strings are unsigned, except that annoyingly the result of find is a size_t.

I think &quot;begin position&quot; is a strange name for a data member, because &quot;begin&quot; is a verb, not a noun. The noun is &quot;beginning&quot;. I know that the C++ standard library uses begin in this peculiar way, but I don’t think we need to follow suit. Maybe startPosition instead. Or even m_substringStart/m_substringEnd or m_substringPosition/m_substringEndPosition or m_position/m_endPosition.

I also think it would be easy to write this in terms of a length instead of an end position. The three places that currently set the end position (there are only three) would just subtract the start position to compute a length, and then the code in ++ would just say: m_position += m_length + 1.

I think that m_position/m_length may in fact be my favorite way to write this, but it would change almost all the assertions I suggested above.

&gt; Source/WebCore/platform/URLParser.cpp:2709
&gt; -    for (auto&amp; bytes : sequences) {
&gt; +    for (const auto&amp; bytes : input.split(&apos;&amp;&apos;)) {

This should just be &quot;auto&quot; or &quot;StringView&quot;. There is no reason to write &quot;const auto&amp;&quot;, which does the same thing as auto in this case, and I don’t think it’s particularly clear.

&gt; Tools/TestWebKitAPI/Tests/WTF/StringView.cpp:274
&gt; +    Vector&lt;String&gt; actual = vectorFromFields(a.split(&apos;T&apos;));
&gt; +    Vector&lt;String&gt; expected({ &quot;his is a sentence.&quot; });
&gt; +    ASSERT_EQ(expected.size(), actual.size());
&gt; +    for (size_t i = 0; i &lt; actual.size(); ++i)
&gt; +        EXPECT_STREQ(expected[i].ascii().data(), actual[i].ascii().data()) &lt;&lt; &quot;Vectors differ at index &quot; &lt;&lt; i;

Shouldn’t use ascii() unless debugging. Should use utf8() instead.

I don’t understand the use of ASSERT for the size check and EXPECT for the values of each element. I think we would want EXPECT for both.

Is there no better idiom for checking if two vectors of strings are the same in one of our unit tests? Code is so repetitive; we should probably use a helper function instead of repeating ourselves so many times. Maybe even have a function where you pass a StringView, a split character, and an initializer list, so each test case could be just one line; I find that style helps encourage me to write a lot of test cases since they don’t occupy much space. Unless it’s valuable to have the line number of the EXPECT failure give us a clue which test failed. I am not familiar enough with the behavior of the test macros to know whether it helps.

&gt; Tools/TestWebKitAPI/Tests/WTF/StringView.cpp:277
&gt; +    expected = Vector&lt;String&gt;({ &quot;This is a sentence&quot; });

I don’t think we need to state the type here, just the braces should work.

&gt; Tools/TestWebKitAPI/Tests/WTF/StringView.cpp:314
&gt; +    actual = vectorFromFields(a.split(&apos; &apos;, a.length() + 1));
&gt; +    EXPECT_EQ(0U, actual.size());

If we are keeping startOffset, we probably also want a test where it is the maximum unsigned value, to make sure we don’t have any overflow.

&gt; Tools/TestWebKitAPI/Tests/WTF/StringView.cpp:351
&gt; +    // Different separators
&gt; +    EXPECT_FALSE(a.split(&apos; &apos;, a.length()).begin() == a.split(&apos;,&apos;, a.length()).begin());
&gt; +    EXPECT_FALSE(a.split(&apos; &apos;, a.length()).end() == a.split(&apos;,&apos;, a.length()).end());
&gt; +
&gt; +    // Different StringView objects
&gt; +    EXPECT_FALSE(a.split(&apos; &apos;).begin() == b.split(&apos; &apos;).begin());
&gt; +    EXPECT_FALSE(a.split(&apos; &apos;, a.length()).begin() == b.split(&apos; &apos;, b.length()).begin());
&gt; +    EXPECT_FALSE(a.split(&apos; &apos;, a.length()).end() == b.split(&apos; &apos;, b.length()).end());

This does not seem like an important property of the iterators to test. If you take my suggestion above, these tests are all just going to trigger assertion failures.

Not sure what the best practice is for testing assertion failures. If there was a way I would want to test for the assertion in ++ too.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1267578</commentid>
    <comment_count>4</comment_count>
      <attachid>298528</attachid>
    <who name="Daniel Bates">dbates</who>
    <bug_when>2017-01-17 17:03:14 -0800</bug_when>
    <thetext>Comment on attachment 298528
Patch and unit tests

View in context: https://bugs.webkit.org/attachment.cgi?id=298528&amp;action=review

&gt;&gt; Source/WTF/wtf/text/StringView.cpp:117
&gt;&gt; +}
&gt; 
&gt; Might want to make an even more efficient implementation of this that uses a different constructor, although we might have to pull some trick since there’s no trivial way to have two constructors that both have no arguments (the enum trick perhaps). There is no reason to call StringView::find when initializing. Could call something that sticks the length into both m_beginPosition and m_endPosition.

Will add another constructor, Iterator(const SplitResult&amp;, PositionTag), so that we can differentiate between iterator instantiation in StringView::Fields::{begin, end}(). The Iterator(const SplitResult&amp;, PositionTag) constructor will be used to instantiate and initialize the &quot;at-end&quot; positioned iterator returned by StringView::Fields::end() and will not call StringView::find().

&gt;&gt; Source/WTF/wtf/text/StringView.cpp:125
&gt;&gt; +        m_beginPosition = length;
&gt; 
&gt; I would have used std::min for this, but I suggest removing this code entirely, since I don’t see the need to support startOffset.

Will remove support for a start offset and hence remove this code.

&gt;&gt; Source/WTF/wtf/text/StringView.cpp:129
&gt;&gt; +void StringView::Fields::Iterator::findNextField()
&gt; 
&gt; This function should be named findNextSubstring; I am not sure that the things we get when splitting are &quot;fields&quot;.

Will rename to findNextSubstring.

&gt;&gt; Source/WTF/wtf/text/StringView.cpp:131
&gt;&gt; +    const StringView&amp; stringView = m_fields.m_stringView;
&gt; 
&gt; Since the stringView is only used twice, I am not sure we should bother with the local variable. Or if you want to keep it, I would use auto:
&gt; 
&gt;     auto&amp; string = m_fields.m_string;

Will remove the local.

&gt;&gt; Source/WTF/wtf/text/StringView.cpp:137
&gt;&gt; +    m_endPosition = stringView.length();
&gt; 
&gt; If we change m_endPosition to be unsigned then we can’t have it directly get the result of find, but I think that might be better anyway, writing it more like this. However, in this version the for line is so long, so maybe that’s a reason to not do this version.
&gt; 
&gt;     for (size_t separatorPosition; (separatorPosition = m_fields.m_string.find(m_fields.separator, m_beginPosition)) != notFound, ++m_beginPosition) {
&gt;         if (separatorPosition &gt; m_beginPosition) {
&gt;             m_endPosition = separatorPosition;
&gt;             return;
&gt;         }
&gt;     }
&gt;     m_endPosition = m_fields.m_string.length();

Will change data type of m_{begin, end}Position from size_t to unsigned and will replace the implementation of this function with your suggested implementation.

&gt;&gt; Source/WTF/wtf/text/StringView.cpp:142
&gt;&gt; +    return m_fields.m_stringView.substring(m_beginPosition, m_endPosition - m_beginPosition);
&gt; 
&gt; This returns the empty string when at the end. But I think it would be even better to assert. We would just add this:
&gt; 
&gt;     ASSERT(m_beginPosition &lt; m_endPosition);
&gt;     ASSERT(m_endPosition &lt; m_fields.m_string.length());
&gt; 
&gt; Seems like we should consider inlining this function since boils down to a single function call.

Will assert that the iterator is not at or past the end of the string.

&gt;&gt; Source/WTF/wtf/text/StringView.cpp:152
&gt;&gt; +    return *this;
&gt; 
&gt; I suggest this alternate implementation:
&gt; 
&gt;     ASSERT(m_beginPosition &lt; m_endPosition);
&gt;     if (m_endPosition == m_fields.m_stringView.length()) {
&gt;         m_beginPosition = m_endPosition;
&gt;         return *this;
&gt;     }
&gt;     m_beginPosition = m_endPosition + 1;
&gt;     findNextField();
&gt;     return *this;
&gt; 
&gt; The assertion is the one we would hit if we erroneously call ++ after reaching the end. Could also add this internal consistency check assertion:
&gt; 
&gt;     ASSERT(m_endPosition &lt;= m_fields.m_string.length());

Will use suggested implementation and add internal consistency check assertion after the first assertion in your suggested implementation.

&gt;&gt; Source/WTF/wtf/text/StringView.cpp:159
&gt;&gt; +        &amp;&amp; m_fields.m_separator == other.m_fields.m_separator;
&gt; 
&gt; If I was writing this, I would assert that the iterators are from the same call to split, rather than returning false in such cases. There is no valid reason to compare iterators from two different calls to split.
&gt; 
&gt; There is some confused code here. The last two comparisons do the same thing as this:
&gt; 
&gt;     &amp;m_fields == &amp;other.m_fields
&gt; 
&gt; Since m_stringView is a StringView, and not a const StringView&amp;, and should be, its address is just an internal pointer inside the Fields structure. So it will only be equal if we have two references to the same Fields structure. And also, each substring is uniquely identified by the begin position and the end position. So we don’t need to compare both. This implementation would work well, the assertion would catch you if you used == on iterators from two different calls to split.
&gt; 
&gt;     ASSERT(&amp;m_fields == &amp;other.m_fields);
&gt;     return m_beginPosition == other.m_beginPosition;
&gt; 
&gt; Once we write it this way, it becomes clear that is a great candidate for inlining since the non-assert part of the function is a single super-simple expression.
&gt; 
&gt; Here are five other internal consistency check assertions we could include if we like:
&gt; 
&gt;     ASSERT((m_beginPosition == other.m_beginPosition) == (m_endPosition == other.m_endPosition));
&gt;     ASSERT(m_beginPosition &lt;= m_endPosition);
&gt;     ASSERT(m_endPosition &lt;= m_fields.m_string.length());
&gt;     ASSERT(other.m_beginPosition &lt;= other.m_endPosition);
&gt;     ASSERT(other.m_endPosition &lt;= other.m_fields.m_string.length());

Will assert that the iterators are from the same call to split, add internal consistency checks, and make this an inline function.

&gt;&gt; Source/WTF/wtf/text/StringView.h:121
&gt;&gt; +    class Fields;
&gt; 
&gt; I don’t think Fields is a great name for this class. I would call this SplitResult or SplitSubstrings.
&gt; 
&gt; Later we might need different names for variations because we might need different flavors of split. Split based on a character, a string, and maybe even a regular expression. Split returning the appropriate number of empty substrings, alongside this kind of split that skips all empty substrings.

Will rename class to SplitResult.

&gt;&gt; Source/WTF/wtf/text/StringView.h:122
&gt;&gt; +    WTF_EXPORT_STRING_API Fields split(UChar, unsigned startOffset = 0) const;
&gt; 
&gt; It’s easy to use substring on a StringView to start at an arbitrary location, and it is efficient and does not memory allocation, so the startOffset seems like an unneeded feature and I suggest omitting it. These were needed in the String class because substrings there are expensive and to be avoided. If one was going to call string.split(&apos;/&apos;, 1) one could call string.subview(1).split(&apos;/&apos;) instead.

Will remove support for specifying a start offset.

&gt;&gt; Source/WTF/wtf/text/StringView.h:620
&gt;&gt; +    explicit Fields(const StringView&amp;, UChar separator, unsigned startOffset);
&gt; 
&gt; The type of the argument here should be StringView, not const StringView&amp;, because StringView is efficient to pass by value so there is no reason to use a reference here.

Will change data type of first parameter from &quot;const StringView&amp;&quot; to StringView.

&gt;&gt; Source/WTF/wtf/text/StringView.h:627
&gt;&gt; +    StringView m_stringView;
&gt; 
&gt; In the context of this class, which is a member of StringView, I think we can just name this m_string since there is no ambiguity about the fact that this is a string view. But roughly speaking, a string.

Will rename to m_string.

&gt;&gt; Source/WTF/wtf/text/StringView.h:673
&gt;&gt; +    Iterator&amp; operator++(int) = delete;
&gt; 
&gt; I believe this is unneeded. If you define operator++() and don’t define operator++(int), it automatically will give an error if you try to post-increment. An explicit delete is not necessary.

Will remove this statement.

I chose to explicitly delete this function to convey to a reader in both code and in a compile-time failure that the post-increment operator was explicitly not implemented (*) as opposed to imply that it was inadvertently not implemented. I take it that such a distinction is not meaningful and trying to invoke deliberate consideration on the usefulness of having a post-increment operator should someone invoke it is not meaningful.

(*) In the hopes that this would make a person consider the benefit of implementing it and whether they really need it.

&gt;&gt; Source/WTF/wtf/text/StringView.h:683
&gt;&gt; +    friend Fields;
&gt; 
&gt; Why does this work? I’ve always seen this written as friend class Fields before. Is this preferred syntax?

This makes use of the C++11 simple type specifier syntax of the friend specifier. See (4) of &lt;http://en.cppreference.com/w/cpp/language/friend&gt; for more details. I do not see a reason to be against such syntax. Let me know if you are against it.

&gt;&gt; Source/WTF/wtf/text/StringView.h:685
&gt;&gt; +    const Fields&amp; m_fields;
&gt; 
&gt; I would probably rename this m_result after changing the type name from Fields to SplitResult or m_substrings if we use the name SplitSubstrings.
&gt; 
&gt; (Hard extra credit project: Would be nice if we could figure out a way to make the iterator assert at runtime if we accidentally used this after the Fields object was destroyed. I wouldn’t want to greatly complicate these classes just to check that, but it would be a bad bug if we kept an iterator around after m_fields was gone.)

Will rename m_fields to m_result as I chose to rename the class from Fields to SplitResult.

&gt;&gt; Source/WTF/wtf/text/StringView.h:687
&gt;&gt; +    size_t m_endPosition;
&gt; 
&gt; These should be unsigned, not size_t. Positions within strings are unsigned, except that annoyingly the result of find is a size_t.
&gt; 
&gt; I think &quot;begin position&quot; is a strange name for a data member, because &quot;begin&quot; is a verb, not a noun. The noun is &quot;beginning&quot;. I know that the C++ standard library uses begin in this peculiar way, but I don’t think we need to follow suit. Maybe startPosition instead. Or even m_substringStart/m_substringEnd or m_substringPosition/m_substringEndPosition or m_position/m_endPosition.
&gt; 
&gt; I also think it would be easy to write this in terms of a length instead of an end position. The three places that currently set the end position (there are only three) would just subtract the start position to compute a length, and then the code in ++ would just say: m_position += m_length + 1.
&gt; 
&gt; I think that m_position/m_length may in fact be my favorite way to write this, but it would change almost all the assertions I suggested above.

Will use m_position/m_length (both unsigned datatypes) and update implementation and suggested assertions.

&gt;&gt; Source/WebCore/platform/URLParser.cpp:2709
&gt;&gt; +    for (const auto&amp; bytes : input.split(&apos;&amp;&apos;)) {
&gt; 
&gt; This should just be &quot;auto&quot; or &quot;StringView&quot;. There is no reason to write &quot;const auto&amp;&quot;, which does the same thing as auto in this case, and I don’t think it’s particularly clear.

Will change &quot;const auto&amp;&quot; to StringView.

&gt;&gt; Tools/TestWebKitAPI/Tests/WTF/StringView.cpp:274
&gt;&gt; +        EXPECT_STREQ(expected[i].ascii().data(), actual[i].ascii().data()) &lt;&lt; &quot;Vectors differ at index &quot; &lt;&lt; i;
&gt; 
&gt; Shouldn’t use ascii() unless debugging. Should use utf8() instead.
&gt; 
&gt; I don’t understand the use of ASSERT for the size check and EXPECT for the values of each element. I think we would want EXPECT for both.
&gt; 
&gt; Is there no better idiom for checking if two vectors of strings are the same in one of our unit tests? Code is so repetitive; we should probably use a helper function instead of repeating ourselves so many times. Maybe even have a function where you pass a StringView, a split character, and an initializer list, so each test case could be just one line; I find that style helps encourage me to write a lot of test cases since they don’t occupy much space. Unless it’s valuable to have the line number of the EXPECT failure give us a clue which test failed. I am not familiar enough with the behavior of the test macros to know whether it helps.

Will substitute utf8() for ascii() here and throughout this function.

Notice that the EXPECT*() macro functions continue test execution on failure and that if expected.size() != actual.size() then the test driver&apos;s helper process will crash due to an out-of-bounds read. I thought it would be clearer to a person to abort the test before we attempt to perform an out-of-bounds read that crashes the test driver&apos;s helper process. Therefore I chose to use the ASSERT*() macro function to abort the current test.

I am also unhappy to duplicate the logic to compare two vectors. I did not see an existing idiom and defining a &quot;check vector&quot; function would affect the line numbers of a failed ASSERT/EXPECT (as they would be relative to the &quot;check vector&quot; function as opposed to the code that called it) and would require emitting some other information to know about the caller of this function. Knowing that you can always rely on the line number of a failed ASSERT/EXPECT can save time (maybe we already violate this assumption in other tests?) compared to determining that the line number is meaningless and needing to read the test failure output again and grep the code for the caller of the &quot;check vector&quot; routine or set breakpoints to determine the caller of the &quot;check vector&quot; function. Let me know if we favor a &quot;check vector&quot; function over meaningful line numbers.

&gt;&gt; Tools/TestWebKitAPI/Tests/WTF/StringView.cpp:277
&gt;&gt; +    expected = Vector&lt;String&gt;({ &quot;This is a sentence&quot; });
&gt; 
&gt; I don’t think we need to state the type here, just the braces should work.

Will remove.

&gt;&gt; Tools/TestWebKitAPI/Tests/WTF/StringView.cpp:314
&gt;&gt; +    EXPECT_EQ(0U, actual.size());
&gt; 
&gt; If we are keeping startOffset, we probably also want a test where it is the maximum unsigned value, to make sure we don’t have any overflow.

Will remove the offset tests as I will remove support for splitting from a start offset.

&gt;&gt; Tools/TestWebKitAPI/Tests/WTF/StringView.cpp:351
&gt;&gt; +    EXPECT_FALSE(a.split(&apos; &apos;, a.length()).end() == b.split(&apos; &apos;, b.length()).end());
&gt; 
&gt; This does not seem like an important property of the iterators to test. If you take my suggestion above, these tests are all just going to trigger assertion failures.
&gt; 
&gt; Not sure what the best practice is for testing assertion failures. If there was a way I would want to test for the assertion in ++ too.

For now, I hope you do not mind that I remove these tests.

Additional remarks:

We may be able to test for an assertion failure using a Death Test, &lt;https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#death-tests&gt;. Obviously this has the disadvantages of slowing down tests runs (the test driver will need to spawn a new subprocess for each death test and we need to wait to generate the crash report) and filling the disk with crash reports. We may be able to come up with a clever way to avoid generating a crash report. Let me know if you would like me to investigate this further.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1267653</commentid>
    <comment_count>5</comment_count>
      <attachid>299113</attachid>
    <who name="Daniel Bates">dbates</who>
    <bug_when>2017-01-17 19:48:25 -0800</bug_when>
    <thetext>Created attachment 299113
Patch and unit tests

Updated patch based on Darin Adler&apos;s feedback.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1267654</commentid>
    <comment_count>6</comment_count>
      <attachid>299113</attachid>
    <who name="Daniel Bates">dbates</who>
    <bug_when>2017-01-17 19:50:00 -0800</bug_when>
    <thetext>Comment on attachment 299113
Patch and unit tests

View in context: https://bugs.webkit.org/attachment.cgi?id=299113&amp;action=review

&gt; Source/WTF/ChangeLog:15
&gt; +        StringView.split() now returns a StringView::Fields object that implements begin()/end()

Will substitute SplitResult for Fields before landing.

&gt; Source/WTF/ChangeLog:17
&gt; +        character. For example, to iterate over the &apos;c&apos;-separated fields of a StringView v, you

Will substitute substring for field before landing.

&gt; Source/WTF/ChangeLog:20
&gt; +        for (StringView field : v.split(&apos;c&apos;))

Ditto.

&gt; Source/WTF/ChangeLog:21
&gt; +            // Do something with field.

Ditto.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1267655</commentid>
    <comment_count>7</comment_count>
    <who name="WebKit Commit Bot">commit-queue</who>
    <bug_when>2017-01-17 19:51:19 -0800</bug_when>
    <thetext>Attachment 299113 did not pass style-queue:


ERROR: Source/WTF/wtf/text/StringView.h:887:  Code inside a namespace should not be indented.  [whitespace/indent] [4]
Total errors found: 1 in 7 files


If any of these errors are false positives, please file a bug against check-webkit-style.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1267656</commentid>
    <comment_count>8</comment_count>
    <who name="Daniel Bates">dbates</who>
    <bug_when>2017-01-17 19:53:36 -0800</bug_when>
    <thetext>(In reply to comment #3)
&gt; (Hard extra credit project: Would be nice if we could figure out a way to
&gt; make the iterator assert at runtime if we accidentally used this after the
&gt; Fields object was destroyed. I wouldn’t want to greatly complicate these
&gt; classes just to check that, but it would be a bad bug if we kept an iterator
&gt; around after m_fields was gone.)
&gt; 

I did not mean to ignore this remark. I have not thought about this problem yet. I will shortly.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1267677</commentid>
    <comment_count>9</comment_count>
      <attachid>299113</attachid>
    <who name="Darin Adler">darin</who>
    <bug_when>2017-01-17 21:49:11 -0800</bug_when>
    <thetext>Comment on attachment 299113
Patch and unit tests

View in context: https://bugs.webkit.org/attachment.cgi?id=299113&amp;action=review

Looks excellent as is. A few thoughts for a tiny bit of refinement.

&gt; Source/WTF/wtf/text/StringView.cpp:111
&gt; +    ASSERT(m_length &lt;= m_result.m_string.length());
&gt; +    ASSERT(m_position &lt;= m_result.m_string.length() - m_length);

These are essentially the same assertions as in operator*, but for some reason you left out the ASSERT(m_length) here. But I suggest we not initialize length and write this instead:

    ASSERT(m_position &lt; m_result.m_string.length());

The above is the assertion that is important. That catches callers that use the iterator when we are past the end of the strings. The following m_length assertions are OK but I think not really all that valuable, so maybe just omit them:

    ASSERT(m_length);
    ASSERT(m_length &lt;= m_result.m_string.length() - m_position);

&gt; Source/WTF/wtf/text/StringView.cpp:119
&gt; +    if (m_position == m_result.m_string.length() - m_length) {
&gt; +        m_position = m_result.m_string.length();
&gt; +        m_length = 0;
&gt; +        return *this;
&gt; +    }
&gt; +    m_position += m_length + 1;
&gt; +    findNextSubstring();
&gt; +    return *this;

I think this can be written a bit more tightly:

    m_position += m_length;
    if (m_position &lt; m_result.m_string.length()) {
        ++m_position;
        findNextSubstring();
    }
    return *this;

&gt; Source/WTF/wtf/text/StringView.h:687
&gt; +    unsigned m_length { 0 };

We should consider not initializing m_length for slightly better efficiency; why not save one store of a zero in both constructors? The assertions I suggested above in the order listed make it clearer that we don’t have to set m_length except as a result of calling findNextSubstring. When we are at the end of the string we don’t care what m_length is set to, since calling the * or ++ operators in that case is an error.

&gt; Source/WTF/wtf/text/StringView.h:917
&gt; +    ASSERT(m_length);
&gt; +    ASSERT(m_length &lt;= m_result.m_string.length());
&gt; +    ASSERT(m_position &lt;= m_result.m_string.length() - m_length);

See above for my suggestion of what to replace these assertions with that does not depend on m_length being set.

&gt; Source/WTF/wtf/text/StringView.h:927
&gt; +    ASSERT(m_length &lt;= m_result.m_string.length());
&gt; +    ASSERT(m_position &lt;= m_result.m_string.length() - m_length);
&gt; +    ASSERT(other.m_length &lt;= other.m_result.m_string.length());
&gt; +    ASSERT(other.m_position &lt;= other.m_result.m_string.length() - other.m_length);

If we don’t set m_length at the end of the string, we have to live without these assertions or write longer versions. But I think we can live without them. No real need to assert all these things. Could assert position &lt;= length on both *this and other, but even that seems unneeded to me; the important assertion is that both iterators are over the same string, since that can detect programming mistakes. These are internal consistency checks that check invariants that won’t ever be wrong. So I think we can just leave the one assertion above and remove all four of these.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1269257</commentid>
    <comment_count>10</comment_count>
    <who name="Daniel Bates">dbates</who>
    <bug_when>2017-01-23 16:18:03 -0800</bug_when>
    <thetext>(In reply to comment #9)
&gt; [...]
&gt; &gt; Source/WTF/wtf/text/StringView.cpp:111
&gt; &gt; +    ASSERT(m_length &lt;= m_result.m_string.length());
&gt; &gt; +    ASSERT(m_position &lt;= m_result.m_string.length() - m_length);
&gt; 
&gt; These are essentially the same assertions as in operator*, but for some
&gt; reason you left out the ASSERT(m_length) here. But I suggest we not
&gt; initialize length and write this instead:
&gt; 
&gt;     ASSERT(m_position &lt; m_result.m_string.length());
&gt; 

Will not initialize m_length and add this assert.

&gt; The above is the assertion that is important. That catches callers that use
&gt; the iterator when we are past the end of the strings. The following m_length
&gt; assertions are OK but I think not really all that valuable, so maybe just
&gt; omit them:
&gt; 
&gt;     ASSERT(m_length);
&gt;     ASSERT(m_length &lt;= m_result.m_string.length() - m_position);
&gt;

Will omit these assertions.

&gt; &gt; Source/WTF/wtf/text/StringView.cpp:119
&gt; &gt; +    if (m_position == m_result.m_string.length() - m_length) {
&gt; &gt; +        m_position = m_result.m_string.length();
&gt; &gt; +        m_length = 0;
&gt; &gt; +        return *this;
&gt; &gt; +    }
&gt; &gt; +    m_position += m_length + 1;
&gt; &gt; +    findNextSubstring();
&gt; &gt; +    return *this;
&gt; 
&gt; I think this can be written a bit more tightly:
&gt; 
&gt;     m_position += m_length;
&gt;     if (m_position &lt; m_result.m_string.length()) {
&gt;         ++m_position;
&gt;         findNextSubstring();
&gt;     }
&gt;     return *this;
&gt; 

Will update code to match your proposed implementation.

&gt; &gt; Source/WTF/wtf/text/StringView.h:687
&gt; &gt; +    unsigned m_length { 0 };
&gt; 

Will remove initialization of m_length.

&gt; We should consider not initializing m_length for slightly better efficiency;
&gt; why not save one store of a zero in both constructors? The assertions I
&gt; suggested above in the order listed make it clearer that we don’t have to
&gt; set m_length except as a result of calling findNextSubstring. When we are at
&gt; the end of the string we don’t care what m_length is set to, since calling
&gt; the * or ++ operators in that case is an error.
&gt; 
&gt; &gt; Source/WTF/wtf/text/StringView.h:917
&gt; &gt; +    ASSERT(m_length);
&gt; &gt; +    ASSERT(m_length &lt;= m_result.m_string.length());
&gt; &gt; +    ASSERT(m_position &lt;= m_result.m_string.length() - m_length);
&gt; 
&gt; See above for my suggestion of what to replace these assertions with that
&gt; does not depend on m_length being set.
&gt; 

Will replace these assertions with:

ASSERT(m_position &lt; m_result.m_string.length());

&gt; &gt; Source/WTF/wtf/text/StringView.h:927
&gt; &gt; +    ASSERT(m_length &lt;= m_result.m_string.length());
&gt; &gt; +    ASSERT(m_position &lt;= m_result.m_string.length() - m_length);
&gt; &gt; +    ASSERT(other.m_length &lt;= other.m_result.m_string.length());
&gt; &gt; +    ASSERT(other.m_position &lt;= other.m_result.m_string.length() - other.m_length);
&gt; 
&gt; If we don’t set m_length at the end of the string, we have to live without
&gt; these assertions or write longer versions. But I think we can live without
&gt; them. No real need to assert all these things. Could assert position &lt;=
&gt; length on both *this and other, but even that seems unneeded to me; the
&gt; important assertion is that both iterators are over the same string, since
&gt; that can detect programming mistakes. These are internal consistency checks
&gt; that check invariants that won’t ever be wrong. So I think we can just leave
&gt; the one assertion above and remove all four of these.

Will remove these assertions such that StringView::SplitResult::Iterator::operator==() has exactly one assertion:

ASSERT(&amp;m_result == &amp;other.m_result);</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1269443</commentid>
    <comment_count>11</comment_count>
    <who name="Daniel Bates">dbates</who>
    <bug_when>2017-01-24 09:46:24 -0800</bug_when>
    <thetext>Committed r211087: &lt;http://trac.webkit.org/changeset/211087&gt;</thetext>
  </long_desc>
      
          <attachment
              isobsolete="1"
              ispatch="1"
              isprivate="0"
          >
            <attachid>298528</attachid>
            <date>2017-01-10 17:20:00 -0800</date>
            <delta_ts>2017-01-17 19:48:20 -0800</delta_ts>
            <desc>Patch and unit tests</desc>
            <filename>bug-163225-20170110171823.patch</filename>
            <type>text/plain</type>
            <size>16786</size>
            <attacher name="Daniel Bates">dbates</attacher>
            
              <data encoding="base64">U3VidmVyc2lvbiBSZXZpc2lvbjogMjEwNTQ2CmRpZmYgLS1naXQgYS9Tb3VyY2UvV1RGL0NoYW5n
ZUxvZyBiL1NvdXJjZS9XVEYvQ2hhbmdlTG9nCmluZGV4IDAyNjU2Y2RlOGNjNDZmMTBjMDM4MmQz
MTEyNWFiNTU2Nzc5MDFkY2YuLmI1NDNmMjVjZjk2ODllZjMyZjhjNTg0MDk2NzE2Y2JlYjQ2NDcx
ZGUgMTAwNjQ0Ci0tLSBhL1NvdXJjZS9XVEYvQ2hhbmdlTG9nCisrKyBiL1NvdXJjZS9XVEYvQ2hh
bmdlTG9nCkBAIC0xLDMgKzEsMzYgQEAKKzIwMTctMDEtMTAgIERhbmllbCBCYXRlcyAgPGRhYmF0
ZXNAYXBwbGUuY29tPgorCisgICAgICAgIFN0cmluZ1ZpZXcuc3BsaXQoKSBzaG91bGQgdXNlIGFu
IGl0ZXJhdG9yIGRlc2lnbiBwYXR0ZXJuIGluc3RlYWQgb2YgYWxsb2NhdGluZyBhIFZlY3Rvcgor
ICAgICAgICBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTYzMjI1CisK
KyAgICAgICAgUmV2aWV3ZWQgYnkgTk9CT0RZIChPT1BTISkuCisKKyAgICAgICAgSW1wbGVtZW50
IFN0cmluZ1ZpZXcuc3BsaXQoKSB1c2luZyBhbiBpdGVyYXRvciBkZXNpZ24uCisKKyAgICAgICAg
VXNpbmcgYW4gaXRlcmF0b3IgZGVzaWduIGF2b2lkcyB0aGUgbmVlZCB0byBhbGxvY2F0ZSBhIFZl
Y3RvciBvZiBTdHJpbmdWaWV3IG9iamVjdHMsCisgICAgICAgIHdoaWNoIGlzIHNwYWNlLWluZWZm
aWNpZW50IGFuZCBlcnJvciBwcm9uZSBhcyB0aGUgcmV0dXJuZWQgVmVjdG9yIG1heSBvdXRsaXZl
IHRoZQorICAgICAgICBsaWZldGltZSBvZiB0aGUgdW5kZXJseWluZyBzdHJpbmcgYXNzb2NpYXRl
ZCB3aXRoIHRoZSBzcGxpdCAoYXMgU3RyaW5nVmlldyBpcyBhIG5vbi0KKyAgICAgICAgb3duaW5n
IHJlZmVyZW5jZSB0byBhIHN0cmluZykuCisKKyAgICAgICAgU3RyaW5nVmlldy5zcGxpdCgpIG5v
dyByZXR1cm5zIGEgU3RyaW5nVmlldzo6RmllbGRzIG9iamVjdCB0aGF0IGltcGxlbWVudHMgYmVn
aW4oKS9lbmQoKQorICAgICAgICB0byBzdXBwb3J0IGl0ZXJhdGluZyBvdmVyIFN0cmluZ1ZpZXcg
c3Vic3RyaW5ncyBkZWxpbWl0ZWQgYnkgdGhlIHNwZWNpZmllZCBzZXBhcmF0b3IKKyAgICAgICAg
Y2hhcmFjdGVyLiBGb3IgZXhhbXBsZSwgdG8gaXRlcmF0ZSBvdmVyIHRoZSAnYyctc2VwYXJhdGVk
IGZpZWxkcyBvZiBhIFN0cmluZ1ZpZXcgdiwgeW91CisgICAgICAgIGNhbiB3cml0ZToKKworICAg
ICAgICBmb3IgKFN0cmluZ1ZpZXcgZmllbGQgOiB2LnNwbGl0KCdjJykpCisgICAgICAgICAgICAv
LyBEbyBzb21ldGhpbmcgd2l0aCBmaWVsZC4KKworICAgICAgICAqIHd0Zi90ZXh0L1N0cmluZ1Zp
ZXcuY3BwOgorICAgICAgICAoV1RGOjpTdHJpbmdWaWV3OjpGaWVsZHM6OkZpZWxkcyk6IEFkZGVk
LgorICAgICAgICAoV1RGOjpTdHJpbmdWaWV3OjpGaWVsZHM6Okl0ZXJhdG9yOjpJdGVyYXRvcik6
IEFkZGVkLgorICAgICAgICAoV1RGOjpTdHJpbmdWaWV3OjpGaWVsZHM6Okl0ZXJhdG9yOjpmaW5k
TmV4dEZpZWxkKTogQ29tcHV0ZXMgdGhlIHJhbmdlIG9mIHRoZSBuZXh0IHN1YnN0cmluZy4KKyAg
ICAgICAgKFdURjo6U3RyaW5nVmlldzo6RmllbGRzOjpJdGVyYXRvcjo6b3BlcmF0b3IqKTogUmV0
dXJucyB0aGUgY3VycmVudCBmaWVsZC4KKyAgICAgICAgKFdURjo6U3RyaW5nVmlldzo6RmllbGRz
OjpJdGVyYXRvcjo6b3BlcmF0b3I9PSk6IEFkZGVkLgorICAgICAgICAoV1RGOjpTdHJpbmdWaWV3
OjpzcGxpdCk6IE1vZGlmaWVkIHRvIHRha2UgYW4gb3B0aW9uYWwgc3RhcnQgb2Zmc2V0IChkZWZh
dWx0cyB0byAwKQorICAgICAgICBhbmQgcmV0dXJucyBhIFN0cmluZ1ZpZXc6OkZpZWxkcyBvYmpl
Y3QgdGhhdCBzdXBwb3J0IGl0ZXJhdGlvbi4KKyAgICAgICAgKiB3dGYvdGV4dC9TdHJpbmdWaWV3
Lmg6CisgICAgICAgIChXVEY6OlN0cmluZ1ZpZXc6OkZpZWxkczo6SXRlcmF0b3I6Om9wZXJhdG9y
IT0pOiBBZGRlZC4KKwogMjAxNy0wMS0wNiAgR3VzdGF2byBOb3JvbmhhIFNpbHZhICA8Z3VzdGF2
by5ub3JvbmhhQGNvbGxhYm9yYS5jby51az4KIAogICAgICAgICBbR1RLXSBTaG91bGQgc3VwcG9y
dCBrZXkgYW5kIGNvZGUgcHJvcGVydGllcyBvbiBrZXlib2FyZCBldmVudHMKZGlmZiAtLWdpdCBh
L1NvdXJjZS9XZWJDb3JlL0NoYW5nZUxvZyBiL1NvdXJjZS9XZWJDb3JlL0NoYW5nZUxvZwppbmRl
eCBhYmUyMjRlOWJlZWNmOWNkODdhNDhlZWM4NGY1ODE2MjViYjA2ZjBkLi4zMmJhOGZkNTlmYzE1
YmMyOTEyNzk4ZDE3MTVhZDRiOTIwN2FhNDM0IDEwMDY0NAotLS0gYS9Tb3VyY2UvV2ViQ29yZS9D
aGFuZ2VMb2cKKysrIGIvU291cmNlL1dlYkNvcmUvQ2hhbmdlTG9nCkBAIC0xLDMgKzEsMTQgQEAK
KzIwMTctMDEtMTAgIERhbmllbCBCYXRlcyAgPGRhYmF0ZXNAYXBwbGUuY29tPgorCisgICAgICAg
IFN0cmluZ1ZpZXcuc3BsaXQoKSBzaG91bGQgdXNlIGFuIGl0ZXJhdG9yIGRlc2lnbiBwYXR0ZXJu
IGluc3RlYWQgb2YgYWxsb2NhdGluZyBhIFZlY3RvcgorICAgICAgICBodHRwczovL2J1Z3Mud2Vi
a2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTYzMjI1CisKKyAgICAgICAgUmV2aWV3ZWQgYnkgTk9C
T0RZIChPT1BTISkuCisKKyAgICAgICAgVXBkYXRlIGNvZGUgdG8gdXNlIHRoZSBuZXcgaXRlcmF0
b3Itc3R5bGUgU3RyaW5nVmlldy5zcGxpdCgpLgorCisgICAgICAgICogcGxhdGZvcm0vVVJMUGFy
c2VyLmNwcDoKKwogMjAxNy0wMS0xMCAgWW91ZW5uIEZhYmxldCAgPHlvdWVubkBhcHBsZS5jb20+
CiAKICAgICAgICAgQ2FjaGVkU2NyaXB0IGNsb25pbmcgZG9lcyBub3QgY2xvbmUgZW5jb2RlZFNp
emUKZGlmZiAtLWdpdCBhL1NvdXJjZS9XVEYvd3RmL3RleHQvU3RyaW5nVmlldy5jcHAgYi9Tb3Vy
Y2UvV1RGL3d0Zi90ZXh0L1N0cmluZ1ZpZXcuY3BwCmluZGV4IGQ3ODU2MmUyYmM1NzBlODhjZDk2
NGU2MDI5NzVlYTk2OGQyOGZlZWQuLjcwNTk0ZDFjZDZmN2ZjODQwNDcwOTQ4YTEwMjM0ODQ1MmU5
MjM5MmYgMTAwNjQ0Ci0tLSBhL1NvdXJjZS9XVEYvd3RmL3RleHQvU3RyaW5nVmlldy5jcHAKKysr
IGIvU291cmNlL1dURi93dGYvdGV4dC9TdHJpbmdWaWV3LmNwcApAQCAtOTQsNiArOTQsNzEgQEAg
c2l6ZV90IFN0cmluZ1ZpZXc6OmZpbmQoU3RyaW5nVmlldyBtYXRjaFN0cmluZywgdW5zaWduZWQg
c3RhcnQpIGNvbnN0CiAgICAgcmV0dXJuIGZpbmRDb21tb24oKnRoaXMsIG1hdGNoU3RyaW5nLCBz
dGFydCk7CiB9CiAKK2F1dG8gU3RyaW5nVmlldzo6c3BsaXQoVUNoYXIgc2VwYXJhdG9yLCB1bnNp
Z25lZCBzdGFydE9mZnNldCkgY29uc3QgLT4gRmllbGRzCit7CisgICAgcmV0dXJuIEZpZWxkcyB7
ICp0aGlzLCBzZXBhcmF0b3IsIHN0YXJ0T2Zmc2V0IH07Cit9CisKK1N0cmluZ1ZpZXc6OkZpZWxk
czo6RmllbGRzKGNvbnN0IFN0cmluZ1ZpZXcmIHN0cmluZ1ZpZXcsIFVDaGFyIHNlcGFyYXRvciwg
dW5zaWduZWQgc3RhcnRPZmZzZXQpCisgICAgOiBtX3N0cmluZ1ZpZXcgeyBzdHJpbmdWaWV3IH0K
KyAgICAsIG1fc2VwYXJhdG9yIHsgc2VwYXJhdG9yIH0KKyAgICAsIG1fc3RhcnRPZmZzZXQgeyBz
dGFydE9mZnNldCB9Cit7Cit9CisKK2F1dG8gU3RyaW5nVmlldzo6RmllbGRzOjpiZWdpbigpIGNv
bnN0IC0+IEl0ZXJhdG9yCit7CisgICAgcmV0dXJuIEl0ZXJhdG9yIHsgKnRoaXMsIG1fc3RhcnRP
ZmZzZXQgfTsKK30KKworYXV0byBTdHJpbmdWaWV3OjpGaWVsZHM6OmVuZCgpIGNvbnN0IC0+IEl0
ZXJhdG9yCit7CisgICAgcmV0dXJuIEl0ZXJhdG9yIHsgKnRoaXMsIG1fc3RyaW5nVmlldy5sZW5n
dGgoKSB9OworfQorCitTdHJpbmdWaWV3OjpGaWVsZHM6Okl0ZXJhdG9yOjpJdGVyYXRvcihjb25z
dCBGaWVsZHMmIGZpZWxkcywgdW5zaWduZWQgc3RhcnRPZmZzZXQpCisgICAgOiBtX2ZpZWxkcyB7
IGZpZWxkcyB9CisgICAgLCBtX2JlZ2luUG9zaXRpb24geyBzdGFydE9mZnNldCB9Cit7CisgICAg
dW5zaWduZWQgbGVuZ3RoID0gZmllbGRzLm1fc3RyaW5nVmlldy5sZW5ndGgoKTsKKyAgICBpZiAo
bV9iZWdpblBvc2l0aW9uID4gbGVuZ3RoKQorICAgICAgICBtX2JlZ2luUG9zaXRpb24gPSBsZW5n
dGg7CisgICAgZmluZE5leHRGaWVsZCgpOworfQorCit2b2lkIFN0cmluZ1ZpZXc6OkZpZWxkczo6
SXRlcmF0b3I6OmZpbmROZXh0RmllbGQoKQoreworICAgIGNvbnN0IFN0cmluZ1ZpZXcmIHN0cmlu
Z1ZpZXcgPSBtX2ZpZWxkcy5tX3N0cmluZ1ZpZXc7CisgICAgd2hpbGUgKChtX2VuZFBvc2l0aW9u
ID0gc3RyaW5nVmlldy5maW5kKG1fZmllbGRzLm1fc2VwYXJhdG9yLCBtX2JlZ2luUG9zaXRpb24p
KSAhPSBub3RGb3VuZCkgeworICAgICAgICBpZiAobV9lbmRQb3NpdGlvbiAhPSBtX2JlZ2luUG9z
aXRpb24pCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIG1fYmVnaW5Qb3NpdGlvbiA9IG1f
ZW5kUG9zaXRpb24gKyAxOworICAgIH0KKyAgICBtX2VuZFBvc2l0aW9uID0gc3RyaW5nVmlldy5s
ZW5ndGgoKTsKK30KKworU3RyaW5nVmlldyBTdHJpbmdWaWV3OjpGaWVsZHM6Okl0ZXJhdG9yOjpv
cGVyYXRvciooKSBjb25zdAoreworICAgIHJldHVybiBtX2ZpZWxkcy5tX3N0cmluZ1ZpZXcuc3Vi
c3RyaW5nKG1fYmVnaW5Qb3NpdGlvbiwgbV9lbmRQb3NpdGlvbiAtIG1fYmVnaW5Qb3NpdGlvbik7
Cit9CisKK2F1dG8gU3RyaW5nVmlldzo6RmllbGRzOjpJdGVyYXRvcjo6b3BlcmF0b3IrKygpIC0+
IEl0ZXJhdG9yJgoreworICAgIHVuc2lnbmVkIGxlbmd0aCA9IG1fZmllbGRzLm1fc3RyaW5nVmll
dy5sZW5ndGgoKTsKKyAgICBtX2JlZ2luUG9zaXRpb24gPSBtX2VuZFBvc2l0aW9uICsgMTsKKyAg
ICBpZiAobV9iZWdpblBvc2l0aW9uID4gbGVuZ3RoKQorICAgICAgICBtX2JlZ2luUG9zaXRpb24g
PSBsZW5ndGg7CisgICAgZmluZE5leHRGaWVsZCgpOworICAgIHJldHVybiAqdGhpczsKK30KKwor
Ym9vbCBTdHJpbmdWaWV3OjpGaWVsZHM6Okl0ZXJhdG9yOjpvcGVyYXRvcj09KGNvbnN0IEl0ZXJh
dG9yJiBvdGhlcikgY29uc3QKK3sKKyAgICByZXR1cm4gbV9iZWdpblBvc2l0aW9uID09IG90aGVy
Lm1fYmVnaW5Qb3NpdGlvbiAmJiBtX2VuZFBvc2l0aW9uID09IG90aGVyLm1fZW5kUG9zaXRpb24K
KyAgICAgICAgJiYgJm1fZmllbGRzLm1fc3RyaW5nVmlldyA9PSAmb3RoZXIubV9maWVsZHMubV9z
dHJpbmdWaWV3CisgICAgICAgICYmIG1fZmllbGRzLm1fc2VwYXJhdG9yID09IG90aGVyLm1fZmll
bGRzLm1fc2VwYXJhdG9yOworfQorCiBjbGFzcyBTdHJpbmdWaWV3OjpHcmFwaGVtZUNsdXN0ZXJz
OjpJdGVyYXRvcjo6SW1wbCB7CiBwdWJsaWM6CiAgICAgSW1wbChjb25zdCBTdHJpbmdWaWV3JiBz
dHJpbmdWaWV3LCBzdGQ6Om9wdGlvbmFsPE5vblNoYXJlZENoYXJhY3RlckJyZWFrSXRlcmF0b3I+
JiYgaXRlcmF0b3IsIHVuc2lnbmVkIGluZGV4KQpAQCAtMTQyLDIxICsyMDcsNiBAQCBwcml2YXRl
OgogICAgIHVuc2lnbmVkIG1faW5kZXhFbmQ7CiB9OwogCi1WZWN0b3I8U3RyaW5nVmlldz4gU3Ry
aW5nVmlldzo6c3BsaXQoVUNoYXIgc2VwYXJhdG9yKQotewotICAgIFZlY3RvcjxTdHJpbmdWaWV3
PiByZXN1bHQ7Ci0gICAgdW5zaWduZWQgc3RhcnRQb3MgPSAwOwotICAgIHNpemVfdCBlbmRQb3M7
Ci0gICAgd2hpbGUgKChlbmRQb3MgPSBmaW5kKHNlcGFyYXRvciwgc3RhcnRQb3MpKSAhPSBub3RG
b3VuZCkgewotICAgICAgICBpZiAoc3RhcnRQb3MgIT0gZW5kUG9zKQotICAgICAgICAgICAgcmVz
dWx0LmFwcGVuZChzdWJzdHJpbmcoc3RhcnRQb3MsIGVuZFBvcyAtIHN0YXJ0UG9zKSk7Ci0gICAg
ICAgIHN0YXJ0UG9zID0gZW5kUG9zICsgMTsKLSAgICB9Ci0gICAgaWYgKHN0YXJ0UG9zICE9IGxl
bmd0aCgpKQotICAgICAgICByZXN1bHQuYXBwZW5kKHN1YnN0cmluZyhzdGFydFBvcykpOwotICAg
IHJldHVybiByZXN1bHQ7Ci19Ci0KIFN0cmluZ1ZpZXc6OkdyYXBoZW1lQ2x1c3RlcnM6Okl0ZXJh
dG9yOjpJdGVyYXRvcihjb25zdCBTdHJpbmdWaWV3JiBzdHJpbmdWaWV3LCB1bnNpZ25lZCBpbmRl
eCkKICAgICA6IG1faW1wbChzdGQ6Om1ha2VfdW5pcXVlPEltcGw+KHN0cmluZ1ZpZXcsIHN0cmlu
Z1ZpZXcuaXNOdWxsKCkgPyBzdGQ6Om51bGxvcHQgOiBzdGQ6Om9wdGlvbmFsPE5vblNoYXJlZENo
YXJhY3RlckJyZWFrSXRlcmF0b3I+KE5vblNoYXJlZENoYXJhY3RlckJyZWFrSXRlcmF0b3Ioc3Ry
aW5nVmlldykpLCBpbmRleCkpCiB7CmRpZmYgLS1naXQgYS9Tb3VyY2UvV1RGL3d0Zi90ZXh0L1N0
cmluZ1ZpZXcuaCBiL1NvdXJjZS9XVEYvd3RmL3RleHQvU3RyaW5nVmlldy5oCmluZGV4IDJjYzI1
Y2QwMjExMjAxYzQyNjNmZWNlYjM0OWM3MmQyMTg2NmEwMzIuLjZkMWMzYjQxMjk4ZDYzYTQ0YzYy
N2FlMTE0ZjVhZmY3NTZhYWUwODcgMTAwNjQ0Ci0tLSBhL1NvdXJjZS9XVEYvd3RmL3RleHQvU3Ry
aW5nVmlldy5oCisrKyBiL1NvdXJjZS9XVEYvd3RmL3RleHQvU3RyaW5nVmlldy5oCkBAIC0xMTcs
NyArMTE3LDkgQEAgcHVibGljOgogICAgIFN0cmluZ1ZpZXcgc3Vic3RyaW5nKHVuc2lnbmVkIHN0
YXJ0LCB1bnNpZ25lZCBsZW5ndGggPSBzdGQ6Om51bWVyaWNfbGltaXRzPHVuc2lnbmVkPjo6bWF4
KCkpIGNvbnN0OwogICAgIFN0cmluZ1ZpZXcgbGVmdCh1bnNpZ25lZCBsZW4pIGNvbnN0IHsgcmV0
dXJuIHN1YnN0cmluZygwLCBsZW4pOyB9CiAgICAgU3RyaW5nVmlldyByaWdodCh1bnNpZ25lZCBs
ZW4pIGNvbnN0IHsgcmV0dXJuIHN1YnN0cmluZyhsZW5ndGgoKSAtIGxlbiwgbGVuKTsgfQotICAg
IFdURl9FWFBPUlRfU1RSSU5HX0FQSSBWZWN0b3I8U3RyaW5nVmlldz4gc3BsaXQoVUNoYXIpOwor
CisgICAgY2xhc3MgRmllbGRzOworICAgIFdURl9FWFBPUlRfU1RSSU5HX0FQSSBGaWVsZHMgc3Bs
aXQoVUNoYXIsIHVuc2lnbmVkIHN0YXJ0T2Zmc2V0ID0gMCkgY29uc3Q7CiAKICAgICBzaXplX3Qg
ZmluZChVQ2hhciwgdW5zaWduZWQgc3RhcnQgPSAwKSBjb25zdDsKICAgICBzaXplX3QgZmluZChD
aGFyYWN0ZXJNYXRjaEZ1bmN0aW9uLCB1bnNpZ25lZCBzdGFydCA9IDApIGNvbnN0OwpAQCAtNjEz
LDYgKzYxNSwyMCBAQCBpbmxpbmUgYm9vbCBlcXVhbElnbm9yaW5nQVNDSUlDYXNlKFN0cmluZ1Zp
ZXcgYSwgY29uc3QgY2hhciogYikKICAgICByZXR1cm4gZXF1YWxJZ25vcmluZ0FTQ0lJQ2FzZUNv
bW1vbihhLCBiKTsKIH0KIAorY2xhc3MgU3RyaW5nVmlldzo6RmllbGRzIHsKK3B1YmxpYzoKKyAg
ICBleHBsaWNpdCBGaWVsZHMoY29uc3QgU3RyaW5nVmlldyYsIFVDaGFyIHNlcGFyYXRvciwgdW5z
aWduZWQgc3RhcnRPZmZzZXQpOworCisgICAgY2xhc3MgSXRlcmF0b3I7CisgICAgV1RGX0VYUE9S
VF9QUklWQVRFIEl0ZXJhdG9yIGJlZ2luKCkgY29uc3Q7CisgICAgV1RGX0VYUE9SVF9QUklWQVRF
IEl0ZXJhdG9yIGVuZCgpIGNvbnN0OworCitwcml2YXRlOgorICAgIFN0cmluZ1ZpZXcgbV9zdHJp
bmdWaWV3OworICAgIFVDaGFyIG1fc2VwYXJhdG9yOworICAgIHVuc2lnbmVkIG1fc3RhcnRPZmZz
ZXQ7Cit9OworCiBjbGFzcyBTdHJpbmdWaWV3OjpHcmFwaGVtZUNsdXN0ZXJzIHsKIHB1YmxpYzoK
ICAgICBleHBsaWNpdCBHcmFwaGVtZUNsdXN0ZXJzKGNvbnN0IFN0cmluZ1ZpZXcmKTsKQEAgLTY0
OSw2ICs2NjUsMjggQEAgcHJpdmF0ZToKICAgICBTdHJpbmdWaWV3IG1fc3RyaW5nVmlldzsKIH07
CiAKK2NsYXNzIFN0cmluZ1ZpZXc6OkZpZWxkczo6SXRlcmF0b3IgeworcHVibGljOgorICAgIFdU
Rl9FWFBPUlRfUFJJVkFURSBTdHJpbmdWaWV3IG9wZXJhdG9yKigpIGNvbnN0OworCisgICAgV1RG
X0VYUE9SVF9QUklWQVRFIEl0ZXJhdG9yJiBvcGVyYXRvcisrKCk7CisgICAgSXRlcmF0b3ImIG9w
ZXJhdG9yKysoaW50KSA9IGRlbGV0ZTsKKworICAgIFdURl9FWFBPUlRfUFJJVkFURSBib29sIG9w
ZXJhdG9yPT0oY29uc3QgSXRlcmF0b3ImKSBjb25zdDsKKyAgICBib29sIG9wZXJhdG9yIT0oY29u
c3QgSXRlcmF0b3ImIG90aGVyKSBjb25zdCB7IHJldHVybiAhKCp0aGlzID09IG90aGVyKTsgfQor
Citwcml2YXRlOgorICAgIEl0ZXJhdG9yKGNvbnN0IEZpZWxkcyYsIHVuc2lnbmVkIHN0YXJ0T2Zm
c2V0KTsKKworICAgIHZvaWQgZmluZE5leHRGaWVsZCgpOworCisgICAgZnJpZW5kIEZpZWxkczsK
KworICAgIGNvbnN0IEZpZWxkcyYgbV9maWVsZHM7CisgICAgc2l6ZV90IG1fYmVnaW5Qb3NpdGlv
bjsKKyAgICBzaXplX3QgbV9lbmRQb3NpdGlvbjsKK307CisKIGNsYXNzIFN0cmluZ1ZpZXc6Okdy
YXBoZW1lQ2x1c3RlcnM6Okl0ZXJhdG9yIHsKIHB1YmxpYzoKICAgICBXVEZfRVhQT1JUX1BSSVZB
VEUgSXRlcmF0b3IoKSA9IGRlbGV0ZTsKZGlmZiAtLWdpdCBhL1NvdXJjZS9XZWJDb3JlL3BsYXRm
b3JtL1VSTFBhcnNlci5jcHAgYi9Tb3VyY2UvV2ViQ29yZS9wbGF0Zm9ybS9VUkxQYXJzZXIuY3Bw
CmluZGV4IDM2NTkzODgzZmU2OTQwMjIwNTY0MzIyNjU5YzE4NjJlOTFhOWQwNTEuLjdmMmVjNWE0
NTBhNzBhZGU0NjczMjQwODI1YzM3NmZhNmYzYjA2ZTggMTAwNjQ0Ci0tLSBhL1NvdXJjZS9XZWJD
b3JlL3BsYXRmb3JtL1VSTFBhcnNlci5jcHAKKysrIGIvU291cmNlL1dlYkNvcmUvcGxhdGZvcm0v
VVJMUGFyc2VyLmNwcApAQCAtMjcwNSwxMCArMjcwNSw4IEBAIHN0ZDo6b3B0aW9uYWw8U3RyaW5n
PiBVUkxQYXJzZXI6OmZvcm1VUkxEZWNvZGUoU3RyaW5nVmlldyBpbnB1dCkKIAogYXV0byBVUkxQ
YXJzZXI6OnBhcnNlVVJMRW5jb2RlZEZvcm0oU3RyaW5nVmlldyBpbnB1dCkgLT4gVVJMRW5jb2Rl
ZEZvcm0KIHsKLSAgICBWZWN0b3I8U3RyaW5nVmlldz4gc2VxdWVuY2VzID0gaW5wdXQuc3BsaXQo
JyYnKTsKLQogICAgIFVSTEVuY29kZWRGb3JtIG91dHB1dDsKLSAgICBmb3IgKGF1dG8mIGJ5dGVz
IDogc2VxdWVuY2VzKSB7CisgICAgZm9yIChjb25zdCBhdXRvJiBieXRlcyA6IGlucHV0LnNwbGl0
KCcmJykpIHsKICAgICAgICAgYXV0byB2YWx1ZVN0YXJ0ID0gYnl0ZXMuZmluZCgnPScpOwogICAg
ICAgICBpZiAodmFsdWVTdGFydCA9PSBub3RGb3VuZCkgewogICAgICAgICAgICAgaWYgKGF1dG8g
bmFtZSA9IGZvcm1VUkxEZWNvZGUoYnl0ZXMpKQpkaWZmIC0tZ2l0IGEvVG9vbHMvQ2hhbmdlTG9n
IGIvVG9vbHMvQ2hhbmdlTG9nCmluZGV4IDFiYzIwYTExNjJjZTc4ZjAwOTk3ZGE3MTAyMTE4YmMw
YzM2OGFhY2IuLjNkYTRlZjg4OGM4NDgwYTRlZjU4ZjMwNTdjMWJlMWM5Yjg0NTI5ZGIgMTAwNjQ0
Ci0tLSBhL1Rvb2xzL0NoYW5nZUxvZworKysgYi9Ub29scy9DaGFuZ2VMb2cKQEAgLTEsMyArMSwy
NCBAQAorMjAxNy0wMS0xMCAgRGFuaWVsIEJhdGVzICA8ZGFiYXRlc0BhcHBsZS5jb20+CisKKyAg
ICAgICAgU3RyaW5nVmlldy5zcGxpdCgpIHNob3VsZCB1c2UgYW4gaXRlcmF0b3IgZGVzaWduIHBh
dHRlcm4gaW5zdGVhZCBvZiBhbGxvY2F0aW5nIGEgVmVjdG9yCisgICAgICAgIGh0dHBzOi8vYnVn
cy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xNjMyMjUKKworICAgICAgICBSZXZpZXdlZCBi
eSBOT0JPRFkgKE9PUFMhKS4KKworICAgICAgICBBZGQgdW5pdCB0ZXN0cyBmb3IgU3RyaW5nVmll
dy5zcGxpdCgpLgorCisgICAgICAgICogVGVzdFdlYktpdEFQSS9UZXN0cy9XVEYvU3RyaW5nVmll
dy5jcHA6CisgICAgICAgIChUZXN0V2ViS2l0QVBJOjpzdHJpbmdWaWV3RnJvbUxpdGVyYWwpOiBN
b3ZlZCB0byB0aGUgdG9wIG9mIHRoZSBmaWxlIHNvIHRoYXQgaXQgY2FuIGJlCisgICAgICAgIHVz
ZWQgaW4gdGhlIFN0cmluZ1ZpZXcuc3BsaXQoKSB1bml0IHRlc3RzLgorICAgICAgICAoVGVzdFdl
YktpdEFQSTo6c3RyaW5nVmlld0Zyb21VVEY4KTogRGl0dG8uCisgICAgICAgIChUZXN0V2ViS2l0
QVBJOjp2ZWN0b3JGcm9tRmllbGRzKTogQ29udmVuaWVuY2UgZnVuY3Rpb24gdG8gY29udmVydCBh
IFN0cmluZ1ZpZXc6OkZpZWxkcworICAgICAgICBvYmplY3QgdG8gYSBWZWN0b3Igb2YgU3RyaW5n
IG9iamVjdHMuCisgICAgICAgIChUZXN0V2ViS2l0QVBJOjpURVNUKTogQWRkZWQgdGhlIGZvbGxv
d2luZyB0ZXN0czoKKyAgICAgICAgICAgIC0gV1RGLlN0cmluZ1ZpZXdTcGxpdEVtcHR5QW5kTnVs
bFN0cmluZ3MKKyAgICAgICAgICAgIC0gV1RGLlN0cmluZ1ZpZXdTcGxpdEJhc2ljCisgICAgICAg
ICAgICAtIFdURi5TdHJpbmdWaWV3U3BsaXRXaXRoQ29uc2VjdXRpdmVTZXBhcmF0b3JzCisgICAg
ICAgICAgICAtIFdURi5TdHJpbmdWaWV3U3BsaXRDb21wYXJlSXRlcmF0b3JzCisKIDIwMTctMDEt
MTAgIENhcmxvcyBBbGJlcnRvIExvcGV6IFBlcmV6ICA8Y2xvcGV6QGlnYWxpYS5jb20+CiAKICAg
ICAgICAgW0dUS10gQWRkIGEgbmV3IHJlbGVhc2UgdGVzdCBib3QgZm9yIFdheWxhbmQgYW5kIHBh
c3MgLS1kaXNwbGF5LXNlcnZlcj14b3JnIHRvIHRoZSBHVEsgUGVyZiBib3QuCmRpZmYgLS1naXQg
YS9Ub29scy9UZXN0V2ViS2l0QVBJL1Rlc3RzL1dURi9TdHJpbmdWaWV3LmNwcCBiL1Rvb2xzL1Rl
c3RXZWJLaXRBUEkvVGVzdHMvV1RGL1N0cmluZ1ZpZXcuY3BwCmluZGV4IDM0NTAzZjQ4Yjk1NjZk
YjllM2I5NTg5N2I0ZDI0ZmFkYmQ3NmI4MmYuLjk3Mzk3NGY5NzA5OTA3ZTVhZGMyZmVjNTBiNDBk
YjE5YjQ0OTU2OTkgMTAwNjQ0Ci0tLSBhL1Rvb2xzL1Rlc3RXZWJLaXRBUEkvVGVzdHMvV1RGL1N0
cmluZ1ZpZXcuY3BwCisrKyBiL1Rvb2xzL1Rlc3RXZWJLaXRBUEkvVGVzdHMvV1RGL1N0cmluZ1Zp
ZXcuY3BwCkBAIC0zMCw2ICszMCwxNyBAQAogCiBuYW1lc3BhY2UgVGVzdFdlYktpdEFQSSB7CiAK
K1N0cmluZ1ZpZXcgc3RyaW5nVmlld0Zyb21MaXRlcmFsKGNvbnN0IGNoYXIqIGNoYXJhY3RlcnMp
Cit7CisgICAgcmV0dXJuIFN0cmluZ1ZpZXcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBMQ2hhcio+
KGNoYXJhY3RlcnMpLCBzdHJsZW4oY2hhcmFjdGVycykpOworfQorCitTdHJpbmdWaWV3IHN0cmlu
Z1ZpZXdGcm9tVVRGOChTdHJpbmcgJnJlZiwgY29uc3QgY2hhciogY2hhcmFjdGVycykKK3sKKyAg
ICByZWYgPSBTdHJpbmc6OmZyb21VVEY4KGNoYXJhY3RlcnMpOworICAgIHJldHVybiByZWY7Cit9
CisKIFRFU1QoV1RGLCBTdHJpbmdWaWV3RW1wdHlWc051bGwpCiB7CiAgICAgU3RyaW5nVmlldyBu
dWxsVmlldzsKQEAgLTIxNCw2ICsyMjUsMTMyIEBAIFRFU1QoV1RGLCBTdHJpbmdWaWV3SXRlcmF0
b3JzKQogICAgICAgICBTdHJpbmdWaWV3KGIuY2hhcmFjdGVyczE2KCkgKyAzLCAzKX0pKTsKIH0K
IAorc3RhdGljIFZlY3RvcjxTdHJpbmc+IHZlY3RvckZyb21GaWVsZHMoY29uc3QgU3RyaW5nVmll
dzo6RmllbGRzJiBmaWVsZHMpCit7CisgICAgVmVjdG9yPFN0cmluZz4gcmVzdWx0OworICAgIGZv
ciAoU3RyaW5nVmlldyBmaWVsZCA6IGZpZWxkcykKKyAgICAgICAgcmVzdWx0LmFwcGVuZChmaWVs
ZC50b1N0cmluZygpKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitURVNUKFdURiwgU3RyaW5n
Vmlld1NwbGl0RW1wdHlBbmROdWxsU3RyaW5ncykKK3sKKyAgICBTdHJpbmdWaWV3IGEgPSBlbXB0
eVN0cmluZygpOworICAgIGF1dG8gZmllbGRzID0gYS5zcGxpdCgnYicpOworICAgIEVYUEVDVF9U
UlVFKGZpZWxkcy5iZWdpbigpID09IGZpZWxkcy5lbmQoKSk7CisKKyAgICBhID0geyBTdHJpbmcg
eyB9IH07CisgICAgZmllbGRzID0gYS5zcGxpdCgnYicpOworICAgIEVYUEVDVF9UUlVFKGZpZWxk
cy5iZWdpbigpID09IGZpZWxkcy5lbmQoKSk7CisKKyAgICBhID0geyB9OworICAgIGZpZWxkcyA9
IGEuc3BsaXQoJ2InKTsKKyAgICBFWFBFQ1RfVFJVRShmaWVsZHMuYmVnaW4oKSA9PSBmaWVsZHMu
ZW5kKCkpOworCisgICAgLy8gV2l0aCBzdGFydCBvZmZzZXQKKyAgICBhID0gZW1wdHlTdHJpbmco
KTsKKyAgICBmaWVsZHMgPSBhLnNwbGl0KCdiJywgMSk7CisgICAgRVhQRUNUX1RSVUUoZmllbGRz
LmJlZ2luKCkgPT0gZmllbGRzLmVuZCgpKTsKKworICAgIGEgPSB7IFN0cmluZyB7IH0gfTsKKyAg
ICBmaWVsZHMgPSBhLnNwbGl0KCdiJywgMSk7CisgICAgRVhQRUNUX1RSVUUoZmllbGRzLmJlZ2lu
KCkgPT0gZmllbGRzLmVuZCgpKTsKKworICAgIGEgPSB7IH07CisgICAgZmllbGRzID0gYS5zcGxp
dCgnYicsIDEpOworICAgIEVYUEVDVF9UUlVFKGZpZWxkcy5iZWdpbigpID09IGZpZWxkcy5lbmQo
KSk7Cit9CisKK1RFU1QoV1RGLCBTdHJpbmdWaWV3U3BsaXRCYXNpYykKK3sKKyAgICBTdHJpbmcg
cmVmZXJlbmNlSG9sZGVyOworICAgIFN0cmluZ1ZpZXcgYSA9IHN0cmluZ1ZpZXdGcm9tVVRGOChy
ZWZlcmVuY2VIb2xkZXIsICJUaGlzIGlzIGEgc2VudGVuY2UuIik7CisKKyAgICAvLyBTaW1wbGUK
KyAgICBWZWN0b3I8U3RyaW5nPiBhY3R1YWwgPSB2ZWN0b3JGcm9tRmllbGRzKGEuc3BsaXQoJ1Qn
KSk7CisgICAgVmVjdG9yPFN0cmluZz4gZXhwZWN0ZWQoeyAiaGlzIGlzIGEgc2VudGVuY2UuIiB9
KTsKKyAgICBBU1NFUlRfRVEoZXhwZWN0ZWQuc2l6ZSgpLCBhY3R1YWwuc2l6ZSgpKTsKKyAgICBm
b3IgKHNpemVfdCBpID0gMDsgaSA8IGFjdHVhbC5zaXplKCk7ICsraSkKKyAgICAgICAgRVhQRUNU
X1NUUkVRKGV4cGVjdGVkW2ldLmFzY2lpKCkuZGF0YSgpLCBhY3R1YWxbaV0uYXNjaWkoKS5kYXRh
KCkpIDw8ICJWZWN0b3JzIGRpZmZlciBhdCBpbmRleCAiIDw8IGk7CisKKyAgICBhY3R1YWwgPSB2
ZWN0b3JGcm9tRmllbGRzKGEuc3BsaXQoJy4nKSk7CisgICAgZXhwZWN0ZWQgPSBWZWN0b3I8U3Ry
aW5nPih7ICJUaGlzIGlzIGEgc2VudGVuY2UiIH0pOworICAgIEFTU0VSVF9FUShleHBlY3RlZC5z
aXplKCksIGFjdHVhbC5zaXplKCkpOworICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgYWN0dWFs
LnNpemUoKTsgKytpKQorICAgICAgICBFWFBFQ1RfU1RSRVEoZXhwZWN0ZWRbaV0uYXNjaWkoKS5k
YXRhKCksIGFjdHVhbFtpXS5hc2NpaSgpLmRhdGEoKSkgPDwgIlZlY3RvcnMgZGlmZmVyIGF0IGlu
ZGV4ICIgPDwgaTsKKworICAgIGFjdHVhbCA9IHZlY3RvckZyb21GaWVsZHMoYS5zcGxpdCgnYScp
KTsKKyAgICBleHBlY3RlZCA9IFZlY3RvcjxTdHJpbmc+KHsgIlRoaXMgaXMgIiwgIiBzZW50ZW5j
ZS4iIH0pOworICAgIEFTU0VSVF9FUShleHBlY3RlZC5zaXplKCksIGFjdHVhbC5zaXplKCkpOwor
ICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgYWN0dWFsLnNpemUoKTsgKytpKQorICAgICAgICBF
WFBFQ1RfU1RSRVEoZXhwZWN0ZWRbaV0uYXNjaWkoKS5kYXRhKCksIGFjdHVhbFtpXS5hc2NpaSgp
LmRhdGEoKSkgPDwgIlZlY3RvcnMgZGlmZmVyIGF0IGluZGV4ICIgPDwgaTsKKworICAgIGFjdHVh
bCA9IHZlY3RvckZyb21GaWVsZHMoYS5zcGxpdCgnICcpKTsKKyAgICBleHBlY3RlZCA9IFZlY3Rv
cjxTdHJpbmc+KHsgIlRoaXMiLCAiaXMiLCAiYSIsICJzZW50ZW5jZS4iIH0pOworICAgIEFTU0VS
VF9FUShleHBlY3RlZC5zaXplKCksIGFjdHVhbC5zaXplKCkpOworICAgIGZvciAoc2l6ZV90IGkg
PSAwOyBpIDwgYWN0dWFsLnNpemUoKTsgKytpKQorICAgICAgICBFWFBFQ1RfU1RSRVEoZXhwZWN0
ZWRbaV0uYXNjaWkoKS5kYXRhKCksIGFjdHVhbFtpXS5hc2NpaSgpLmRhdGEoKSkgPDwgIlZlY3Rv
cnMgZGlmZmVyIGF0IGluZGV4ICIgPDwgaTsKKworICAgIC8vIFdpdGggc3RhcnQgb2Zmc2V0Cisg
ICAgYWN0dWFsID0gdmVjdG9yRnJvbUZpZWxkcyhhLnNwbGl0KCcgJywgMykpOworICAgIGV4cGVj
dGVkID0gVmVjdG9yPFN0cmluZz4oeyAicyIsICJpcyIsICJhIiwgInNlbnRlbmNlLiIgfSk7Cisg
ICAgQVNTRVJUX0VRKGV4cGVjdGVkLnNpemUoKSwgYWN0dWFsLnNpemUoKSk7CisgICAgZm9yIChz
aXplX3QgaSA9IDA7IGkgPCBhY3R1YWwuc2l6ZSgpOyArK2kpCisgICAgICAgIEVYUEVDVF9TVFJF
UShleHBlY3RlZFtpXS5hc2NpaSgpLmRhdGEoKSwgYWN0dWFsW2ldLmFzY2lpKCkuZGF0YSgpKSA8
PCAiVmVjdG9ycyBkaWZmZXIgYXQgaW5kZXggIiA8PCBpOworCisgICAgYWN0dWFsID0gdmVjdG9y
RnJvbUZpZWxkcyhhLnNwbGl0KCcgJywgNCkpOworICAgIGV4cGVjdGVkID0gVmVjdG9yPFN0cmlu
Zz4oeyAiaXMiLCAiYSIsICJzZW50ZW5jZS4iIH0pOworICAgIEFTU0VSVF9FUShleHBlY3RlZC5z
aXplKCksIGFjdHVhbC5zaXplKCkpOworICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgYWN0dWFs
LnNpemUoKTsgKytpKQorICAgICAgICBFWFBFQ1RfU1RSRVEoZXhwZWN0ZWRbaV0uYXNjaWkoKS5k
YXRhKCksIGFjdHVhbFtpXS5hc2NpaSgpLmRhdGEoKSkgPDwgIlZlY3RvcnMgZGlmZmVyIGF0IGlu
ZGV4ICIgPDwgaTsKKworICAgIGFjdHVhbCA9IHZlY3RvckZyb21GaWVsZHMoYS5zcGxpdCgnLics
IGEubGVuZ3RoKCkgLSAxKSk7CisgICAgRVhQRUNUX0VRKDBVLCBhY3R1YWwuc2l6ZSgpKTsKKwor
ICAgIGFjdHVhbCA9IHZlY3RvckZyb21GaWVsZHMoYS5zcGxpdCgnICcsIGEubGVuZ3RoKCkpKTsK
KyAgICBFWFBFQ1RfRVEoMFUsIGFjdHVhbC5zaXplKCkpOworCisgICAgYWN0dWFsID0gdmVjdG9y
RnJvbUZpZWxkcyhhLnNwbGl0KCcgJywgYS5sZW5ndGgoKSArIDEpKTsKKyAgICBFWFBFQ1RfRVEo
MFUsIGFjdHVhbC5zaXplKCkpOworCisgICAgLy8gTm9uLWV4aXN0ZW50IHNlcGFyYXRvcgorICAg
IGFjdHVhbCA9IHZlY3RvckZyb21GaWVsZHMoYS5zcGxpdCgneicpKTsKKyAgICBleHBlY3RlZCA9
IFZlY3RvcjxTdHJpbmc+KHsgIlRoaXMgaXMgYSBzZW50ZW5jZS4iIH0pOworICAgIEFTU0VSVF9F
UShleHBlY3RlZC5zaXplKCksIGFjdHVhbC5zaXplKCkpOworICAgIGZvciAoc2l6ZV90IGkgPSAw
OyBpIDwgYWN0dWFsLnNpemUoKTsgKytpKQorICAgICAgICBFWFBFQ1RfU1RSRVEoZXhwZWN0ZWRb
aV0uYXNjaWkoKS5kYXRhKCksIGFjdHVhbFtpXS5hc2NpaSgpLmRhdGEoKSkgPDwgIlZlY3RvcnMg
ZGlmZmVyIGF0IGluZGV4ICIgPDwgaTsKK30KKworVEVTVChXVEYsIFN0cmluZ1ZpZXdTcGxpdFdp
dGhDb25zZWN1dGl2ZVNlcGFyYXRvcnMpCit7CisgICAgU3RyaW5nIHJlZmVyZW5jZUhvbGRlcjsK
KyAgICBTdHJpbmdWaWV3IGEgPSBzdHJpbmdWaWV3RnJvbVVURjgocmVmZXJlbmNlSG9sZGVyLCAi
VGhpcyAgICAgaXMgIGEgICAgICAgc2VudGVuY2UuIik7CisKKyAgICBWZWN0b3I8U3RyaW5nPiBh
Y3R1YWwgPSB2ZWN0b3JGcm9tRmllbGRzKGEuc3BsaXQoJyAnKSk7CisgICAgVmVjdG9yPFN0cmlu
Zz4gZXhwZWN0ZWQoeyAiVGhpcyIsICJpcyIsICJhIiwgInNlbnRlbmNlLiIgfSk7CisgICAgQVNT
RVJUX0VRKGV4cGVjdGVkLnNpemUoKSwgYWN0dWFsLnNpemUoKSk7CisgICAgZm9yIChzaXplX3Qg
aSA9IDA7IGkgPCBhY3R1YWwuc2l6ZSgpOyArK2kpCisgICAgICAgIEVYUEVDVF9TVFJFUShleHBl
Y3RlZFtpXS5hc2NpaSgpLmRhdGEoKSwgYWN0dWFsW2ldLmFzY2lpKCkuZGF0YSgpKSA8PCAiVmVj
dG9ycyBkaWZmZXIgYXQgaW5kZXggIiA8PCBpOworfQorCitURVNUKFdURiwgU3RyaW5nVmlld1Nw
bGl0Q29tcGFyZUl0ZXJhdG9ycykKK3sKKyAgICBTdHJpbmcgZmlyc3RSZWZlcmVuY2VIb2xkZXI7
CisgICAgU3RyaW5nVmlldyBhID0gc3RyaW5nVmlld0Zyb21VVEY4KGZpcnN0UmVmZXJlbmNlSG9s
ZGVyLCAiVGhpcyBpcyBhIHNlbnRlbmNlLiIpOworCisgICAgU3RyaW5nIHNlY29uZFJlZmVyZW5j
ZUhvbGRlcjsKKyAgICBTdHJpbmdWaWV3IGIgPSBzdHJpbmdWaWV3RnJvbVVURjgoc2Vjb25kUmVm
ZXJlbmNlSG9sZGVyLCAiVGhpcyBpcyBhIHNlbnRlbmNlLiIpOworCisgICAgLy8gRGlmZmVyZW50
IHNlcGFyYXRvcnMKKyAgICBFWFBFQ1RfRkFMU0UoYS5zcGxpdCgnICcsIGEubGVuZ3RoKCkpLmJl
Z2luKCkgPT0gYS5zcGxpdCgnLCcsIGEubGVuZ3RoKCkpLmJlZ2luKCkpOworICAgIEVYUEVDVF9G
QUxTRShhLnNwbGl0KCcgJywgYS5sZW5ndGgoKSkuZW5kKCkgPT0gYS5zcGxpdCgnLCcsIGEubGVu
Z3RoKCkpLmVuZCgpKTsKKworICAgIC8vIERpZmZlcmVudCBTdHJpbmdWaWV3IG9iamVjdHMKKyAg
ICBFWFBFQ1RfRkFMU0UoYS5zcGxpdCgnICcpLmJlZ2luKCkgPT0gYi5zcGxpdCgnICcpLmJlZ2lu
KCkpOworICAgIEVYUEVDVF9GQUxTRShhLnNwbGl0KCcgJywgYS5sZW5ndGgoKSkuYmVnaW4oKSA9
PSBiLnNwbGl0KCcgJywgYi5sZW5ndGgoKSkuYmVnaW4oKSk7CisgICAgRVhQRUNUX0ZBTFNFKGEu
c3BsaXQoJyAnLCBhLmxlbmd0aCgpKS5lbmQoKSA9PSBiLnNwbGl0KCcgJywgYi5sZW5ndGgoKSku
ZW5kKCkpOworfQorCiBURVNUKFdURiwgU3RyaW5nVmlld0VxdWFsSWdub3JpbmdBU0NJSUNhc2VC
YXNpYykKIHsKICAgICBSZWZQdHI8U3RyaW5nSW1wbD4gYSA9IFN0cmluZ0ltcGw6OmNyZWF0ZUZy
b21MaXRlcmFsKCJhQmNEZUZHIik7CkBAIC0zMDQsMTcgKzQ0MSw2IEBAIFRFU1QoV1RGLCBTdHJp
bmdWaWV3RXF1YWxJZ25vcmluZ0FTQ0lJQ2FzZVdpdGhMYXRpbjFDaGFyYWN0ZXJzKQogICAgIEFT
U0VSVF9GQUxTRShlcXVhbElnbm9yaW5nQVNDSUlDYXNlKHN0cmluZ1ZpZXdELCBlKSk7CiB9CiAK
LVN0cmluZ1ZpZXcgc3RyaW5nVmlld0Zyb21MaXRlcmFsKGNvbnN0IGNoYXIqIGNoYXJhY3RlcnMp
Ci17Ci0gICAgcmV0dXJuIFN0cmluZ1ZpZXcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBMQ2hhcio+
KGNoYXJhY3RlcnMpLCBzdHJsZW4oY2hhcmFjdGVycykpOwotfQotCi1TdHJpbmdWaWV3IHN0cmlu
Z1ZpZXdGcm9tVVRGOChTdHJpbmcgJnJlZiwgY29uc3QgY2hhciogY2hhcmFjdGVycykKLXsKLSAg
ICByZWYgPSBTdHJpbmc6OmZyb21VVEY4KGNoYXJhY3RlcnMpOwotICAgIHJldHVybiByZWY7Ci19
Ci0KIFRFU1QoV1RGLCBTdHJpbmdWaWV3RmluZElnbm9yaW5nQVNDSUlDYXNlQmFzaWMpCiB7CiAg
ICAgU3RyaW5nIHJlZmVyZW5jZUFIb2xkZXI7Cg==
</data>

          </attachment>
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>299113</attachid>
            <date>2017-01-17 19:48:25 -0800</date>
            <delta_ts>2017-01-17 21:49:11 -0800</delta_ts>
            <desc>Patch and unit tests</desc>
            <filename>bug-163225-20170117194638.patch</filename>
            <type>text/plain</type>
            <size>15915</size>
            <attacher name="Daniel Bates">dbates</attacher>
            
              <data encoding="base64">U3VidmVyc2lvbiBSZXZpc2lvbjogMjEwODI1CmRpZmYgLS1naXQgYS9Tb3VyY2UvV1RGL0NoYW5n
ZUxvZyBiL1NvdXJjZS9XVEYvQ2hhbmdlTG9nCmluZGV4IDNkMmYwZjMyZmFlNGNhNmYzNjE5ZWUz
ZTc2NGY0MWNiYzM2MWUxMTYuLjI0MzY2OGUyYzRmOTkwOTNlYTYyYjEyMDY0N2Q1MTcxOTlmNTcw
NjUgMTAwNjQ0Ci0tLSBhL1NvdXJjZS9XVEYvQ2hhbmdlTG9nCisrKyBiL1NvdXJjZS9XVEYvQ2hh
bmdlTG9nCkBAIC0xLDMgKzEsMzcgQEAKKzIwMTctMDEtMTcgIERhbmllbCBCYXRlcyAgPGRhYmF0
ZXNAYXBwbGUuY29tPgorCisgICAgICAgIFN0cmluZ1ZpZXcuc3BsaXQoKSBzaG91bGQgdXNlIGFu
IGl0ZXJhdG9yIGRlc2lnbiBwYXR0ZXJuIGluc3RlYWQgb2YgYWxsb2NhdGluZyBhIFZlY3Rvcgor
ICAgICAgICBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTYzMjI1CisK
KyAgICAgICAgUmV2aWV3ZWQgYnkgTk9CT0RZIChPT1BTISkuCisKKyAgICAgICAgSW1wbGVtZW50
IFN0cmluZ1ZpZXcuc3BsaXQoKSB1c2luZyBhbiBpdGVyYXRvciBkZXNpZ24uCisKKyAgICAgICAg
VXNpbmcgYW4gaXRlcmF0b3IgZGVzaWduIGF2b2lkcyB0aGUgbmVlZCB0byBhbGxvY2F0ZSBhIFZl
Y3RvciBvZiBTdHJpbmdWaWV3IG9iamVjdHMsCisgICAgICAgIHdoaWNoIGlzIHNwYWNlLWluZWZm
aWNpZW50IGFuZCBlcnJvciBwcm9uZSBhcyB0aGUgcmV0dXJuZWQgVmVjdG9yIG1heSBvdXRsaXZl
IHRoZQorICAgICAgICBsaWZldGltZSBvZiB0aGUgdW5kZXJseWluZyBzdHJpbmcgYXNzb2NpYXRl
ZCB3aXRoIHRoZSBzcGxpdCAoYXMgU3RyaW5nVmlldyBpcyBhIG5vbi0KKyAgICAgICAgb3duaW5n
IHJlZmVyZW5jZSB0byBhIHN0cmluZykuCisKKyAgICAgICAgU3RyaW5nVmlldy5zcGxpdCgpIG5v
dyByZXR1cm5zIGEgU3RyaW5nVmlldzo6RmllbGRzIG9iamVjdCB0aGF0IGltcGxlbWVudHMgYmVn
aW4oKS9lbmQoKQorICAgICAgICB0byBzdXBwb3J0IGl0ZXJhdGluZyBvdmVyIFN0cmluZ1ZpZXcg
c3Vic3RyaW5ncyBkZWxpbWl0ZWQgYnkgdGhlIHNwZWNpZmllZCBzZXBhcmF0b3IKKyAgICAgICAg
Y2hhcmFjdGVyLiBGb3IgZXhhbXBsZSwgdG8gaXRlcmF0ZSBvdmVyIHRoZSAnYyctc2VwYXJhdGVk
IGZpZWxkcyBvZiBhIFN0cmluZ1ZpZXcgdiwgeW91CisgICAgICAgIGNhbiB3cml0ZToKKworICAg
ICAgICBmb3IgKFN0cmluZ1ZpZXcgZmllbGQgOiB2LnNwbGl0KCdjJykpCisgICAgICAgICAgICAv
LyBEbyBzb21ldGhpbmcgd2l0aCBmaWVsZC4KKworICAgICAgICAqIHd0Zi90ZXh0L1N0cmluZ1Zp
ZXcuY3BwOgorICAgICAgICAoV1RGOjpTdHJpbmdWaWV3OjpTcGxpdFJlc3VsdDo6SXRlcmF0b3I6
OmZpbmROZXh0U3Vic3RyaW5nKTogQWR2YW5jZXMgdGhlIGl0ZXJhdG9yIHRvIHBvaW50IHRvIHRo
ZQorICAgICAgICBuZXh0IHN1YnN0cmluZy4KKyAgICAgICAgKFdURjo6U3RyaW5nVmlldzo6c3Bs
aXQpOiBNb2RpZmllZCB0byByZXR1cm4gYSBTcGxpdFJlc3VsdDo6SXRlcmF0b3Igb2JqZWN0IGlu
c3RlYWQgb2YgYSBWZWN0b3I8U3RyaW5nVmlldz4uCisgICAgICAgICogd3RmL3RleHQvU3RyaW5n
Vmlldy5oOgorICAgICAgICAoV1RGOjpTdHJpbmdWaWV3OjpTcGxpdFJlc3VsdDo6U3BsaXRSZXN1
bHQpOgorICAgICAgICAoV1RGOjpTdHJpbmdWaWV3OjpTcGxpdFJlc3VsdDo6SXRlcmF0b3I6Okl0
ZXJhdG9yKToKKyAgICAgICAgKFdURjo6U3RyaW5nVmlldzo6U3BsaXRSZXN1bHQ6Okl0ZXJhdG9y
OjpvcGVyYXRvciopOgorICAgICAgICAoV1RGOjpTdHJpbmdWaWV3OjpTcGxpdFJlc3VsdDo6SXRl
cmF0b3I6Om9wZXJhdG9yPT0pOgorICAgICAgICAoV1RGOjpTdHJpbmdWaWV3OjpTcGxpdFJlc3Vs
dDo6SXRlcmF0b3I6Om9wZXJhdG9yIT0pOgorICAgICAgICBJbXBsZW1lbnRzIHRoZSBpdGVyYXRv
ciBpbnRlcmZhY2UuCisKIDIwMTctMDEtMTYgIEpvc2VwaCBQZWNvcmFybyAgPHBlY29yYXJvQGFw
cGxlLmNvbT4KIAogICAgICAgICBSZW1vdmUgdGhlIFJFUVVFU1RfQU5JTUFUSU9OX0ZSQU1FIGZs
YWcKZGlmZiAtLWdpdCBhL1NvdXJjZS9XZWJDb3JlL0NoYW5nZUxvZyBiL1NvdXJjZS9XZWJDb3Jl
L0NoYW5nZUxvZwppbmRleCBmYjc4MWU3NmEzYTJiYjc5MDVkMjhlMmI4M2MxMmY5OGI3NjIxOWU5
Li44YTlkNjRkZmYzNmY1Njc4Mjg1N2MwNzg3NjEzYWU1NTdhY2VmNmJhIDEwMDY0NAotLS0gYS9T
b3VyY2UvV2ViQ29yZS9DaGFuZ2VMb2cKKysrIGIvU291cmNlL1dlYkNvcmUvQ2hhbmdlTG9nCkBA
IC0xLDMgKzEsMTQgQEAKKzIwMTctMDEtMTcgIERhbmllbCBCYXRlcyAgPGRhYmF0ZXNAYXBwbGUu
Y29tPgorCisgICAgICAgIFN0cmluZ1ZpZXcuc3BsaXQoKSBzaG91bGQgdXNlIGFuIGl0ZXJhdG9y
IGRlc2lnbiBwYXR0ZXJuIGluc3RlYWQgb2YgYWxsb2NhdGluZyBhIFZlY3RvcgorICAgICAgICBo
dHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTYzMjI1CisKKyAgICAgICAg
UmV2aWV3ZWQgYnkgTk9CT0RZIChPT1BTISkuCisKKyAgICAgICAgVXBkYXRlIGNvZGUgdG8gdXNl
IHRoZSBuZXcgaXRlcmF0b3Itc3R5bGUgU3RyaW5nVmlldy5zcGxpdCgpLgorCisgICAgICAgICog
cGxhdGZvcm0vVVJMUGFyc2VyLmNwcDoKKwogMjAxNy0wMS0xNyAgRmlsaXAgUGl6bG8gIDxmcGl6
bG9AYXBwbGUuY29tPgogCiAgICAgICAgIFVucmV2aWV3ZWQsIHJvbGwgb3V0IGh0dHA6Ly90cmFj
LndlYmtpdC5vcmcvY2hhbmdlc2V0LzIxMDgyMQpkaWZmIC0tZ2l0IGEvU291cmNlL1dURi93dGYv
dGV4dC9TdHJpbmdWaWV3LmNwcCBiL1NvdXJjZS9XVEYvd3RmL3RleHQvU3RyaW5nVmlldy5jcHAK
aW5kZXggZDc4NTYyZTJiYzU3MGU4OGNkOTY0ZTYwMjk3NWVhOTY4ZDI4ZmVlZC4uZTdkZWRjMWY2
MGVhNDcxOWJiYWFmYjNkYWZjMGMwYWE2OTUwODVhMCAxMDA2NDQKLS0tIGEvU291cmNlL1dURi93
dGYvdGV4dC9TdHJpbmdWaWV3LmNwcAorKysgYi9Tb3VyY2UvV1RGL3d0Zi90ZXh0L1N0cmluZ1Zp
ZXcuY3BwCkBAIC0xLDYgKzEsNiBAQAogLyoKIAotQ29weXJpZ2h0IChDKSAyMDE0LCAyMDE2IEFw
cGxlIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KK0NvcHlyaWdodCAoQykgMjAxNC0yMDE3IEFw
cGxlIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KIAogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBp
biBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiBtb2RpZmljYXRpb24s
IGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKQEAg
LTk0LDYgKzk0LDMxIEBAIHNpemVfdCBTdHJpbmdWaWV3OjpmaW5kKFN0cmluZ1ZpZXcgbWF0Y2hT
dHJpbmcsIHVuc2lnbmVkIHN0YXJ0KSBjb25zdAogICAgIHJldHVybiBmaW5kQ29tbW9uKCp0aGlz
LCBtYXRjaFN0cmluZywgc3RhcnQpOwogfQogCit2b2lkIFN0cmluZ1ZpZXc6OlNwbGl0UmVzdWx0
OjpJdGVyYXRvcjo6ZmluZE5leHRTdWJzdHJpbmcoKQoreworICAgIGZvciAoc2l6ZV90IHNlcGFy
YXRvclBvc2l0aW9uOyAoc2VwYXJhdG9yUG9zaXRpb24gPSBtX3Jlc3VsdC5tX3N0cmluZy5maW5k
KG1fcmVzdWx0Lm1fc2VwYXJhdG9yLCBtX3Bvc2l0aW9uKSkgIT0gbm90Rm91bmQ7ICsrbV9wb3Np
dGlvbikgeworICAgICAgICBpZiAoc2VwYXJhdG9yUG9zaXRpb24gPiBtX3Bvc2l0aW9uKSB7Cisg
ICAgICAgICAgICBtX2xlbmd0aCA9IHNlcGFyYXRvclBvc2l0aW9uIC0gbV9wb3NpdGlvbjsKKyAg
ICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKyAgICBtX2xlbmd0aCA9IG1fcmVz
dWx0Lm1fc3RyaW5nLmxlbmd0aCgpIC0gbV9wb3NpdGlvbjsKK30KKworYXV0byBTdHJpbmdWaWV3
OjpTcGxpdFJlc3VsdDo6SXRlcmF0b3I6Om9wZXJhdG9yKysoKSAtPiBJdGVyYXRvciYKK3sKKyAg
ICBBU1NFUlQobV9sZW5ndGggPD0gbV9yZXN1bHQubV9zdHJpbmcubGVuZ3RoKCkpOworICAgIEFT
U0VSVChtX3Bvc2l0aW9uIDw9IG1fcmVzdWx0Lm1fc3RyaW5nLmxlbmd0aCgpIC0gbV9sZW5ndGgp
OworICAgIGlmIChtX3Bvc2l0aW9uID09IG1fcmVzdWx0Lm1fc3RyaW5nLmxlbmd0aCgpIC0gbV9s
ZW5ndGgpIHsKKyAgICAgICAgbV9wb3NpdGlvbiA9IG1fcmVzdWx0Lm1fc3RyaW5nLmxlbmd0aCgp
OworICAgICAgICBtX2xlbmd0aCA9IDA7CisgICAgICAgIHJldHVybiAqdGhpczsKKyAgICB9Cisg
ICAgbV9wb3NpdGlvbiArPSBtX2xlbmd0aCArIDE7CisgICAgZmluZE5leHRTdWJzdHJpbmcoKTsK
KyAgICByZXR1cm4gKnRoaXM7Cit9CisKIGNsYXNzIFN0cmluZ1ZpZXc6OkdyYXBoZW1lQ2x1c3Rl
cnM6Okl0ZXJhdG9yOjpJbXBsIHsKIHB1YmxpYzoKICAgICBJbXBsKGNvbnN0IFN0cmluZ1ZpZXcm
IHN0cmluZ1ZpZXcsIHN0ZDo6b3B0aW9uYWw8Tm9uU2hhcmVkQ2hhcmFjdGVyQnJlYWtJdGVyYXRv
cj4mJiBpdGVyYXRvciwgdW5zaWduZWQgaW5kZXgpCkBAIC0xNDIsMjEgKzE2Nyw2IEBAIHByaXZh
dGU6CiAgICAgdW5zaWduZWQgbV9pbmRleEVuZDsKIH07CiAKLVZlY3RvcjxTdHJpbmdWaWV3PiBT
dHJpbmdWaWV3OjpzcGxpdChVQ2hhciBzZXBhcmF0b3IpCi17Ci0gICAgVmVjdG9yPFN0cmluZ1Zp
ZXc+IHJlc3VsdDsKLSAgICB1bnNpZ25lZCBzdGFydFBvcyA9IDA7Ci0gICAgc2l6ZV90IGVuZFBv
czsKLSAgICB3aGlsZSAoKGVuZFBvcyA9IGZpbmQoc2VwYXJhdG9yLCBzdGFydFBvcykpICE9IG5v
dEZvdW5kKSB7Ci0gICAgICAgIGlmIChzdGFydFBvcyAhPSBlbmRQb3MpCi0gICAgICAgICAgICBy
ZXN1bHQuYXBwZW5kKHN1YnN0cmluZyhzdGFydFBvcywgZW5kUG9zIC0gc3RhcnRQb3MpKTsKLSAg
ICAgICAgc3RhcnRQb3MgPSBlbmRQb3MgKyAxOwotICAgIH0KLSAgICBpZiAoc3RhcnRQb3MgIT0g
bGVuZ3RoKCkpCi0gICAgICAgIHJlc3VsdC5hcHBlbmQoc3Vic3RyaW5nKHN0YXJ0UG9zKSk7Ci0g
ICAgcmV0dXJuIHJlc3VsdDsKLX0KLQogU3RyaW5nVmlldzo6R3JhcGhlbWVDbHVzdGVyczo6SXRl
cmF0b3I6Okl0ZXJhdG9yKGNvbnN0IFN0cmluZ1ZpZXcmIHN0cmluZ1ZpZXcsIHVuc2lnbmVkIGlu
ZGV4KQogICAgIDogbV9pbXBsKHN0ZDo6bWFrZV91bmlxdWU8SW1wbD4oc3RyaW5nVmlldywgc3Ry
aW5nVmlldy5pc051bGwoKSA/IHN0ZDo6bnVsbG9wdCA6IHN0ZDo6b3B0aW9uYWw8Tm9uU2hhcmVk
Q2hhcmFjdGVyQnJlYWtJdGVyYXRvcj4oTm9uU2hhcmVkQ2hhcmFjdGVyQnJlYWtJdGVyYXRvcihz
dHJpbmdWaWV3KSksIGluZGV4KSkKIHsKZGlmZiAtLWdpdCBhL1NvdXJjZS9XVEYvd3RmL3RleHQv
U3RyaW5nVmlldy5oIGIvU291cmNlL1dURi93dGYvdGV4dC9TdHJpbmdWaWV3LmgKaW5kZXggMmNj
MjVjZDAyMTEyMDFjNDI2M2ZlY2ViMzQ5YzcyZDIxODY2YTAzMi4uMmM0YzdjN2VmZGQ3ZGM4OWEz
MzIzYmRiN2M1NjY1MTU4NzgyNDQzYiAxMDA2NDQKLS0tIGEvU291cmNlL1dURi93dGYvdGV4dC9T
dHJpbmdWaWV3LmgKKysrIGIvU291cmNlL1dURi93dGYvdGV4dC9TdHJpbmdWaWV3LmgKQEAgLTEs
NSArMSw1IEBACiAvKgotICogQ29weXJpZ2h0IChDKSAyMDE0LTIwMTYgQXBwbGUgSW5jLiBBbGwg
cmlnaHRzIHJlc2VydmVkLgorICogQ29weXJpZ2h0IChDKSAyMDE0LTIwMTcgQXBwbGUgSW5jLiBB
bGwgcmlnaHRzIHJlc2VydmVkLgogICoKICAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291
cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogICogbW9kaWZpY2F0aW9uLCBh
cmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCkBAIC0x
MTcsNyArMTE3LDkgQEAgcHVibGljOgogICAgIFN0cmluZ1ZpZXcgc3Vic3RyaW5nKHVuc2lnbmVk
IHN0YXJ0LCB1bnNpZ25lZCBsZW5ndGggPSBzdGQ6Om51bWVyaWNfbGltaXRzPHVuc2lnbmVkPjo6
bWF4KCkpIGNvbnN0OwogICAgIFN0cmluZ1ZpZXcgbGVmdCh1bnNpZ25lZCBsZW4pIGNvbnN0IHsg
cmV0dXJuIHN1YnN0cmluZygwLCBsZW4pOyB9CiAgICAgU3RyaW5nVmlldyByaWdodCh1bnNpZ25l
ZCBsZW4pIGNvbnN0IHsgcmV0dXJuIHN1YnN0cmluZyhsZW5ndGgoKSAtIGxlbiwgbGVuKTsgfQot
ICAgIFdURl9FWFBPUlRfU1RSSU5HX0FQSSBWZWN0b3I8U3RyaW5nVmlldz4gc3BsaXQoVUNoYXIp
OworCisgICAgY2xhc3MgU3BsaXRSZXN1bHQ7CisgICAgU3BsaXRSZXN1bHQgc3BsaXQoVUNoYXIp
IGNvbnN0OwogCiAgICAgc2l6ZV90IGZpbmQoVUNoYXIsIHVuc2lnbmVkIHN0YXJ0ID0gMCkgY29u
c3Q7CiAgICAgc2l6ZV90IGZpbmQoQ2hhcmFjdGVyTWF0Y2hGdW5jdGlvbiwgdW5zaWduZWQgc3Rh
cnQgPSAwKSBjb25zdDsKQEAgLTYxMyw2ICs2MTUsMTkgQEAgaW5saW5lIGJvb2wgZXF1YWxJZ25v
cmluZ0FTQ0lJQ2FzZShTdHJpbmdWaWV3IGEsIGNvbnN0IGNoYXIqIGIpCiAgICAgcmV0dXJuIGVx
dWFsSWdub3JpbmdBU0NJSUNhc2VDb21tb24oYSwgYik7CiB9CiAKK2NsYXNzIFN0cmluZ1ZpZXc6
OlNwbGl0UmVzdWx0IHsKK3B1YmxpYzoKKyAgICBleHBsaWNpdCBTcGxpdFJlc3VsdChTdHJpbmdW
aWV3LCBVQ2hhciBzZXBhcmF0b3IpOworCisgICAgY2xhc3MgSXRlcmF0b3I7CisgICAgSXRlcmF0
b3IgYmVnaW4oKSBjb25zdDsKKyAgICBJdGVyYXRvciBlbmQoKSBjb25zdDsKKworcHJpdmF0ZToK
KyAgICBTdHJpbmdWaWV3IG1fc3RyaW5nOworICAgIFVDaGFyIG1fc2VwYXJhdG9yOworfTsKKwog
Y2xhc3MgU3RyaW5nVmlldzo6R3JhcGhlbWVDbHVzdGVycyB7CiBwdWJsaWM6CiAgICAgZXhwbGlj
aXQgR3JhcGhlbWVDbHVzdGVycyhjb25zdCBTdHJpbmdWaWV3Jik7CkBAIC02NDksNiArNjY0LDI5
IEBAIHByaXZhdGU6CiAgICAgU3RyaW5nVmlldyBtX3N0cmluZ1ZpZXc7CiB9OwogCitjbGFzcyBT
dHJpbmdWaWV3OjpTcGxpdFJlc3VsdDo6SXRlcmF0b3IgeworcHVibGljOgorICAgIFN0cmluZ1Zp
ZXcgb3BlcmF0b3IqKCkgY29uc3Q7CisKKyAgICBXVEZfRVhQT1JUX1BSSVZBVEUgSXRlcmF0b3Im
IG9wZXJhdG9yKysoKTsKKworICAgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBJdGVyYXRvciYpIGNv
bnN0OworICAgIGJvb2wgb3BlcmF0b3IhPShjb25zdCBJdGVyYXRvciYpIGNvbnN0OworCitwcml2
YXRlOgorICAgIGVudW0gUG9zaXRpb25UYWcgeyBBdEVuZCB9OworICAgIEl0ZXJhdG9yKGNvbnN0
IFNwbGl0UmVzdWx0Jik7CisgICAgSXRlcmF0b3IoY29uc3QgU3BsaXRSZXN1bHQmLCBQb3NpdGlv
blRhZyk7CisKKyAgICBXVEZfRVhQT1JUX1BSSVZBVEUgdm9pZCBmaW5kTmV4dFN1YnN0cmluZygp
OworCisgICAgZnJpZW5kIFNwbGl0UmVzdWx0OworCisgICAgY29uc3QgU3BsaXRSZXN1bHQmIG1f
cmVzdWx0OworICAgIHVuc2lnbmVkIG1fcG9zaXRpb24geyAwIH07CisgICAgdW5zaWduZWQgbV9s
ZW5ndGggeyAwIH07Cit9OworCiBjbGFzcyBTdHJpbmdWaWV3OjpHcmFwaGVtZUNsdXN0ZXJzOjpJ
dGVyYXRvciB7CiBwdWJsaWM6CiAgICAgV1RGX0VYUE9SVF9QUklWQVRFIEl0ZXJhdG9yKCkgPSBk
ZWxldGU7CkBAIC04MzksNiArODc3LDYyIEBAIGlubGluZSBhdXRvIFN0cmluZ1ZpZXc6OkNvZGVV
bml0czo6ZW5kKCkgY29uc3QgLT4gSXRlcmF0b3IKICAgICByZXR1cm4gSXRlcmF0b3IobV9zdHJp
bmdWaWV3LCBtX3N0cmluZ1ZpZXcubGVuZ3RoKCkpOwogfQogCitpbmxpbmUgYXV0byBTdHJpbmdW
aWV3OjpzcGxpdChVQ2hhciBzZXBhcmF0b3IpIGNvbnN0IC0+IFNwbGl0UmVzdWx0Cit7CisgICAg
cmV0dXJuIFNwbGl0UmVzdWx0IHsgKnRoaXMsIHNlcGFyYXRvciB9OworfQorCitpbmxpbmUgU3Ry
aW5nVmlldzo6U3BsaXRSZXN1bHQ6OlNwbGl0UmVzdWx0KFN0cmluZ1ZpZXcgc3RyaW5nVmlldywg
VUNoYXIgc2VwYXJhdG9yKQorICAgIDogbV9zdHJpbmcgeyBzdHJpbmdWaWV3IH0KKyAgICAsIG1f
c2VwYXJhdG9yIHsgc2VwYXJhdG9yIH0KK3sKK30KKworaW5saW5lIGF1dG8gU3RyaW5nVmlldzo6
U3BsaXRSZXN1bHQ6OmJlZ2luKCkgY29uc3QgLT4gSXRlcmF0b3IKK3sKKyAgICByZXR1cm4gSXRl
cmF0b3IgeyAqdGhpcyB9OworfQorCitpbmxpbmUgYXV0byBTdHJpbmdWaWV3OjpTcGxpdFJlc3Vs
dDo6ZW5kKCkgY29uc3QgLT4gSXRlcmF0b3IKK3sKKyAgICByZXR1cm4gSXRlcmF0b3IgeyAqdGhp
cywgSXRlcmF0b3I6OkF0RW5kIH07Cit9CisKK2lubGluZSBTdHJpbmdWaWV3OjpTcGxpdFJlc3Vs
dDo6SXRlcmF0b3I6Okl0ZXJhdG9yKGNvbnN0IFNwbGl0UmVzdWx0JiByZXN1bHQpCisgICAgOiBt
X3Jlc3VsdCB7IHJlc3VsdCB9Cit7CisgICAgZmluZE5leHRTdWJzdHJpbmcoKTsKK30KKworaW5s
aW5lIFN0cmluZ1ZpZXc6OlNwbGl0UmVzdWx0OjpJdGVyYXRvcjo6SXRlcmF0b3IoY29uc3QgU3Bs
aXRSZXN1bHQmIHJlc3VsdCwgUG9zaXRpb25UYWcpCisgICAgOiBtX3Jlc3VsdCB7IHJlc3VsdCB9
CisgICAgLCBtX3Bvc2l0aW9uIHsgcmVzdWx0Lm1fc3RyaW5nLmxlbmd0aCgpIH0KK3sKK30KKwor
aW5saW5lIFN0cmluZ1ZpZXcgU3RyaW5nVmlldzo6U3BsaXRSZXN1bHQ6Okl0ZXJhdG9yOjpvcGVy
YXRvciooKSBjb25zdAoreworICAgIEFTU0VSVChtX2xlbmd0aCk7CisgICAgQVNTRVJUKG1fbGVu
Z3RoIDw9IG1fcmVzdWx0Lm1fc3RyaW5nLmxlbmd0aCgpKTsKKyAgICBBU1NFUlQobV9wb3NpdGlv
biA8PSBtX3Jlc3VsdC5tX3N0cmluZy5sZW5ndGgoKSAtIG1fbGVuZ3RoKTsKKyAgICByZXR1cm4g
bV9yZXN1bHQubV9zdHJpbmcuc3Vic3RyaW5nKG1fcG9zaXRpb24sIG1fbGVuZ3RoKTsKK30KKwor
aW5saW5lIGJvb2wgU3RyaW5nVmlldzo6U3BsaXRSZXN1bHQ6Okl0ZXJhdG9yOjpvcGVyYXRvcj09
KGNvbnN0IEl0ZXJhdG9yJiBvdGhlcikgY29uc3QKK3sKKyAgICBBU1NFUlQoJm1fcmVzdWx0ID09
ICZvdGhlci5tX3Jlc3VsdCk7CisgICAgQVNTRVJUKG1fbGVuZ3RoIDw9IG1fcmVzdWx0Lm1fc3Ry
aW5nLmxlbmd0aCgpKTsKKyAgICBBU1NFUlQobV9wb3NpdGlvbiA8PSBtX3Jlc3VsdC5tX3N0cmlu
Zy5sZW5ndGgoKSAtIG1fbGVuZ3RoKTsKKyAgICBBU1NFUlQob3RoZXIubV9sZW5ndGggPD0gb3Ro
ZXIubV9yZXN1bHQubV9zdHJpbmcubGVuZ3RoKCkpOworICAgIEFTU0VSVChvdGhlci5tX3Bvc2l0
aW9uIDw9IG90aGVyLm1fcmVzdWx0Lm1fc3RyaW5nLmxlbmd0aCgpIC0gb3RoZXIubV9sZW5ndGgp
OworICAgIHJldHVybiBtX3Bvc2l0aW9uID09IG90aGVyLm1fcG9zaXRpb247Cit9CisKK2lubGlu
ZSBib29sIFN0cmluZ1ZpZXc6OlNwbGl0UmVzdWx0OjpJdGVyYXRvcjo6b3BlcmF0b3IhPShjb25z
dCBJdGVyYXRvciYgb3RoZXIpIGNvbnN0Cit7CisgICAgcmV0dXJuICEoKnRoaXMgPT0gb3RoZXIp
OworfQorCiB0ZW1wbGF0ZTx1bnNpZ25lZCBsZW5ndGg+IGlubGluZSBib29sIGVxdWFsTGV0dGVy
c0lnbm9yaW5nQVNDSUlDYXNlKFN0cmluZ1ZpZXcgc3RyaW5nLCBjb25zdCBjaGFyICgmbG93ZXJj
YXNlTGV0dGVycylbbGVuZ3RoXSkKIHsKICAgICByZXR1cm4gZXF1YWxMZXR0ZXJzSWdub3JpbmdB
U0NJSUNhc2VDb21tb24oc3RyaW5nLCBsb3dlcmNhc2VMZXR0ZXJzKTsKZGlmZiAtLWdpdCBhL1Nv
dXJjZS9XZWJDb3JlL3BsYXRmb3JtL1VSTFBhcnNlci5jcHAgYi9Tb3VyY2UvV2ViQ29yZS9wbGF0
Zm9ybS9VUkxQYXJzZXIuY3BwCmluZGV4IDM2NTkzODgzZmU2OTQwMjIwNTY0MzIyNjU5YzE4NjJl
OTFhOWQwNTEuLmIzMWZlZjgxZDI5Nzk3MDhjZmJlNjI4NmI4ZDYyNjlmNGYxYjg2ZDAgMTAwNjQ0
Ci0tLSBhL1NvdXJjZS9XZWJDb3JlL3BsYXRmb3JtL1VSTFBhcnNlci5jcHAKKysrIGIvU291cmNl
L1dlYkNvcmUvcGxhdGZvcm0vVVJMUGFyc2VyLmNwcApAQCAtMjcwNSwxMCArMjcwNSw4IEBAIHN0
ZDo6b3B0aW9uYWw8U3RyaW5nPiBVUkxQYXJzZXI6OmZvcm1VUkxEZWNvZGUoU3RyaW5nVmlldyBp
bnB1dCkKIAogYXV0byBVUkxQYXJzZXI6OnBhcnNlVVJMRW5jb2RlZEZvcm0oU3RyaW5nVmlldyBp
bnB1dCkgLT4gVVJMRW5jb2RlZEZvcm0KIHsKLSAgICBWZWN0b3I8U3RyaW5nVmlldz4gc2VxdWVu
Y2VzID0gaW5wdXQuc3BsaXQoJyYnKTsKLQogICAgIFVSTEVuY29kZWRGb3JtIG91dHB1dDsKLSAg
ICBmb3IgKGF1dG8mIGJ5dGVzIDogc2VxdWVuY2VzKSB7CisgICAgZm9yIChTdHJpbmdWaWV3IGJ5
dGVzIDogaW5wdXQuc3BsaXQoJyYnKSkgewogICAgICAgICBhdXRvIHZhbHVlU3RhcnQgPSBieXRl
cy5maW5kKCc9Jyk7CiAgICAgICAgIGlmICh2YWx1ZVN0YXJ0ID09IG5vdEZvdW5kKSB7CiAgICAg
ICAgICAgICBpZiAoYXV0byBuYW1lID0gZm9ybVVSTERlY29kZShieXRlcykpCmRpZmYgLS1naXQg
YS9Ub29scy9DaGFuZ2VMb2cgYi9Ub29scy9DaGFuZ2VMb2cKaW5kZXggYzFlOGM1ZDE5OThiYWNi
OWY5MjgxMGE4NzUwNDc5Njc2OWMzNWZkNC4uZmIzMWNmMDFhNDdjNjJiOTIxMTcxY2RiMGU3MGE0
ODA3ZmQ0ZDQ2ZSAxMDA2NDQKLS0tIGEvVG9vbHMvQ2hhbmdlTG9nCisrKyBiL1Rvb2xzL0NoYW5n
ZUxvZwpAQCAtMSwzICsxLDIzIEBACisyMDE3LTAxLTE3ICBEYW5pZWwgQmF0ZXMgIDxkYWJhdGVz
QGFwcGxlLmNvbT4KKworICAgICAgICBTdHJpbmdWaWV3LnNwbGl0KCkgc2hvdWxkIHVzZSBhbiBp
dGVyYXRvciBkZXNpZ24gcGF0dGVybiBpbnN0ZWFkIG9mIGFsbG9jYXRpbmcgYSBWZWN0b3IKKyAg
ICAgICAgaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE2MzIyNQorCisg
ICAgICAgIFJldmlld2VkIGJ5IE5PQk9EWSAoT09QUyEpLgorCisgICAgICAgIEFkZCB1bml0IHRl
c3RzIGZvciBTdHJpbmdWaWV3LnNwbGl0KCkuCisKKyAgICAgICAgKiBUZXN0V2ViS2l0QVBJL1Rl
c3RzL1dURi9TdHJpbmdWaWV3LmNwcDoKKyAgICAgICAgKFRlc3RXZWJLaXRBUEk6OnN0cmluZ1Zp
ZXdGcm9tTGl0ZXJhbCk6IE1vdmVkIHRvIHRoZSB0b3Agb2YgdGhlIGZpbGUgc28gdGhhdCBpdCBj
YW4gYmUKKyAgICAgICAgdXNlZCBpbiB0aGUgU3RyaW5nVmlldy5zcGxpdCgpIHVuaXQgdGVzdHMu
CisgICAgICAgIChUZXN0V2ViS2l0QVBJOjpzdHJpbmdWaWV3RnJvbVVURjgpOiBEaXR0by4KKyAg
ICAgICAgKFRlc3RXZWJLaXRBUEk6OnZlY3RvckZyb21TcGxpdFJlc3VsdCk6IENvbnZlbmllbmNl
IGZ1bmN0aW9uIHRvIGNvbnZlcnQgYSBTdHJpbmdWaWV3OjpTcGxpdFJlc3VsdAorICAgICAgICBv
YmplY3QgdG8gYSBWZWN0b3Igb2YgU3RyaW5nIG9iamVjdHMuCisgICAgICAgIChUZXN0V2ViS2l0
QVBJOjpURVNUKTogQWRkZWQgdGhlIGZvbGxvd2luZyB0ZXN0czoKKyAgICAgICAgICAgIC0gV1RG
LlN0cmluZ1ZpZXdTcGxpdEVtcHR5QW5kTnVsbFN0cmluZ3MKKyAgICAgICAgICAgIC0gV1RGLlN0
cmluZ1ZpZXdTcGxpdEJhc2ljCisgICAgICAgICAgICAtIFdURi5TdHJpbmdWaWV3U3BsaXRXaXRo
Q29uc2VjdXRpdmVTZXBhcmF0b3JzCisKIDIwMTctMDEtMTcgIEpvbmF0aGFuIEJlZGFyZCAgPGpi
ZWRhcmRAYXBwbGUuY29tPgogCiAgICAgICAgICd3ZWJraXQtcGF0Y2ggcG9zdCcgbm8gbG9uZ2Vy
IHdvcmtzIHdpdGggbW92ZWQvY29waWVkIGZpbGVzCmRpZmYgLS1naXQgYS9Ub29scy9UZXN0V2Vi
S2l0QVBJL1Rlc3RzL1dURi9TdHJpbmdWaWV3LmNwcCBiL1Rvb2xzL1Rlc3RXZWJLaXRBUEkvVGVz
dHMvV1RGL1N0cmluZ1ZpZXcuY3BwCmluZGV4IDM0NTAzZjQ4Yjk1NjZkYjllM2I5NTg5N2I0ZDI0
ZmFkYmQ3NmI4MmYuLjkzNTkyODM0YTliZTg4NjhhYzEwZDU0YzBlMTVjMGQzNjUwZTI0ODggMTAw
NjQ0Ci0tLSBhL1Rvb2xzL1Rlc3RXZWJLaXRBUEkvVGVzdHMvV1RGL1N0cmluZ1ZpZXcuY3BwCisr
KyBiL1Rvb2xzL1Rlc3RXZWJLaXRBUEkvVGVzdHMvV1RGL1N0cmluZ1ZpZXcuY3BwCkBAIC0zMCw2
ICszMCwxNyBAQAogCiBuYW1lc3BhY2UgVGVzdFdlYktpdEFQSSB7CiAKK1N0cmluZ1ZpZXcgc3Ry
aW5nVmlld0Zyb21MaXRlcmFsKGNvbnN0IGNoYXIqIGNoYXJhY3RlcnMpCit7CisgICAgcmV0dXJu
IFN0cmluZ1ZpZXcocmVpbnRlcnByZXRfY2FzdDxjb25zdCBMQ2hhcio+KGNoYXJhY3RlcnMpLCBz
dHJsZW4oY2hhcmFjdGVycykpOworfQorCitTdHJpbmdWaWV3IHN0cmluZ1ZpZXdGcm9tVVRGOChT
dHJpbmcgJnJlZiwgY29uc3QgY2hhciogY2hhcmFjdGVycykKK3sKKyAgICByZWYgPSBTdHJpbmc6
OmZyb21VVEY4KGNoYXJhY3RlcnMpOworICAgIHJldHVybiByZWY7Cit9CisKIFRFU1QoV1RGLCBT
dHJpbmdWaWV3RW1wdHlWc051bGwpCiB7CiAgICAgU3RyaW5nVmlldyBudWxsVmlldzsKQEAgLTIx
NCw2ICsyMjUsNzkgQEAgVEVTVChXVEYsIFN0cmluZ1ZpZXdJdGVyYXRvcnMpCiAgICAgICAgIFN0
cmluZ1ZpZXcoYi5jaGFyYWN0ZXJzMTYoKSArIDMsIDMpfSkpOwogfQogCitzdGF0aWMgVmVjdG9y
PFN0cmluZz4gdmVjdG9yRnJvbVNwbGl0UmVzdWx0KGNvbnN0IFN0cmluZ1ZpZXc6OlNwbGl0UmVz
dWx0JiBzdWJzdHJpbmdzKQoreworICAgIFZlY3RvcjxTdHJpbmc+IHJlc3VsdDsKKyAgICBmb3Ig
KFN0cmluZ1ZpZXcgc3Vic3RyaW5nIDogc3Vic3RyaW5ncykKKyAgICAgICAgcmVzdWx0LmFwcGVu
ZChzdWJzdHJpbmcudG9TdHJpbmcoKSk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworVEVTVChX
VEYsIFN0cmluZ1ZpZXdTcGxpdEVtcHR5QW5kTnVsbFN0cmluZ3MpCit7CisgICAgU3RyaW5nVmll
dyBhID0gZW1wdHlTdHJpbmcoKTsKKyAgICBhdXRvIHNwbGl0UmVzdWx0ID0gYS5zcGxpdCgnYicp
OworICAgIEVYUEVDVF9UUlVFKHNwbGl0UmVzdWx0LmJlZ2luKCkgPT0gc3BsaXRSZXN1bHQuZW5k
KCkpOworCisgICAgYSA9IHsgU3RyaW5nIHsgfSB9OworICAgIHNwbGl0UmVzdWx0ID0gYS5zcGxp
dCgnYicpOworICAgIEVYUEVDVF9UUlVFKHNwbGl0UmVzdWx0LmJlZ2luKCkgPT0gc3BsaXRSZXN1
bHQuZW5kKCkpOworCisgICAgYSA9IHsgfTsKKyAgICBzcGxpdFJlc3VsdCA9IGEuc3BsaXQoJ2In
KTsKKyAgICBFWFBFQ1RfVFJVRShzcGxpdFJlc3VsdC5iZWdpbigpID09IHNwbGl0UmVzdWx0LmVu
ZCgpKTsKK30KKworVEVTVChXVEYsIFN0cmluZ1ZpZXdTcGxpdEJhc2ljKQoreworICAgIFN0cmlu
ZyByZWZlcmVuY2VIb2xkZXI7CisgICAgU3RyaW5nVmlldyBhID0gc3RyaW5nVmlld0Zyb21VVEY4
KHJlZmVyZW5jZUhvbGRlciwgIlRoaXMgaXMgYSBzZW50ZW5jZS4iKTsKKworICAgIC8vIFNpbXBs
ZQorICAgIFZlY3RvcjxTdHJpbmc+IGFjdHVhbCA9IHZlY3RvckZyb21TcGxpdFJlc3VsdChhLnNw
bGl0KCdUJykpOworICAgIFZlY3RvcjxTdHJpbmc+IGV4cGVjdGVkKHsgImhpcyBpcyBhIHNlbnRl
bmNlLiIgfSk7CisgICAgQVNTRVJUX0VRKGV4cGVjdGVkLnNpemUoKSwgYWN0dWFsLnNpemUoKSk7
CisgICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBhY3R1YWwuc2l6ZSgpOyArK2kpCisgICAgICAg
IEVYUEVDVF9TVFJFUShleHBlY3RlZFtpXS51dGY4KCkuZGF0YSgpLCBhY3R1YWxbaV0udXRmOCgp
LmRhdGEoKSkgPDwgIlZlY3RvcnMgZGlmZmVyIGF0IGluZGV4ICIgPDwgaTsKKworICAgIGFjdHVh
bCA9IHZlY3RvckZyb21TcGxpdFJlc3VsdChhLnNwbGl0KCcuJykpOworICAgIGV4cGVjdGVkID0g
eyAiVGhpcyBpcyBhIHNlbnRlbmNlIiB9OworICAgIEFTU0VSVF9FUShleHBlY3RlZC5zaXplKCks
IGFjdHVhbC5zaXplKCkpOworICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgYWN0dWFsLnNpemUo
KTsgKytpKQorICAgICAgICBFWFBFQ1RfU1RSRVEoZXhwZWN0ZWRbaV0udXRmOCgpLmRhdGEoKSwg
YWN0dWFsW2ldLnV0ZjgoKS5kYXRhKCkpIDw8ICJWZWN0b3JzIGRpZmZlciBhdCBpbmRleCAiIDw8
IGk7CisKKyAgICBhY3R1YWwgPSB2ZWN0b3JGcm9tU3BsaXRSZXN1bHQoYS5zcGxpdCgnYScpKTsK
KyAgICBleHBlY3RlZCA9IHsgIlRoaXMgaXMgIiwgIiBzZW50ZW5jZS4iIH07CisgICAgQVNTRVJU
X0VRKGV4cGVjdGVkLnNpemUoKSwgYWN0dWFsLnNpemUoKSk7CisgICAgZm9yIChzaXplX3QgaSA9
IDA7IGkgPCBhY3R1YWwuc2l6ZSgpOyArK2kpCisgICAgICAgIEVYUEVDVF9TVFJFUShleHBlY3Rl
ZFtpXS51dGY4KCkuZGF0YSgpLCBhY3R1YWxbaV0udXRmOCgpLmRhdGEoKSkgPDwgIlZlY3RvcnMg
ZGlmZmVyIGF0IGluZGV4ICIgPDwgaTsKKworICAgIGFjdHVhbCA9IHZlY3RvckZyb21TcGxpdFJl
c3VsdChhLnNwbGl0KCcgJykpOworICAgIGV4cGVjdGVkID0geyAiVGhpcyIsICJpcyIsICJhIiwg
InNlbnRlbmNlLiIgfTsKKyAgICBBU1NFUlRfRVEoZXhwZWN0ZWQuc2l6ZSgpLCBhY3R1YWwuc2l6
ZSgpKTsKKyAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGFjdHVhbC5zaXplKCk7ICsraSkKKyAg
ICAgICAgRVhQRUNUX1NUUkVRKGV4cGVjdGVkW2ldLnV0ZjgoKS5kYXRhKCksIGFjdHVhbFtpXS51
dGY4KCkuZGF0YSgpKSA8PCAiVmVjdG9ycyBkaWZmZXIgYXQgaW5kZXggIiA8PCBpOworCisgICAg
Ly8gTm9uLWV4aXN0ZW50IHNlcGFyYXRvcgorICAgIGFjdHVhbCA9IHZlY3RvckZyb21TcGxpdFJl
c3VsdChhLnNwbGl0KCd6JykpOworICAgIGV4cGVjdGVkID0geyAiVGhpcyBpcyBhIHNlbnRlbmNl
LiIgfTsKKyAgICBBU1NFUlRfRVEoZXhwZWN0ZWQuc2l6ZSgpLCBhY3R1YWwuc2l6ZSgpKTsKKyAg
ICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGFjdHVhbC5zaXplKCk7ICsraSkKKyAgICAgICAgRVhQ
RUNUX1NUUkVRKGV4cGVjdGVkW2ldLnV0ZjgoKS5kYXRhKCksIGFjdHVhbFtpXS51dGY4KCkuZGF0
YSgpKSA8PCAiVmVjdG9ycyBkaWZmZXIgYXQgaW5kZXggIiA8PCBpOworfQorCitURVNUKFdURiwg
U3RyaW5nVmlld1NwbGl0V2l0aENvbnNlY3V0aXZlU2VwYXJhdG9ycykKK3sKKyAgICBTdHJpbmcg
cmVmZXJlbmNlSG9sZGVyOworICAgIFN0cmluZ1ZpZXcgYSA9IHN0cmluZ1ZpZXdGcm9tVVRGOChy
ZWZlcmVuY2VIb2xkZXIsICJUaGlzICAgICBpcyAgYSAgICAgICBzZW50ZW5jZS4iKTsKKworICAg
IFZlY3RvcjxTdHJpbmc+IGFjdHVhbCA9IHZlY3RvckZyb21TcGxpdFJlc3VsdChhLnNwbGl0KCcg
JykpOworICAgIFZlY3RvcjxTdHJpbmc+IGV4cGVjdGVkKHsgIlRoaXMiLCAiaXMiLCAiYSIsICJz
ZW50ZW5jZS4iIH0pOworICAgIEFTU0VSVF9FUShleHBlY3RlZC5zaXplKCksIGFjdHVhbC5zaXpl
KCkpOworICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgYWN0dWFsLnNpemUoKTsgKytpKQorICAg
ICAgICBFWFBFQ1RfU1RSRVEoZXhwZWN0ZWRbaV0udXRmOCgpLmRhdGEoKSwgYWN0dWFsW2ldLnV0
ZjgoKS5kYXRhKCkpIDw8ICJWZWN0b3JzIGRpZmZlciBhdCBpbmRleCAiIDw8IGk7Cit9CisKIFRF
U1QoV1RGLCBTdHJpbmdWaWV3RXF1YWxJZ25vcmluZ0FTQ0lJQ2FzZUJhc2ljKQogewogICAgIFJl
ZlB0cjxTdHJpbmdJbXBsPiBhID0gU3RyaW5nSW1wbDo6Y3JlYXRlRnJvbUxpdGVyYWwoImFCY0Rl
RkciKTsKQEAgLTMwNCwxNyArMzg4LDYgQEAgVEVTVChXVEYsIFN0cmluZ1ZpZXdFcXVhbElnbm9y
aW5nQVNDSUlDYXNlV2l0aExhdGluMUNoYXJhY3RlcnMpCiAgICAgQVNTRVJUX0ZBTFNFKGVxdWFs
SWdub3JpbmdBU0NJSUNhc2Uoc3RyaW5nVmlld0QsIGUpKTsKIH0KIAotU3RyaW5nVmlldyBzdHJp
bmdWaWV3RnJvbUxpdGVyYWwoY29uc3QgY2hhciogY2hhcmFjdGVycykKLXsKLSAgICByZXR1cm4g
U3RyaW5nVmlldyhyZWludGVycHJldF9jYXN0PGNvbnN0IExDaGFyKj4oY2hhcmFjdGVycyksIHN0
cmxlbihjaGFyYWN0ZXJzKSk7Ci19Ci0KLVN0cmluZ1ZpZXcgc3RyaW5nVmlld0Zyb21VVEY4KFN0
cmluZyAmcmVmLCBjb25zdCBjaGFyKiBjaGFyYWN0ZXJzKQotewotICAgIHJlZiA9IFN0cmluZzo6
ZnJvbVVURjgoY2hhcmFjdGVycyk7Ci0gICAgcmV0dXJuIHJlZjsKLX0KLQogVEVTVChXVEYsIFN0
cmluZ1ZpZXdGaW5kSWdub3JpbmdBU0NJSUNhc2VCYXNpYykKIHsKICAgICBTdHJpbmcgcmVmZXJl
bmNlQUhvbGRlcjsK
</data>
<flag name="review"
          id="321114"
          type_id="1"
          status="+"
          setter="darin"
    />
          </attachment>
      

    </bug>

</bugzilla>