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

<bugzilla version="5.0.6"
          urlbase="https://bugs.kde.org/"
          
          maintainer="sysadmin@kde.org"
>

    <bug>
          <bug_id>154408</bug_id>
          
          <creation_ts>2007-12-21 02:24:20 +0000</creation_ts>
          <short_desc>collection sort should not always be lexicographic</short_desc>
          <delta_ts>2008-10-26 11:21:39 +0000</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>2</classification_id>
          <classification>Applications</classification>
          <product>amarok</product>
          <component>general</component>
          <version>1.4.7</version>
          <rep_platform>Debian testing</rep_platform>
          <op_sys>Linux</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>NOR</priority>
          <bug_severity>wishlist</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>0</everconfirmed>
          <reporter name="Nicholas Wilson">nicholas</reporter>
          <assigned_to name="Amarok Bugs">amarok-bugs-null</assigned_to>
          
          
          <cf_commitlink></cf_commitlink>
          <cf_versionfixedin></cf_versionfixedin>
          <cf_sentryurl></cf_sentryurl>
          <votes>0</votes>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>565278</commentid>
    <comment_count>0</comment_count>
    <who name="Nicholas Wilson">nicholas</who>
    <bug_when>2007-12-21 02:24:20 +0000</bug_when>
    <thetext>Version:           1.4.7 (using KDE KDE 3.5.8)
Installed from:    Debian testing/unstable Packages
OS:                Linux

For numbers in strings, could the sorting switch to numerical ordering?  In my collection, I have all sorts of incongruities, like

- Mahler, Gustav
 | ...
 | Symphony 1
 | Symphony 10
 | Symphony 2
 |-...

To fix this, we might have something like (pseudocode)

operator customSort (QString a, Qstring b) {
    int aIndex = find [0-9] in a;
    int bIndex;
    if (aIndex != npos &amp;&amp; (bIndex = find [0-9] in b) != npos &amp;&amp; aIndex != bIndex) return a &lt; b; //lexicographically
    
    //tokenise at the digit boundaries: 
    //a[initial] is a up to aIndex, a[number] is the number contained in the string, and a[final] is the end
    //eg. if a = &quot;test123test123&quot;, then a[initial] = &quot;test&quot;, a[number] = 123, and a[final] = &quot;test123&quot;
    
    if (a[initial] != b[inital]) return a &lt; b; //lexicographically

    if (a[number] != b[number]) return a[number] &lt; b[number]; //numerically

    return customSort(a[final], b[final]);  //recurse on the tails
}

This quite simple procedure would make things much more intuitive for me, and it is restrictive enough that it should not annoy people: the numerical part never kicks in until we know all the letters before match.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>567058</commentid>
    <comment_count>1</comment_count>
    <who name="Nicholas Wilson">nicholas</who>
    <bug_when>2007-12-29 22:20:36 +0000</bug_when>
    <thetext>This works now with new versions of collectionbrowser/CollectionSortFilterProxyModel.h and collectionbrowser/CollectionSortFilterProxyModel.cpp.  (Against SVN 29/12/07)

collectionbrowser/CollectionSortFilterProxyModel.h:
---------------------------------------------------

class CollectionSortFilterProxyModel : public QSortFilterProxyModel
{
    public:
        CollectionSortFilterProxyModel( QObject * parent = 0 ); 
         virtual ~CollectionSortFilterProxyModel();
 
        bool hasChildren(const QModelIndex &amp;parent) const;

    protected:
        virtual bool lessThan( const QModelIndex &amp;left, const QModelIndex &amp;right ) const;
        virtual bool lessThanString( const QString a, const QString b ) const;
};

collectionbrowser/CollectionSortFilterProxyModel.cpp:
-----------------------------------------------------

bool
CollectionSortFilterProxyModel::lessThan( const QModelIndex &amp;left, const QModelIndex &amp;right ) const
{
    CollectionTreeItem *leftItem = static_cast&lt;CollectionTreeItem*&gt;( left.internalPointer() );
    CollectionTreeItem *rightItem = static_cast&lt;CollectionTreeItem*&gt;( right.internalPointer() );

    //Here we catch the bottom &apos;track&apos; level
    if( leftItem-&gt;level() == rightItem-&gt;level() )
    {
        const Meta::TrackPtr leftTrack = Meta::TrackPtr::dynamicCast( leftItem-&gt;data() );
        const Meta::TrackPtr rightTrack = Meta::TrackPtr::dynamicCast( rightItem-&gt;data() );
        if( !leftTrack.isNull()  &amp;&amp; !rightTrack.isNull() )
            return leftTrack-&gt;trackNumber() &lt; rightTrack-&gt;trackNumber();
    }

    //This should catch everything else
    QVariant leftData = left.data();
    QVariant rightData = right.data();
    if( leftData.canConvert( QVariant::String ) &amp;&amp; rightData.canConvert( QVariant::String ) ) {
        return lessThanString( leftData.toString().toLower(), rightData.toString().toLower() );
    }

    warning() &lt;&lt; &quot;failed: an unexpected comparison was made&quot;;

    //Just in case
    return QSortFilterProxyModel::lessThan( left, right );
}

bool
CollectionSortFilterProxyModel::lessThanString( const QString a, const QString b ) const
{
    int compareIndices[2];
    compareIndices[0] = a.indexOf(QRegExp(&quot;\\d&quot;));
    if ( compareIndices[0] == -1 || (compareIndices[1] = b.indexOf(QRegExp(&quot;\\d&quot;))) == -1
            || compareIndices[0] != compareIndices[1])
        return QString::localeAwareCompare( a, b ) &lt; 0;

    QString toCompare[2];
    int intToCompare[2];
    toCompare[0] = a.left( compareIndices[0] );
    toCompare[1] = b.left( compareIndices[1] );
    int rv = QString::localeAwareCompare( toCompare[0], toCompare[1] );
    if( rv != 0 ) return rv &lt; 0;

    toCompare[0] = a.mid( compareIndices[0] );
    toCompare[1] = b.mid( compareIndices[1] );
    for( int i = 0; i &lt; 2; ++i )
    {
        compareIndices[i] = toCompare[i].indexOf( QRegExp(&quot;\\D&quot;) );
        if ( compareIndices[i] == -1 ) compareIndices[i] = toCompare[i].length();
        intToCompare[i] = toCompare[i].left( compareIndices[i] ).toInt();
    }

    rv = intToCompare[0] - intToCompare[1];
    if( rv != 0 ) return rv &lt; 0;

    for( int i = 0; i &lt; 2; ++i )
        toCompare[i] =  toCompare[i].mid( compareIndices[i] );

    return CollectionSortFilterProxyModel::lessThanString( toCompare[0], toCompare[1] );
}</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>567060</commentid>
    <comment_count>2</comment_count>
    <who name="Nicholas Wilson">nicholas</who>
    <bug_when>2007-12-29 22:29:15 +0000</bug_when>
    <thetext>Better:

Index: src/collectionbrowser/CollectionSortFilterProxyModel.h
===================================================================
--- src/collectionbrowser/CollectionSortFilterProxyModel.h      (revision 754278)
+++ src/collectionbrowser/CollectionSortFilterProxyModel.h      (working copy)
@@ -38,6 +38,7 @@

     protected:
         virtual bool lessThan( const QModelIndex &amp;left, const QModelIndex &amp;right ) const;
+        virtual bool lessThanString( const QString a, const QString b ) const;


 };
Index: src/collectionbrowser/CollectionSortFilterProxyModel.cpp
===================================================================
--- src/collectionbrowser/CollectionSortFilterProxyModel.cpp    (revision 754278)
+++ src/collectionbrowser/CollectionSortFilterProxyModel.cpp    (working copy)
@@ -19,11 +19,16 @@

 #include &quot;CollectionSortFilterProxyModel.h&quot;
 #include &quot;CollectionTreeItem.h&quot;
+#include &quot;debug.h&quot;
+#include &quot;QVariant&quot;
+#include &quot;QString&quot;

 CollectionSortFilterProxyModel::CollectionSortFilterProxyModel(  QObject * parent )
  : QSortFilterProxyModel( parent )
 {
     setDynamicSortFilter( true );
+    setSortLocaleAware( true );
+    setSortCaseSensitivity( Qt::CaseInsensitive );
 }


@@ -44,6 +49,7 @@
     CollectionTreeItem *leftItem = static_cast&lt;CollectionTreeItem*&gt;( left.internalPointer() );
     CollectionTreeItem *rightItem = static_cast&lt;CollectionTreeItem*&gt;( right.internalPointer() );

+    //Here we catch the bottom &apos;track&apos; level
     if( leftItem-&gt;level() == rightItem-&gt;level() )
     {
         const Meta::TrackPtr leftTrack = Meta::TrackPtr::dynamicCast( leftItem-&gt;data() );
@@ -51,7 +57,50 @@
         if( !leftTrack.isNull()  &amp;&amp; !rightTrack.isNull() )
             return leftTrack-&gt;trackNumber() &lt; rightTrack-&gt;trackNumber();
     }
-    return QSortFilterProxyModel::lessThan( left, right ); //Bad idea fallthrough
+
+    //This should catch everything else
+    QVariant leftData = left.data();
+    QVariant rightData = right.data();
+    if( leftData.canConvert( QVariant::String ) &amp;&amp; rightData.canConvert( QVariant::String ) ) {
+        return lessThanString( leftData.toString().toLower(), rightData.toString().toLower() );
+    }
+
+    warning() &lt;&lt; &quot;failed: an unexpected comparison was made&quot;;
+
+    //Just in case
+    return QSortFilterProxyModel::lessThan( left, right );
 }

+bool
+CollectionSortFilterProxyModel::lessThanString( const QString a, const QString b ) const
+{
+    int compareIndices[2];
+    compareIndices[0] = a.indexOf(QRegExp(&quot;\\d&quot;));
+    if ( compareIndices[0] == -1 || (compareIndices[1] = b.indexOf(QRegExp(&quot;\\d&quot;))) == -1
+            || compareIndices[0] != compareIndices[1])
+        return QString::localeAwareCompare( a, b ) &lt; 0;

+    QString toCompare[2];
+    int intToCompare[2];
+    toCompare[0] = a.left( compareIndices[0] );
+    toCompare[1] = b.left( compareIndices[1] );
+    int rv = QString::localeAwareCompare( toCompare[0], toCompare[1] );
+    if( rv != 0 ) return rv &lt; 0;
+
+    toCompare[0] = a.mid( compareIndices[0] );
+    toCompare[1] = b.mid( compareIndices[1] );
+    for( int i = 0; i &lt; 2; ++i )
+    {
+        compareIndices[i] = toCompare[i].indexOf( QRegExp(&quot;\\D&quot;) );
+        if ( compareIndices[i] == -1 ) compareIndices[i] = toCompare[i].length();
+        intToCompare[i] = toCompare[i].left( compareIndices[i] ).toInt();
+    }
+
+    rv = intToCompare[0] - intToCompare[1];
+    if( rv != 0 ) return rv &lt; 0;
+
+    for( int i = 0; i &lt; 2; ++i )
+        toCompare[i] =  toCompare[i].mid( compareIndices[i] );
+
+    return CollectionSortFilterProxyModel::lessThanString( toCompare[0], toCompare[1] );
+}</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>567063</commentid>
    <comment_count>3</comment_count>
    <who name="Seb Ruiz">ruiz</who>
    <bug_when>2007-12-29 22:34:16 +0000</bug_when>
    <thetext>Thanks for the patch! But can you please attach it to the bug report, not as a text dump?

Use the command:
svn diff &gt; mypatch.diff

then upload the diff file.

Cheers</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>567239</commentid>
    <comment_count>4</comment_count>
      <attachid>22777</attachid>
    <who name="Nicholas Wilson">nicholas</who>
    <bug_when>2007-12-30 20:31:42 +0000</bug_when>
    <thetext>Created attachment 22777
Fixes the sorting behaviour</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>657080</commentid>
    <comment_count>5</comment_count>
    <who name="Seb Ruiz">ruiz</who>
    <bug_when>2008-10-26 11:19:38 +0000</bug_when>
    <thetext>SVN commit 876025 by seb:

Collection browser: Use an intelligent natural sort algorithm which isn&apos;t necessarily a lexicographical comparison.
Eg: &quot;Symphony 2&quot; &lt; &quot;Symphony 10&quot;
Patch by Nicholas Wilson &lt;nicholas@nickcwilson.co.uk&gt;
BUG: 154408

@nick: sorry it took so long to apply this patch. a combination of new years and me being overseas directly after that obviously contributing factors to overlooking your patch :)


 M  +63 -1     CollectionSortFilterProxyModel.cpp  
 M  +1 -2      CollectionSortFilterProxyModel.h  
 M  +3 -3      CollectionTreeItemModelBase.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&amp;revision=876025
</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>657081</commentid>
    <comment_count>6</comment_count>
    <who name="Seb Ruiz">ruiz</who>
    <bug_when>2008-10-26 11:21:39 +0000</bug_when>
    <thetext>SVN commit 876026 by seb:

Update changelog
CCBUG: 154408


 M  +3 -0      ChangeLog  


WebSVN link: http://websvn.kde.org/?view=rev&amp;revision=876026
</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>22777</attachid>
            <date>2007-12-30 20:31:42 +0000</date>
            <delta_ts>2007-12-30 20:31:42 +0000</delta_ts>
            <desc>Fixes the sorting behaviour</desc>
            <filename>sortingPatch.diff</filename>
            <type>text/plain</type>
            <size>3842</size>
            <attacher name="Nicholas Wilson">nicholas</attacher>
            
              <data encoding="base64">SW5kZXg6IHNyYy9jb2xsZWN0aW9uYnJvd3Nlci9Db2xsZWN0aW9uU29ydEZpbHRlclByb3h5TW9k
ZWwuaCAKID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT0gCiAtLS0gc3JjL2NvbGxlY3Rpb25icm93c2VyL0NvbGxlY3Rpb25T
b3J0RmlsdGVyUHJveHlNb2RlbC5oICAgICAgKHJldmlzaW9uIDc1NDI3OCkgCiArKysgc3JjL2Nv
bGxlY3Rpb25icm93c2VyL0NvbGxlY3Rpb25Tb3J0RmlsdGVyUHJveHlNb2RlbC5oICAgICAgKHdv
cmtpbmcgY29weSkgCiAgYXQgIGF0ICAtMzgsNiArMzgsNyAgYXQgIGF0IAogCiAgICAgIHByb3Rl
Y3RlZDogCiAgICAgICAgICB2aXJ0dWFsIGJvb2wgbGVzc1RoYW4oIGNvbnN0IFFNb2RlbEluZGV4
ICZsZWZ0LCBjb25zdCBRTW9kZWxJbmRleCAmcmlnaHQgKSBjb25zdDsgCiArICAgICAgICB2aXJ0
dWFsIGJvb2wgbGVzc1RoYW5TdHJpbmcoIGNvbnN0IFFTdHJpbmcgYSwgY29uc3QgUVN0cmluZyBi
ICkgY29uc3Q7IAogCiAKICB9OyAKIEluZGV4OiBzcmMvY29sbGVjdGlvbmJyb3dzZXIvQ29sbGVj
dGlvblNvcnRGaWx0ZXJQcm94eU1vZGVsLmNwcCAKID09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gCiAtLS0gc3JjL2NvbGxl
Y3Rpb25icm93c2VyL0NvbGxlY3Rpb25Tb3J0RmlsdGVyUHJveHlNb2RlbC5jcHAgICAgKHJldmlz
aW9uIDc1NDI3OCkgCiArKysgc3JjL2NvbGxlY3Rpb25icm93c2VyL0NvbGxlY3Rpb25Tb3J0Rmls
dGVyUHJveHlNb2RlbC5jcHAgICAgKHdvcmtpbmcgY29weSkgCiAgYXQgIGF0ICAtMTksMTEgKzE5
LDE2ICBhdCAgYXQgCiAKICAjaW5jbHVkZSAiQ29sbGVjdGlvblNvcnRGaWx0ZXJQcm94eU1vZGVs
LmgiIAogICNpbmNsdWRlICJDb2xsZWN0aW9uVHJlZUl0ZW0uaCIgCiArI2luY2x1ZGUgImRlYnVn
LmgiIAogKyNpbmNsdWRlICJRVmFyaWFudCIgCiArI2luY2x1ZGUgIlFTdHJpbmciIAogCiAgQ29s
bGVjdGlvblNvcnRGaWx0ZXJQcm94eU1vZGVsOjpDb2xsZWN0aW9uU29ydEZpbHRlclByb3h5TW9k
ZWwoICBRT2JqZWN0ICogcGFyZW50ICkgCiAgIDogUVNvcnRGaWx0ZXJQcm94eU1vZGVsKCBwYXJl
bnQgKSAKICB7IAogICAgICBzZXREeW5hbWljU29ydEZpbHRlciggdHJ1ZSApOyAKICsgICAgc2V0
U29ydExvY2FsZUF3YXJlKCB0cnVlICk7IAogKyAgICBzZXRTb3J0Q2FzZVNlbnNpdGl2aXR5KCBR
dDo6Q2FzZUluc2Vuc2l0aXZlICk7IAogIH0gCiAKIAogIGF0ICBhdCAgLTQ0LDYgKzQ5LDcgIGF0
ICBhdCAKICAgICAgQ29sbGVjdGlvblRyZWVJdGVtICpsZWZ0SXRlbSA9IHN0YXRpY19jYXN0PENv
bGxlY3Rpb25UcmVlSXRlbSo+KCBsZWZ0LmludGVybmFsUG9pbnRlcigpICk7IAogICAgICBDb2xs
ZWN0aW9uVHJlZUl0ZW0gKnJpZ2h0SXRlbSA9IHN0YXRpY19jYXN0PENvbGxlY3Rpb25UcmVlSXRl
bSo+KCByaWdodC5pbnRlcm5hbFBvaW50ZXIoKSApOyAKIAogKyAgICAvL0hlcmUgd2UgY2F0Y2gg
dGhlIGJvdHRvbSAndHJhY2snIGxldmVsIAogICAgICBpZiggbGVmdEl0ZW0tPmxldmVsKCkgPT0g
cmlnaHRJdGVtLT5sZXZlbCgpICkgCiAgICAgIHsgCiAgICAgICAgICBjb25zdCBNZXRhOjpUcmFj
a1B0ciBsZWZ0VHJhY2sgPSBNZXRhOjpUcmFja1B0cjo6ZHluYW1pY0Nhc3QoIGxlZnRJdGVtLT5k
YXRhKCkgKTsgCiAgYXQgIGF0ICAtNTEsNyArNTcsNTAgIGF0ICBhdCAKICAgICAgICAgIGlmKCAh
bGVmdFRyYWNrLmlzTnVsbCgpICAmJiAhcmlnaHRUcmFjay5pc051bGwoKSApIAogICAgICAgICAg
ICAgIHJldHVybiBsZWZ0VHJhY2stPnRyYWNrTnVtYmVyKCkgPCByaWdodFRyYWNrLT50cmFja051
bWJlcigpOyAKICAgICAgfSAKIC0gICAgcmV0dXJuIFFTb3J0RmlsdGVyUHJveHlNb2RlbDo6bGVz
c1RoYW4oIGxlZnQsIHJpZ2h0ICk7IC8vQmFkIGlkZWEgZmFsbHRocm91Z2ggCiArIAogKyAgICAv
L1RoaXMgc2hvdWxkIGNhdGNoIGV2ZXJ5dGhpbmcgZWxzZSAKICsgICAgUVZhcmlhbnQgbGVmdERh
dGEgPSBsZWZ0LmRhdGEoKTsgCiArICAgIFFWYXJpYW50IHJpZ2h0RGF0YSA9IHJpZ2h0LmRhdGEo
KTsgCiArICAgIGlmKCBsZWZ0RGF0YS5jYW5Db252ZXJ0KCBRVmFyaWFudDo6U3RyaW5nICkgJiYg
cmlnaHREYXRhLmNhbkNvbnZlcnQoIFFWYXJpYW50OjpTdHJpbmcgKSApIHsgCiArICAgICAgICBy
ZXR1cm4gbGVzc1RoYW5TdHJpbmcoIGxlZnREYXRhLnRvU3RyaW5nKCkudG9Mb3dlcigpLCByaWdo
dERhdGEudG9TdHJpbmcoKS50b0xvd2VyKCkgKTsgCiArICAgIH0gCiArIAogKyAgICB3YXJuaW5n
KCkgPDwgImZhaWxlZDogYW4gdW5leHBlY3RlZCBjb21wYXJpc29uIHdhcyBtYWRlIjsgCiArIAog
KyAgICAvL0p1c3QgaW4gY2FzZSAKICsgICAgcmV0dXJuIFFTb3J0RmlsdGVyUHJveHlNb2RlbDo6
bGVzc1RoYW4oIGxlZnQsIHJpZ2h0ICk7IAogIH0gCiAKICtib29sIAogK0NvbGxlY3Rpb25Tb3J0
RmlsdGVyUHJveHlNb2RlbDo6bGVzc1RoYW5TdHJpbmcoIGNvbnN0IFFTdHJpbmcgYSwgY29uc3Qg
UVN0cmluZyBiICkgY29uc3QgCiAreyAKICsgICAgaW50IGNvbXBhcmVJbmRpY2VzWzJdOyAKICsg
ICAgY29tcGFyZUluZGljZXNbMF0gPSBhLmluZGV4T2YoUVJlZ0V4cCgiXFxkIikpOyAKICsgICAg
aWYgKCBjb21wYXJlSW5kaWNlc1swXSA9PSAtMSB8fCAoY29tcGFyZUluZGljZXNbMV0gPSBiLmlu
ZGV4T2YoUVJlZ0V4cCgiXFxkIikpKSA9PSAtMSAKICsgICAgICAgICAgICB8fCBjb21wYXJlSW5k
aWNlc1swXSAhPSBjb21wYXJlSW5kaWNlc1sxXSkgCiArICAgICAgICByZXR1cm4gUVN0cmluZzo6
bG9jYWxlQXdhcmVDb21wYXJlKCBhLCBiICkgPCAwOyAKIAogKyAgICBRU3RyaW5nIHRvQ29tcGFy
ZVsyXTsgCiArICAgIGludCBpbnRUb0NvbXBhcmVbMl07IAogKyAgICB0b0NvbXBhcmVbMF0gPSBh
LmxlZnQoIGNvbXBhcmVJbmRpY2VzWzBdICk7IAogKyAgICB0b0NvbXBhcmVbMV0gPSBiLmxlZnQo
IGNvbXBhcmVJbmRpY2VzWzFdICk7IAogKyAgICBpbnQgcnYgPSBRU3RyaW5nOjpsb2NhbGVBd2Fy
ZUNvbXBhcmUoIHRvQ29tcGFyZVswXSwgdG9Db21wYXJlWzFdICk7IAogKyAgICBpZiggcnYgIT0g
MCApIHJldHVybiBydiA8IDA7IAogKyAKICsgICAgdG9Db21wYXJlWzBdID0gYS5taWQoIGNvbXBh
cmVJbmRpY2VzWzBdICk7IAogKyAgICB0b0NvbXBhcmVbMV0gPSBiLm1pZCggY29tcGFyZUluZGlj
ZXNbMV0gKTsgCiArICAgIGZvciggaW50IGkgPSAwOyBpIDwgMjsgKytpICkgCiArICAgIHsgCiAr
ICAgICAgICBjb21wYXJlSW5kaWNlc1tpXSA9IHRvQ29tcGFyZVtpXS5pbmRleE9mKCBRUmVnRXhw
KCJcXEQiKSApOyAKICsgICAgICAgIGlmICggY29tcGFyZUluZGljZXNbaV0gPT0gLTEgKSBjb21w
YXJlSW5kaWNlc1tpXSA9IHRvQ29tcGFyZVtpXS5sZW5ndGgoKTsgCiArICAgICAgICBpbnRUb0Nv
bXBhcmVbaV0gPSB0b0NvbXBhcmVbaV0ubGVmdCggY29tcGFyZUluZGljZXNbaV0gKS50b0ludCgp
OyAKICsgICAgfSAKICsgCiArICAgIHJ2ID0gaW50VG9Db21wYXJlWzBdIC0gaW50VG9Db21wYXJl
WzFdOyAKICsgICAgaWYoIHJ2ICE9IDAgKSByZXR1cm4gcnYgPCAwOyAKICsgCiArICAgIGZvcigg
aW50IGkgPSAwOyBpIDwgMjsgKytpICkgCiArICAgICAgICB0b0NvbXBhcmVbaV0gPSAgdG9Db21w
YXJlW2ldLm1pZCggY29tcGFyZUluZGljZXNbaV0gKTsgCiArIAogKyAgICByZXR1cm4gQ29sbGVj
dGlvblNvcnRGaWx0ZXJQcm94eU1vZGVsOjpsZXNzVGhhblN0cmluZyggdG9Db21wYXJlWzBdLCB0
b0NvbXBhcmVbMV0gKTsgCiArfSAKIAo=
</data>

          </attachment>
      

    </bug>

</bugzilla>