LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA2IE9yYWNsZSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgMi4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHBzOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAvCiAqCiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wCiAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgIE9yYWNsZSBDb3Jwb3JhdGlvbiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS5icGVsLnZhbGlkYXRvci5ydWxlczsKCi8qKgogKiBEZXBlbmRlbmN5IG9uIHRoZSBCUEVMIHZhbGlkYXRpb24gbW9kZWwgb25seSBpbiBoZXJlIC4uLgogKi8KaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmJwZWwudmFsaWRhdG9yLm1vZGVsLkFSdWxlOwppbXBvcnQgb3JnLmVjbGlwc2UuYnBlbC52YWxpZGF0b3IubW9kZWwuRmlsdGVyczsKaW1wb3J0IG9yZy5lY2xpcHNlLmJwZWwudmFsaWRhdG9yLm1vZGVsLklNb2RlbFF1ZXJ5TG9va3VwczsKaW1wb3J0IG9yZy5lY2xpcHNlLmJwZWwudmFsaWRhdG9yLm1vZGVsLklOb2RlOwppbXBvcnQgb3JnLmVjbGlwc2UuYnBlbC52YWxpZGF0b3IubW9kZWwuSVByb2JsZW07CgoKLyoqCiAqIFZhbGlkYXRlIHRoZSBpbnZva2UgYWN0aXZpdHkuCiAqIAogKiBAYXV0aG9yIE1pY2hhbCBDaG1pZWxld3NraSAobWljaGFsLmNobWllbGV3c2tpQG9yYWNsZS5jb20pCiAqIEBkYXRlIFNlcCAxOSwgMjAwNgogKgogKi8KCkBTdXBwcmVzc1dhcm5pbmdzKHsgIm5scyIsICJib3hpbmciIH0pCgpwdWJsaWMgY2xhc3MgSW52b2tlVmFsaWRhdG9yIGV4dGVuZHMgQ1BhcnRuZXJBY3Rpdml0eVZhbGlkYXRvciB7CgoJLyoqCgkgKiBSdWxlIHRvIGNoZWNrIHRoZSBuYW1lIG9mIHRoZSB2YXJpYWJsZS4gCgkgKi8KCQoJSU5vZGUgZlBhcnRuZXJSb2xlTm9kZTsKCUlOb2RlIGZJbnB1dFZhcmlhYmxlTm9kZTsKCUlOb2RlIGZPdXRwdXRWYXJpYWJsZU5vZGU7CgoJCglJTm9kZSBmUG9ydFR5cGVGcm9tUm9sZU5vZGU7CglMaXN0PElOb2RlPiBmVG9QYXJ0c1BhcnRzOwoJTGlzdDxJTm9kZT4gZkZyb21QYXJ0czsKCQoJU3RyaW5nIGZJbnB1dFZhcmlhYmxlTmFtZTsKCVN0cmluZyBmT3V0cHV0VmFyaWFibGVOYW1lOwoJCQkKCQoJLyoqIChub24tSmF2YWRvYykKCSAqIEBzZWUgb3JnLmVjbGlwc2UuYnBlbC52YWxpZGF0b3IucnVsZXMuQ1ZhbGlkYXRvciNjaGVja0NoaWxkcmVuKCkKCSAqLwoJQE92ZXJyaWRlCglwdWJsaWMgdm9pZCBjaGVja0NoaWxkcmVuICgpIHsKCQlzdXBlci5jaGVja0NoaWxkcmVuKCk7CgkJY2hlY2tDaGlsZChORF9DQVRDSCwwLEludGVnZXIuTUFYX1ZBTFVFKTsKCQljaGVja0NoaWxkKE5EX0NBVENIX0FMTCwwLDEpOwoJCWNoZWNrQ2hpbGQoTkRfQ09NUEVOU0FUSU9OX0hBTkRMRVIsMCwxKTsKCQljaGVja0NoaWxkKE5EX1RPX1BBUlRTLDAsMSk7CQkKCQljaGVja0NoaWxkKE5EX0ZST01fUEFSVFMsMCwxKTsKCX0KCgkKCS8qKgoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLmJwZWwudmFsaWRhdG9yLm1vZGVsLlZhbGlkYXRvciNzdGFydCgpCgkgKi8KCQoJQE92ZXJyaWRlCglwcm90ZWN0ZWQgdm9pZCBzdGFydCAoKSB7CgkJCgkJc3VwZXIuc3RhcnQoKTsJCQoJCQkJCgkJZklucHV0VmFyaWFibGVOYW1lID0gZ2V0QXR0cmlidXRlKG1Ob2RlLCBBVF9JTlBVVF9WQVJJQUJMRSwgS0lORF9BQ1RJVklUWSwgRmlsdGVycy5OQ19OQU1FLGZhbHNlKTsKCQkKCQlpZiAoaXNFbXB0eShmSW5wdXRWYXJpYWJsZU5hbWUpID09IGZhbHNlKSB7CgkJCQoJCQlmSW5wdXRWYXJpYWJsZU5vZGUgPSBtTW9kZWxRdWVyeS5sb29rdXAobU5vZGUsCgkJCQkJSU1vZGVsUXVlcnlMb29rdXBzLkxPT0tVUF9OT0RFX1ZBUklBQkxFLAoJCQkJCWZJbnB1dFZhcmlhYmxlTmFtZSApOwoJCQkKCQl9CgkJCgkJZk91dHB1dFZhcmlhYmxlTmFtZSA9IGdldEF0dHJpYnV0ZShtTm9kZSwgQVRfT1VUUFVUX1ZBUklBQkxFLCBLSU5EX0FDVElWSVRZLCBGaWx0ZXJzLk5DX05BTUUsIGZhbHNlKTsKCQkKCQlpZiAoaXNFbXB0eShmT3V0cHV0VmFyaWFibGVOYW1lKSA9PSBmYWxzZSkgewkJCQkJCgkJCWZPdXRwdXRWYXJpYWJsZU5vZGUgPSBtTW9kZWxRdWVyeS5sb29rdXAobU5vZGUsCQkJCQkKCQkJCQlJTW9kZWxRdWVyeUxvb2t1cHMuTE9PS1VQX05PREVfVkFSSUFCTEUsCgkJCQkJZk91dHB1dFZhcmlhYmxlTmFtZSApOwoJCX0JCQkKCQoJCWZQYXJ0bmVyTGlua1R5cGUgPSBudWxsOwoJCWZQYXJ0bmVyUm9sZU5vZGUgPSBudWxsOwoJCQoJfQoKCgkvKioKCSAqIENoZWNrIHRoZSBpbnB1dCB2YXJpYWJsZSBvbiB0aGlzIEludm9rZSBhY3Rpdml0eS4KCSAqCgkgKi8KCQoJQEFSdWxlKAoJCXNhID0gMjAwMywKCQlkZXNjID0gIkNoZWNrIGlmIGlucHV0VmFyaWFibGUgaXMgc2V0IGFuZCBleGlzdHMgYW5kIGlzIGRlZmluZWQgY29ycmVjdGx5LiIsCgkJYXV0aG9yPSJtaWNoYWwuY2htaWVsZXdza2lAb3JhY2xlLmNvbSIsCgkJZGF0ZSA9ICIwMS8yMC8yMDA3IiwKCQllcnJvcnM9IkJQRUxDX19VTlNFVF9BVFRSSUJVVEUsQlBFTENfX1VOUkVTT0xWRURfQVRUUklCVVRFLEJQRUxDX19JTlZBTElEX0FUVFJJQlVURV9WQUxVRSIsCgkJd2FybmluZ3M9IkJQRUxDX1JFRl9OT0RFX1BST0JMRU1TIgoJKQoJcHVibGljIHZvaWQgcnVsZV9DaGVja0lucHV0VmFyaWFibGVfMyAoKSB7CgkJZklucHV0VmFyaWFibGVOb2RlID0gdmVyaWZ5VmFyaWFibGUoZklucHV0VmFyaWFibGVOb2RlLCBBVF9JTlBVVF9WQVJJQUJMRSk7Cgl9CgoJLyoqCgkgKiBDaGVjayB0aGUgb3V0cHV0IHZhcmlhYmxlIG9uIHRoaXMgSW52b2tlIGFjdGl2aXR5LgoJICoKCSAqLwoJQEFSdWxlKAoJCXNhID0gMjAwNCwKCQlkZXNjID0gIkNoZWNrIGlmIG91dHB1dFZhcmlhYmxlIGlzIHNldCBhbmQgZXhpc3RzIGFuZCBpcyBkZWZpbmVkIGNvcnJlY3RseS4iLAoJCWF1dGhvcj0ibWljaGFsLmNobWllbGV3c2tpQG9yYWNsZS5jb20iLAoJCWRhdGUgPSAiMDEvMjAvMjAwNyIsCgkJZXJyb3JzPSJCUEVMQ19fVU5TRVRfQVRUUklCVVRFLEJQRUxDX19VTlJFU09MVkVEX0FUVFJJQlVURSxCUEVMQ19fSU5WQUxJRF9BVFRSSUJVVEVfVkFMVUUiLAoJCXdhcm5pbmdzPSJCUEVMQ19SRUZfTk9ERV9QUk9CTEVNUyIKCSkKCglwdWJsaWMgdm9pZCBydWxlX0NoZWNrT3V0cHV0VmFyaWFibGVfMyAoKSB7CgkJZk91dHB1dFZhcmlhYmxlTm9kZSA9IHZlcmlmeVZhcmlhYmxlKGZPdXRwdXRWYXJpYWJsZU5vZGUsIEFUX09VVFBVVF9WQVJJQUJMRSk7Cgl9CgkKCQoJCgkvKioKCSAqIENoZWNrIHRoZSBwcmVzZW5jZSBvZiB0b1BhcnRzLgoJICovCgkKCUBBUnVsZSgKCQlzYSA9IDUxLAoJCWRlc2MgPSAiQ2hlY2sgdG8gc2VlIGlmIHRvUGFydCBpcyBzcGVjaWZpZWQ7IGlmIHNvIHRoZW4gIiArCgkJICAgICAgICIgaW5wdXRWYXJpYWJsZSBtdXN0IG5vdCBiZSB1c2VkIG9uIHRoZSByZXBseS4iLAoJCWF1dGhvciA9ICJtaWNoYWwuY2htaWVsZXdza2lAb3JhY2xlLmNvbSIsCgkJZGF0ZSA9ICIwMS8yMC8yMDA3IiwKCQllcnJvcnM9IkJQRUxDX19QQV9QQVJUUyIKCSkJCglwdWJsaWMgdm9pZCBydWxlX2NoZWNrVG9QYXJ0c1ByZXNlbmNlXzEwICgpIHsKCQkJCgkJZlRvUGFydHNQYXJ0cyA9IG1TZWxlY3Rvci5zZWxlY3ROb2RlcyhtTm9kZSwgTkRfVE9fUEFSVFMsIE5EX1RPX1BBUlQgKTsKCQkKCQlJUHJvYmxlbSBwcm9ibGVtOwoJCQoJCWlmIChmVG9QYXJ0c1BhcnRzLnNpemUoKSA+IDAgJiYgaXNFbXB0eShmSW5wdXRWYXJpYWJsZU5hbWUpID09IGZhbHNlICkgIHsJCQkKCQkJcHJvYmxlbSA9IGNyZWF0ZUVycm9yKCk7CgkJCXByb2JsZW0uZmlsbCgiQlBFTENfX1BBX1BBUlRTIiwKCQkJCQl0b1N0cmluZyhtTm9kZS5ub2RlTmFtZSgpKSwKCQkJCQlORF9UT19QQVJULAoJCQkJCUFUX0lOUFVUX1ZBUklBQkxFLAoJCQkJCUtJTkRfQUNUSVZJVFkpOwoJCQkKCQl9Cgl9CgkJCQoJCgkvKioKCSAqIENoZWNrIHRoZSBwcmVzZW5jZSBvZiBmcm9tUGFydHMuCgkgKi8KCQoJCgkKCUBBUnVsZSgKCQlzYSA9IDUyLAoJCWRlc2MgPSAiQ2hlY2sgdG8gc2VlIGlmIGZyb21QYXJ0IGlzIHNwZWNpZmllZDsgaWYgc28gdGhlbiAiICsKCQkgICAgICAgIiBvdXRwdXRWYXJpYWJsZSBtdXN0IG5vdCBiZSB1c2VkIG9uIGludm9rZS4iLAoJCWF1dGhvciA9ICJtaWNoYWwuY2htaWVsZXdza2lAb3JhY2xlLmNvbSIsCgkJZGF0ZSA9ICIwMS8yMC8yMDA3IiwKCQllcnJvcnM9IkJQRUxDX19QQV9QQVJUUyIKCSkKCQoJcHVibGljIHZvaWQgcnVsZV9jaGVja0Zyb21QYXJ0c1ByZXNlbmNlXzExICgpIHsJCQkKCQkJCQoJCWZGcm9tUGFydHMgPSBtU2VsZWN0b3Iuc2VsZWN0Tm9kZXMobU5vZGUsIE5EX0ZST01fUEFSVFMsIE5EX0ZST01fUEFSVCApOwoJCQoJCUlQcm9ibGVtIHByb2JsZW07CgkJCgkJaWYgKGZGcm9tUGFydHMuc2l6ZSgpID4gMCAmJiBpc0VtcHR5KGZPdXRwdXRWYXJpYWJsZU5hbWUpID09IGZhbHNlKSAgewkJCQoJCQlwcm9ibGVtID0gY3JlYXRlRXJyb3IoKTsKCQkJcHJvYmxlbS5maWxsKCJCUEVMQ19fUEFfUEFSVFMiLAoJCQkJCXRvU3RyaW5nKG1Ob2RlLm5vZGVOYW1lKCkpLAoJCQkJCU5EX0ZST01fUEFSVCwKCQkJCQlBVF9PVVRQVVRfVkFSSUFCTEUsCgkJCQkJS0lORF9BQ1RJVklUWSk7CgkJCXJldHVybiA7CgkJfQoJCQoJfQoJCgkKCQoJCgkvKioKCSAqIENoZWNrIGlmIHRoZSBwYXJ0bmVyIHJvbGUgaXMgZGVmaW5lZCBvbiB0aGlzIHBhcnRuZXIgbGluay4KCSAqLwoJCQoJQEFSdWxlKAoJCQlhdXRob3IgPSAibWljaGFsLmNobWllbGV3c2tpQG9yYWNsZS5jb20iLAoJCQlkYXRlID0gIjkvMjUvMjAwNiIsCgkJCWRlc2MgPSAiQ2hlY2tzIGlmIHBhcnRuZXIgcm9sZSBpcyBkZWZpbmVkIGluIGludm9rZSBhY3Rpdml0eS4iLAoJCQllcnJvcnMgPSAiQlBFTENfTUlTU0lOR19ST0xFIgoJCSkKCQkKCXB1YmxpYyB2b2lkIHJ1bGVfQ2hlY2tJZlBhcnRuZXJSb2xlSXNEZWZpbmVkXzUgKCkgewkJCgkJZlBhcnRuZXJSb2xlTm9kZSA9IGxvb2t1cFJvbGVOb2RlICggZlBhcnRuZXJMaW5rTm9kZSwgQVRfUEFSVE5FUl9ST0xFICk7Cgl9CgoKCQoKCS8qKgoJICogQ2hlY2sgaWYgdGhlIHBhcnRuZXJMaW5rVHlwZSBkZXJpdmVkIHBvcnQgdHlwZSBhbmQgdGhlIHBvcnQgdHlwZSBwcmVzZW50CgkgKiBvbiB0aGUgaW52b2tlIGFyZSBvbmUgYW5kIHRoZSBzYW1lLgoJICovCglAQVJ1bGUoCgkJYXV0aG9yID0gIm1pY2hhbC5jaG1pZWxld3NraUBvcmFjbGUuY29tIiwKCQlkYXRlID0gIjkvMjUvMjAwNiIsCgkJZGVzYyA9ICJDaGVja3MgcG9ydFR5cGUgYW5kIGRlcml2ZWQgcG9ydFR5cGUgdmFsdWVzIG9uIGludm9rZSBhY3Rpdml0eS4iLAoJCXNhID0gNSAsCgkJZXJyb3JzPSJCUEVMQ19NSVNNQVRDSF9ST0xFX1BPUlRfVFlQRSIKCSkKCXB1YmxpYyB2b2lkIHJ1bGVfQ2hlY2tSb2xlUG9ydFR5cGVXaXRoSW52b2tlUG9ydFR5cGVfMTAgKCkKCXsKCQlmUG9ydFR5cGVGcm9tUm9sZU5vZGUgPSB2ZXJpZnlQb3J0VHlwZUZyb21Sb2xlKGZQYXJ0bmVyUm9sZU5vZGUsIEFUX1BBUlRORVJfUk9MRSxmUG9ydFR5cGUpOwkJCgl9CgkKCS8qKgoJICogMSkgSW52b2tlIG5lZWRzIHBhcnRuZXJSb2xlIHNldC4gCgkgKiAyKSBwYXJ0bmVyUm9sZSAtPiBwb3J0VHlwZQoJICogMykgcG9ydFR5cGUgKGhhcyBvcGVyYXRpb25zKSAtPiBvcGVyYXRpb24KCSAqIDQpIG9wZXJhdGlvbiAtPiAiaW5wdXQiIG1lc3NhZ2UgbXVzdCBiZSBzZXQuICJvdXRwdXQiIG1lc3NhZ2UgbWF5IGJlIHNldCAKCSAqICAKCSAqLwoJCglJTm9kZSBmT3V0cHV0TWVzc2FnZVR5cGU7CglJTm9kZSBmSW5wdXRNZXNzYWdlVHlwZTsKCXByb3RlY3RlZCBib29sZWFuIGZiSXMyV2F5OwoJCgkKCS8qKiAKCSAqIENoZWNrcyB0aGUgSW5wdXQgTWVzc2FnZSBmb3IgdGhlIGludm9rZS4gVGhpcyBqdXN0IG1ha2VzCgkgKiBzdXJlIHRoYXQgaW5wdXQgbWVzc2FnZSBpcyBkZWZpbmVkIGluIHRoZSBXU0RMLgoJICogCgkgKi8KCUBBUnVsZSgKCQkJYXV0aG9yID0gIm1pY2hhbC5jaG1pZWxld3NraUBvcmFjbGUuY29tIiwKCQkJZGF0ZSA9ICI5LzI1LzIwMDYiLAoJCQlkZXNjID0gIkNoZWNrcyBpZiBpbnB1dCBhbmQgb3V0cHV0IG1lc3NhZ2VzIGFyZSBkZWZpbmVkIGZvciBpbnZva2UgYWN0aXZpdHkuIiwKCQkJZXJyb3JzPSJCUEVMQ19QQV9fTk9fTUVTU0FHRSxCUEVMQ19QQV9fTVNHX1RZUEUiCgkJKQoJcHVibGljIHZvaWQgcnVsZV9DaGVja0lucHV0T3V0cHV0TWVzc2FnZXNfMTIgKCkgewoJCQoJCWZJbnB1dE1lc3NhZ2VUeXBlID0gZmluZE1lc3NhZ2VUeXBlIChmUG9ydFR5cGVGcm9tUm9sZU5vZGUsZk9wZXJhdGlvbixXU0RMX05EX0lOUFVULHRydWUgKTsKCQlzZXRWYWx1ZSgiaW5wdXQubWVzc2FnZS50eXBlIiwgZklucHV0TWVzc2FnZVR5cGUpOwoJCQoJCWZPdXRwdXRNZXNzYWdlVHlwZSA9IGZpbmRNZXNzYWdlVHlwZSAoZlBvcnRUeXBlRnJvbVJvbGVOb2RlLGZPcGVyYXRpb24sV1NETF9ORF9PVVRQVVQsIGZhbHNlICk7CQkJCgkJc2V0VmFsdWUoIm91dHB1dC5tZXNzYWdlLnR5cGUiLCBmT3V0cHV0TWVzc2FnZVR5cGUpOwoJCQoKCX0KCgkKCS8qKgoJICogT25lLXdheSBpbnZvY2F0aW9uIHJlcXVpcmVzIG9ubHkgdGhlIGlucHV0VmFyaWFibGUgKG9yIGl0cyBlcXVpdmFsZW50CgkgKiA8dG9QYXJ0PiBlbGVtZW50cykgc2luY2UgYSByZXNwb25zZSBpcyBub3QgZXhwZWN0ZWQgYXMgcGFydCBvZiB0aGUKCSAqIG9wZXJhdGlvbiAoc2VlIHNlY3Rpb24gMTAuNC4gUHJvdmlkaW5nIFdlYiBTZXJ2aWNlIE9wZXJhdGlvbnMgliBSZWNlaXZlCgkgKiBhbmQgUmVwbHkgKS4gUmVxdWVzdC1yZXNwb25zZSBpbnZvY2F0aW9uIHJlcXVpcmVzIGJvdGggYW4gaW5wdXRWYXJpYWJsZQoJICogKG9yIGl0cyBlcXVpdmFsZW50IDx0b1BhcnQ+IGVsZW1lbnRzKSBhbmQgYW4gb3V0cHV0VmFyaWFibGUgKG9yIGl0cwoJICogZXF1aXZhbGVudCA8ZnJvbVBhcnQ+IGVsZW1lbnRzKS4gSWYgYSBXU0RMIG1lc3NhZ2UgZGVmaW5pdGlvbiBkb2VzIG5vdAoJICogY29udGFpbiBhbnkgcGFydHMsIHRoZW4gdGhlIGFzc29jaWF0ZWQgYXR0cmlidXRlcyB2YXJpYWJsZSwgaW5wdXRWYXJpYWJsZQoJICogb3Igb3V0cHV0VmFyaWFibGUsIE1BWSBiZSBvbWl0dGVkLGFuZCB0aGUgPGZyb21QYXJ0cz4gb3IgPHRvUGFydHM+CgkgKiBjb25zdHJ1Y3QgTVVTVCBiZSBvbWl0dGVkLgoJICogCgkgKi8KCQoJQEFSdWxlKAoJCXNhID0gNDcsCgkJZGVzYyA9ICJPbmUgaW52b2NhdGlvbiByZXF1aXJlcyBpbnB1dFZhcmlhYmxlIChvciB0b1BhcnQpOyAiIAoJCQkgICsgIiAyLXdheSBpbnZvY2F0aW9uIHJlcXVpcmVzIG91dHB1dFZhcmlhYmxlIChvciBmcm9tUGFydCkiLAoJCQkgIAoJCWF1dGhvciA9ICJtaWNoYWwuY2htaWVsZXdza2lAb3JhY2xlLmNvbSIsCgkJZGF0ZSA9ICIwMi8yMi8yMDA3IiwKCQllcnJvcnM9IkJQRUxDX1BBX19PTUlULEJQRUxDX19VTlNFVF9BVFRSSUJVVEUsIgoJKQkKCQoJcHVibGljIHZvaWQgcnVsZV9DaGVja1R3b1dheUludm9jYXRpb25fMjUgKCkgewoKCQlib29sZWFuIGlzMldheSA9IGlzRGVmaW5lZChmSW5wdXRNZXNzYWdlVHlwZSkgJiYgaXNEZWZpbmVkKGZPdXRwdXRNZXNzYWdlVHlwZSk7CgkJCgkJc2V0VmFsdWUoIjJ3YXkiLCBpczJXYXkpOwoJCQoJCWlmIChpc1VuZGVmaW5lZChmUGFydG5lckxpbmtOb2RlKSkgewoJCQlyZXR1cm4gOwoJCX0KCQkKCQlJUHJvYmxlbSBwcm9ibGVtOwoJCQkJCgkJaWYgKGlzVW5kZWZpbmVkKGZJbnB1dE1lc3NhZ2VUeXBlKSkgewoJCQkKCQkJaWYgKGZUb1BhcnRzUGFydHMuc2l6ZSgpID4gMCkgewoJCQkJcHJvYmxlbSA9IGNyZWF0ZUVycm9yKCk7CgkJCQlwcm9ibGVtLmZpbGwoIkJQRUxDX1BBX19PTUlUIiwKCQkJCQl0b1N0cmluZyhtTm9kZS5ub2RlTmFtZSgpKSwKCQkJCQlmUGFydG5lckxpbmtOb2RlLmdldEF0dHJpYnV0ZShBVF9OQU1FKSwKCQkJCQlXU0RMX05EX0lOUFVULAoJCQkJCUtJTkRfTk9ERSwKCQkJCQlORF9UT19QQVJUCgkJCQkpOwoJCQl9CgkJCQoJCX0gZWxzZSB7CgkJCS8qKiBNZXNzYWdlIGlzIGRlZmluZWQgKi8KCQkJaWYgKGlzRW1wdHkoZklucHV0VmFyaWFibGVOYW1lKSAmJiBmVG9QYXJ0c1BhcnRzLnNpemUoKSA9PSAwKSB7CgkJCQlwcm9ibGVtID0gY3JlYXRlRXJyb3IoKTsKCQkJCXByb2JsZW0uZmlsbCgiQlBFTENfX1VOU0VUX0FUVFJJQlVURSIsCgkJCQkJCXRvU3RyaW5nKG1Ob2RlLm5vZGVOYW1lKCkpLAoJCQkJCQlBVF9JTlBVVF9WQVJJQUJMRSwKCQkJCQkJS0lORF9BQ1RJVklUWQoJCQkJICk7CgkJCX0KCQl9CgkJCgkJCgkJCgkJaWYgKCBpc1VuZGVmaW5lZChmT3V0cHV0TWVzc2FnZVR5cGUpICkgewoJCQkKCQkJaWYgKGlzRGVmaW5lZChmT3V0cHV0VmFyaWFibGVOb2RlKSkgewoJCQkJcHJvYmxlbSA9IGNyZWF0ZUVycm9yKCk7CgkJCQlwcm9ibGVtLmZpbGwoIkJQRUxDX1BBX19PTUlUIiwKCQkJCQl0b1N0cmluZyhtTm9kZS5ub2RlTmFtZSgpKSwKCQkJCQlmUGFydG5lckxpbmtOb2RlLmdldEF0dHJpYnV0ZShBVF9OQU1FKSwKCQkJCQlXU0RMX05EX09VVFBVVCwKCQkJCQlLSU5EX0FUVFJJQlVURSwKCQkJCQlBVF9PVVRQVVRfVkFSSUFCTEUKCQkJCSk7CQkJCQoJCQl9CgkJCQoJCQlpZiAoZkZyb21QYXJ0cy5zaXplKCkgPiAwKSB7CgkJCQlwcm9ibGVtID0gY3JlYXRlRXJyb3IoKTsKCQkJCXByb2JsZW0uZmlsbCgiQlBFTENfUEFfX09NSVQiLAoJCQkJCXRvU3RyaW5nKG1Ob2RlLm5vZGVOYW1lKCkpLAoJCQkJCWZQYXJ0bmVyTGlua05vZGUuZ2V0QXR0cmlidXRlKEFUX05BTUUpLAoJCQkJCVdTRExfTkRfT1VUUFVULAoJCQkJCUtJTkRfTk9ERSwKCQkJCQlORF9GUk9NX1BBUlQKCQkJCSk7CgkJCQkKCQkJfQoJCX0gZWxzZSB7CgkJCS8qKiBPdXRwdXQgbWVzc2FnZSBpcyBkZWZpbmVkICovCgkJCWlmIChpc0VtcHR5KGZPdXRwdXRWYXJpYWJsZU5hbWUpICYmIGZGcm9tUGFydHMuc2l6ZSgpID09IDApIHsKCQkJCXByb2JsZW0gPSBjcmVhdGVFcnJvcigpOwoJCQkJcHJvYmxlbS5maWxsKCJCUEVMQ19fVU5TRVRfQVRUUklCVVRFIiwKCQkJCQkJdG9TdHJpbmcobU5vZGUubm9kZU5hbWUoKSksCgkJCQkJCUFUX09VVFBVVF9WQVJJQUJMRSwKCQkJCQkJS0lORF9BQ1RJVklUWQoJCQkJICk7CgkJCX0KCQl9CgkJCgkJCgkJCgl9CgkvKioKCSAqIENoZWNrIHZhcmlhYmxlIGFuZCBtZXNzYWdlIHN0cnVjdHVyZSBjb21wYXRpYmlsaXR5LgoJICoKCSAqLwoJQEFSdWxlKAoJCXNhID0gNDgsCgkJZGVzYyA9ICJDaGVjayBtZXNzYWdlIHR5cGUgY29tcGF0YWJpbGl0eSBvbiBpbnZva2UiLAoJCWF1dGhvciA9ICJtaWNoYWwuY2htaWVsZXdza2lAb3JhY2xlLmNvbSIsCgkJZGF0ZSA9ICIwMi8yMi8yMDA3IiwKCQllcnJvcnM9IkJQRUxDX1BBX19NRVNTQUdFX1RZUEVfTUlTTUFUQ0giCgkpCglwdWJsaWMgdm9pZCBydWxlX0NoZWNrVmFyaWFibGVBbmRNZXNzYWdlU3RydWN0dXJlQ29tcGF0aWJpbGl0eV80MCAoKQoJewoJCUlQcm9ibGVtIHByb2JsZW07CgkJSU5vZGUgdmFyVHlwZSA7CgkJCgkJaWYgKGlzRGVmaW5lZChmSW5wdXRNZXNzYWdlVHlwZSkgJiYgaXNEZWZpbmVkKCBmSW5wdXRWYXJpYWJsZU5vZGUgKSkgewoJCQkvLyB0aGUgdmFyaWFibGUgdmFsaWRhdG9yIHdpbGwgaGF2ZSB0aGUgdHlwZSBvZiB2YXJpYWJsZS4KCQkJdmFyVHlwZSA9IGdldFZhbHVlKGZJbnB1dFZhcmlhYmxlTm9kZSwidHlwZSIsIG51bGwgKTsKCQkKCQkJaWYgKGlzRGVmaW5lZCh2YXJUeXBlKSkgewoJCQkJCgkJCQkvLyBzb3VyY2UgLT4gZGVzdGluYXRpb24JCQoJCQkJaWYgKG1Nb2RlbFF1ZXJ5LmNoZWNrKCBJTW9kZWxRdWVyeUxvb2t1cHMuVEVTVF9DT01QQVRJQkxFX1BBUlRORVJfQUNUSVZJVFlfTUVTU0FHRSwgdmFyVHlwZSwgZklucHV0TWVzc2FnZVR5cGUgKSA9PSBmYWxzZSkgewoJCQkJCQkKCQkJCQlwcm9ibGVtID0gY3JlYXRlRXJyb3IoICk7CgkJCQkJcHJvYmxlbS5maWxsKCAiQlBFTENfUEFfX01FU1NBR0VfVFlQRV9NSVNNQVRDSCIsICAvLyROT04tTkxTLTEkCgkJCQkJCQl0b1N0cmluZyhtTm9kZS5ub2RlTmFtZSgpKSwKCQkJCQkJCUFUX0lOUFVUX1ZBUklBQkxFLAoJCQkJCQkJZklucHV0VmFyaWFibGVOb2RlLmdldEF0dHJpYnV0ZSggQVRfTkFNRSApLAoJCQkJCQkJZklucHV0TWVzc2FnZVR5cGUsCgkJCQkJCQl2YXJUeXBlCgkJCQkJKTsKCQkJCX0KCQkJfQoJCX0KCQkKCQlpZiAoaXNEZWZpbmVkKGZPdXRwdXRNZXNzYWdlVHlwZSkgJiYgaXNEZWZpbmVkKCBmT3V0cHV0VmFyaWFibGVOb2RlICkpIHsKCQkJCgkJCS8vIHRoZSB2YXJpYWJsZSB2YWxpZGF0b3Igd2lsbCBoYXZlIHRoZSB0eXBlIG9mIHZhcmlhYmxlLgoJCQl2YXJUeXBlID0gZ2V0VmFsdWUoZk91dHB1dFZhcmlhYmxlTm9kZSwidHlwZSIsIG51bGwgKTsKCQkKCQkJaWYgKGlzRGVmaW5lZCh2YXJUeXBlKSkgewoJCQkJCgkJCQkvLyBzb3VyY2UgLT4gZGVzdGluYXRpb24JCQoJCQkJaWYgKG1Nb2RlbFF1ZXJ5LmNoZWNrKCBJTW9kZWxRdWVyeUxvb2t1cHMuVEVTVF9DT01QQVRJQkxFX1BBUlRORVJfQUNUSVZJVFlfTUVTU0FHRSwgdmFyVHlwZSwgZk91dHB1dE1lc3NhZ2VUeXBlICkgPT0gZmFsc2UpIHsKCQkJCQkJCgkJCQkJcHJvYmxlbSA9IGNyZWF0ZUVycm9yKCApOwoJCQkJCXByb2JsZW0uZmlsbCggIkJQRUxDX1BBX19NRVNTQUdFX1RZUEVfTUlTTUFUQ0giLCAgLy8kTk9OLU5MUy0xJAoJCQkJCQkJdG9TdHJpbmcobU5vZGUubm9kZU5hbWUoKSksCgkJCQkJCQlBVF9PVVRQVVRfVkFSSUFCTEUsCgkJCQkJCQlmT3V0cHV0VmFyaWFibGVOb2RlLmdldEF0dHJpYnV0ZSggQVRfTkFNRSApLAoJCQkJCQkJZk91dHB1dE1lc3NhZ2VUeXBlLAoJCQkJCQkJdmFyVHlwZQoJCQkJCSk7CgkJCQl9CgkJCX0KCQl9CgkJCgkJCgkJCgkJCgl9CgkKCQoJCgkKfQo=