<?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>24872</bug_id>
          
          <creation_ts>2009-03-26 19:46:19 -0700</creation_ts>
          <short_desc>Pasting from one bulleted list to another adds an extra level of outdent</short_desc>
          <delta_ts>2010-02-05 01:23:21 -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>HTML Editing</component>
          <version>528+ (Nightly build)</version>
          <rep_platform>PC</rep_platform>
          <op_sys>OS X 10.5</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc>http://www.mozilla.org/editor/midasdemo/</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="Annie Sullivan">sullivan</reporter>
          <assigned_to name="Nobody">webkit-unassigned</assigned_to>
          <cc>enrica</cc>
    
    <cc>eric</cc>
    
    <cc>jparent</cc>
    
    <cc>michaelthomas</cc>
    
    <cc>tony</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>115480</commentid>
    <comment_count>0</comment_count>
    <who name="Annie Sullivan">sullivan</who>
    <bug_when>2009-03-26 19:46:19 -0700</bug_when>
    <thetext>Steps to reproduce:
Create a bulleted list:
* a
* b
* c
* 

Select &quot;b&quot; and &quot;c&quot; and copy. Place cursor at start of empty list item and paste.

Actual result:
New indented list is created under blank list item:
* a
* b
* c
* 
  o b
  o c

Expected result:
List pastes at same indentation level:
* a
* b
* c
* b
* c</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>187254</commentid>
    <comment_count>1</comment_count>
      <attachid>47992</attachid>
    <who name="Tony Chang">tony</who>
    <bug_when>2010-02-02 21:15:02 -0800</bug_when>
    <thetext>Created attachment 47992
Patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>187257</commentid>
    <comment_count>2</comment_count>
    <who name="Tony Chang">tony</who>
    <bug_when>2010-02-02 21:17:04 -0800</bug_when>
    <thetext>(In reply to comment #1)
&gt; Created an attachment (id=47992) [details]
&gt; Patch

This handles copy/paste of list items at any of indent level and seems to match Firefox and IE&apos;s behavior in this regard.  There&apos;s still some work to be done to handle the split list item case (if you paste a list into the middle of text on a list item), but I think it&apos;s better to do one thing at a time.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>187434</commentid>
    <comment_count>3</comment_count>
      <attachid>47992</attachid>
    <who name="Enrica Casucci">enrica</who>
    <bug_when>2010-02-03 10:38:24 -0800</bug_when>
    <thetext>Comment on attachment 47992
Patch

&gt; diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
&gt; index 6b5ab6f..d54a47e 100644
&gt; --- a/LayoutTests/ChangeLog
&gt; +++ b/LayoutTests/ChangeLog
&gt; @@ -1,3 +1,14 @@
&gt; +2010-02-02  Tony Chang  &lt;tony@chromium.org&gt;
&gt; +
&gt; +        Reviewed by NOBODY (OOPS!).
&gt; +
&gt; +        https://bugs.webkit.org/show_bug.cgi?id=24872
&gt; +        Add a test to make sure copying from a list and pasting into a list
&gt; +        keeps the list at the same indention level rather than nesting.
&gt; +
&gt; +        * editing/pasteboard/paste-list-002-expected.txt: Added.
&gt; +        * editing/pasteboard/paste-list-002.html: Added.
&gt; +
&gt;  2010-02-02  Eric Seidel  &lt;eric@webkit.org&gt;
&gt;  
&gt;          Reviewed by Gustavo Noronha Silva.
&gt; diff --git a/LayoutTests/editing/pasteboard/paste-list-002-expected.txt b/LayoutTests/editing/pasteboard/paste-list-002-expected.txt
&gt; new file mode 100644
&gt; index 0000000..5ff1cb6
&gt; --- /dev/null
&gt; +++ b/LayoutTests/editing/pasteboard/paste-list-002-expected.txt
&gt; @@ -0,0 +1,13 @@
&gt; +Copy/pasting list items in a list. This test should be run with DRT for pasteboard access.
&gt; +
&gt; +PASS: &lt;li&gt;alpha&lt;/li&gt;&lt;ul&gt;&lt;li&gt;beta&lt;/li&gt;&lt;li&gt;gamma&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;beta&lt;/li&gt;&lt;li&gt;gamma&lt;/li&gt;&lt;li id=&quot;delta&quot;&gt;delta&lt;/li&gt;&lt;li&gt;beta&lt;/li&gt;&lt;li&gt;gamma&lt;/li&gt;&lt;li&gt;&lt;/li&gt;
&gt; +
&gt; +alpha
&gt; +beta
&gt; +gamma
&gt; +beta
&gt; +gamma
&gt; +delta
&gt; +beta
&gt; +gamma
&gt; +
&gt; diff --git a/LayoutTests/editing/pasteboard/paste-list-002.html b/LayoutTests/editing/pasteboard/paste-list-002.html
&gt; new file mode 100644
&gt; index 0000000..2fae410
&gt; --- /dev/null
&gt; +++ b/LayoutTests/editing/pasteboard/paste-list-002.html
&gt; @@ -0,0 +1,63 @@
&gt; +&lt;html&gt; 
&gt; +&lt;script src=../editing.js language=&quot;JavaScript&quot; type=&quot;text/JavaScript&quot; &gt;&lt;/script&gt;
&gt; +&lt;script&gt;
&gt; +
&gt; +function editingTest() {
&gt; +    // Select &quot;beta&quot; and &quot;gamma&quot;.
&gt; +    moveSelectionForwardByLineCommand();
&gt; +    for (i = 0; i &lt; 2; i++)
&gt; +        extendSelectionForwardByLineCommand();
&gt; +    copyCommand();
&gt; +
&gt; +    // Paste with the cursor right before &quot;delta&quot;.
&gt; +    moveSelectionForwardByLineCommand();
&gt; +    pasteCommand();
&gt; +
&gt; +    // Verify that the cursor is in the right place (still before delta).
&gt; +    var selection = window.getSelection();
&gt; +    if (selection.baseNode.parentNode != document.getElementById(&quot;delta&quot;) ||
&gt; +        selection.baseOffset != 0 || !selection.isCollapsed)
&gt; +        throw &quot;Wrong selection position on before paste.&quot;;
&gt; +
&gt; +    // Paste with the cursor at the end of &quot;delta&quot;.
&gt; +    moveSelectionForwardByWordCommand();
&gt; +    pasteCommand();    
&gt; +
&gt; +    // Verify that the cursor is in the right place (new list item after delta).
&gt; +    var selection = window.getSelection();
&gt; +    if (!selection.isCollapsed || selection.baseNode.value != &quot;&quot;)
&gt; +        throw &quot;Wrong selection position on after paste.&quot;;
&gt; +}
&gt; +
&gt; +&lt;/script&gt;
&gt; +&lt;body&gt;
&gt; +&lt;div contentEditable=&quot;true&quot;&gt;
&gt; +&lt;p&gt;Copy/pasting list items in a list.  This test should be run with DRT for pasteboard access.&lt;/p&gt;
&gt; +&lt;p id=&quot;results&quot;&gt;FAIL&lt;/p&gt;
&gt; +&lt;ul id=&quot;test&quot;&gt;
&gt; +    &lt;li&gt;alpha&lt;/li&gt;
&gt; +    &lt;li&gt;beta&lt;/li&gt;
&gt; +    &lt;li&gt;gamma&lt;/li&gt;
&gt; +    &lt;li id=&quot;delta&quot;&gt;delta&lt;/li&gt;
&gt; +&lt;/ul&gt;
&gt; +&lt;/div&gt;
&gt; +
&gt; +&lt;script&gt;
&gt; +if (window.layoutTestController)
&gt; +    layoutTestController.dumpAsText();
&gt; +
&gt; +var elem = document.getElementById(&quot;test&quot;);
&gt; +var selection = window.getSelection();
&gt; +selection.setPosition(elem, 0);
&gt; +editingTest();
&gt; +
&gt; +// Rerun the test but have the source list be indented.
&gt; +document.getElementById(&quot;test&quot;).innerHTML = &quot;&lt;li&gt;alpha&lt;/li&gt;&lt;ul&gt;&lt;li&gt;beta&lt;/li&gt;&lt;li&gt;gamma&lt;/li&gt;&lt;/ul&gt;&lt;li id=&apos;delta&apos;&gt;delta&lt;/li&gt;&quot;;
&gt; +selection.setPosition(elem, 0);
&gt; +editingTest();
&gt; +
&gt; +document.getElementById(&quot;results&quot;).innerText = &quot;PASS: &quot; + document.getElementById(&quot;test&quot;).innerHTML;
&gt; +&lt;/script&gt;
&gt; +
&gt; +&lt;/body&gt;
&gt; +&lt;/html&gt;
&gt; diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
&gt; index 67f5b56..6f365d0 100644
&gt; --- a/WebCore/ChangeLog
&gt; +++ b/WebCore/ChangeLog
&gt; @@ -1,3 +1,30 @@
&gt; +2010-02-02  Tony Chang  &lt;tony@chromium.org&gt;
&gt; +
&gt; +        Reviewed by NOBODY (OOPS!).
&gt; +
&gt; +        https://bugs.webkit.org/show_bug.cgi?id=24872
&gt; +        When pasting a list into another list should not indent another level.
&gt; +        If the cursor is at the beginning of the line, it should insert the
&gt; +        list items before the current list item.  If the cursor is at the end
&gt; +        of the line, it should insert the list items after the current list item.
&gt; +
&gt; +        This matches Firefox and IE and makes the common activity of reordering a list
&gt; +        work as expected.
&gt; +
&gt; +        This also adds a small helper method (isListItem) to htmlediting.h.
&gt; +
&gt; +        Test: editing/pasteboard/paste-list-002.html
&gt; +
&gt; +        * editing/ReplaceSelectionCommand.cpp:
&gt; +        (WebCore::ReplaceSelectionCommand::doApply):
&gt; +        (WebCore::ReplaceSelectionCommand::insertNodeAtAndUpdateNodesInserted):
&gt; +        (WebCore::ReplaceSelectionCommand::insertAsListItems):
&gt; +        * editing/ReplaceSelectionCommand.h:
&gt; +        * editing/htmlediting.cpp:
&gt; +        (WebCore::isListItem):
&gt; +        (WebCore::appendedSublist):
&gt; +        * editing/htmlediting.h:
&gt; +
&gt;  2010-02-02  Steve Falkenburg  &lt;sfalken@apple.com&gt;
&gt;  
&gt;          Reviewed by Darin Adler.
&gt; diff --git a/WebCore/editing/ReplaceSelectionCommand.cpp b/WebCore/editing/ReplaceSelectionCommand.cpp
&gt; index 85a4471..77d69d1 100644
&gt; --- a/WebCore/editing/ReplaceSelectionCommand.cpp
&gt; +++ b/WebCore/editing/ReplaceSelectionCommand.cpp
&gt; @@ -752,9 +752,7 @@ void ReplaceSelectionCommand::doApply()
&gt;      bool startIsInsideMailBlockquote = nearestMailBlockquote(insertionPos.node());
&gt;      
&gt;      if ((selectionStartWasStartOfParagraph &amp;&amp; selectionEndWasEndOfParagraph &amp;&amp; !startIsInsideMailBlockquote) ||
&gt; -        startBlock == currentRoot ||
&gt; -        (startBlock &amp;&amp; startBlock-&gt;renderer() &amp;&amp; startBlock-&gt;renderer()-&gt;isListItem()) ||
&gt; -        selectionIsPlainText)
&gt; +        startBlock == currentRoot || isListItem(startBlock) || selectionIsPlainText)
&gt;          m_preventNesting = false;
&gt;      
&gt;      if (selection.isRange()) {
&gt; @@ -871,7 +869,7 @@ void ReplaceSelectionCommand::doApply()
&gt;      RefPtr&lt;Node&gt; node = refNode-&gt;nextSibling();
&gt;      
&gt;      fragment.removeNode(refNode);
&gt; -    insertNodeAtAndUpdateNodesInserted(refNode, insertionPos);
&gt; +    refNode = insertNodeAtAndUpdateNodesInserted(refNode, insertionPos);
&gt;  
&gt;      // Mutation events (bug 22634) may have already removed the inserted content
&gt;      if (!refNode-&gt;inDocument())
&gt; @@ -960,9 +958,15 @@ void ReplaceSelectionCommand::doApply()
&gt;          if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedContent) || next.isNull()) {
&gt;              if (!isStartOfParagraph(endOfInsertedContent)) {
&gt;                  setEndingSelection(endOfInsertedContent);
&gt; -                // Use a default paragraph element (a plain div) for the empty paragraph, using the last paragraph
&gt; -                // block&apos;s style seems to annoy users.
&gt; -                insertParagraphSeparator(true);
&gt; +                Node* enclosingNode = enclosingBlock(endOfInsertedContent.deepEquivalent().node());
&gt; +                if (isListItem(enclosingNode)) {
&gt; +                    RefPtr&lt;Node&gt; newListItem = createListItemElement(document());
&gt; +                    insertNodeAfter(newListItem, enclosingNode);
&gt; +                    setEndingSelection(VisiblePosition(Position(newListItem, 0)));
&gt; +                } else
&gt; +                    // Use a default paragraph element (a plain div) for the empty paragraph, using the last paragraph
&gt; +                    // block&apos;s style seems to annoy users.
&gt; +                    insertParagraphSeparator(true);
&gt;  
&gt;                  // Select up to the paragraph separator that was added.
&gt;                  lastPositionToSelect = endingSelection().visibleStart().deepEquivalent();
&gt; @@ -1097,11 +1101,16 @@ void ReplaceSelectionCommand::insertNodeAfterAndUpdateNodesInserted(PassRefPtr&lt;N
&gt;      updateNodesInserted(nodeToUpdate);
&gt;  }
&gt;  
&gt; -void ReplaceSelectionCommand::insertNodeAtAndUpdateNodesInserted(PassRefPtr&lt;Node&gt; insertChild, const Position&amp; p)
&gt; +Node* ReplaceSelectionCommand::insertNodeAtAndUpdateNodesInserted(PassRefPtr&lt;Node&gt; insertChild, const Position&amp; p)
&gt;  {
&gt;      Node* nodeToUpdate = insertChild.get(); // insertChild will be cleared when passed
&gt; +    Node* blockStart = enclosingBlock(p.node());
&gt; +    if (isListElement(insertChild.get()) &amp;&amp; blockStart-&gt;renderer()-&gt;isListItem())
&gt; +        return insertAsListItems(insertChild, blockStart, p);
&gt; +
&gt;      insertNodeAt(insertChild, p);
&gt;      updateNodesInserted(nodeToUpdate);
&gt; +    return nodeToUpdate;
&gt;  }
&gt;  
&gt;  void ReplaceSelectionCommand::insertNodeBeforeAndUpdateNodesInserted(PassRefPtr&lt;Node&gt; insertChild, Node* refChild)
&gt; @@ -1111,6 +1120,39 @@ void ReplaceSelectionCommand::insertNodeBeforeAndUpdateNodesInserted(PassRefPtr&lt;
&gt;      updateNodesInserted(nodeToUpdate);
&gt;  }
&gt;  
&gt; +// If the user is inserting a list into an existing list, instead of nesting the list,
&gt; +// we put the list items into the existing list.
&gt; +Node* ReplaceSelectionCommand::insertAsListItems(PassRefPtr&lt;Node&gt; listElement, Node* insertionNode, const Position&amp; p)
&gt; +{
&gt; +    while (listElement-&gt;hasChildNodes() &amp;&amp; isListElement(listElement-&gt;firstChild()) &amp;&amp; listElement-&gt;childNodeCount() == 1)
&gt; +        listElement = listElement-&gt;firstChild();
&gt; +
&gt; +    bool isStart = isStartOfParagraph(p);
&gt; +    bool isEnd = isEndOfParagraph(p);
&gt; +
&gt; +    Node* lastNode = insertionNode;
&gt; +    while (RefPtr&lt;Node&gt; listItem = listElement-&gt;firstChild()) {
&gt; +        ExceptionCode ec = 0;
&gt; +        listElement-&gt;removeChild(listItem.get(), ec);
&gt; +        ASSERT(!ec);
&gt; +        if (isStart)
&gt; +            insertNodeBefore(listItem, lastNode);
&gt; +        else if (isEnd) {
&gt; +            insertNodeAfter(listItem, lastNode);
&gt; +            lastNode = listItem.get();
&gt; +        } else {
&gt; +            // FIXME: If we&apos;re in the middle of a list item, we should split it into two separate
&gt; +            // list items and insert these nodes between them.  For now, just append the nodes.
&gt; +            insertNodeAfter(listItem, lastNode);
&gt; +            lastNode = listItem.get();
&gt; +        }
&gt; +    }
&gt; +    if (isStart)
&gt; +        lastNode = lastNode-&gt;previousSibling();
&gt; +    updateNodesInserted(lastNode);
&gt; +    return lastNode;
&gt; +}
&gt; +
&gt;  void ReplaceSelectionCommand::updateNodesInserted(Node *node)
&gt;  {
&gt;      if (!node)
&gt; diff --git a/WebCore/editing/ReplaceSelectionCommand.h b/WebCore/editing/ReplaceSelectionCommand.h
&gt; index 1cb93c3..b7ff857 100644
&gt; --- a/WebCore/editing/ReplaceSelectionCommand.h
&gt; +++ b/WebCore/editing/ReplaceSelectionCommand.h
&gt; @@ -52,8 +52,9 @@ private:
&gt;      void completeHTMLReplacement(const Position&amp; lastPositionToSelect);
&gt;  
&gt;      void insertNodeAfterAndUpdateNodesInserted(PassRefPtr&lt;Node&gt; insertChild, Node* refChild);
&gt; -    void insertNodeAtAndUpdateNodesInserted(PassRefPtr&lt;Node&gt;, const Position&amp;);
&gt; +    Node* insertNodeAtAndUpdateNodesInserted(PassRefPtr&lt;Node&gt;, const Position&amp;);
&gt;      void insertNodeBeforeAndUpdateNodesInserted(PassRefPtr&lt;Node&gt; insertChild, Node* refChild);
&gt; +    Node* insertAsListItems(PassRefPtr&lt;Node&gt;, Node* insertionNode, const Position&amp;);
&gt;  
&gt;      void updateNodesInserted(Node*);
&gt;      bool shouldRemoveEndBR(Node*, const VisiblePosition&amp;);
&gt; diff --git a/WebCore/editing/htmlediting.cpp b/WebCore/editing/htmlediting.cpp
&gt; index b58dff3..4981f63 100644
&gt; --- a/WebCore/editing/htmlediting.cpp
&gt; +++ b/WebCore/editing/htmlediting.cpp
&gt; @@ -658,6 +658,11 @@ bool isListElement(Node *n)
&gt;      return (n &amp;&amp; (n-&gt;hasTagName(ulTag) || n-&gt;hasTagName(olTag) || n-&gt;hasTagName(dlTag)));
&gt;  }
&gt;  
&gt; +bool isListItem(Node *n)
&gt; +{
&gt; +    return n &amp;&amp; n-&gt;renderer() &amp;&amp; n-&gt;renderer()-&gt;isListItem();
&gt; +}
&gt; +
&gt;  Node* enclosingNodeWithTag(const Position&amp; p, const QualifiedName&amp; tagName)
&gt;  {
&gt;      if (p.isNull())
&gt; @@ -779,7 +784,7 @@ static Node* appendedSublist(Node* listItem)
&gt;      for (Node* n = listItem-&gt;nextSibling(); n; n = n-&gt;nextSibling()) {
&gt;          if (isListElement(n))
&gt;              return static_cast&lt;HTMLElement*&gt;(n);
&gt; -        if (n-&gt;renderer() &amp;&amp; n-&gt;renderer()-&gt;isListItem())
&gt; +        if (isListItem(listItem))
&gt;              return 0;
&gt;      }
&gt;      
&gt; diff --git a/WebCore/editing/htmlediting.h b/WebCore/editing/htmlediting.h
&gt; index c5a44ac..ef3db35 100644
&gt; --- a/WebCore/editing/htmlediting.h
&gt; +++ b/WebCore/editing/htmlediting.h
&gt; @@ -90,6 +90,7 @@ bool isTableCell(const Node*);
&gt;  bool isEmptyTableCell(const Node*);
&gt;  bool isTableStructureNode(const Node*);
&gt;  bool isListElement(Node*);
&gt; +bool isListItem(Node*);
&gt;  bool isNodeRendered(const Node*);
&gt;  bool isNodeVisiblyContainedWithin(Node*, const Range*);
&gt;  bool isRenderedAsNonInlineTableImageOrHR(const Node*);

The approach looks ok to me. I don&apos;t like very much the fact that you&apos;ve changed insertNodeAndUpdateNodesInserted to add a return value that is used only at the beginning of the loop.
I&apos;d rather see that method stay the same and add another for the specific purpose. I believe it makes it more clear, it is already such a complex piece of code :-).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>187564</commentid>
    <comment_count>4</comment_count>
      <attachid>48083</attachid>
    <who name="Tony Chang">tony</who>
    <bug_when>2010-02-03 17:36:14 -0800</bug_when>
    <thetext>Created attachment 48083
Patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>187566</commentid>
    <comment_count>5</comment_count>
    <who name="Tony Chang">tony</who>
    <bug_when>2010-02-03 17:38:12 -0800</bug_when>
    <thetext>(In reply to comment #3)
&gt; The approach looks ok to me. I don&apos;t like very much the fact that you&apos;ve
&gt; changed insertNodeAndUpdateNodesInserted to add a return value that is used
&gt; only at the beginning of the loop.
&gt; I&apos;d rather see that method stay the same and add another for the specific
&gt; purpose. I believe it makes it more clear, it is already such a complex piece
&gt; of code :-).

Good idea.  I restored insertNodeAtAndUpdateNodesInserted and moved the list handling into doApply().</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>187600</commentid>
    <comment_count>6</comment_count>
      <attachid>48083</attachid>
    <who name="Enrica Casucci">enrica</who>
    <bug_when>2010-02-03 19:26:11 -0800</bug_when>
    <thetext>Comment on attachment 48083
Patch

&gt; diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
&gt; index a660e4b..a6c6fe6 100644
&gt; --- a/LayoutTests/ChangeLog
&gt; +++ b/LayoutTests/ChangeLog
&gt; @@ -1,3 +1,14 @@
&gt; +2010-02-03  Tony Chang  &lt;tony@chromium.org&gt;
&gt; +
&gt; +        Reviewed by NOBODY (OOPS!).
&gt; +
&gt; +        https://bugs.webkit.org/show_bug.cgi?id=24872
&gt; +        Add a test to make sure copying from a list and pasting into a list
&gt; +        keeps the list at the same indention level rather than nesting.
&gt; +
&gt; +        * editing/pasteboard/paste-list-002-expected.txt: Added.
&gt; +        * editing/pasteboard/paste-list-002.html: Added.
&gt; +
&gt;  2010-02-03  Csaba OsztrogonÃ¡c  &lt;ossy@webkit.org&gt;
&gt;  
&gt;          Rubber-stamped by Ariya Hidayat.
&gt; diff --git a/LayoutTests/editing/pasteboard/paste-list-002-expected.txt b/LayoutTests/editing/pasteboard/paste-list-002-expected.txt
&gt; new file mode 100644
&gt; index 0000000..5ff1cb6
&gt; --- /dev/null
&gt; +++ b/LayoutTests/editing/pasteboard/paste-list-002-expected.txt
&gt; @@ -0,0 +1,13 @@
&gt; +Copy/pasting list items in a list. This test should be run with DRT for pasteboard access.
&gt; +
&gt; +PASS: &lt;li&gt;alpha&lt;/li&gt;&lt;ul&gt;&lt;li&gt;beta&lt;/li&gt;&lt;li&gt;gamma&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;beta&lt;/li&gt;&lt;li&gt;gamma&lt;/li&gt;&lt;li id=&quot;delta&quot;&gt;delta&lt;/li&gt;&lt;li&gt;beta&lt;/li&gt;&lt;li&gt;gamma&lt;/li&gt;&lt;li&gt;&lt;/li&gt;
&gt; +
&gt; +alpha
&gt; +beta
&gt; +gamma
&gt; +beta
&gt; +gamma
&gt; +delta
&gt; +beta
&gt; +gamma
&gt; +
&gt; diff --git a/LayoutTests/editing/pasteboard/paste-list-002.html b/LayoutTests/editing/pasteboard/paste-list-002.html
&gt; new file mode 100644
&gt; index 0000000..ff4c97c
&gt; --- /dev/null
&gt; +++ b/LayoutTests/editing/pasteboard/paste-list-002.html
&gt; @@ -0,0 +1,63 @@
&gt; +&lt;html&gt;
&gt; +&lt;script src=../editing.js language=&quot;JavaScript&quot; type=&quot;text/JavaScript&quot; &gt;&lt;/script&gt;
&gt; +&lt;script&gt;
&gt; +
&gt; +function editingTest() {
&gt; +    // Select &quot;beta&quot; and &quot;gamma&quot;.
&gt; +    moveSelectionForwardByLineCommand();
&gt; +    for (i = 0; i &lt; 2; i++)
&gt; +        extendSelectionForwardByLineCommand();
&gt; +    copyCommand();
&gt; +
&gt; +    // Paste with the cursor right before &quot;delta&quot;.
&gt; +    moveSelectionForwardByLineCommand();
&gt; +    pasteCommand();
&gt; +
&gt; +    // Verify that the cursor is in the right place (still before delta).
&gt; +    var selection = window.getSelection();
&gt; +    if (selection.baseNode.parentNode != document.getElementById(&quot;delta&quot;) ||
&gt; +        selection.baseOffset != 0 || !selection.isCollapsed)
&gt; +        throw &quot;Wrong selection position on before paste.&quot;;
&gt; +
&gt; +    // Paste with the cursor at the end of &quot;delta&quot;.
&gt; +    moveSelectionForwardByWordCommand();
&gt; +    pasteCommand();
&gt; +
&gt; +    // Verify that the cursor is in the right place (new list item after delta).
&gt; +    var selection = window.getSelection();
&gt; +    if (!selection.isCollapsed || selection.baseNode.value != &quot;&quot;)
&gt; +        throw &quot;Wrong selection position on after paste.&quot;;
&gt; +}
&gt; +
&gt; +&lt;/script&gt;
&gt; +&lt;body&gt;
&gt; +&lt;div contentEditable=&quot;true&quot;&gt;
&gt; +&lt;p&gt;Copy/pasting list items in a list.  This test should be run with DRT for pasteboard access.&lt;/p&gt;
&gt; +&lt;p id=&quot;results&quot;&gt;FAIL&lt;/p&gt;
&gt; +&lt;ul id=&quot;test&quot;&gt;
&gt; +    &lt;li&gt;alpha&lt;/li&gt;
&gt; +    &lt;li&gt;beta&lt;/li&gt;
&gt; +    &lt;li&gt;gamma&lt;/li&gt;
&gt; +    &lt;li id=&quot;delta&quot;&gt;delta&lt;/li&gt;
&gt; +&lt;/ul&gt;
&gt; +&lt;/div&gt;
&gt; +
&gt; +&lt;script&gt;
&gt; +if (window.layoutTestController)
&gt; +    layoutTestController.dumpAsText();
&gt; +
&gt; +var elem = document.getElementById(&quot;test&quot;);
&gt; +var selection = window.getSelection();
&gt; +selection.setPosition(elem, 0);
&gt; +editingTest();
&gt; +
&gt; +// Rerun the test but have the source list be indented.
&gt; +document.getElementById(&quot;test&quot;).innerHTML = &quot;&lt;li&gt;alpha&lt;/li&gt;&lt;ul&gt;&lt;li&gt;beta&lt;/li&gt;&lt;li&gt;gamma&lt;/li&gt;&lt;/ul&gt;&lt;li id=&apos;delta&apos;&gt;delta&lt;/li&gt;&quot;;
&gt; +selection.setPosition(elem, 0);
&gt; +editingTest();
&gt; +
&gt; +document.getElementById(&quot;results&quot;).innerText = &quot;PASS: &quot; + document.getElementById(&quot;test&quot;).innerHTML;
&gt; +&lt;/script&gt;
&gt; +
&gt; +&lt;/body&gt;
&gt; +&lt;/html&gt;
&gt; diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
&gt; index dc9a30a..0e88eb1 100644
&gt; --- a/WebCore/ChangeLog
&gt; +++ b/WebCore/ChangeLog
&gt; @@ -1,3 +1,29 @@
&gt; +2010-02-03  Tony Chang  &lt;tony@chromium.org&gt;
&gt; +
&gt; +        Reviewed by NOBODY (OOPS!).
&gt; +
&gt; +        https://bugs.webkit.org/show_bug.cgi?id=24872
&gt; +        When pasting a list into another list should not indent another level.
&gt; +        If the cursor is at the beginning of the line, it should insert the
&gt; +        list items before the current list item.  If the cursor is at the end
&gt; +        of the line, it should insert the list items after the current list item.
&gt; +
&gt; +        This matches Firefox and IE and makes the common activity of reordering a list
&gt; +        work as expected.
&gt; +
&gt; +        This also adds a small helper method (isListItem) to htmlediting.h.
&gt; +
&gt; +        Test: editing/pasteboard/paste-list-002.html
&gt; +
&gt; +        * editing/ReplaceSelectionCommand.cpp:
&gt; +        (WebCore::ReplaceSelectionCommand::doApply):
&gt; +        (WebCore::ReplaceSelectionCommand::insertAsListItems):
&gt; +        * editing/ReplaceSelectionCommand.h:
&gt; +        * editing/htmlediting.cpp:
&gt; +        (WebCore::isListItem):
&gt; +        (WebCore::appendedSublist):
&gt; +        * editing/htmlediting.h:
&gt; +
&gt;  2010-02-03  Adele Peterson  &lt;adele@apple.com&gt;
&gt;  
&gt;          Reviewed by Brady Eidson.
&gt; diff --git a/WebCore/editing/ReplaceSelectionCommand.cpp b/WebCore/editing/ReplaceSelectionCommand.cpp
&gt; index 85a4471..f26757e 100644
&gt; --- a/WebCore/editing/ReplaceSelectionCommand.cpp
&gt; +++ b/WebCore/editing/ReplaceSelectionCommand.cpp
&gt; @@ -752,9 +752,7 @@ void ReplaceSelectionCommand::doApply()
&gt;      bool startIsInsideMailBlockquote = nearestMailBlockquote(insertionPos.node());
&gt;      
&gt;      if ((selectionStartWasStartOfParagraph &amp;&amp; selectionEndWasEndOfParagraph &amp;&amp; !startIsInsideMailBlockquote) ||
&gt; -        startBlock == currentRoot ||
&gt; -        (startBlock &amp;&amp; startBlock-&gt;renderer() &amp;&amp; startBlock-&gt;renderer()-&gt;isListItem()) ||
&gt; -        selectionIsPlainText)
&gt; +        startBlock == currentRoot || isListItem(startBlock) || selectionIsPlainText)
&gt;          m_preventNesting = false;
&gt;      
&gt;      if (selection.isRange()) {
&gt; @@ -871,7 +869,12 @@ void ReplaceSelectionCommand::doApply()
&gt;      RefPtr&lt;Node&gt; node = refNode-&gt;nextSibling();
&gt;      
&gt;      fragment.removeNode(refNode);
&gt; -    insertNodeAtAndUpdateNodesInserted(refNode, insertionPos);
&gt; +
&gt; +    Node* blockStart = enclosingBlock(insertionPos.node());
&gt; +    if (isListElement(refNode.get()) &amp;&amp; blockStart-&gt;renderer()-&gt;isListItem())
&gt; +        refNode = insertAsListItems(refNode, blockStart, insertionPos);
&gt; +    else
&gt; +        insertNodeAtAndUpdateNodesInserted(refNode, insertionPos);
&gt;  
&gt;      // Mutation events (bug 22634) may have already removed the inserted content
&gt;      if (!refNode-&gt;inDocument())
&gt; @@ -960,9 +963,15 @@ void ReplaceSelectionCommand::doApply()
&gt;          if (selectionEndWasEndOfParagraph || !isEndOfParagraph(endOfInsertedContent) || next.isNull()) {
&gt;              if (!isStartOfParagraph(endOfInsertedContent)) {
&gt;                  setEndingSelection(endOfInsertedContent);
&gt; -                // Use a default paragraph element (a plain div) for the empty paragraph, using the last paragraph
&gt; -                // block&apos;s style seems to annoy users.
&gt; -                insertParagraphSeparator(true);
&gt; +                Node* enclosingNode = enclosingBlock(endOfInsertedContent.deepEquivalent().node());
&gt; +                if (isListItem(enclosingNode)) {
&gt; +                    RefPtr&lt;Node&gt; newListItem = createListItemElement(document());
&gt; +                    insertNodeAfter(newListItem, enclosingNode);
&gt; +                    setEndingSelection(VisiblePosition(Position(newListItem, 0)));
&gt; +                } else
&gt; +                    // Use a default paragraph element (a plain div) for the empty paragraph, using the last paragraph
&gt; +                    // block&apos;s style seems to annoy users.
&gt; +                    insertParagraphSeparator(true);
&gt;  
&gt;                  // Select up to the paragraph separator that was added.
&gt;                  lastPositionToSelect = endingSelection().visibleStart().deepEquivalent();
&gt; @@ -1111,6 +1120,39 @@ void ReplaceSelectionCommand::insertNodeBeforeAndUpdateNodesInserted(PassRefPtr&lt;
&gt;      updateNodesInserted(nodeToUpdate);
&gt;  }
&gt;  
&gt; +// If the user is inserting a list into an existing list, instead of nesting the list,
&gt; +// we put the list items into the existing list.
&gt; +Node* ReplaceSelectionCommand::insertAsListItems(PassRefPtr&lt;Node&gt; listElement, Node* insertionNode, const Position&amp; p)
&gt; +{
&gt; +    while (listElement-&gt;hasChildNodes() &amp;&amp; isListElement(listElement-&gt;firstChild()) &amp;&amp; listElement-&gt;childNodeCount() == 1)
&gt; +        listElement = listElement-&gt;firstChild();
&gt; +
&gt; +    bool isStart = isStartOfParagraph(p);
&gt; +    bool isEnd = isEndOfParagraph(p);
&gt; +
&gt; +    Node* lastNode = insertionNode;
&gt; +    while (RefPtr&lt;Node&gt; listItem = listElement-&gt;firstChild()) {
&gt; +        ExceptionCode ec = 0;
&gt; +        listElement-&gt;removeChild(listItem.get(), ec);
&gt; +        ASSERT(!ec);
&gt; +        if (isStart)
&gt; +            insertNodeBefore(listItem, lastNode);
&gt; +        else if (isEnd) {
&gt; +            insertNodeAfter(listItem, lastNode);
&gt; +            lastNode = listItem.get();
&gt; +        } else {
&gt; +            // FIXME: If we&apos;re in the middle of a list item, we should split it into two separate
&gt; +            // list items and insert these nodes between them.  For now, just append the nodes.
&gt; +            insertNodeAfter(listItem, lastNode);
&gt; +            lastNode = listItem.get();
&gt; +        }
&gt; +    }
&gt; +    if (isStart)
&gt; +        lastNode = lastNode-&gt;previousSibling();
&gt; +    updateNodesInserted(lastNode);
&gt; +    return lastNode;
&gt; +}
&gt; +
&gt;  void ReplaceSelectionCommand::updateNodesInserted(Node *node)
&gt;  {
&gt;      if (!node)
&gt; diff --git a/WebCore/editing/ReplaceSelectionCommand.h b/WebCore/editing/ReplaceSelectionCommand.h
&gt; index 1cb93c3..19f63bb 100644
&gt; --- a/WebCore/editing/ReplaceSelectionCommand.h
&gt; +++ b/WebCore/editing/ReplaceSelectionCommand.h
&gt; @@ -54,6 +54,7 @@ private:
&gt;      void insertNodeAfterAndUpdateNodesInserted(PassRefPtr&lt;Node&gt; insertChild, Node* refChild);
&gt;      void insertNodeAtAndUpdateNodesInserted(PassRefPtr&lt;Node&gt;, const Position&amp;);
&gt;      void insertNodeBeforeAndUpdateNodesInserted(PassRefPtr&lt;Node&gt; insertChild, Node* refChild);
&gt; +    Node* insertAsListItems(PassRefPtr&lt;Node&gt;, Node* insertionNode, const Position&amp;);
&gt;  
&gt;      void updateNodesInserted(Node*);
&gt;      bool shouldRemoveEndBR(Node*, const VisiblePosition&amp;);
&gt; diff --git a/WebCore/editing/htmlediting.cpp b/WebCore/editing/htmlediting.cpp
&gt; index b58dff3..4981f63 100644
&gt; --- a/WebCore/editing/htmlediting.cpp
&gt; +++ b/WebCore/editing/htmlediting.cpp
&gt; @@ -658,6 +658,11 @@ bool isListElement(Node *n)
&gt;      return (n &amp;&amp; (n-&gt;hasTagName(ulTag) || n-&gt;hasTagName(olTag) || n-&gt;hasTagName(dlTag)));
&gt;  }
&gt;  
&gt; +bool isListItem(Node *n)
&gt; +{
&gt; +    return n &amp;&amp; n-&gt;renderer() &amp;&amp; n-&gt;renderer()-&gt;isListItem();
&gt; +}
&gt; +
&gt;  Node* enclosingNodeWithTag(const Position&amp; p, const QualifiedName&amp; tagName)
&gt;  {
&gt;      if (p.isNull())
&gt; @@ -779,7 +784,7 @@ static Node* appendedSublist(Node* listItem)
&gt;      for (Node* n = listItem-&gt;nextSibling(); n; n = n-&gt;nextSibling()) {
&gt;          if (isListElement(n))
&gt;              return static_cast&lt;HTMLElement*&gt;(n);
&gt; -        if (n-&gt;renderer() &amp;&amp; n-&gt;renderer()-&gt;isListItem())
&gt; +        if (isListItem(listItem))
&gt;              return 0;
&gt;      }
&gt;      
&gt; diff --git a/WebCore/editing/htmlediting.h b/WebCore/editing/htmlediting.h
&gt; index c5a44ac..ef3db35 100644
&gt; --- a/WebCore/editing/htmlediting.h
&gt; +++ b/WebCore/editing/htmlediting.h
&gt; @@ -90,6 +90,7 @@ bool isTableCell(const Node*);
&gt;  bool isEmptyTableCell(const Node*);
&gt;  bool isTableStructureNode(const Node*);
&gt;  bool isListElement(Node*);
&gt; +bool isListItem(Node*);
&gt;  bool isNodeRendered(const Node*);
&gt;  bool isNodeVisiblyContainedWithin(Node*, const Range*);
&gt;  bool isRenderedAsNonInlineTableImageOrHR(const Node*);

It looks good to me.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>187996</commentid>
    <comment_count>7</comment_count>
      <attachid>48083</attachid>
    <who name="Eric Seidel (no email)">eric</who>
    <bug_when>2010-02-04 16:26:34 -0800</bug_when>
    <thetext>Comment on attachment 48083
Patch

The language/type stuff is unneeded:
 2 &lt;script src=../editing.js language=&quot;JavaScript&quot; type=&quot;text/JavaScript&quot; &gt;&lt;/script&gt;

Looks sane.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>188110</commentid>
    <comment_count>8</comment_count>
    <who name="Tony Chang">tony</who>
    <bug_when>2010-02-05 01:23:21 -0800</bug_when>
    <thetext>Committed r54413: &lt;http://trac.webkit.org/changeset/54413&gt;</thetext>
  </long_desc>
      
          <attachment
              isobsolete="1"
              ispatch="1"
              isprivate="0"
          >
            <attachid>47992</attachid>
            <date>2010-02-02 21:15:02 -0800</date>
            <delta_ts>2010-02-03 17:36:06 -0800</delta_ts>
            <desc>Patch</desc>
            <filename>bug-24872-20100203141500.patch</filename>
            <type>text/plain</type>
            <size>12159</size>
            <attacher name="Tony Chang">tony</attacher>
            
              <data encoding="base64">ZGlmZiAtLWdpdCBhL0xheW91dFRlc3RzL0NoYW5nZUxvZyBiL0xheW91dFRlc3RzL0NoYW5nZUxv
ZwppbmRleCA2YjVhYjZmLi5kNTRhNDdlIDEwMDY0NAotLS0gYS9MYXlvdXRUZXN0cy9DaGFuZ2VM
b2cKKysrIGIvTGF5b3V0VGVzdHMvQ2hhbmdlTG9nCkBAIC0xLDMgKzEsMTQgQEAKKzIwMTAtMDIt
MDIgIFRvbnkgQ2hhbmcgIDx0b255QGNocm9taXVtLm9yZz4KKworICAgICAgICBSZXZpZXdlZCBi
eSBOT0JPRFkgKE9PUFMhKS4KKworICAgICAgICBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93
X2J1Zy5jZ2k/aWQ9MjQ4NzIKKyAgICAgICAgQWRkIGEgdGVzdCB0byBtYWtlIHN1cmUgY29weWlu
ZyBmcm9tIGEgbGlzdCBhbmQgcGFzdGluZyBpbnRvIGEgbGlzdAorICAgICAgICBrZWVwcyB0aGUg
bGlzdCBhdCB0aGUgc2FtZSBpbmRlbnRpb24gbGV2ZWwgcmF0aGVyIHRoYW4gbmVzdGluZy4KKwor
ICAgICAgICAqIGVkaXRpbmcvcGFzdGVib2FyZC9wYXN0ZS1saXN0LTAwMi1leHBlY3RlZC50eHQ6
IEFkZGVkLgorICAgICAgICAqIGVkaXRpbmcvcGFzdGVib2FyZC9wYXN0ZS1saXN0LTAwMi5odG1s
OiBBZGRlZC4KKwogMjAxMC0wMi0wMiAgRXJpYyBTZWlkZWwgIDxlcmljQHdlYmtpdC5vcmc+CiAK
ICAgICAgICAgUmV2aWV3ZWQgYnkgR3VzdGF2byBOb3JvbmhhIFNpbHZhLgpkaWZmIC0tZ2l0IGEv
TGF5b3V0VGVzdHMvZWRpdGluZy9wYXN0ZWJvYXJkL3Bhc3RlLWxpc3QtMDAyLWV4cGVjdGVkLnR4
dCBiL0xheW91dFRlc3RzL2VkaXRpbmcvcGFzdGVib2FyZC9wYXN0ZS1saXN0LTAwMi1leHBlY3Rl
ZC50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWZmMWNiNgotLS0gL2Rl
di9udWxsCisrKyBiL0xheW91dFRlc3RzL2VkaXRpbmcvcGFzdGVib2FyZC9wYXN0ZS1saXN0LTAw
Mi1leHBlY3RlZC50eHQKQEAgLTAsMCArMSwxMyBAQAorQ29weS9wYXN0aW5nIGxpc3QgaXRlbXMg
aW4gYSBsaXN0LiBUaGlzIHRlc3Qgc2hvdWxkIGJlIHJ1biB3aXRoIERSVCBmb3IgcGFzdGVib2Fy
ZCBhY2Nlc3MuCisKK1BBU1M6IDxsaT5hbHBoYTwvbGk+PHVsPjxsaT5iZXRhPC9saT48bGk+Z2Ft
bWE8L2xpPjwvdWw+PGxpPmJldGE8L2xpPjxsaT5nYW1tYTwvbGk+PGxpIGlkPSJkZWx0YSI+ZGVs
dGE8L2xpPjxsaT5iZXRhPC9saT48bGk+Z2FtbWE8L2xpPjxsaT48L2xpPgorCithbHBoYQorYmV0
YQorZ2FtbWEKK2JldGEKK2dhbW1hCitkZWx0YQorYmV0YQorZ2FtbWEKKwpkaWZmIC0tZ2l0IGEv
TGF5b3V0VGVzdHMvZWRpdGluZy9wYXN0ZWJvYXJkL3Bhc3RlLWxpc3QtMDAyLmh0bWwgYi9MYXlv
dXRUZXN0cy9lZGl0aW5nL3Bhc3RlYm9hcmQvcGFzdGUtbGlzdC0wMDIuaHRtbApuZXcgZmlsZSBt
b2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZmFlNDEwCi0tLSAvZGV2L251bGwKKysrIGIvTGF5
b3V0VGVzdHMvZWRpdGluZy9wYXN0ZWJvYXJkL3Bhc3RlLWxpc3QtMDAyLmh0bWwKQEAgLTAsMCAr
MSw2MyBAQAorPGh0bWw+IAorPHNjcmlwdCBzcmM9Li4vZWRpdGluZy5qcyBsYW5ndWFnZT0iSmF2
YVNjcmlwdCIgdHlwZT0idGV4dC9KYXZhU2NyaXB0IiA+PC9zY3JpcHQ+Cis8c2NyaXB0PgorCitm
dW5jdGlvbiBlZGl0aW5nVGVzdCgpIHsKKyAgICAvLyBTZWxlY3QgImJldGEiIGFuZCAiZ2FtbWEi
LgorICAgIG1vdmVTZWxlY3Rpb25Gb3J3YXJkQnlMaW5lQ29tbWFuZCgpOworICAgIGZvciAoaSA9
IDA7IGkgPCAyOyBpKyspCisgICAgICAgIGV4dGVuZFNlbGVjdGlvbkZvcndhcmRCeUxpbmVDb21t
YW5kKCk7CisgICAgY29weUNvbW1hbmQoKTsKKworICAgIC8vIFBhc3RlIHdpdGggdGhlIGN1cnNv
ciByaWdodCBiZWZvcmUgImRlbHRhIi4KKyAgICBtb3ZlU2VsZWN0aW9uRm9yd2FyZEJ5TGluZUNv
bW1hbmQoKTsKKyAgICBwYXN0ZUNvbW1hbmQoKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBj
dXJzb3IgaXMgaW4gdGhlIHJpZ2h0IHBsYWNlIChzdGlsbCBiZWZvcmUgZGVsdGEpLgorICAgIHZh
ciBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7CisgICAgaWYgKHNlbGVjdGlvbi5i
YXNlTm9kZS5wYXJlbnROb2RlICE9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJkZWx0YSIpIHx8
CisgICAgICAgIHNlbGVjdGlvbi5iYXNlT2Zmc2V0ICE9IDAgfHwgIXNlbGVjdGlvbi5pc0NvbGxh
cHNlZCkKKyAgICAgICAgdGhyb3cgIldyb25nIHNlbGVjdGlvbiBwb3NpdGlvbiBvbiBiZWZvcmUg
cGFzdGUuIjsKKworICAgIC8vIFBhc3RlIHdpdGggdGhlIGN1cnNvciBhdCB0aGUgZW5kIG9mICJk
ZWx0YSIuCisgICAgbW92ZVNlbGVjdGlvbkZvcndhcmRCeVdvcmRDb21tYW5kKCk7CisgICAgcGFz
dGVDb21tYW5kKCk7ICAgIAorCisgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGN1cnNvciBpcyBpbiB0
aGUgcmlnaHQgcGxhY2UgKG5ldyBsaXN0IGl0ZW0gYWZ0ZXIgZGVsdGEpLgorICAgIHZhciBzZWxl
Y3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7CisgICAgaWYgKCFzZWxlY3Rpb24uaXNDb2xs
YXBzZWQgfHwgc2VsZWN0aW9uLmJhc2VOb2RlLnZhbHVlICE9ICIiKQorICAgICAgICB0aHJvdyAi
V3Jvbmcgc2VsZWN0aW9uIHBvc2l0aW9uIG9uIGFmdGVyIHBhc3RlLiI7Cit9CisKKzwvc2NyaXB0
PgorPGJvZHk+Cis8ZGl2IGNvbnRlbnRFZGl0YWJsZT0idHJ1ZSI+Cis8cD5Db3B5L3Bhc3Rpbmcg
bGlzdCBpdGVtcyBpbiBhIGxpc3QuICBUaGlzIHRlc3Qgc2hvdWxkIGJlIHJ1biB3aXRoIERSVCBm
b3IgcGFzdGVib2FyZCBhY2Nlc3MuPC9wPgorPHAgaWQ9InJlc3VsdHMiPkZBSUw8L3A+Cis8dWwg
aWQ9InRlc3QiPgorICAgIDxsaT5hbHBoYTwvbGk+CisgICAgPGxpPmJldGE8L2xpPgorICAgIDxs
aT5nYW1tYTwvbGk+CisgICAgPGxpIGlkPSJkZWx0YSI+ZGVsdGE8L2xpPgorPC91bD4KKzwvZGl2
PgorCis8c2NyaXB0PgoraWYgKHdpbmRvdy5sYXlvdXRUZXN0Q29udHJvbGxlcikKKyAgICBsYXlv
dXRUZXN0Q29udHJvbGxlci5kdW1wQXNUZXh0KCk7CisKK3ZhciBlbGVtID0gZG9jdW1lbnQuZ2V0
RWxlbWVudEJ5SWQoInRlc3QiKTsKK3ZhciBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9u
KCk7CitzZWxlY3Rpb24uc2V0UG9zaXRpb24oZWxlbSwgMCk7CitlZGl0aW5nVGVzdCgpOworCisv
LyBSZXJ1biB0aGUgdGVzdCBidXQgaGF2ZSB0aGUgc291cmNlIGxpc3QgYmUgaW5kZW50ZWQuCitk
b2N1bWVudC5nZXRFbGVtZW50QnlJZCgidGVzdCIpLmlubmVySFRNTCA9ICI8bGk+YWxwaGE8L2xp
Pjx1bD48bGk+YmV0YTwvbGk+PGxpPmdhbW1hPC9saT48L3VsPjxsaSBpZD0nZGVsdGEnPmRlbHRh
PC9saT4iOworc2VsZWN0aW9uLnNldFBvc2l0aW9uKGVsZW0sIDApOworZWRpdGluZ1Rlc3QoKTsK
KworZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInJlc3VsdHMiKS5pbm5lclRleHQgPSAiUEFTUzog
IiArIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0ZXN0IikuaW5uZXJIVE1MOworPC9zY3JpcHQ+
CisKKzwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL1dlYkNvcmUvQ2hhbmdlTG9nIGIvV2Vi
Q29yZS9DaGFuZ2VMb2cKaW5kZXggNjdmNWI1Ni4uNmYzNjVkMCAxMDA2NDQKLS0tIGEvV2ViQ29y
ZS9DaGFuZ2VMb2cKKysrIGIvV2ViQ29yZS9DaGFuZ2VMb2cKQEAgLTEsMyArMSwzMCBAQAorMjAx
MC0wMi0wMiAgVG9ueSBDaGFuZyAgPHRvbnlAY2hyb21pdW0ub3JnPgorCisgICAgICAgIFJldmll
d2VkIGJ5IE5PQk9EWSAoT09QUyEpLgorCisgICAgICAgIGh0dHBzOi8vYnVncy53ZWJraXQub3Jn
L3Nob3dfYnVnLmNnaT9pZD0yNDg3MgorICAgICAgICBXaGVuIHBhc3RpbmcgYSBsaXN0IGludG8g
YW5vdGhlciBsaXN0IHNob3VsZCBub3QgaW5kZW50IGFub3RoZXIgbGV2ZWwuCisgICAgICAgIElm
IHRoZSBjdXJzb3IgaXMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgbGluZSwgaXQgc2hvdWxkIGlu
c2VydCB0aGUKKyAgICAgICAgbGlzdCBpdGVtcyBiZWZvcmUgdGhlIGN1cnJlbnQgbGlzdCBpdGVt
LiAgSWYgdGhlIGN1cnNvciBpcyBhdCB0aGUgZW5kCisgICAgICAgIG9mIHRoZSBsaW5lLCBpdCBz
aG91bGQgaW5zZXJ0IHRoZSBsaXN0IGl0ZW1zIGFmdGVyIHRoZSBjdXJyZW50IGxpc3QgaXRlbS4K
KworICAgICAgICBUaGlzIG1hdGNoZXMgRmlyZWZveCBhbmQgSUUgYW5kIG1ha2VzIHRoZSBjb21t
b24gYWN0aXZpdHkgb2YgcmVvcmRlcmluZyBhIGxpc3QKKyAgICAgICAgd29yayBhcyBleHBlY3Rl
ZC4KKworICAgICAgICBUaGlzIGFsc28gYWRkcyBhIHNtYWxsIGhlbHBlciBtZXRob2QgKGlzTGlz
dEl0ZW0pIHRvIGh0bWxlZGl0aW5nLmguCisKKyAgICAgICAgVGVzdDogZWRpdGluZy9wYXN0ZWJv
YXJkL3Bhc3RlLWxpc3QtMDAyLmh0bWwKKworICAgICAgICAqIGVkaXRpbmcvUmVwbGFjZVNlbGVj
dGlvbkNvbW1hbmQuY3BwOgorICAgICAgICAoV2ViQ29yZTo6UmVwbGFjZVNlbGVjdGlvbkNvbW1h
bmQ6OmRvQXBwbHkpOgorICAgICAgICAoV2ViQ29yZTo6UmVwbGFjZVNlbGVjdGlvbkNvbW1hbmQ6
Omluc2VydE5vZGVBdEFuZFVwZGF0ZU5vZGVzSW5zZXJ0ZWQpOgorICAgICAgICAoV2ViQ29yZTo6
UmVwbGFjZVNlbGVjdGlvbkNvbW1hbmQ6Omluc2VydEFzTGlzdEl0ZW1zKToKKyAgICAgICAgKiBl
ZGl0aW5nL1JlcGxhY2VTZWxlY3Rpb25Db21tYW5kLmg6CisgICAgICAgICogZWRpdGluZy9odG1s
ZWRpdGluZy5jcHA6CisgICAgICAgIChXZWJDb3JlOjppc0xpc3RJdGVtKToKKyAgICAgICAgKFdl
YkNvcmU6OmFwcGVuZGVkU3VibGlzdCk6CisgICAgICAgICogZWRpdGluZy9odG1sZWRpdGluZy5o
OgorCiAyMDEwLTAyLTAyICBTdGV2ZSBGYWxrZW5idXJnICA8c2ZhbGtlbkBhcHBsZS5jb20+CiAK
ICAgICAgICAgUmV2aWV3ZWQgYnkgRGFyaW4gQWRsZXIuCmRpZmYgLS1naXQgYS9XZWJDb3JlL2Vk
aXRpbmcvUmVwbGFjZVNlbGVjdGlvbkNvbW1hbmQuY3BwIGIvV2ViQ29yZS9lZGl0aW5nL1JlcGxh
Y2VTZWxlY3Rpb25Db21tYW5kLmNwcAppbmRleCA4NWE0NDcxLi43N2Q2OWQxIDEwMDY0NAotLS0g
YS9XZWJDb3JlL2VkaXRpbmcvUmVwbGFjZVNlbGVjdGlvbkNvbW1hbmQuY3BwCisrKyBiL1dlYkNv
cmUvZWRpdGluZy9SZXBsYWNlU2VsZWN0aW9uQ29tbWFuZC5jcHAKQEAgLTc1Miw5ICs3NTIsNyBA
QCB2b2lkIFJlcGxhY2VTZWxlY3Rpb25Db21tYW5kOjpkb0FwcGx5KCkKICAgICBib29sIHN0YXJ0
SXNJbnNpZGVNYWlsQmxvY2txdW90ZSA9IG5lYXJlc3RNYWlsQmxvY2txdW90ZShpbnNlcnRpb25Q
b3Mubm9kZSgpKTsKICAgICAKICAgICBpZiAoKHNlbGVjdGlvblN0YXJ0V2FzU3RhcnRPZlBhcmFn
cmFwaCAmJiBzZWxlY3Rpb25FbmRXYXNFbmRPZlBhcmFncmFwaCAmJiAhc3RhcnRJc0luc2lkZU1h
aWxCbG9ja3F1b3RlKSB8fAotICAgICAgICBzdGFydEJsb2NrID09IGN1cnJlbnRSb290IHx8Ci0g
ICAgICAgIChzdGFydEJsb2NrICYmIHN0YXJ0QmxvY2stPnJlbmRlcmVyKCkgJiYgc3RhcnRCbG9j
ay0+cmVuZGVyZXIoKS0+aXNMaXN0SXRlbSgpKSB8fAotICAgICAgICBzZWxlY3Rpb25Jc1BsYWlu
VGV4dCkKKyAgICAgICAgc3RhcnRCbG9jayA9PSBjdXJyZW50Um9vdCB8fCBpc0xpc3RJdGVtKHN0
YXJ0QmxvY2spIHx8IHNlbGVjdGlvbklzUGxhaW5UZXh0KQogICAgICAgICBtX3ByZXZlbnROZXN0
aW5nID0gZmFsc2U7CiAgICAgCiAgICAgaWYgKHNlbGVjdGlvbi5pc1JhbmdlKCkpIHsKQEAgLTg3
MSw3ICs4NjksNyBAQCB2b2lkIFJlcGxhY2VTZWxlY3Rpb25Db21tYW5kOjpkb0FwcGx5KCkKICAg
ICBSZWZQdHI8Tm9kZT4gbm9kZSA9IHJlZk5vZGUtPm5leHRTaWJsaW5nKCk7CiAgICAgCiAgICAg
ZnJhZ21lbnQucmVtb3ZlTm9kZShyZWZOb2RlKTsKLSAgICBpbnNlcnROb2RlQXRBbmRVcGRhdGVO
b2Rlc0luc2VydGVkKHJlZk5vZGUsIGluc2VydGlvblBvcyk7CisgICAgcmVmTm9kZSA9IGluc2Vy
dE5vZGVBdEFuZFVwZGF0ZU5vZGVzSW5zZXJ0ZWQocmVmTm9kZSwgaW5zZXJ0aW9uUG9zKTsKIAog
ICAgIC8vIE11dGF0aW9uIGV2ZW50cyAoYnVnIDIyNjM0KSBtYXkgaGF2ZSBhbHJlYWR5IHJlbW92
ZWQgdGhlIGluc2VydGVkIGNvbnRlbnQKICAgICBpZiAoIXJlZk5vZGUtPmluRG9jdW1lbnQoKSkK
QEAgLTk2MCw5ICs5NTgsMTUgQEAgdm9pZCBSZXBsYWNlU2VsZWN0aW9uQ29tbWFuZDo6ZG9BcHBs
eSgpCiAgICAgICAgIGlmIChzZWxlY3Rpb25FbmRXYXNFbmRPZlBhcmFncmFwaCB8fCAhaXNFbmRP
ZlBhcmFncmFwaChlbmRPZkluc2VydGVkQ29udGVudCkgfHwgbmV4dC5pc051bGwoKSkgewogICAg
ICAgICAgICAgaWYgKCFpc1N0YXJ0T2ZQYXJhZ3JhcGgoZW5kT2ZJbnNlcnRlZENvbnRlbnQpKSB7
CiAgICAgICAgICAgICAgICAgc2V0RW5kaW5nU2VsZWN0aW9uKGVuZE9mSW5zZXJ0ZWRDb250ZW50
KTsKLSAgICAgICAgICAgICAgICAvLyBVc2UgYSBkZWZhdWx0IHBhcmFncmFwaCBlbGVtZW50IChh
IHBsYWluIGRpdikgZm9yIHRoZSBlbXB0eSBwYXJhZ3JhcGgsIHVzaW5nIHRoZSBsYXN0IHBhcmFn
cmFwaAotICAgICAgICAgICAgICAgIC8vIGJsb2NrJ3Mgc3R5bGUgc2VlbXMgdG8gYW5ub3kgdXNl
cnMuCi0gICAgICAgICAgICAgICAgaW5zZXJ0UGFyYWdyYXBoU2VwYXJhdG9yKHRydWUpOworICAg
ICAgICAgICAgICAgIE5vZGUqIGVuY2xvc2luZ05vZGUgPSBlbmNsb3NpbmdCbG9jayhlbmRPZklu
c2VydGVkQ29udGVudC5kZWVwRXF1aXZhbGVudCgpLm5vZGUoKSk7CisgICAgICAgICAgICAgICAg
aWYgKGlzTGlzdEl0ZW0oZW5jbG9zaW5nTm9kZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgUmVm
UHRyPE5vZGU+IG5ld0xpc3RJdGVtID0gY3JlYXRlTGlzdEl0ZW1FbGVtZW50KGRvY3VtZW50KCkp
OworICAgICAgICAgICAgICAgICAgICBpbnNlcnROb2RlQWZ0ZXIobmV3TGlzdEl0ZW0sIGVuY2xv
c2luZ05vZGUpOworICAgICAgICAgICAgICAgICAgICBzZXRFbmRpbmdTZWxlY3Rpb24oVmlzaWJs
ZVBvc2l0aW9uKFBvc2l0aW9uKG5ld0xpc3RJdGVtLCAwKSkpOworICAgICAgICAgICAgICAgIH0g
ZWxzZQorICAgICAgICAgICAgICAgICAgICAvLyBVc2UgYSBkZWZhdWx0IHBhcmFncmFwaCBlbGVt
ZW50IChhIHBsYWluIGRpdikgZm9yIHRoZSBlbXB0eSBwYXJhZ3JhcGgsIHVzaW5nIHRoZSBsYXN0
IHBhcmFncmFwaAorICAgICAgICAgICAgICAgICAgICAvLyBibG9jaydzIHN0eWxlIHNlZW1zIHRv
IGFubm95IHVzZXJzLgorICAgICAgICAgICAgICAgICAgICBpbnNlcnRQYXJhZ3JhcGhTZXBhcmF0
b3IodHJ1ZSk7CiAKICAgICAgICAgICAgICAgICAvLyBTZWxlY3QgdXAgdG8gdGhlIHBhcmFncmFw
aCBzZXBhcmF0b3IgdGhhdCB3YXMgYWRkZWQuCiAgICAgICAgICAgICAgICAgbGFzdFBvc2l0aW9u
VG9TZWxlY3QgPSBlbmRpbmdTZWxlY3Rpb24oKS52aXNpYmxlU3RhcnQoKS5kZWVwRXF1aXZhbGVu
dCgpOwpAQCAtMTA5NywxMSArMTEwMSwxNiBAQCB2b2lkIFJlcGxhY2VTZWxlY3Rpb25Db21tYW5k
OjppbnNlcnROb2RlQWZ0ZXJBbmRVcGRhdGVOb2Rlc0luc2VydGVkKFBhc3NSZWZQdHI8TgogICAg
IHVwZGF0ZU5vZGVzSW5zZXJ0ZWQobm9kZVRvVXBkYXRlKTsKIH0KIAotdm9pZCBSZXBsYWNlU2Vs
ZWN0aW9uQ29tbWFuZDo6aW5zZXJ0Tm9kZUF0QW5kVXBkYXRlTm9kZXNJbnNlcnRlZChQYXNzUmVm
UHRyPE5vZGU+IGluc2VydENoaWxkLCBjb25zdCBQb3NpdGlvbiYgcCkKK05vZGUqIFJlcGxhY2VT
ZWxlY3Rpb25Db21tYW5kOjppbnNlcnROb2RlQXRBbmRVcGRhdGVOb2Rlc0luc2VydGVkKFBhc3NS
ZWZQdHI8Tm9kZT4gaW5zZXJ0Q2hpbGQsIGNvbnN0IFBvc2l0aW9uJiBwKQogewogICAgIE5vZGUq
IG5vZGVUb1VwZGF0ZSA9IGluc2VydENoaWxkLmdldCgpOyAvLyBpbnNlcnRDaGlsZCB3aWxsIGJl
IGNsZWFyZWQgd2hlbiBwYXNzZWQKKyAgICBOb2RlKiBibG9ja1N0YXJ0ID0gZW5jbG9zaW5nQmxv
Y2socC5ub2RlKCkpOworICAgIGlmIChpc0xpc3RFbGVtZW50KGluc2VydENoaWxkLmdldCgpKSAm
JiBibG9ja1N0YXJ0LT5yZW5kZXJlcigpLT5pc0xpc3RJdGVtKCkpCisgICAgICAgIHJldHVybiBp
bnNlcnRBc0xpc3RJdGVtcyhpbnNlcnRDaGlsZCwgYmxvY2tTdGFydCwgcCk7CisKICAgICBpbnNl
cnROb2RlQXQoaW5zZXJ0Q2hpbGQsIHApOwogICAgIHVwZGF0ZU5vZGVzSW5zZXJ0ZWQobm9kZVRv
VXBkYXRlKTsKKyAgICByZXR1cm4gbm9kZVRvVXBkYXRlOwogfQogCiB2b2lkIFJlcGxhY2VTZWxl
Y3Rpb25Db21tYW5kOjppbnNlcnROb2RlQmVmb3JlQW5kVXBkYXRlTm9kZXNJbnNlcnRlZChQYXNz
UmVmUHRyPE5vZGU+IGluc2VydENoaWxkLCBOb2RlKiByZWZDaGlsZCkKQEAgLTExMTEsNiArMTEy
MCwzOSBAQCB2b2lkIFJlcGxhY2VTZWxlY3Rpb25Db21tYW5kOjppbnNlcnROb2RlQmVmb3JlQW5k
VXBkYXRlTm9kZXNJbnNlcnRlZChQYXNzUmVmUHRyPAogICAgIHVwZGF0ZU5vZGVzSW5zZXJ0ZWQo
bm9kZVRvVXBkYXRlKTsKIH0KIAorLy8gSWYgdGhlIHVzZXIgaXMgaW5zZXJ0aW5nIGEgbGlzdCBp
bnRvIGFuIGV4aXN0aW5nIGxpc3QsIGluc3RlYWQgb2YgbmVzdGluZyB0aGUgbGlzdCwKKy8vIHdl
IHB1dCB0aGUgbGlzdCBpdGVtcyBpbnRvIHRoZSBleGlzdGluZyBsaXN0LgorTm9kZSogUmVwbGFj
ZVNlbGVjdGlvbkNvbW1hbmQ6Omluc2VydEFzTGlzdEl0ZW1zKFBhc3NSZWZQdHI8Tm9kZT4gbGlz
dEVsZW1lbnQsIE5vZGUqIGluc2VydGlvbk5vZGUsIGNvbnN0IFBvc2l0aW9uJiBwKQoreworICAg
IHdoaWxlIChsaXN0RWxlbWVudC0+aGFzQ2hpbGROb2RlcygpICYmIGlzTGlzdEVsZW1lbnQobGlz
dEVsZW1lbnQtPmZpcnN0Q2hpbGQoKSkgJiYgbGlzdEVsZW1lbnQtPmNoaWxkTm9kZUNvdW50KCkg
PT0gMSkKKyAgICAgICAgbGlzdEVsZW1lbnQgPSBsaXN0RWxlbWVudC0+Zmlyc3RDaGlsZCgpOwor
CisgICAgYm9vbCBpc1N0YXJ0ID0gaXNTdGFydE9mUGFyYWdyYXBoKHApOworICAgIGJvb2wgaXNF
bmQgPSBpc0VuZE9mUGFyYWdyYXBoKHApOworCisgICAgTm9kZSogbGFzdE5vZGUgPSBpbnNlcnRp
b25Ob2RlOworICAgIHdoaWxlIChSZWZQdHI8Tm9kZT4gbGlzdEl0ZW0gPSBsaXN0RWxlbWVudC0+
Zmlyc3RDaGlsZCgpKSB7CisgICAgICAgIEV4Y2VwdGlvbkNvZGUgZWMgPSAwOworICAgICAgICBs
aXN0RWxlbWVudC0+cmVtb3ZlQ2hpbGQobGlzdEl0ZW0uZ2V0KCksIGVjKTsKKyAgICAgICAgQVNT
RVJUKCFlYyk7CisgICAgICAgIGlmIChpc1N0YXJ0KQorICAgICAgICAgICAgaW5zZXJ0Tm9kZUJl
Zm9yZShsaXN0SXRlbSwgbGFzdE5vZGUpOworICAgICAgICBlbHNlIGlmIChpc0VuZCkgeworICAg
ICAgICAgICAgaW5zZXJ0Tm9kZUFmdGVyKGxpc3RJdGVtLCBsYXN0Tm9kZSk7CisgICAgICAgICAg
ICBsYXN0Tm9kZSA9IGxpc3RJdGVtLmdldCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAg
ICAgLy8gRklYTUU6IElmIHdlJ3JlIGluIHRoZSBtaWRkbGUgb2YgYSBsaXN0IGl0ZW0sIHdlIHNo
b3VsZCBzcGxpdCBpdCBpbnRvIHR3byBzZXBhcmF0ZQorICAgICAgICAgICAgLy8gbGlzdCBpdGVt
cyBhbmQgaW5zZXJ0IHRoZXNlIG5vZGVzIGJldHdlZW4gdGhlbS4gIEZvciBub3csIGp1c3QgYXBw
ZW5kIHRoZSBub2Rlcy4KKyAgICAgICAgICAgIGluc2VydE5vZGVBZnRlcihsaXN0SXRlbSwgbGFz
dE5vZGUpOworICAgICAgICAgICAgbGFzdE5vZGUgPSBsaXN0SXRlbS5nZXQoKTsKKyAgICAgICAg
fQorICAgIH0KKyAgICBpZiAoaXNTdGFydCkKKyAgICAgICAgbGFzdE5vZGUgPSBsYXN0Tm9kZS0+
cHJldmlvdXNTaWJsaW5nKCk7CisgICAgdXBkYXRlTm9kZXNJbnNlcnRlZChsYXN0Tm9kZSk7Cisg
ICAgcmV0dXJuIGxhc3ROb2RlOworfQorCiB2b2lkIFJlcGxhY2VTZWxlY3Rpb25Db21tYW5kOjp1
cGRhdGVOb2Rlc0luc2VydGVkKE5vZGUgKm5vZGUpCiB7CiAgICAgaWYgKCFub2RlKQpkaWZmIC0t
Z2l0IGEvV2ViQ29yZS9lZGl0aW5nL1JlcGxhY2VTZWxlY3Rpb25Db21tYW5kLmggYi9XZWJDb3Jl
L2VkaXRpbmcvUmVwbGFjZVNlbGVjdGlvbkNvbW1hbmQuaAppbmRleCAxY2I5M2MzLi5iN2ZmODU3
IDEwMDY0NAotLS0gYS9XZWJDb3JlL2VkaXRpbmcvUmVwbGFjZVNlbGVjdGlvbkNvbW1hbmQuaAor
KysgYi9XZWJDb3JlL2VkaXRpbmcvUmVwbGFjZVNlbGVjdGlvbkNvbW1hbmQuaApAQCAtNTIsOCAr
NTIsOSBAQCBwcml2YXRlOgogICAgIHZvaWQgY29tcGxldGVIVE1MUmVwbGFjZW1lbnQoY29uc3Qg
UG9zaXRpb24mIGxhc3RQb3NpdGlvblRvU2VsZWN0KTsKIAogICAgIHZvaWQgaW5zZXJ0Tm9kZUFm
dGVyQW5kVXBkYXRlTm9kZXNJbnNlcnRlZChQYXNzUmVmUHRyPE5vZGU+IGluc2VydENoaWxkLCBO
b2RlKiByZWZDaGlsZCk7Ci0gICAgdm9pZCBpbnNlcnROb2RlQXRBbmRVcGRhdGVOb2Rlc0luc2Vy
dGVkKFBhc3NSZWZQdHI8Tm9kZT4sIGNvbnN0IFBvc2l0aW9uJik7CisgICAgTm9kZSogaW5zZXJ0
Tm9kZUF0QW5kVXBkYXRlTm9kZXNJbnNlcnRlZChQYXNzUmVmUHRyPE5vZGU+LCBjb25zdCBQb3Np
dGlvbiYpOwogICAgIHZvaWQgaW5zZXJ0Tm9kZUJlZm9yZUFuZFVwZGF0ZU5vZGVzSW5zZXJ0ZWQo
UGFzc1JlZlB0cjxOb2RlPiBpbnNlcnRDaGlsZCwgTm9kZSogcmVmQ2hpbGQpOworICAgIE5vZGUq
IGluc2VydEFzTGlzdEl0ZW1zKFBhc3NSZWZQdHI8Tm9kZT4sIE5vZGUqIGluc2VydGlvbk5vZGUs
IGNvbnN0IFBvc2l0aW9uJik7CiAKICAgICB2b2lkIHVwZGF0ZU5vZGVzSW5zZXJ0ZWQoTm9kZSop
OwogICAgIGJvb2wgc2hvdWxkUmVtb3ZlRW5kQlIoTm9kZSosIGNvbnN0IFZpc2libGVQb3NpdGlv
biYpOwpkaWZmIC0tZ2l0IGEvV2ViQ29yZS9lZGl0aW5nL2h0bWxlZGl0aW5nLmNwcCBiL1dlYkNv
cmUvZWRpdGluZy9odG1sZWRpdGluZy5jcHAKaW5kZXggYjU4ZGZmMy4uNDk4MWY2MyAxMDA2NDQK
LS0tIGEvV2ViQ29yZS9lZGl0aW5nL2h0bWxlZGl0aW5nLmNwcAorKysgYi9XZWJDb3JlL2VkaXRp
bmcvaHRtbGVkaXRpbmcuY3BwCkBAIC02NTgsNiArNjU4LDExIEBAIGJvb2wgaXNMaXN0RWxlbWVu
dChOb2RlICpuKQogICAgIHJldHVybiAobiAmJiAobi0+aGFzVGFnTmFtZSh1bFRhZykgfHwgbi0+
aGFzVGFnTmFtZShvbFRhZykgfHwgbi0+aGFzVGFnTmFtZShkbFRhZykpKTsKIH0KIAorYm9vbCBp
c0xpc3RJdGVtKE5vZGUgKm4pCit7CisgICAgcmV0dXJuIG4gJiYgbi0+cmVuZGVyZXIoKSAmJiBu
LT5yZW5kZXJlcigpLT5pc0xpc3RJdGVtKCk7Cit9CisKIE5vZGUqIGVuY2xvc2luZ05vZGVXaXRo
VGFnKGNvbnN0IFBvc2l0aW9uJiBwLCBjb25zdCBRdWFsaWZpZWROYW1lJiB0YWdOYW1lKQogewog
ICAgIGlmIChwLmlzTnVsbCgpKQpAQCAtNzc5LDcgKzc4NCw3IEBAIHN0YXRpYyBOb2RlKiBhcHBl
bmRlZFN1Ymxpc3QoTm9kZSogbGlzdEl0ZW0pCiAgICAgZm9yIChOb2RlKiBuID0gbGlzdEl0ZW0t
Pm5leHRTaWJsaW5nKCk7IG47IG4gPSBuLT5uZXh0U2libGluZygpKSB7CiAgICAgICAgIGlmIChp
c0xpc3RFbGVtZW50KG4pKQogICAgICAgICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PEhUTUxFbGVt
ZW50Kj4obik7Ci0gICAgICAgIGlmIChuLT5yZW5kZXJlcigpICYmIG4tPnJlbmRlcmVyKCktPmlz
TGlzdEl0ZW0oKSkKKyAgICAgICAgaWYgKGlzTGlzdEl0ZW0obGlzdEl0ZW0pKQogICAgICAgICAg
ICAgcmV0dXJuIDA7CiAgICAgfQogICAgIApkaWZmIC0tZ2l0IGEvV2ViQ29yZS9lZGl0aW5nL2h0
bWxlZGl0aW5nLmggYi9XZWJDb3JlL2VkaXRpbmcvaHRtbGVkaXRpbmcuaAppbmRleCBjNWE0NGFj
Li5lZjNkYjM1IDEwMDY0NAotLS0gYS9XZWJDb3JlL2VkaXRpbmcvaHRtbGVkaXRpbmcuaAorKysg
Yi9XZWJDb3JlL2VkaXRpbmcvaHRtbGVkaXRpbmcuaApAQCAtOTAsNiArOTAsNyBAQCBib29sIGlz
VGFibGVDZWxsKGNvbnN0IE5vZGUqKTsKIGJvb2wgaXNFbXB0eVRhYmxlQ2VsbChjb25zdCBOb2Rl
Kik7CiBib29sIGlzVGFibGVTdHJ1Y3R1cmVOb2RlKGNvbnN0IE5vZGUqKTsKIGJvb2wgaXNMaXN0
RWxlbWVudChOb2RlKik7Citib29sIGlzTGlzdEl0ZW0oTm9kZSopOwogYm9vbCBpc05vZGVSZW5k
ZXJlZChjb25zdCBOb2RlKik7CiBib29sIGlzTm9kZVZpc2libHlDb250YWluZWRXaXRoaW4oTm9k
ZSosIGNvbnN0IFJhbmdlKik7CiBib29sIGlzUmVuZGVyZWRBc05vbklubGluZVRhYmxlSW1hZ2VP
ckhSKGNvbnN0IE5vZGUqKTsK
</data>

          </attachment>
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>48083</attachid>
            <date>2010-02-03 17:36:14 -0800</date>
            <delta_ts>2010-02-04 16:26:33 -0800</delta_ts>
            <desc>Patch</desc>
            <filename>bug-24872-20100204103612.patch</filename>
            <type>text/plain</type>
            <size>11246</size>
            <attacher name="Tony Chang">tony</attacher>
            
              <data encoding="base64">ZGlmZiAtLWdpdCBhL0xheW91dFRlc3RzL0NoYW5nZUxvZyBiL0xheW91dFRlc3RzL0NoYW5nZUxv
ZwppbmRleCBhNjYwZTRiLi5hNmM2ZmU2IDEwMDY0NAotLS0gYS9MYXlvdXRUZXN0cy9DaGFuZ2VM
b2cKKysrIGIvTGF5b3V0VGVzdHMvQ2hhbmdlTG9nCkBAIC0xLDMgKzEsMTQgQEAKKzIwMTAtMDIt
MDMgIFRvbnkgQ2hhbmcgIDx0b255QGNocm9taXVtLm9yZz4KKworICAgICAgICBSZXZpZXdlZCBi
eSBOT0JPRFkgKE9PUFMhKS4KKworICAgICAgICBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93
X2J1Zy5jZ2k/aWQ9MjQ4NzIKKyAgICAgICAgQWRkIGEgdGVzdCB0byBtYWtlIHN1cmUgY29weWlu
ZyBmcm9tIGEgbGlzdCBhbmQgcGFzdGluZyBpbnRvIGEgbGlzdAorICAgICAgICBrZWVwcyB0aGUg
bGlzdCBhdCB0aGUgc2FtZSBpbmRlbnRpb24gbGV2ZWwgcmF0aGVyIHRoYW4gbmVzdGluZy4KKwor
ICAgICAgICAqIGVkaXRpbmcvcGFzdGVib2FyZC9wYXN0ZS1saXN0LTAwMi1leHBlY3RlZC50eHQ6
IEFkZGVkLgorICAgICAgICAqIGVkaXRpbmcvcGFzdGVib2FyZC9wYXN0ZS1saXN0LTAwMi5odG1s
OiBBZGRlZC4KKwogMjAxMC0wMi0wMyAgQ3NhYmEgT3N6dHJvZ29uw6FjICA8b3NzeUB3ZWJraXQu
b3JnPgogCiAgICAgICAgIFJ1YmJlci1zdGFtcGVkIGJ5IEFyaXlhIEhpZGF5YXQuCmRpZmYgLS1n
aXQgYS9MYXlvdXRUZXN0cy9lZGl0aW5nL3Bhc3RlYm9hcmQvcGFzdGUtbGlzdC0wMDItZXhwZWN0
ZWQudHh0IGIvTGF5b3V0VGVzdHMvZWRpdGluZy9wYXN0ZWJvYXJkL3Bhc3RlLWxpc3QtMDAyLWV4
cGVjdGVkLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZmYxY2I2Ci0t
LSAvZGV2L251bGwKKysrIGIvTGF5b3V0VGVzdHMvZWRpdGluZy9wYXN0ZWJvYXJkL3Bhc3RlLWxp
c3QtMDAyLWV4cGVjdGVkLnR4dApAQCAtMCwwICsxLDEzIEBACitDb3B5L3Bhc3RpbmcgbGlzdCBp
dGVtcyBpbiBhIGxpc3QuIFRoaXMgdGVzdCBzaG91bGQgYmUgcnVuIHdpdGggRFJUIGZvciBwYXN0
ZWJvYXJkIGFjY2Vzcy4KKworUEFTUzogPGxpPmFscGhhPC9saT48dWw+PGxpPmJldGE8L2xpPjxs
aT5nYW1tYTwvbGk+PC91bD48bGk+YmV0YTwvbGk+PGxpPmdhbW1hPC9saT48bGkgaWQ9ImRlbHRh
Ij5kZWx0YTwvbGk+PGxpPmJldGE8L2xpPjxsaT5nYW1tYTwvbGk+PGxpPjwvbGk+CisKK2FscGhh
CitiZXRhCitnYW1tYQorYmV0YQorZ2FtbWEKK2RlbHRhCitiZXRhCitnYW1tYQorCmRpZmYgLS1n
aXQgYS9MYXlvdXRUZXN0cy9lZGl0aW5nL3Bhc3RlYm9hcmQvcGFzdGUtbGlzdC0wMDIuaHRtbCBi
L0xheW91dFRlc3RzL2VkaXRpbmcvcGFzdGVib2FyZC9wYXN0ZS1saXN0LTAwMi5odG1sCm5ldyBm
aWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZmNGM5N2MKLS0tIC9kZXYvbnVsbAorKysg
Yi9MYXlvdXRUZXN0cy9lZGl0aW5nL3Bhc3RlYm9hcmQvcGFzdGUtbGlzdC0wMDIuaHRtbApAQCAt
MCwwICsxLDYzIEBACis8aHRtbD4KKzxzY3JpcHQgc3JjPS4uL2VkaXRpbmcuanMgbGFuZ3VhZ2U9
IkphdmFTY3JpcHQiIHR5cGU9InRleHQvSmF2YVNjcmlwdCIgPjwvc2NyaXB0PgorPHNjcmlwdD4K
KworZnVuY3Rpb24gZWRpdGluZ1Rlc3QoKSB7CisgICAgLy8gU2VsZWN0ICJiZXRhIiBhbmQgImdh
bW1hIi4KKyAgICBtb3ZlU2VsZWN0aW9uRm9yd2FyZEJ5TGluZUNvbW1hbmQoKTsKKyAgICBmb3Ig
KGkgPSAwOyBpIDwgMjsgaSsrKQorICAgICAgICBleHRlbmRTZWxlY3Rpb25Gb3J3YXJkQnlMaW5l
Q29tbWFuZCgpOworICAgIGNvcHlDb21tYW5kKCk7CisKKyAgICAvLyBQYXN0ZSB3aXRoIHRoZSBj
dXJzb3IgcmlnaHQgYmVmb3JlICJkZWx0YSIuCisgICAgbW92ZVNlbGVjdGlvbkZvcndhcmRCeUxp
bmVDb21tYW5kKCk7CisgICAgcGFzdGVDb21tYW5kKCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0
aGUgY3Vyc29yIGlzIGluIHRoZSByaWdodCBwbGFjZSAoc3RpbGwgYmVmb3JlIGRlbHRhKS4KKyAg
ICB2YXIgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpOworICAgIGlmIChzZWxlY3Rp
b24uYmFzZU5vZGUucGFyZW50Tm9kZSAhPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZGVsdGEi
KSB8fAorICAgICAgICBzZWxlY3Rpb24uYmFzZU9mZnNldCAhPSAwIHx8ICFzZWxlY3Rpb24uaXND
b2xsYXBzZWQpCisgICAgICAgIHRocm93ICJXcm9uZyBzZWxlY3Rpb24gcG9zaXRpb24gb24gYmVm
b3JlIHBhc3RlLiI7CisKKyAgICAvLyBQYXN0ZSB3aXRoIHRoZSBjdXJzb3IgYXQgdGhlIGVuZCBv
ZiAiZGVsdGEiLgorICAgIG1vdmVTZWxlY3Rpb25Gb3J3YXJkQnlXb3JkQ29tbWFuZCgpOworICAg
IHBhc3RlQ29tbWFuZCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGN1cnNvciBpcyBpbiB0
aGUgcmlnaHQgcGxhY2UgKG5ldyBsaXN0IGl0ZW0gYWZ0ZXIgZGVsdGEpLgorICAgIHZhciBzZWxl
Y3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7CisgICAgaWYgKCFzZWxlY3Rpb24uaXNDb2xs
YXBzZWQgfHwgc2VsZWN0aW9uLmJhc2VOb2RlLnZhbHVlICE9ICIiKQorICAgICAgICB0aHJvdyAi
V3Jvbmcgc2VsZWN0aW9uIHBvc2l0aW9uIG9uIGFmdGVyIHBhc3RlLiI7Cit9CisKKzwvc2NyaXB0
PgorPGJvZHk+Cis8ZGl2IGNvbnRlbnRFZGl0YWJsZT0idHJ1ZSI+Cis8cD5Db3B5L3Bhc3Rpbmcg
bGlzdCBpdGVtcyBpbiBhIGxpc3QuICBUaGlzIHRlc3Qgc2hvdWxkIGJlIHJ1biB3aXRoIERSVCBm
b3IgcGFzdGVib2FyZCBhY2Nlc3MuPC9wPgorPHAgaWQ9InJlc3VsdHMiPkZBSUw8L3A+Cis8dWwg
aWQ9InRlc3QiPgorICAgIDxsaT5hbHBoYTwvbGk+CisgICAgPGxpPmJldGE8L2xpPgorICAgIDxs
aT5nYW1tYTwvbGk+CisgICAgPGxpIGlkPSJkZWx0YSI+ZGVsdGE8L2xpPgorPC91bD4KKzwvZGl2
PgorCis8c2NyaXB0PgoraWYgKHdpbmRvdy5sYXlvdXRUZXN0Q29udHJvbGxlcikKKyAgICBsYXlv
dXRUZXN0Q29udHJvbGxlci5kdW1wQXNUZXh0KCk7CisKK3ZhciBlbGVtID0gZG9jdW1lbnQuZ2V0
RWxlbWVudEJ5SWQoInRlc3QiKTsKK3ZhciBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9u
KCk7CitzZWxlY3Rpb24uc2V0UG9zaXRpb24oZWxlbSwgMCk7CitlZGl0aW5nVGVzdCgpOworCisv
LyBSZXJ1biB0aGUgdGVzdCBidXQgaGF2ZSB0aGUgc291cmNlIGxpc3QgYmUgaW5kZW50ZWQuCitk
b2N1bWVudC5nZXRFbGVtZW50QnlJZCgidGVzdCIpLmlubmVySFRNTCA9ICI8bGk+YWxwaGE8L2xp
Pjx1bD48bGk+YmV0YTwvbGk+PGxpPmdhbW1hPC9saT48L3VsPjxsaSBpZD0nZGVsdGEnPmRlbHRh
PC9saT4iOworc2VsZWN0aW9uLnNldFBvc2l0aW9uKGVsZW0sIDApOworZWRpdGluZ1Rlc3QoKTsK
KworZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInJlc3VsdHMiKS5pbm5lclRleHQgPSAiUEFTUzog
IiArIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0ZXN0IikuaW5uZXJIVE1MOworPC9zY3JpcHQ+
CisKKzwvYm9keT4KKzwvaHRtbD4KZGlmZiAtLWdpdCBhL1dlYkNvcmUvQ2hhbmdlTG9nIGIvV2Vi
Q29yZS9DaGFuZ2VMb2cKaW5kZXggZGM5YTMwYS4uMGU4OGViMSAxMDA2NDQKLS0tIGEvV2ViQ29y
ZS9DaGFuZ2VMb2cKKysrIGIvV2ViQ29yZS9DaGFuZ2VMb2cKQEAgLTEsMyArMSwyOSBAQAorMjAx
MC0wMi0wMyAgVG9ueSBDaGFuZyAgPHRvbnlAY2hyb21pdW0ub3JnPgorCisgICAgICAgIFJldmll
d2VkIGJ5IE5PQk9EWSAoT09QUyEpLgorCisgICAgICAgIGh0dHBzOi8vYnVncy53ZWJraXQub3Jn
L3Nob3dfYnVnLmNnaT9pZD0yNDg3MgorICAgICAgICBXaGVuIHBhc3RpbmcgYSBsaXN0IGludG8g
YW5vdGhlciBsaXN0IHNob3VsZCBub3QgaW5kZW50IGFub3RoZXIgbGV2ZWwuCisgICAgICAgIElm
IHRoZSBjdXJzb3IgaXMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgbGluZSwgaXQgc2hvdWxkIGlu
c2VydCB0aGUKKyAgICAgICAgbGlzdCBpdGVtcyBiZWZvcmUgdGhlIGN1cnJlbnQgbGlzdCBpdGVt
LiAgSWYgdGhlIGN1cnNvciBpcyBhdCB0aGUgZW5kCisgICAgICAgIG9mIHRoZSBsaW5lLCBpdCBz
aG91bGQgaW5zZXJ0IHRoZSBsaXN0IGl0ZW1zIGFmdGVyIHRoZSBjdXJyZW50IGxpc3QgaXRlbS4K
KworICAgICAgICBUaGlzIG1hdGNoZXMgRmlyZWZveCBhbmQgSUUgYW5kIG1ha2VzIHRoZSBjb21t
b24gYWN0aXZpdHkgb2YgcmVvcmRlcmluZyBhIGxpc3QKKyAgICAgICAgd29yayBhcyBleHBlY3Rl
ZC4KKworICAgICAgICBUaGlzIGFsc28gYWRkcyBhIHNtYWxsIGhlbHBlciBtZXRob2QgKGlzTGlz
dEl0ZW0pIHRvIGh0bWxlZGl0aW5nLmguCisKKyAgICAgICAgVGVzdDogZWRpdGluZy9wYXN0ZWJv
YXJkL3Bhc3RlLWxpc3QtMDAyLmh0bWwKKworICAgICAgICAqIGVkaXRpbmcvUmVwbGFjZVNlbGVj
dGlvbkNvbW1hbmQuY3BwOgorICAgICAgICAoV2ViQ29yZTo6UmVwbGFjZVNlbGVjdGlvbkNvbW1h
bmQ6OmRvQXBwbHkpOgorICAgICAgICAoV2ViQ29yZTo6UmVwbGFjZVNlbGVjdGlvbkNvbW1hbmQ6
Omluc2VydEFzTGlzdEl0ZW1zKToKKyAgICAgICAgKiBlZGl0aW5nL1JlcGxhY2VTZWxlY3Rpb25D
b21tYW5kLmg6CisgICAgICAgICogZWRpdGluZy9odG1sZWRpdGluZy5jcHA6CisgICAgICAgIChX
ZWJDb3JlOjppc0xpc3RJdGVtKToKKyAgICAgICAgKFdlYkNvcmU6OmFwcGVuZGVkU3VibGlzdCk6
CisgICAgICAgICogZWRpdGluZy9odG1sZWRpdGluZy5oOgorCiAyMDEwLTAyLTAzICBBZGVsZSBQ
ZXRlcnNvbiAgPGFkZWxlQGFwcGxlLmNvbT4KIAogICAgICAgICBSZXZpZXdlZCBieSBCcmFkeSBF
aWRzb24uCmRpZmYgLS1naXQgYS9XZWJDb3JlL2VkaXRpbmcvUmVwbGFjZVNlbGVjdGlvbkNvbW1h
bmQuY3BwIGIvV2ViQ29yZS9lZGl0aW5nL1JlcGxhY2VTZWxlY3Rpb25Db21tYW5kLmNwcAppbmRl
eCA4NWE0NDcxLi5mMjY3NTdlIDEwMDY0NAotLS0gYS9XZWJDb3JlL2VkaXRpbmcvUmVwbGFjZVNl
bGVjdGlvbkNvbW1hbmQuY3BwCisrKyBiL1dlYkNvcmUvZWRpdGluZy9SZXBsYWNlU2VsZWN0aW9u
Q29tbWFuZC5jcHAKQEAgLTc1Miw5ICs3NTIsNyBAQCB2b2lkIFJlcGxhY2VTZWxlY3Rpb25Db21t
YW5kOjpkb0FwcGx5KCkKICAgICBib29sIHN0YXJ0SXNJbnNpZGVNYWlsQmxvY2txdW90ZSA9IG5l
YXJlc3RNYWlsQmxvY2txdW90ZShpbnNlcnRpb25Qb3Mubm9kZSgpKTsKICAgICAKICAgICBpZiAo
KHNlbGVjdGlvblN0YXJ0V2FzU3RhcnRPZlBhcmFncmFwaCAmJiBzZWxlY3Rpb25FbmRXYXNFbmRP
ZlBhcmFncmFwaCAmJiAhc3RhcnRJc0luc2lkZU1haWxCbG9ja3F1b3RlKSB8fAotICAgICAgICBz
dGFydEJsb2NrID09IGN1cnJlbnRSb290IHx8Ci0gICAgICAgIChzdGFydEJsb2NrICYmIHN0YXJ0
QmxvY2stPnJlbmRlcmVyKCkgJiYgc3RhcnRCbG9jay0+cmVuZGVyZXIoKS0+aXNMaXN0SXRlbSgp
KSB8fAotICAgICAgICBzZWxlY3Rpb25Jc1BsYWluVGV4dCkKKyAgICAgICAgc3RhcnRCbG9jayA9
PSBjdXJyZW50Um9vdCB8fCBpc0xpc3RJdGVtKHN0YXJ0QmxvY2spIHx8IHNlbGVjdGlvbklzUGxh
aW5UZXh0KQogICAgICAgICBtX3ByZXZlbnROZXN0aW5nID0gZmFsc2U7CiAgICAgCiAgICAgaWYg
KHNlbGVjdGlvbi5pc1JhbmdlKCkpIHsKQEAgLTg3MSw3ICs4NjksMTIgQEAgdm9pZCBSZXBsYWNl
U2VsZWN0aW9uQ29tbWFuZDo6ZG9BcHBseSgpCiAgICAgUmVmUHRyPE5vZGU+IG5vZGUgPSByZWZO
b2RlLT5uZXh0U2libGluZygpOwogICAgIAogICAgIGZyYWdtZW50LnJlbW92ZU5vZGUocmVmTm9k
ZSk7Ci0gICAgaW5zZXJ0Tm9kZUF0QW5kVXBkYXRlTm9kZXNJbnNlcnRlZChyZWZOb2RlLCBpbnNl
cnRpb25Qb3MpOworCisgICAgTm9kZSogYmxvY2tTdGFydCA9IGVuY2xvc2luZ0Jsb2NrKGluc2Vy
dGlvblBvcy5ub2RlKCkpOworICAgIGlmIChpc0xpc3RFbGVtZW50KHJlZk5vZGUuZ2V0KCkpICYm
IGJsb2NrU3RhcnQtPnJlbmRlcmVyKCktPmlzTGlzdEl0ZW0oKSkKKyAgICAgICAgcmVmTm9kZSA9
IGluc2VydEFzTGlzdEl0ZW1zKHJlZk5vZGUsIGJsb2NrU3RhcnQsIGluc2VydGlvblBvcyk7Cisg
ICAgZWxzZQorICAgICAgICBpbnNlcnROb2RlQXRBbmRVcGRhdGVOb2Rlc0luc2VydGVkKHJlZk5v
ZGUsIGluc2VydGlvblBvcyk7CiAKICAgICAvLyBNdXRhdGlvbiBldmVudHMgKGJ1ZyAyMjYzNCkg
bWF5IGhhdmUgYWxyZWFkeSByZW1vdmVkIHRoZSBpbnNlcnRlZCBjb250ZW50CiAgICAgaWYgKCFy
ZWZOb2RlLT5pbkRvY3VtZW50KCkpCkBAIC05NjAsOSArOTYzLDE1IEBAIHZvaWQgUmVwbGFjZVNl
bGVjdGlvbkNvbW1hbmQ6OmRvQXBwbHkoKQogICAgICAgICBpZiAoc2VsZWN0aW9uRW5kV2FzRW5k
T2ZQYXJhZ3JhcGggfHwgIWlzRW5kT2ZQYXJhZ3JhcGgoZW5kT2ZJbnNlcnRlZENvbnRlbnQpIHx8
IG5leHQuaXNOdWxsKCkpIHsKICAgICAgICAgICAgIGlmICghaXNTdGFydE9mUGFyYWdyYXBoKGVu
ZE9mSW5zZXJ0ZWRDb250ZW50KSkgewogICAgICAgICAgICAgICAgIHNldEVuZGluZ1NlbGVjdGlv
bihlbmRPZkluc2VydGVkQ29udGVudCk7Ci0gICAgICAgICAgICAgICAgLy8gVXNlIGEgZGVmYXVs
dCBwYXJhZ3JhcGggZWxlbWVudCAoYSBwbGFpbiBkaXYpIGZvciB0aGUgZW1wdHkgcGFyYWdyYXBo
LCB1c2luZyB0aGUgbGFzdCBwYXJhZ3JhcGgKLSAgICAgICAgICAgICAgICAvLyBibG9jaydzIHN0
eWxlIHNlZW1zIHRvIGFubm95IHVzZXJzLgotICAgICAgICAgICAgICAgIGluc2VydFBhcmFncmFw
aFNlcGFyYXRvcih0cnVlKTsKKyAgICAgICAgICAgICAgICBOb2RlKiBlbmNsb3NpbmdOb2RlID0g
ZW5jbG9zaW5nQmxvY2soZW5kT2ZJbnNlcnRlZENvbnRlbnQuZGVlcEVxdWl2YWxlbnQoKS5ub2Rl
KCkpOworICAgICAgICAgICAgICAgIGlmIChpc0xpc3RJdGVtKGVuY2xvc2luZ05vZGUpKSB7Cisg
ICAgICAgICAgICAgICAgICAgIFJlZlB0cjxOb2RlPiBuZXdMaXN0SXRlbSA9IGNyZWF0ZUxpc3RJ
dGVtRWxlbWVudChkb2N1bWVudCgpKTsKKyAgICAgICAgICAgICAgICAgICAgaW5zZXJ0Tm9kZUFm
dGVyKG5ld0xpc3RJdGVtLCBlbmNsb3NpbmdOb2RlKTsKKyAgICAgICAgICAgICAgICAgICAgc2V0
RW5kaW5nU2VsZWN0aW9uKFZpc2libGVQb3NpdGlvbihQb3NpdGlvbihuZXdMaXN0SXRlbSwgMCkp
KTsKKyAgICAgICAgICAgICAgICB9IGVsc2UKKyAgICAgICAgICAgICAgICAgICAgLy8gVXNlIGEg
ZGVmYXVsdCBwYXJhZ3JhcGggZWxlbWVudCAoYSBwbGFpbiBkaXYpIGZvciB0aGUgZW1wdHkgcGFy
YWdyYXBoLCB1c2luZyB0aGUgbGFzdCBwYXJhZ3JhcGgKKyAgICAgICAgICAgICAgICAgICAgLy8g
YmxvY2sncyBzdHlsZSBzZWVtcyB0byBhbm5veSB1c2Vycy4KKyAgICAgICAgICAgICAgICAgICAg
aW5zZXJ0UGFyYWdyYXBoU2VwYXJhdG9yKHRydWUpOwogCiAgICAgICAgICAgICAgICAgLy8gU2Vs
ZWN0IHVwIHRvIHRoZSBwYXJhZ3JhcGggc2VwYXJhdG9yIHRoYXQgd2FzIGFkZGVkLgogICAgICAg
ICAgICAgICAgIGxhc3RQb3NpdGlvblRvU2VsZWN0ID0gZW5kaW5nU2VsZWN0aW9uKCkudmlzaWJs
ZVN0YXJ0KCkuZGVlcEVxdWl2YWxlbnQoKTsKQEAgLTExMTEsNiArMTEyMCwzOSBAQCB2b2lkIFJl
cGxhY2VTZWxlY3Rpb25Db21tYW5kOjppbnNlcnROb2RlQmVmb3JlQW5kVXBkYXRlTm9kZXNJbnNl
cnRlZChQYXNzUmVmUHRyPAogICAgIHVwZGF0ZU5vZGVzSW5zZXJ0ZWQobm9kZVRvVXBkYXRlKTsK
IH0KIAorLy8gSWYgdGhlIHVzZXIgaXMgaW5zZXJ0aW5nIGEgbGlzdCBpbnRvIGFuIGV4aXN0aW5n
IGxpc3QsIGluc3RlYWQgb2YgbmVzdGluZyB0aGUgbGlzdCwKKy8vIHdlIHB1dCB0aGUgbGlzdCBp
dGVtcyBpbnRvIHRoZSBleGlzdGluZyBsaXN0LgorTm9kZSogUmVwbGFjZVNlbGVjdGlvbkNvbW1h
bmQ6Omluc2VydEFzTGlzdEl0ZW1zKFBhc3NSZWZQdHI8Tm9kZT4gbGlzdEVsZW1lbnQsIE5vZGUq
IGluc2VydGlvbk5vZGUsIGNvbnN0IFBvc2l0aW9uJiBwKQoreworICAgIHdoaWxlIChsaXN0RWxl
bWVudC0+aGFzQ2hpbGROb2RlcygpICYmIGlzTGlzdEVsZW1lbnQobGlzdEVsZW1lbnQtPmZpcnN0
Q2hpbGQoKSkgJiYgbGlzdEVsZW1lbnQtPmNoaWxkTm9kZUNvdW50KCkgPT0gMSkKKyAgICAgICAg
bGlzdEVsZW1lbnQgPSBsaXN0RWxlbWVudC0+Zmlyc3RDaGlsZCgpOworCisgICAgYm9vbCBpc1N0
YXJ0ID0gaXNTdGFydE9mUGFyYWdyYXBoKHApOworICAgIGJvb2wgaXNFbmQgPSBpc0VuZE9mUGFy
YWdyYXBoKHApOworCisgICAgTm9kZSogbGFzdE5vZGUgPSBpbnNlcnRpb25Ob2RlOworICAgIHdo
aWxlIChSZWZQdHI8Tm9kZT4gbGlzdEl0ZW0gPSBsaXN0RWxlbWVudC0+Zmlyc3RDaGlsZCgpKSB7
CisgICAgICAgIEV4Y2VwdGlvbkNvZGUgZWMgPSAwOworICAgICAgICBsaXN0RWxlbWVudC0+cmVt
b3ZlQ2hpbGQobGlzdEl0ZW0uZ2V0KCksIGVjKTsKKyAgICAgICAgQVNTRVJUKCFlYyk7CisgICAg
ICAgIGlmIChpc1N0YXJ0KQorICAgICAgICAgICAgaW5zZXJ0Tm9kZUJlZm9yZShsaXN0SXRlbSwg
bGFzdE5vZGUpOworICAgICAgICBlbHNlIGlmIChpc0VuZCkgeworICAgICAgICAgICAgaW5zZXJ0
Tm9kZUFmdGVyKGxpc3RJdGVtLCBsYXN0Tm9kZSk7CisgICAgICAgICAgICBsYXN0Tm9kZSA9IGxp
c3RJdGVtLmdldCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gRklYTUU6IElm
IHdlJ3JlIGluIHRoZSBtaWRkbGUgb2YgYSBsaXN0IGl0ZW0sIHdlIHNob3VsZCBzcGxpdCBpdCBp
bnRvIHR3byBzZXBhcmF0ZQorICAgICAgICAgICAgLy8gbGlzdCBpdGVtcyBhbmQgaW5zZXJ0IHRo
ZXNlIG5vZGVzIGJldHdlZW4gdGhlbS4gIEZvciBub3csIGp1c3QgYXBwZW5kIHRoZSBub2Rlcy4K
KyAgICAgICAgICAgIGluc2VydE5vZGVBZnRlcihsaXN0SXRlbSwgbGFzdE5vZGUpOworICAgICAg
ICAgICAgbGFzdE5vZGUgPSBsaXN0SXRlbS5nZXQoKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBp
ZiAoaXNTdGFydCkKKyAgICAgICAgbGFzdE5vZGUgPSBsYXN0Tm9kZS0+cHJldmlvdXNTaWJsaW5n
KCk7CisgICAgdXBkYXRlTm9kZXNJbnNlcnRlZChsYXN0Tm9kZSk7CisgICAgcmV0dXJuIGxhc3RO
b2RlOworfQorCiB2b2lkIFJlcGxhY2VTZWxlY3Rpb25Db21tYW5kOjp1cGRhdGVOb2Rlc0luc2Vy
dGVkKE5vZGUgKm5vZGUpCiB7CiAgICAgaWYgKCFub2RlKQpkaWZmIC0tZ2l0IGEvV2ViQ29yZS9l
ZGl0aW5nL1JlcGxhY2VTZWxlY3Rpb25Db21tYW5kLmggYi9XZWJDb3JlL2VkaXRpbmcvUmVwbGFj
ZVNlbGVjdGlvbkNvbW1hbmQuaAppbmRleCAxY2I5M2MzLi4xOWY2M2JiIDEwMDY0NAotLS0gYS9X
ZWJDb3JlL2VkaXRpbmcvUmVwbGFjZVNlbGVjdGlvbkNvbW1hbmQuaAorKysgYi9XZWJDb3JlL2Vk
aXRpbmcvUmVwbGFjZVNlbGVjdGlvbkNvbW1hbmQuaApAQCAtNTQsNiArNTQsNyBAQCBwcml2YXRl
OgogICAgIHZvaWQgaW5zZXJ0Tm9kZUFmdGVyQW5kVXBkYXRlTm9kZXNJbnNlcnRlZChQYXNzUmVm
UHRyPE5vZGU+IGluc2VydENoaWxkLCBOb2RlKiByZWZDaGlsZCk7CiAgICAgdm9pZCBpbnNlcnRO
b2RlQXRBbmRVcGRhdGVOb2Rlc0luc2VydGVkKFBhc3NSZWZQdHI8Tm9kZT4sIGNvbnN0IFBvc2l0
aW9uJik7CiAgICAgdm9pZCBpbnNlcnROb2RlQmVmb3JlQW5kVXBkYXRlTm9kZXNJbnNlcnRlZChQ
YXNzUmVmUHRyPE5vZGU+IGluc2VydENoaWxkLCBOb2RlKiByZWZDaGlsZCk7CisgICAgTm9kZSog
aW5zZXJ0QXNMaXN0SXRlbXMoUGFzc1JlZlB0cjxOb2RlPiwgTm9kZSogaW5zZXJ0aW9uTm9kZSwg
Y29uc3QgUG9zaXRpb24mKTsKIAogICAgIHZvaWQgdXBkYXRlTm9kZXNJbnNlcnRlZChOb2RlKik7
CiAgICAgYm9vbCBzaG91bGRSZW1vdmVFbmRCUihOb2RlKiwgY29uc3QgVmlzaWJsZVBvc2l0aW9u
Jik7CmRpZmYgLS1naXQgYS9XZWJDb3JlL2VkaXRpbmcvaHRtbGVkaXRpbmcuY3BwIGIvV2ViQ29y
ZS9lZGl0aW5nL2h0bWxlZGl0aW5nLmNwcAppbmRleCBiNThkZmYzLi40OTgxZjYzIDEwMDY0NAot
LS0gYS9XZWJDb3JlL2VkaXRpbmcvaHRtbGVkaXRpbmcuY3BwCisrKyBiL1dlYkNvcmUvZWRpdGlu
Zy9odG1sZWRpdGluZy5jcHAKQEAgLTY1OCw2ICs2NTgsMTEgQEAgYm9vbCBpc0xpc3RFbGVtZW50
KE5vZGUgKm4pCiAgICAgcmV0dXJuIChuICYmIChuLT5oYXNUYWdOYW1lKHVsVGFnKSB8fCBuLT5o
YXNUYWdOYW1lKG9sVGFnKSB8fCBuLT5oYXNUYWdOYW1lKGRsVGFnKSkpOwogfQogCitib29sIGlz
TGlzdEl0ZW0oTm9kZSAqbikKK3sKKyAgICByZXR1cm4gbiAmJiBuLT5yZW5kZXJlcigpICYmIG4t
PnJlbmRlcmVyKCktPmlzTGlzdEl0ZW0oKTsKK30KKwogTm9kZSogZW5jbG9zaW5nTm9kZVdpdGhU
YWcoY29uc3QgUG9zaXRpb24mIHAsIGNvbnN0IFF1YWxpZmllZE5hbWUmIHRhZ05hbWUpCiB7CiAg
ICAgaWYgKHAuaXNOdWxsKCkpCkBAIC03NzksNyArNzg0LDcgQEAgc3RhdGljIE5vZGUqIGFwcGVu
ZGVkU3VibGlzdChOb2RlKiBsaXN0SXRlbSkKICAgICBmb3IgKE5vZGUqIG4gPSBsaXN0SXRlbS0+
bmV4dFNpYmxpbmcoKTsgbjsgbiA9IG4tPm5leHRTaWJsaW5nKCkpIHsKICAgICAgICAgaWYgKGlz
TGlzdEVsZW1lbnQobikpCiAgICAgICAgICAgICByZXR1cm4gc3RhdGljX2Nhc3Q8SFRNTEVsZW1l
bnQqPihuKTsKLSAgICAgICAgaWYgKG4tPnJlbmRlcmVyKCkgJiYgbi0+cmVuZGVyZXIoKS0+aXNM
aXN0SXRlbSgpKQorICAgICAgICBpZiAoaXNMaXN0SXRlbShsaXN0SXRlbSkpCiAgICAgICAgICAg
ICByZXR1cm4gMDsKICAgICB9CiAgICAgCmRpZmYgLS1naXQgYS9XZWJDb3JlL2VkaXRpbmcvaHRt
bGVkaXRpbmcuaCBiL1dlYkNvcmUvZWRpdGluZy9odG1sZWRpdGluZy5oCmluZGV4IGM1YTQ0YWMu
LmVmM2RiMzUgMTAwNjQ0Ci0tLSBhL1dlYkNvcmUvZWRpdGluZy9odG1sZWRpdGluZy5oCisrKyBi
L1dlYkNvcmUvZWRpdGluZy9odG1sZWRpdGluZy5oCkBAIC05MCw2ICs5MCw3IEBAIGJvb2wgaXNU
YWJsZUNlbGwoY29uc3QgTm9kZSopOwogYm9vbCBpc0VtcHR5VGFibGVDZWxsKGNvbnN0IE5vZGUq
KTsKIGJvb2wgaXNUYWJsZVN0cnVjdHVyZU5vZGUoY29uc3QgTm9kZSopOwogYm9vbCBpc0xpc3RF
bGVtZW50KE5vZGUqKTsKK2Jvb2wgaXNMaXN0SXRlbShOb2RlKik7CiBib29sIGlzTm9kZVJlbmRl
cmVkKGNvbnN0IE5vZGUqKTsKIGJvb2wgaXNOb2RlVmlzaWJseUNvbnRhaW5lZFdpdGhpbihOb2Rl
KiwgY29uc3QgUmFuZ2UqKTsKIGJvb2wgaXNSZW5kZXJlZEFzTm9uSW5saW5lVGFibGVJbWFnZU9y
SFIoY29uc3QgTm9kZSopOwo=
</data>
<flag name="review"
          id="30701"
          type_id="1"
          status="+"
          setter="eric"
    />
          </attachment>
      

    </bug>

</bugzilla>