LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKgogKiBDb250cmlidXRvcnM6CiAqICAgIElCTSBDb3Jwb3JhdGlvbiAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5jb3JlLmludGVybmFsOwoKaW1wb3J0IGphdmEubmV0LlVSTDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGb2xkZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIuY29yZS5JV2ViTW9kdWxlOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5jb3JlLmludGVybmFsLkoyRUVVdGlsOwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS51dGlsLk5MUzsKCmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC4qOwovKioKICogR2VuZXJpYyBUb21jYXQgc2VydmVyLgogKi8KcHVibGljIGNsYXNzIFRvbWNhdFNlcnZlciBleHRlbmRzIFNlcnZlckRlbGVnYXRlIGltcGxlbWVudHMgSVRvbWNhdFNlcnZlciwgSVRvbWNhdFNlcnZlcldvcmtpbmdDb3B5IHsKCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZX1NFQ1VSRSA9ICJzZWN1cmUiOwoJcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJPUEVSVFlfREVCVUcgPSAiZGVidWciOwoKCXByb3RlY3RlZCB0cmFuc2llbnQgVG9tY2F0Q29uZmlndXJhdGlvbiBjb25maWd1cmF0aW9uOwoKCS8qKgoJICogVG9tY2F0U2VydmVyLgoJICovCglwdWJsaWMgVG9tY2F0U2VydmVyKCkgewoJCXN1cGVyKCk7Cgl9CgoJcHVibGljIFRvbWNhdFJ1bnRpbWUgZ2V0VG9tY2F0UnVudGltZSgpIHsKCQlpZiAoZ2V0U2VydmVyKCkuZ2V0UnVudGltZSgpID09IG51bGwpCgkJCXJldHVybiBudWxsOwoJCQoJCXJldHVybiAoVG9tY2F0UnVudGltZSkgZ2V0U2VydmVyKCkuZ2V0UnVudGltZSgpLmxvYWRBZGFwdGVyKFRvbWNhdFJ1bnRpbWUuY2xhc3MsIG51bGwpOwoJfQoKCXB1YmxpYyBJVG9tY2F0VmVyc2lvbkhhbmRsZXIgZ2V0VG9tY2F0VmVyc2lvbkhhbmRsZXIoKSB7CgkJaWYgKGdldFNlcnZlcigpLmdldFJ1bnRpbWUoKSA9PSBudWxsIHx8IGdldFRvbWNhdFJ1bnRpbWUoKSA9PSBudWxsKQoJCQlyZXR1cm4gbnVsbDsKCgkJcmV0dXJuIGdldFRvbWNhdFJ1bnRpbWUoKS5nZXRWZXJzaW9uSGFuZGxlcigpOwoJfQoKCXB1YmxpYyBJVG9tY2F0Q29uZmlndXJhdGlvbiBnZXRTZXJ2ZXJDb25maWd1cmF0aW9uKCkgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCXJldHVybiBnZXRUb21jYXRDb25maWd1cmF0aW9uKCk7Cgl9CgoJcHVibGljIFRvbWNhdENvbmZpZ3VyYXRpb24gZ2V0VG9tY2F0Q29uZmlndXJhdGlvbigpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQlpZiAoY29uZmlndXJhdGlvbiA9PSBudWxsKSB7CgkJCUlGb2xkZXIgZm9sZGVyID0gZ2V0U2VydmVyKCkuZ2V0U2VydmVyQ29uZmlndXJhdGlvbigpOwoJCQlpZiAoZm9sZGVyID09IG51bGwgfHwgIWZvbGRlci5leGlzdHMoKSkgewoJCQkJU3RyaW5nIHBhdGggPSBudWxsOwoJCQkJaWYgKGZvbGRlciAhPSBudWxsKQoJCQkJCXBhdGggPSBmb2xkZXIuZ2V0RnVsbFBhdGgoKS50b09TU3RyaW5nKCk7CgkJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIE5MUy5iaW5kKE1lc3NhZ2VzLmVycm9yTm9Db25maWd1cmF0aW9uLCBwYXRoKSwgbnVsbCkpOwoJCQl9CgkJCQoJCQlTdHJpbmcgaWQgPSBnZXRTZXJ2ZXIoKS5nZXRTZXJ2ZXJUeXBlKCkuZ2V0SWQoKTsKCQkJaWYgKGlkLmluZGV4T2YoIjMyIikgPiAwKQoJCQkJY29uZmlndXJhdGlvbiA9IG5ldyBUb21jYXQzMkNvbmZpZ3VyYXRpb24oZm9sZGVyKTsKCQkJZWxzZSBpZiAoaWQuaW5kZXhPZigiNDAiKSA+IDApCgkJCQljb25maWd1cmF0aW9uID0gbmV3IFRvbWNhdDQwQ29uZmlndXJhdGlvbihmb2xkZXIpOwoJCQllbHNlIGlmIChpZC5pbmRleE9mKCI0MSIpID4gMCkKCQkJCWNvbmZpZ3VyYXRpb24gPSBuZXcgVG9tY2F0NDFDb25maWd1cmF0aW9uKGZvbGRlcik7CgkJCWVsc2UgaWYgKGlkLmluZGV4T2YoIjUwIikgPiAwKQoJCQkJY29uZmlndXJhdGlvbiA9IG5ldyBUb21jYXQ1MENvbmZpZ3VyYXRpb24oZm9sZGVyKTsKCQkJZWxzZSBpZiAoaWQuaW5kZXhPZigiNTUiKSA+IDApCgkJCQljb25maWd1cmF0aW9uID0gbmV3IFRvbWNhdDU1Q29uZmlndXJhdGlvbihmb2xkZXIpOwoJCQl0cnkgewoJCQkJY29uZmlndXJhdGlvbi5sb2FkKGZvbGRlciwgbnVsbCk7CgkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJCS8vIGlnbm9yZQoJCQkJY29uZmlndXJhdGlvbiA9IG51bGw7CgkJCQl0aHJvdyBjZTsKCQkJfQoJCX0KCQlyZXR1cm4gY29uZmlndXJhdGlvbjsKCX0KCglwdWJsaWMgdm9pZCBpbXBvcnRDb25maWd1cmF0aW9uKElSdW50aW1lIHJ1bnRpbWUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCWlmIChydW50aW1lID09IG51bGwpIHsKCQkJY29uZmlndXJhdGlvbiA9IG51bGw7CgkJCXJldHVybjsKCQl9CgkJSVBhdGggcGF0aCA9IHJ1bnRpbWUuZ2V0TG9jYXRpb24oKS5hcHBlbmQoImNvbmYiKTsKCQkKCQlTdHJpbmcgaWQgPSBnZXRTZXJ2ZXIoKS5nZXRTZXJ2ZXJUeXBlKCkuZ2V0SWQoKTsKCQlJRm9sZGVyIGZvbGRlciA9IGdldFNlcnZlcigpLmdldFNlcnZlckNvbmZpZ3VyYXRpb24oKTsKCQlpZiAoaWQuaW5kZXhPZigiMzIiKSA+IDApCgkJCWNvbmZpZ3VyYXRpb24gPSBuZXcgVG9tY2F0MzJDb25maWd1cmF0aW9uKGZvbGRlcik7CgkJZWxzZSBpZiAoaWQuaW5kZXhPZigiNDAiKSA+IDApCgkJCWNvbmZpZ3VyYXRpb24gPSBuZXcgVG9tY2F0NDBDb25maWd1cmF0aW9uKGZvbGRlcik7CgkJZWxzZSBpZiAoaWQuaW5kZXhPZigiNDEiKSA+IDApCgkJCWNvbmZpZ3VyYXRpb24gPSBuZXcgVG9tY2F0NDFDb25maWd1cmF0aW9uKGZvbGRlcik7CgkJZWxzZSBpZiAoaWQuaW5kZXhPZigiNTAiKSA+IDApCgkJCWNvbmZpZ3VyYXRpb24gPSBuZXcgVG9tY2F0NTBDb25maWd1cmF0aW9uKGZvbGRlcik7CgkJZWxzZSBpZiAoaWQuaW5kZXhPZigiNTUiKSA+IDApCgkJCWNvbmZpZ3VyYXRpb24gPSBuZXcgVG9tY2F0NTVDb25maWd1cmF0aW9uKGZvbGRlcik7CgkJdHJ5IHsKCQkJY29uZmlndXJhdGlvbi5pbXBvcnRGcm9tUGF0aChwYXRoLCBpc1Rlc3RFbnZpcm9ubWVudCgpLCBtb25pdG9yKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCS8vIGlnbm9yZQoJCQljb25maWd1cmF0aW9uID0gbnVsbDsKCQl9Cgl9CgoJcHVibGljIHZvaWQgc2F2ZUNvbmZpZ3VyYXRpb24oSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJaWYgKGNvbmZpZ3VyYXRpb24gPT0gbnVsbCkKCQkJcmV0dXJuOwoJCWNvbmZpZ3VyYXRpb24uc2F2ZShnZXRTZXJ2ZXIoKS5nZXRTZXJ2ZXJDb25maWd1cmF0aW9uKCksIG1vbml0b3IpOwoJfQoKCXB1YmxpYyB2b2lkIGNvbmZpZ3VyYXRpb25DaGFuZ2VkKCkgewoJCWNvbmZpZ3VyYXRpb24gPSBudWxsOwoJfQoKCS8qKgoJICogUmV0dXJuIHRoZSByb290IFVSTCBvZiB0aGlzIG1vZHVsZS4KCSAqIEBwYXJhbSBtb2R1bGUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGUKCSAqIEByZXR1cm4gamF2YS5uZXQuVVJMCgkgKi8KCXB1YmxpYyBVUkwgZ2V0TW9kdWxlUm9vdFVSTChJTW9kdWxlIG1vZHVsZSkgewoJCXRyeSB7CgkJCWlmIChtb2R1bGUgPT0gbnVsbCkKCQkJCXJldHVybiBudWxsOwoJCQkKCQkJVG9tY2F0Q29uZmlndXJhdGlvbiBjb25maWcgPSBnZXRUb21jYXRDb25maWd1cmF0aW9uKCk7CgkJCWlmIChjb25maWcgPT0gbnVsbCkKCQkJCXJldHVybiBudWxsOwoJCQkKCQkJU3RyaW5nIHVybCA9ICJodHRwOi8vbG9jYWxob3N0IjsKCQkJaW50IHBvcnQgPSBjb25maWcuZ2V0TWFpblBvcnQoKS5nZXRQb3J0KCk7CgkJCXBvcnQgPSBTZXJ2ZXJVdGlsLmdldE1vbml0b3JlZFBvcnQoZ2V0U2VydmVyKCksIHBvcnQsICJ3ZWIiKTsKCQkJaWYgKHBvcnQgIT0gODApCgkJCQl1cmwgKz0gIjoiICsgcG9ydDsKCQkJCgkJCXVybCArPSBjb25maWcuZ2V0V2ViTW9kdWxlVVJMKG1vZHVsZSk7CgkJCQoJCQlpZiAoIXVybC5lbmRzV2l0aCgiLyIpKQoJCQkJdXJsICs9ICIvIjsKCQkJCgkJCXJldHVybiBuZXcgVVJMKHVybCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiQ291bGQgbm90IGdldCByb290IFVSTCIsIGUpOwoJCQlyZXR1cm4gbnVsbDsKCQl9Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHByb2Nlc3MgaXMgc2V0IHRvIHJ1biBpbiBkZWJ1ZyBtb2RlLgoJICogVGhpcyBmZWF0dXJlIG9ubHkgd29ya3Mgd2l0aCBUb21jYXQgdjQuMC4KCSAqCgkgKiBAcmV0dXJuIGJvb2xlYW4KCSAqLwoJcHVibGljIGJvb2xlYW4gaXNEZWJ1ZygpIHsKCQlyZXR1cm4gZ2V0QXR0cmlidXRlKFBST1BFUlRZX0RFQlVHLCBmYWxzZSk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIHRlc3QgKHJ1biBjb2RlIG91dCBvZiB0aGUgd29ya2JlbmNoKSBzZXJ2ZXIuCgkgKgoJICogQHJldHVybiBib29sZWFuCgkgKi8KCXB1YmxpYyBib29sZWFuIGlzVGVzdEVudmlyb25tZW50KCkgewoJCXJldHVybiBnZXRBdHRyaWJ1dGUoUFJPUEVSVFlfVEVTVF9FTlZJUk9OTUVOVCwgZmFsc2UpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIHRoZSBwcm9jZXNzIGlzIHNldCB0byBydW4gaW4gc2VjdXJlIG1vZGUuCgkgKgoJICogQHJldHVybiBib29sZWFuCgkgKi8KCXB1YmxpYyBib29sZWFuIGlzU2VjdXJlKCkgewoJCXJldHVybiBnZXRBdHRyaWJ1dGUoUFJPUEVSVFlfU0VDVVJFLCBmYWxzZSk7Cgl9CgkKCXByb3RlY3RlZCBzdGF0aWMgU3RyaW5nIHJlbmRlckNvbW1hbmRMaW5lKFN0cmluZ1tdIGNvbW1hbmRMaW5lLCBTdHJpbmcgc2VwYXJhdG9yKSB7CgkJaWYgKGNvbW1hbmRMaW5lID09IG51bGwgfHwgY29tbWFuZExpbmUubGVuZ3RoIDwgMSkKCQkJcmV0dXJuICIiOwoJCVN0cmluZ0J1ZmZlciBidWY9IG5ldyBTdHJpbmdCdWZmZXIoY29tbWFuZExpbmVbMF0pOwoJCWZvciAoaW50IGkgPSAxOyBpIDwgY29tbWFuZExpbmUubGVuZ3RoOyBpKyspIHsKCQkJYnVmLmFwcGVuZChzZXBhcmF0b3IpOwoJCQlidWYuYXBwZW5kKGNvbW1hbmRMaW5lW2ldKTsKCQl9CQoJCXJldHVybiBidWYudG9TdHJpbmcoKTsKCX0KCgkvKgoJICogUmV0dXJucyB0aGUgY2hpbGQgbW9kdWxlKHMpIG9mIHRoaXMgbW9kdWxlLgoJICovCglwdWJsaWMgSU1vZHVsZVtdIGdldENoaWxkTW9kdWxlcyhJTW9kdWxlW10gbW9kdWxlKSB7CgkJaWYgKG1vZHVsZSA9PSBudWxsKQoJCQlyZXR1cm4gbnVsbDsKCQkKCQlpZiAobW9kdWxlLmxlbmd0aCA9PSAxICYmICJqc3Qud2ViIi5lcXVhbHMobW9kdWxlWzBdLmdldE1vZHVsZVR5cGUoKS5nZXRJZCgpKSkgewoJCQlJV2ViTW9kdWxlIHdlYk1vZHVsZSA9IChJV2ViTW9kdWxlKSBtb2R1bGVbMF0ubG9hZEFkYXB0ZXIoSVdlYk1vZHVsZS5jbGFzcywgbnVsbCk7CgkJCWlmICh3ZWJNb2R1bGUgIT0gbnVsbCkgewoJCQkJSU1vZHVsZVtdIG1vZHVsZXMgPSB3ZWJNb2R1bGUuZ2V0TW9kdWxlcygpOwoJCQkJLy9pZiAobW9kdWxlcyAhPSBudWxsKQoJCQkJLy8JU3lzdGVtLm91dC5wcmludGxuKG1vZHVsZXMubGVuZ3RoKTsKCQkJCXJldHVybiBtb2R1bGVzOwoJCQl9CgkJfQoJCXJldHVybiBuZXcgSU1vZHVsZVswXTsKCX0KCgkvKgoJICogUmV0dXJucyB0aGUgcm9vdCBtb2R1bGUocykgb2YgdGhpcyBtb2R1bGUuCgkgKi8KCXB1YmxpYyBJTW9kdWxlW10gZ2V0Um9vdE1vZHVsZXMoSU1vZHVsZSBtb2R1bGUpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQlpZiAoImpzdC53ZWIiLmVxdWFscyhtb2R1bGUuZ2V0TW9kdWxlVHlwZSgpLmdldElkKCkpKSB7CgkJCUlTdGF0dXMgc3RhdHVzID0gY2FuTW9kaWZ5TW9kdWxlcyhuZXcgSU1vZHVsZVtdIHsgbW9kdWxlIH0sIG51bGwpOwoJCQlpZiAoc3RhdHVzID09IG51bGwgfHwgIXN0YXR1cy5pc09LKCkpCgkJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihzdGF0dXMpOwoJCQlyZXR1cm4gbmV3IElNb2R1bGVbXSB7IG1vZHVsZSB9OwoJCX0KCQkKCQlyZXR1cm4gSjJFRVV0aWwuZ2V0V2ViTW9kdWxlcyhtb2R1bGUsIG51bGwpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBwcm9qZWN0IGlzIHN1cHBvcnRlZCBieSB0aGlzCgkgKiBzZXJ2ZXIsIGFuZCBmYWxzZSBvdGhlcndpc2UuCgkgKgoJICogQHBhcmFtIGFkZCBtb2R1bGVzCgkgKiBAcGFyYW0gcmVtb3ZlIG1vZHVsZXMKCSAqIEByZXR1cm4gdGhlIHN0YXR1cwoJICovCglwdWJsaWMgSVN0YXR1cyBjYW5Nb2RpZnlNb2R1bGVzKElNb2R1bGVbXSBhZGQsIElNb2R1bGVbXSByZW1vdmUpIHsKCQlpZiAoYWRkICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBhZGQubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJSU1vZHVsZSBtb2R1bGUgPSBhZGRbaV07CgkJCQlpZiAoISJqc3Qud2ViIi5lcXVhbHMobW9kdWxlLmdldE1vZHVsZVR5cGUoKS5nZXRJZCgpKSkKCQkJCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBUb21jYXRQbHVnaW4uUExVR0lOX0lELCAwLCBNZXNzYWdlcy5lcnJvcldlYk1vZHVsZXNPbmx5LCBudWxsKTsKCQkJCQoJCQkJSVN0YXR1cyBzdGF0dXMgPSBnZXRUb21jYXRWZXJzaW9uSGFuZGxlcigpLmNhbkFkZE1vZHVsZShtb2R1bGUpOwoJCQkJaWYgKHN0YXR1cyAhPSBudWxsICYmICFzdGF0dXMuaXNPSygpKQoJCQkJCXJldHVybiBzdGF0dXM7CgkJCX0KCQl9CgkJCgkJcmV0dXJuIFN0YXR1cy5PS19TVEFUVVM7Cgl9CgoJcHVibGljIFNlcnZlclBvcnRbXSBnZXRTZXJ2ZXJQb3J0cygpIHsKCQlpZiAoZ2V0U2VydmVyKCkuZ2V0U2VydmVyQ29uZmlndXJhdGlvbigpID09IG51bGwpCgkJCXJldHVybiBuZXcgU2VydmVyUG9ydFswXTsKCQkKCQl0cnkgewoJCQlMaXN0IGxpc3QgPSBnZXRUb21jYXRDb25maWd1cmF0aW9uKCkuZ2V0U2VydmVyUG9ydHMoKTsKCQkJU2VydmVyUG9ydFtdIHNwID0gbmV3IFNlcnZlclBvcnRbbGlzdC5zaXplKCldOwoJCQlsaXN0LnRvQXJyYXkoc3ApOwoJCQlyZXR1cm4gc3A7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJcmV0dXJuIG5ldyBTZXJ2ZXJQb3J0WzBdOyAKCQl9Cgl9CgoJcHVibGljIHZvaWQgc2V0RGVmYXVsdHMoSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB7CgkJc2V0VGVzdEVudmlyb25tZW50KHRydWUpOwoJfQoKCS8qKgoJICogU2V0cyB0aGlzIHByb2Nlc3MgdG8gZGVidWcgbW9kZS4gVGhpcyBmZWF0dXJlIG9ubHkgd29ya3MKCSAqIHdpdGggVG9tY2F0IHY0LjAuCgkgKgoJICogQHBhcmFtIGIgYm9vbGVhbgoJICovCglwdWJsaWMgdm9pZCBzZXREZWJ1Zyhib29sZWFuIGIpIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUEVSVFlfREVCVUcsIGIpOwoJfQoKCS8qKgoJICogU2V0cyB0aGlzIHByb2Nlc3MgdG8gc2VjdXJlIG1vZGUuCgkgKiBAcGFyYW0gYiBib29sZWFuCgkgKi8KCXB1YmxpYyB2b2lkIHNldFNlY3VyZShib29sZWFuIGIpIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUEVSVFlfU0VDVVJFLCBiKTsKCX0KCgkvKioKCSAqIFNldHMgdGhpcyBzZXJ2ZXIgdG8gdGVzdCBlbnZpcm9ubWVudCBtb2RlLgoJICogCgkgKiBAcGFyYW0gYiBib29sZWFuCgkgKi8KCXB1YmxpYyB2b2lkIHNldFRlc3RFbnZpcm9ubWVudChib29sZWFuIGIpIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUEVSVFlfVEVTVF9FTlZJUk9OTUVOVCwgYik7Cgl9CgkKCS8qKgoJICogQHNlZSBTZXJ2ZXJEZWxlZ2F0ZSNtb2RpZnlNb2R1bGVzKElNb2R1bGVbXSwgSU1vZHVsZVtdLCBJUHJvZ3Jlc3NNb25pdG9yKQoJICovCglwdWJsaWMgdm9pZCBtb2RpZnlNb2R1bGVzKElNb2R1bGVbXSBhZGQsIElNb2R1bGVbXSByZW1vdmUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCUlTdGF0dXMgc3RhdHVzID0gY2FuTW9kaWZ5TW9kdWxlcyhhZGQsIHJlbW92ZSk7CgkJaWYgKHN0YXR1cyA9PSBudWxsIHx8ICFzdGF0dXMuaXNPSygpKQoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihzdGF0dXMpOwoJCQoJCVRvbWNhdENvbmZpZ3VyYXRpb24gY29uZmlnID0gZ2V0VG9tY2F0Q29uZmlndXJhdGlvbigpOwoJCQoJCWlmIChhZGQgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IGFkZC5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlJTW9kdWxlIG1vZHVsZTMgPSBhZGRbaV07CgkJCQlJV2ViTW9kdWxlIG1vZHVsZSA9IChJV2ViTW9kdWxlKSBtb2R1bGUzLmxvYWRBZGFwdGVyKElXZWJNb2R1bGUuY2xhc3MsIG1vbml0b3IpOwoJCQkJU3RyaW5nIGNvbnRleHRSb290ID0gbW9kdWxlLmdldENvbnRleHRSb290KCk7CgkJCQlpZiAoY29udGV4dFJvb3QgIT0gbnVsbCAmJiAhY29udGV4dFJvb3Quc3RhcnRzV2l0aCgiLyIpICYmIGNvbnRleHRSb290Lmxlbmd0aCgpID4gMCkKCQkJCQljb250ZXh0Um9vdCA9ICIvIiArIGNvbnRleHRSb290OwoJCQkJU3RyaW5nIGRvY0Jhc2UgPSBjb25maWcuZ2V0RG9jQmFzZVByZWZpeCgpICsgbW9kdWxlMy5nZXROYW1lKCk7CgkJCQlXZWJNb2R1bGUgbW9kdWxlMiA9IG5ldyBXZWJNb2R1bGUoY29udGV4dFJvb3QsIGRvY0Jhc2UsIG1vZHVsZTMuZ2V0SWQoKSwgdHJ1ZSk7CgkJCQljb25maWcuYWRkV2ViTW9kdWxlKC0xLCBtb2R1bGUyKTsKCQkJfQoJCX0KCQkKCQlpZiAocmVtb3ZlICE9IG51bGwpIHsKCQkJaW50IHNpemUyID0gcmVtb3ZlLmxlbmd0aDsKCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMjsgaisrKSB7CgkJCQlJTW9kdWxlIG1vZHVsZTMgPSByZW1vdmVbal07CgkJCQlTdHJpbmcgbWVtZW50byA9IG1vZHVsZTMuZ2V0SWQoKTsKCQkJCUxpc3QgbW9kdWxlcyA9IGdldFRvbWNhdENvbmZpZ3VyYXRpb24oKS5nZXRXZWJNb2R1bGVzKCk7CgkJCQlpbnQgc2l6ZSA9IG1vZHVsZXMuc2l6ZSgpOwoJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCQlXZWJNb2R1bGUgbW9kdWxlID0gKFdlYk1vZHVsZSkgbW9kdWxlcy5nZXQoaSk7CgkJCQkJaWYgKG1lbWVudG8uZXF1YWxzKG1vZHVsZS5nZXRNZW1lbnRvKCkpKQoJCQkJCQljb25maWcucmVtb3ZlV2ViTW9kdWxlKGkpOwoJCQkJfQoJCQl9CgkJfQoJCS8vY29uZmlnLnNhdmUoY29uZmlnLmdldEZvbGRlcigpLCBtb25pdG9yKTsKCX0KCgkvKioKCSAqIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG9iamVjdC4KCSAqIEByZXR1cm4gamF2YS5sYW5nLlN0cmluZwoJICovCglwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewoJCXJldHVybiAiVG9tY2F0U2VydmVyIjsKCX0KfQ==