LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKgogKiBDb250cmlidXRvcnM6CiAqICAgIElCTSBDb3Jwb3JhdGlvbiAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5jb3JlLmludGVybmFsOwoKaW1wb3J0IGphdmEubmV0LlVSTDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGb2xkZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIuY29yZS5JV2ViTW9kdWxlOwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS51dGlsLk5MUzsKCmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5TZXJ2ZXJNb25pdG9yTWFuYWdlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC4qOwovKioKICogR2VuZXJpYyBUb21jYXQgc2VydmVyLgogKi8KcHVibGljIGNsYXNzIFRvbWNhdFNlcnZlciBleHRlbmRzIFNlcnZlckRlbGVnYXRlIGltcGxlbWVudHMgSVRvbWNhdFNlcnZlciwgSVRvbWNhdFNlcnZlcldvcmtpbmdDb3B5IHsKCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZX1NFQ1VSRSA9ICJzZWN1cmUiOwoJcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJPUEVSVFlfREVCVUcgPSAiZGVidWciOwoKCXByb3RlY3RlZCB0cmFuc2llbnQgVG9tY2F0Q29uZmlndXJhdGlvbiBjb25maWd1cmF0aW9uOwoKCS8qKgoJICogVG9tY2F0U2VydmVyLgoJICovCglwdWJsaWMgVG9tY2F0U2VydmVyKCkgewoJCXN1cGVyKCk7Cgl9CgoJcHVibGljIFRvbWNhdFJ1bnRpbWUgZ2V0VG9tY2F0UnVudGltZSgpIHsKCQlpZiAoZ2V0U2VydmVyKCkuZ2V0UnVudGltZSgpID09IG51bGwpCgkJCXJldHVybiBudWxsOwoJCQoJCXJldHVybiAoVG9tY2F0UnVudGltZSkgZ2V0U2VydmVyKCkuZ2V0UnVudGltZSgpLmxvYWRBZGFwdGVyKFRvbWNhdFJ1bnRpbWUuY2xhc3MsIG51bGwpOwoJfQoKCXB1YmxpYyBJVG9tY2F0VmVyc2lvbkhhbmRsZXIgZ2V0VG9tY2F0VmVyc2lvbkhhbmRsZXIoKSB7CgkJaWYgKGdldFNlcnZlcigpLmdldFJ1bnRpbWUoKSA9PSBudWxsIHx8IGdldFRvbWNhdFJ1bnRpbWUoKSA9PSBudWxsKQoJCQlyZXR1cm4gbnVsbDsKCgkJcmV0dXJuIGdldFRvbWNhdFJ1bnRpbWUoKS5nZXRWZXJzaW9uSGFuZGxlcigpOwoJfQoKCXB1YmxpYyBJVG9tY2F0Q29uZmlndXJhdGlvbiBnZXRTZXJ2ZXJDb25maWd1cmF0aW9uKCkgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCXJldHVybiBnZXRUb21jYXRDb25maWd1cmF0aW9uKCk7Cgl9CgoJcHVibGljIFRvbWNhdENvbmZpZ3VyYXRpb24gZ2V0VG9tY2F0Q29uZmlndXJhdGlvbigpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQlpZiAoY29uZmlndXJhdGlvbiA9PSBudWxsKSB7CgkJCUlGb2xkZXIgZm9sZGVyID0gZ2V0U2VydmVyKCkuZ2V0U2VydmVyQ29uZmlndXJhdGlvbigpOwoJCQlpZiAoZm9sZGVyID09IG51bGwgfHwgIWZvbGRlci5leGlzdHMoKSkgewoJCQkJU3RyaW5nIHBhdGggPSBudWxsOwoJCQkJaWYgKGZvbGRlciAhPSBudWxsKQoJCQkJCXBhdGggPSBmb2xkZXIuZ2V0RnVsbFBhdGgoKS50b09TU3RyaW5nKCk7CgkJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIE5MUy5iaW5kKE1lc3NhZ2VzLmVycm9yTm9Db25maWd1cmF0aW9uLCBwYXRoKSwgbnVsbCkpOwoJCQl9CgkJCQoJCQlTdHJpbmcgaWQgPSBnZXRTZXJ2ZXIoKS5nZXRTZXJ2ZXJUeXBlKCkuZ2V0SWQoKTsKCQkJaWYgKGlkLmluZGV4T2YoIjMyIikgPiAwKQoJCQkJY29uZmlndXJhdGlvbiA9IG5ldyBUb21jYXQzMkNvbmZpZ3VyYXRpb24oZm9sZGVyKTsKCQkJZWxzZSBpZiAoaWQuaW5kZXhPZigiNDAiKSA+IDApCgkJCQljb25maWd1cmF0aW9uID0gbmV3IFRvbWNhdDQwQ29uZmlndXJhdGlvbihmb2xkZXIpOwoJCQllbHNlIGlmIChpZC5pbmRleE9mKCI0MSIpID4gMCkKCQkJCWNvbmZpZ3VyYXRpb24gPSBuZXcgVG9tY2F0NDFDb25maWd1cmF0aW9uKGZvbGRlcik7CgkJCWVsc2UgaWYgKGlkLmluZGV4T2YoIjUwIikgPiAwKQoJCQkJY29uZmlndXJhdGlvbiA9IG5ldyBUb21jYXQ1MENvbmZpZ3VyYXRpb24oZm9sZGVyKTsKCQkJZWxzZSBpZiAoaWQuaW5kZXhPZigiNTUiKSA+IDApCgkJCQljb25maWd1cmF0aW9uID0gbmV3IFRvbWNhdDU1Q29uZmlndXJhdGlvbihmb2xkZXIpOwoJCQl0cnkgewoJCQkJY29uZmlndXJhdGlvbi5sb2FkKGZvbGRlciwgbnVsbCk7CgkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJCS8vIGlnbm9yZQoJCQkJY29uZmlndXJhdGlvbiA9IG51bGw7CgkJCQl0aHJvdyBjZTsKCQkJfQoJCX0KCQlyZXR1cm4gY29uZmlndXJhdGlvbjsKCX0KCglwdWJsaWMgdm9pZCBpbXBvcnRDb25maWd1cmF0aW9uKElSdW50aW1lIHJ1bnRpbWUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCWlmIChydW50aW1lID09IG51bGwpIHsKCQkJY29uZmlndXJhdGlvbiA9IG51bGw7CgkJCXJldHVybjsKCQl9CgkJSVBhdGggcGF0aCA9IHJ1bnRpbWUuZ2V0TG9jYXRpb24oKS5hcHBlbmQoImNvbmYiKTsKCQkKCQlTdHJpbmcgaWQgPSBnZXRTZXJ2ZXIoKS5nZXRTZXJ2ZXJUeXBlKCkuZ2V0SWQoKTsKCQlJRm9sZGVyIGZvbGRlciA9IGdldFNlcnZlcigpLmdldFNlcnZlckNvbmZpZ3VyYXRpb24oKTsKCQlpZiAoaWQuaW5kZXhPZigiMzIiKSA+IDApCgkJCWNvbmZpZ3VyYXRpb24gPSBuZXcgVG9tY2F0MzJDb25maWd1cmF0aW9uKGZvbGRlcik7CgkJZWxzZSBpZiAoaWQuaW5kZXhPZigiNDAiKSA+IDApCgkJCWNvbmZpZ3VyYXRpb24gPSBuZXcgVG9tY2F0NDBDb25maWd1cmF0aW9uKGZvbGRlcik7CgkJZWxzZSBpZiAoaWQuaW5kZXhPZigiNDEiKSA+IDApCgkJCWNvbmZpZ3VyYXRpb24gPSBuZXcgVG9tY2F0NDFDb25maWd1cmF0aW9uKGZvbGRlcik7CgkJZWxzZSBpZiAoaWQuaW5kZXhPZigiNTAiKSA+IDApCgkJCWNvbmZpZ3VyYXRpb24gPSBuZXcgVG9tY2F0NTBDb25maWd1cmF0aW9uKGZvbGRlcik7CgkJZWxzZSBpZiAoaWQuaW5kZXhPZigiNTUiKSA+IDApCgkJCWNvbmZpZ3VyYXRpb24gPSBuZXcgVG9tY2F0NTVDb25maWd1cmF0aW9uKGZvbGRlcik7CgkJdHJ5IHsKCQkJY29uZmlndXJhdGlvbi5pbXBvcnRGcm9tUGF0aChwYXRoLCBpc1Rlc3RFbnZpcm9ubWVudCgpLCBtb25pdG9yKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCS8vIGlnbm9yZQoJCQljb25maWd1cmF0aW9uID0gbnVsbDsKCQl9Cgl9CgoJcHVibGljIHZvaWQgc2F2ZUNvbmZpZ3VyYXRpb24oSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJVG9tY2F0Q29uZmlndXJhdGlvbiBjb25maWcgPSBnZXRUb21jYXRDb25maWd1cmF0aW9uKCk7CgkJaWYgKGNvbmZpZyA9PSBudWxsKQoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIE5MUy5iaW5kKE1lc3NhZ2VzLmVycm9yQ291bGROb3RTYXZlQ29uZmlndXJhdGlvbiwgIm51bGwiKSwgbnVsbCkpOwoJCWNvbmZpZy5zYXZlKGdldFNlcnZlcigpLmdldFNlcnZlckNvbmZpZ3VyYXRpb24oKSwgbW9uaXRvcik7Cgl9CgoJcHVibGljIHZvaWQgY29uZmlndXJhdGlvbkNoYW5nZWQoKSB7CgkJY29uZmlndXJhdGlvbiA9IG51bGw7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gdGhlIHJvb3QgVVJMIG9mIHRoaXMgbW9kdWxlLgoJICogQHBhcmFtIG1vZHVsZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vZHVsZQoJICogQHJldHVybiBqYXZhLm5ldC5VUkwKCSAqLwoJcHVibGljIFVSTCBnZXRNb2R1bGVSb290VVJMKElNb2R1bGUgbW9kdWxlKSB7CgkJdHJ5IHsKCQkJaWYgKG1vZHVsZSA9PSBudWxsKQoJCQkJcmV0dXJuIG51bGw7CgkKCQkJVG9tY2F0Q29uZmlndXJhdGlvbiBjb25maWcgPSBnZXRUb21jYXRDb25maWd1cmF0aW9uKCk7CgkJCWlmIChjb25maWcgPT0gbnVsbCkKCQkJCXJldHVybiBudWxsOwoJCgkJCVN0cmluZyB1cmwgPSAiaHR0cDovL2xvY2FsaG9zdCI7CgkJCWludCBwb3J0ID0gY29uZmlnLmdldE1haW5Qb3J0KCkuZ2V0UG9ydCgpOwoJCQlwb3J0ID0gU2VydmVyTW9uaXRvck1hbmFnZXIuZ2V0SW5zdGFuY2UoKS5nZXRNb25pdG9yZWRQb3J0KGdldFNlcnZlcigpLCBwb3J0LCAid2ViIik7CgkJCWlmIChwb3J0ICE9IDgwKQoJCQkJdXJsICs9ICI6IiArIHBvcnQ7CgoJCQl1cmwgKz0gY29uZmlnLmdldFdlYk1vZHVsZVVSTChtb2R1bGUpOwoJCQkKCQkJaWYgKCF1cmwuZW5kc1dpdGgoIi8iKSkKCQkJCXVybCArPSAiLyI7CgoJCQlyZXR1cm4gbmV3IFVSTCh1cmwpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkNvdWxkIG5vdCBnZXQgcm9vdCBVUkwiLCBlKTsKCQkJcmV0dXJuIG51bGw7CgkJfQoJfQoKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIHRoZSBwcm9jZXNzIGlzIHNldCB0byBydW4gaW4gZGVidWcgbW9kZS4KCSAqIFRoaXMgZmVhdHVyZSBvbmx5IHdvcmtzIHdpdGggVG9tY2F0IHY0LjAuCgkgKgoJICogQHJldHVybiBib29sZWFuCgkgKi8KCXB1YmxpYyBib29sZWFuIGlzRGVidWcoKSB7CgkJcmV0dXJuIGdldEF0dHJpYnV0ZShQUk9QRVJUWV9ERUJVRywgZmFsc2UpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYSB0ZXN0IChydW4gY29kZSBvdXQgb2YgdGhlIHdvcmtiZW5jaCkgc2VydmVyLgoJICoKCSAqIEByZXR1cm4gYm9vbGVhbgoJICovCglwdWJsaWMgYm9vbGVhbiBpc1Rlc3RFbnZpcm9ubWVudCgpIHsKCQlyZXR1cm4gZ2V0QXR0cmlidXRlKFBST1BFUlRZX1RFU1RfRU5WSVJPTk1FTlQsIGZhbHNlKTsKCX0KCgkvKioKCSAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcHJvY2VzcyBpcyBzZXQgdG8gcnVuIGluIHNlY3VyZSBtb2RlLgoJICoKCSAqIEByZXR1cm4gYm9vbGVhbgoJICovCglwdWJsaWMgYm9vbGVhbiBpc1NlY3VyZSgpIHsKCQlyZXR1cm4gZ2V0QXR0cmlidXRlKFBST1BFUlRZX1NFQ1VSRSwgZmFsc2UpOwoJfQoJCglwcm90ZWN0ZWQgc3RhdGljIFN0cmluZyByZW5kZXJDb21tYW5kTGluZShTdHJpbmdbXSBjb21tYW5kTGluZSwgU3RyaW5nIHNlcGFyYXRvcikgewoJCWlmIChjb21tYW5kTGluZSA9PSBudWxsIHx8IGNvbW1hbmRMaW5lLmxlbmd0aCA8IDEpCgkJCXJldHVybiAiIjsKCQlTdHJpbmdCdWZmZXIgYnVmPSBuZXcgU3RyaW5nQnVmZmVyKGNvbW1hbmRMaW5lWzBdKTsKCQlmb3IgKGludCBpID0gMTsgaSA8IGNvbW1hbmRMaW5lLmxlbmd0aDsgaSsrKSB7CgkJCWJ1Zi5hcHBlbmQoc2VwYXJhdG9yKTsKCQkJYnVmLmFwcGVuZChjb21tYW5kTGluZVtpXSk7CgkJfQkKCQlyZXR1cm4gYnVmLnRvU3RyaW5nKCk7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBvYmplY3QuCgkgKiBAcmV0dXJuIGphdmEubGFuZy5TdHJpbmcKCSAqLwoJcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKCQlyZXR1cm4gIlRvbWNhdFNlcnZlciI7Cgl9CgoJLyoKCSAqIFJldHVybnMgdGhlIGNoaWxkIG1vZHVsZShzKSBvZiB0aGlzIG1vZHVsZS4KCSAqLwoJcHVibGljIElNb2R1bGVbXSBnZXRDaGlsZE1vZHVsZXMoSU1vZHVsZVtdIG1vZHVsZSkgewoJCXJldHVybiBuZXcgSU1vZHVsZVswXTsKCX0KCgkvKgoJICogUmV0dXJucyB0aGUgcm9vdCBtb2R1bGUocykgb2YgdGhpcyBtb2R1bGUuCgkgKi8KCXB1YmxpYyBJTW9kdWxlW10gZ2V0Um9vdE1vZHVsZXMoSU1vZHVsZSBtb2R1bGUpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQlpZiAobW9kdWxlLmxvYWRBZGFwdGVyKElXZWJNb2R1bGUuY2xhc3MsIG51bGwpICE9IG51bGwpIHsKCQkJSVN0YXR1cyBzdGF0dXMgPSBjYW5Nb2RpZnlNb2R1bGVzKG5ldyBJTW9kdWxlW10geyBtb2R1bGUgfSwgbnVsbCk7CgkJCWlmIChzdGF0dXMgPT0gbnVsbCB8fCAhc3RhdHVzLmlzT0soKSkKCQkJCXRocm93IG5ldyBDb3JlRXhjZXB0aW9uKHN0YXR1cyk7CgkJCXJldHVybiBuZXcgSU1vZHVsZVtdIHsgbW9kdWxlIH07CgkJfQoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBwcm9qZWN0IGlzIHN1cHBvcnRlZCBieSB0aGlzCgkgKiBzZXJ2ZXIsIGFuZCBmYWxzZSBvdGhlcndpc2UuCgkgKgoJICogQHBhcmFtIGFkZCBtb2R1bGVzCgkgKiBAcGFyYW0gcmVtb3ZlIG1vZHVsZXMKCSAqIEByZXR1cm4gdGhlIHN0YXR1cwoJICovCglwdWJsaWMgSVN0YXR1cyBjYW5Nb2RpZnlNb2R1bGVzKElNb2R1bGVbXSBhZGQsIElNb2R1bGVbXSByZW1vdmUpIHsKCQlpZiAoYWRkICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBhZGQubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJSU1vZHVsZSBtb2R1bGUgPSBhZGRbaV07CgkJCQlJV2ViTW9kdWxlIHdlYk1vZHVsZSA9IChJV2ViTW9kdWxlKSBtb2R1bGUubG9hZEFkYXB0ZXIoSVdlYk1vZHVsZS5jbGFzcywgbnVsbCk7CgkJCQlpZiAod2ViTW9kdWxlID09IG51bGwpCgkJCQkJcmV0dXJuIG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgVG9tY2F0UGx1Z2luLlBMVUdJTl9JRCwgMCwgTWVzc2FnZXMuZXJyb3JXZWJNb2R1bGVzT25seSwgbnVsbCk7CgkJCQkKCQkJCUlTdGF0dXMgc3RhdHVzID0gZ2V0VG9tY2F0VmVyc2lvbkhhbmRsZXIoKS5jYW5BZGRNb2R1bGUod2ViTW9kdWxlKTsKCQkJCWlmIChzdGF0dXMgIT0gbnVsbCAmJiAhc3RhdHVzLmlzT0soKSkKCQkJCQlyZXR1cm4gc3RhdHVzOwoJCQl9CgkJfQoJCQoJCXJldHVybiBuZXcgU3RhdHVzKElTdGF0dXMuT0ssIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsICIlY2FuTW9kaWZ5TW9kdWxlcyIsIG51bGwpOwoJfQoKCXB1YmxpYyBTZXJ2ZXJQb3J0W10gZ2V0U2VydmVyUG9ydHMoKSB7CgkJaWYgKGdldFNlcnZlcigpLmdldFNlcnZlckNvbmZpZ3VyYXRpb24oKSA9PSBudWxsKQoJCQlyZXR1cm4gbmV3IFNlcnZlclBvcnRbMF07CgkJCgkJdHJ5IHsKCQkJTGlzdCBsaXN0ID0gZ2V0VG9tY2F0Q29uZmlndXJhdGlvbigpLmdldFNlcnZlclBvcnRzKCk7CgkJCVNlcnZlclBvcnRbXSBzcCA9IG5ldyBTZXJ2ZXJQb3J0W2xpc3Quc2l6ZSgpXTsKCQkJbGlzdC50b0FycmF5KHNwKTsKCQkJcmV0dXJuIHNwOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCXJldHVybiBuZXcgU2VydmVyUG9ydFswXTsgCgkJfQoJfQoJCglwdWJsaWMgdm9pZCBzZXREZWZhdWx0cygpIHsKCQlzZXRUZXN0RW52aXJvbm1lbnQodHJ1ZSk7Cgl9CgkKCS8qKgoJICogU2V0cyB0aGlzIHByb2Nlc3MgdG8gZGVidWcgbW9kZS4gVGhpcyBmZWF0dXJlIG9ubHkgd29ya3MKCSAqIHdpdGggVG9tY2F0IHY0LjAuCgkgKgoJICogQHBhcmFtIGIgYm9vbGVhbgoJICovCglwdWJsaWMgdm9pZCBzZXREZWJ1Zyhib29sZWFuIGIpIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUEVSVFlfREVCVUcsIGIpOwoJfQoKCS8qKgoJICogU2V0cyB0aGlzIHByb2Nlc3MgdG8gc2VjdXJlIG1vZGUuCgkgKiBAcGFyYW0gYiBib29sZWFuCgkgKi8KCXB1YmxpYyB2b2lkIHNldFNlY3VyZShib29sZWFuIGIpIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUEVSVFlfU0VDVVJFLCBiKTsKCX0KCgkvKioKCSAqIFNldHMgdGhpcyBzZXJ2ZXIgdG8gdGVzdCBlbnZpcm9ubWVudCBtb2RlLgoJICogCgkgKiBAcGFyYW0gYiBib29sZWFuCgkgKi8KCXB1YmxpYyB2b2lkIHNldFRlc3RFbnZpcm9ubWVudChib29sZWFuIGIpIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUEVSVFlfVEVTVF9FTlZJUk9OTUVOVCwgYik7Cgl9CgkKCS8qKgoJICogQHNlZSBTZXJ2ZXJEZWxlZ2F0ZSNtb2RpZnlNb2R1bGVzKElNb2R1bGVbXSwgSU1vZHVsZVtdLCBJUHJvZ3Jlc3NNb25pdG9yKQoJICovCglwdWJsaWMgdm9pZCBtb2RpZnlNb2R1bGVzKElNb2R1bGVbXSBhZGQsIElNb2R1bGVbXSByZW1vdmUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCUlTdGF0dXMgc3RhdHVzID0gY2FuTW9kaWZ5TW9kdWxlcyhhZGQsIHJlbW92ZSk7CgkJaWYgKHN0YXR1cyA9PSBudWxsIHx8ICFzdGF0dXMuaXNPSygpKQoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihzdGF0dXMpOwoJCQoJCVRvbWNhdENvbmZpZ3VyYXRpb24gY29uZmlnID0gZ2V0VG9tY2F0Q29uZmlndXJhdGlvbigpOwoKCQlpZiAoYWRkICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBhZGQubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJSU1vZHVsZSBtb2R1bGUzID0gYWRkW2ldOwoJCQkJSVdlYk1vZHVsZSBtb2R1bGUgPSAoSVdlYk1vZHVsZSkgbW9kdWxlMy5sb2FkQWRhcHRlcihJV2ViTW9kdWxlLmNsYXNzLCBtb25pdG9yKTsKCQkJCVN0cmluZyBjb250ZXh0Um9vdCA9IG1vZHVsZS5nZXRDb250ZXh0Um9vdCgpOwoJCQkJaWYgKGNvbnRleHRSb290ICE9IG51bGwgJiYgIWNvbnRleHRSb290LnN0YXJ0c1dpdGgoIi8iKSkKCQkJCQljb250ZXh0Um9vdCA9ICIvIiArIGNvbnRleHRSb290OwoJCQkJV2ViTW9kdWxlIG1vZHVsZTIgPSBuZXcgV2ViTW9kdWxlKGNvbnRleHRSb290LAoJCQkJCQltb2R1bGUuZ2V0TG9jYXRpb24oKS50b09TU3RyaW5nKCksIG1vZHVsZTMuZ2V0SWQoKSwgdHJ1ZSk7CgkJCQljb25maWcuYWRkV2ViTW9kdWxlKC0xLCBtb2R1bGUyKTsKCQkJfQoJCX0KCQkKCQlpZiAocmVtb3ZlICE9IG51bGwpIHsKCQkJaW50IHNpemUyID0gcmVtb3ZlLmxlbmd0aDsKCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMjsgaisrKSB7CgkJCQlJTW9kdWxlIG1vZHVsZTMgPSByZW1vdmVbal07CgkJCQlTdHJpbmcgbWVtZW50byA9IG1vZHVsZTMuZ2V0SWQoKTsKCQkJCUxpc3QgbW9kdWxlcyA9IGdldFRvbWNhdENvbmZpZ3VyYXRpb24oKS5nZXRXZWJNb2R1bGVzKCk7CgkJCQlpbnQgc2l6ZSA9IG1vZHVsZXMuc2l6ZSgpOwoJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCQlXZWJNb2R1bGUgbW9kdWxlID0gKFdlYk1vZHVsZSkgbW9kdWxlcy5nZXQoaSk7CgkJCQkJaWYgKG1lbWVudG8uZXF1YWxzKG1vZHVsZS5nZXRNZW1lbnRvKCkpKQoJCQkJCQljb25maWcucmVtb3ZlV2ViTW9kdWxlKGkpOwoJCQkJfQoJCQl9CgkJfQoJCWNvbmZpZy5zYXZlKGNvbmZpZy5nZXRGb2xkZXIoKSwgbW9uaXRvcik7Cgl9Cn0=