LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKgogKiBDb250cmlidXRvcnM6CiAqICAgIElCTSBDb3Jwb3JhdGlvbiAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5jb3JlLmludGVybmFsOwoKaW1wb3J0IGphdmEuaW8uKjsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRmlsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGb2xkZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIudG9tY2F0LmNvcmUuaW50ZXJuYWwueG1sLkZhY3Rvcnk7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5jb3JlLmludGVybmFsLnhtbC5YTUxVdGlsOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci50b21jYXQuY29yZS5pbnRlcm5hbC54bWwuc2VydmVyNDAuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudXRpbC5OTFM7CmltcG9ydCBvcmcudzNjLmRvbS5Eb2N1bWVudDsKaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CmltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKCmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuU2VydmVyUG9ydDsKLyoqCiAqIFRvbWNhdCB2NC4xIHNlcnZlciBjb25maWd1cmF0aW9uLgogKi8KcHVibGljIGNsYXNzIFRvbWNhdDQxQ29uZmlndXJhdGlvbiBleHRlbmRzIFRvbWNhdENvbmZpZ3VyYXRpb24gewoJcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9TRVJWSUNFID0gIlRvbWNhdC1TdGFuZGFsb25lIjsKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEhUVFBfQ09OTkVDVE9SID0gIm9yZy5hcGFjaGUuY295b3RlLnRvbWNhdDQuQ295b3RlQ29ubmVjdG9yIjsKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEpLX1BST1RPQ09MX0hBTkRMRVIgPSAib3JnLmFwYWNoZS5qay5zZXJ2ZXIuSmtDb3lvdGVIYW5kbGVyIjsKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIFNTTF9TT0NLRVRfRkFDVE9SWSA9ICJvcmcuYXBhY2hlLmNveW90ZS50b21jYXQ0LkNveW90ZVNlcnZlclNvY2tldEZhY3RvcnkiOwoJLy9wcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBURVNUX0NPTk5FQ1RPUiA9ICJvcmcuYXBhY2hlLmNhdGFsaW5hLmNvbm5lY3Rvci50ZXN0Lkh0dHBDb25uZWN0b3IiOwoJLy9vcmcuYXBhY2hlLmFqcC50b21jYXQ0LkFqcDEzQ29ubmVjdG9yCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBBUEFDSEVfQ09OTkVDVE9SID0gIm9yZy5hcGFjaGUuY2F0YWxpbmEuY29ubmVjdG9yLndhcnAuV2FycENvbm5lY3RvciI7CgoJcHJvdGVjdGVkIFNlcnZlciBzZXJ2ZXI7Cglwcm90ZWN0ZWQgRmFjdG9yeSBzZXJ2ZXJGYWN0b3J5OwoJcHJvdGVjdGVkIGJvb2xlYW4gaXNTZXJ2ZXJEaXJ0eTsKCglwcm90ZWN0ZWQgV2ViQXBwRG9jdW1lbnQgd2ViQXBwRG9jdW1lbnQ7CgoJcHJvdGVjdGVkIERvY3VtZW50IHRvbWNhdFVzZXJzRG9jdW1lbnQ7CgoJcHJvdGVjdGVkIFN0cmluZyBwb2xpY3lGaWxlOwoJcHJvdGVjdGVkIGJvb2xlYW4gaXNQb2xpY3lEaXJ0eTsKCgkvKioKCSAqIFRvbWNhdDQxQ29uZmlndXJhdGlvbiBjb25zdHJ1Y3Rvci4KCSAqIAoJICogQHBhcmFtIHBhdGggYSBwYXRoCgkgKi8KCXB1YmxpYyBUb21jYXQ0MUNvbmZpZ3VyYXRpb24oSUZvbGRlciBwYXRoKSB7CgkJc3VwZXIocGF0aCk7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gdGhlIHBvcnQgbnVtYmVyLgoJICogQHJldHVybiBpbnQKCSAqLwoJcHVibGljIFNlcnZlclBvcnQgZ2V0TWFpblBvcnQoKSB7CgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBnZXRTZXJ2ZXJQb3J0cygpLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlTZXJ2ZXJQb3J0IHBvcnQgPSAoU2VydmVyUG9ydCkgaXRlcmF0b3IubmV4dCgpOwoJCQlpZiAocG9ydC5nZXROYW1lKCkuZXF1YWxzKCJIVFRQIENvbm5lY3RvciIpKQoJCQkJcmV0dXJuIHBvcnQ7CgkJfQoJCXJldHVybiBudWxsOwoJfQoJCgkvKioKCSAqIFJldHVybnMgdGhlIG1pbWUgbWFwcGluZ3MuCgkgKiBAcmV0dXJuIGphdmEudXRpbC5MaXN0CgkgKi8KCXB1YmxpYyBMaXN0IGdldE1pbWVNYXBwaW5ncygpIHsKCQlyZXR1cm4gd2ViQXBwRG9jdW1lbnQuZ2V0TWltZU1hcHBpbmdzKCk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGEgbGlzdCBvZiBTZXJ2ZXJQb3J0cyB0aGF0IHRoaXMgY29uZmlndXJhdGlvbiB1c2VzLgoJICoKCSAqIEByZXR1cm4gamF2YS51dGlsLkxpc3QKCSAqLwoJcHVibGljIExpc3QgZ2V0U2VydmVyUG9ydHMoKSB7CgkJTGlzdCBwb3J0cyA9IG5ldyBBcnJheUxpc3QoKTsKCQoJCS8vIGZpcnN0IGFkZCBzZXJ2ZXIgcG9ydAoJCXRyeSB7CgkJCWludCBwb3J0ID0gSW50ZWdlci5wYXJzZUludChzZXJ2ZXIuZ2V0UG9ydCgpKTsKCQkJcG9ydHMuYWRkKG5ldyBTZXJ2ZXJQb3J0KCJzZXJ2ZXIiLCBNZXNzYWdlcy5wb3J0U2VydmVyLCBwb3J0LCAiVENQSVAiKSk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJLy8gaWdub3JlCgkJfQoJCgkJLy8gYWRkIGNvbm5lY3RvcnMKCQl0cnkgewoJCQlpbnQgc2l6ZSA9IHNlcnZlci5nZXRTZXJ2aWNlQ291bnQoKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCVNlcnZpY2Ugc2VydmljZSA9IHNlcnZlci5nZXRTZXJ2aWNlKGkpOwoJCQkJaW50IHNpemUyID0gc2VydmljZS5nZXRDb25uZWN0b3JDb3VudCgpOwoJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMjsgaisrKSB7CgkJCQkJQ29ubmVjdG9yIGNvbm5lY3RvciA9IHNlcnZpY2UuZ2V0Q29ubmVjdG9yKGopOwoJCQkJCVN0cmluZyBjbGFzc05hbWUgPSBjb25uZWN0b3IuZ2V0Q2xhc3NOYW1lKCk7CgkJCQkJU3RyaW5nIG5hbWUgPSBjbGFzc05hbWU7CgkJCQkJU3RyaW5nIHByb3RvY29sID0gIlRDUElQIjsKCQkJCQlib29sZWFuIGFkdmFuY2VkID0gdHJ1ZTsKCQkJCQlTdHJpbmdbXSBjb250ZW50VHlwZXMgPSBudWxsOwoJCQkJCWludCBwb3J0ID0gLTE7CgkJCQkJdHJ5IHsKCQkJCQkJcG9ydCA9IEludGVnZXIucGFyc2VJbnQoY29ubmVjdG9yLmdldFBvcnQoKSk7CgkJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCQkJLy8gaWdub3JlCgkJCQkJfQoJCQkJCWlmIChIVFRQX0NPTk5FQ1RPUi5lcXVhbHMoY2xhc3NOYW1lKSkgewoJCQkJCQluYW1lID0gIkhUVFAgQ29ubmVjdG9yIjsKCQkJCQkJcHJvdG9jb2wgPSAiSFRUUCI7CgkJCQkJCWNvbnRlbnRUeXBlcyA9IG5ldyBTdHJpbmdbXSB7ICJ3ZWIiLCAid2Vic2VydmljZXMiIH07CgkJCQkJCS8vIGNoZWNrIGZvciBBSlAvMS4zIENveW90ZSBjb25uZWN0b3IKCQkJCQkJU3RyaW5nIHByb3RvY29sSGFuZGxlciA9IGNvbm5lY3Rvci5nZXRQcm90b2NvbEhhbmRsZXJDbGFzc05hbWUoKTsKCQkJCQkJaWYgKEpLX1BST1RPQ09MX0hBTkRMRVIuZXF1YWxzKHByb3RvY29sSGFuZGxlcikpIHsKCQkJCQkJCW5hbWUgPSAiQUpQLzEuMyBDb25uZWN0b3IiOwoJCQkJCQkJcHJvdG9jb2wgPSAiQUpQLzEuMyI7IAoJCQkJCQl9IGVsc2UgewoJCQkJCQkJLy8gYXNzdW1lIEhUVFAsIGNoZWNrIGZvciBIVFRQIFNTTCBjb25uZWN0b3IKCQkJCQkJCXRyeSB7CgkJCQkJCQkJRWxlbWVudCBlbGVtZW50ID0gY29ubmVjdG9yLmdldFN1YkVsZW1lbnQoIkZhY3RvcnkiKTsKCQkJCQkJCQlpZiAoU1NMX1NPQ0tFVF9GQUNUT1JZLmVxdWFscyhlbGVtZW50LmdldEF0dHJpYnV0ZSgiY2xhc3NOYW1lIikpKSB7CgkJCQkJCQkJCW5hbWUgPSAiU1NMIENvbm5lY3RvciI7CgkJCQkJCQkJCXByb3RvY29sID0gIlNTTCI7CgkJCQkJCQkJfQoJCQkJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCQkJCQkvLyBpZ25vcmUKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQlpZiAoIkhUVFAiLmVxdWFscyhwcm90b2NvbCkpCgkJCQkJCQlhZHZhbmNlZCA9IGZhbHNlOwoJCQkJCX0gZWxzZSBpZiAoQVBBQ0hFX0NPTk5FQ1RPUi5lcXVhbHMoY2xhc3NOYW1lKSkKCQkJCQkJbmFtZSA9ICJBcGFjaGUgQ29ubmVjdG9yIjsKCQkJCQlpZiAoY2xhc3NOYW1lICE9IG51bGwgJiYgY2xhc3NOYW1lLmxlbmd0aCgpID4gMCkKCQkJCQkJcG9ydHMuYWRkKG5ldyBTZXJ2ZXJQb3J0KGkgKyAiLyIgKyBqLCBuYW1lLCBwb3J0LCBwcm90b2NvbCwgY29udGVudFR5cGVzLCBhZHZhbmNlZCkpOwoJCQkJfQoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgZ2V0dGluZyBzZXJ2ZXIgcG9ydHMiLCBlKTsKCQl9CgkJcmV0dXJuIHBvcnRzOwoJfQoJCgkvKioKCSAqIFJldHVybiBhIGxpc3Qgb2YgdGhlIHdlYiBtb2R1bGVzIGluIHRoaXMgc2VydmVyLgoJICogQHJldHVybiBqYXZhLnV0aWwuTGlzdAoJICovCglwdWJsaWMgTGlzdCBnZXRXZWJNb2R1bGVzKCkgewoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQoJCXRyeSB7CgkJCWludCBzaXplID0gc2VydmVyLmdldFNlcnZpY2VDb3VudCgpOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJU2VydmljZSBzZXJ2aWNlID0gc2VydmVyLmdldFNlcnZpY2UoaSk7CgkJCQlpZiAoc2VydmljZS5nZXROYW1lKCkuZXF1YWxzSWdub3JlQ2FzZShERUZBVUxUX1NFUlZJQ0UpKSB7CgkJCQkJRW5naW5lIGVuZ2luZSA9IHNlcnZpY2UuZ2V0RW5naW5lKCk7CgkJCQkJSG9zdCBob3N0ID0gZW5naW5lLmdldEhvc3QoKTsKCQkJCQlpbnQgc2l6ZTIgPSBob3N0LmdldENvbnRleHRDb3VudCgpOwoJCQkJCWZvciAoaW50IGogPSAwOyBqIDwgc2l6ZTI7IGorKykgewoJCQkJCQlDb250ZXh0IGNvbnRleHQgPSBob3N0LmdldENvbnRleHQoaik7CgkJCQkJCVN0cmluZyByZWxvYWQgPSBjb250ZXh0LmdldFJlbG9hZGFibGUoKTsKCQkJCQkJaWYgKHJlbG9hZCA9PSBudWxsKQoJCQkJCQkJcmVsb2FkID0gImZhbHNlIjsKCQkJCQkJV2ViTW9kdWxlIG1vZHVsZSA9IG5ldyBXZWJNb2R1bGUoY29udGV4dC5nZXRQYXRoKCksIAoJCQkJCQkJY29udGV4dC5nZXREb2NCYXNlKCksIGNvbnRleHQuZ2V0U291cmNlKCksCgkJCQkJCQlyZWxvYWQuZXF1YWxzSWdub3JlQ2FzZSgidHJ1ZSIpID8gdHJ1ZSA6IGZhbHNlKTsKCQkJCQkJbGlzdC5hZGQobW9kdWxlKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBnZXR0aW5nIHByb2plY3QgcmVmcyIsIGUpOwoJCX0KCQlyZXR1cm4gbGlzdDsKCX0KCQoJcHVibGljIHZvaWQgaW1wb3J0RnJvbVBhdGgoSVBhdGggcGF0aCwgYm9vbGVhbiBpc1Rlc3RFbnYsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCWxvYWQocGF0aCwgbW9uaXRvcik7CgkJCgkJLy8gZm9yIHRlc3QgZW52aXJvbm1lbnQsIHJlbW92ZSBleGlzdGluZyBjb250ZXh0cyBzaW5jZSBhIHNlcGFyYXRlCgkJLy8gY2F0YWxpbmEuYmFzZSB3aWxsIGJlIHVzZWQKCQlpZiAoaXNUZXN0RW52KSB7CgkJCWludCBzaXplID0gc2VydmVyLmdldFNlcnZpY2VDb3VudCgpOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJU2VydmljZSBzZXJ2aWNlID0gc2VydmVyLmdldFNlcnZpY2UoaSk7CgkJCQlpZiAoc2VydmljZS5nZXROYW1lKCkuZXF1YWxzSWdub3JlQ2FzZShERUZBVUxUX1NFUlZJQ0UpKSB7CgkJCQkJSG9zdCBob3N0ID0gc2VydmljZS5nZXRFbmdpbmUoKS5nZXRIb3N0KCk7CgkJCQkJaW50IHNpemUyID0gaG9zdC5nZXRDb250ZXh0Q291bnQoKTsKCQkJCQlmb3IgKGludCBqID0gMDsgaiA8IHNpemUyOyBqKyspIHsKCQkJCQkJaG9zdC5yZW1vdmVFbGVtZW50KCJDb250ZXh0IiwgMCk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJfQoJCgkvKioKCSAqIEBzZWUgVG9tY2F0Q29uZmlndXJhdGlvbiNsb2FkKElQYXRoLCBJUHJvZ3Jlc3NNb25pdG9yKQoJICovCglwdWJsaWMgdm9pZCBsb2FkKElQYXRoIHBhdGgsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCXRyeSB7CgkJCW1vbml0b3IgPSBQcm9ncmVzc1V0aWwuZ2V0TW9uaXRvckZvcihtb25pdG9yKTsKCQkJbW9uaXRvci5iZWdpblRhc2soTWVzc2FnZXMubG9hZGluZ1Rhc2ssIDUpOwoJCQkKCQkJLy8gY2hlY2sgZm9yIGNhdGFsaW5hLnBvbGljeSB0byB2ZXJpZnkgdGhhdCB0aGlzIGlzIGEgdjQuMCBjb25maWcKCQkJSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKHBhdGguYXBwZW5kKCJjYXRhbGluYS5wb2xpY3kiKS50b0ZpbGUoKSk7CgkJCWluLnJlYWQoKTsKCQkJaW4uY2xvc2UoKTsKCQkJbW9uaXRvci53b3JrZWQoMSk7CgoJCQlzZXJ2ZXJGYWN0b3J5ID0gbmV3IEZhY3RvcnkoKTsKCQkJc2VydmVyRmFjdG9yeS5zZXRQYWNrYWdlTmFtZSgib3JnLmVjbGlwc2UuanN0LnNlcnZlci50b21jYXQuY29yZS5pbnRlcm5hbC54bWwuc2VydmVyNDAiKTsKCQkJc2VydmVyID0gKFNlcnZlcikgc2VydmVyRmFjdG9yeS5sb2FkRG9jdW1lbnQobmV3IEZpbGVJbnB1dFN0cmVhbShwYXRoLmFwcGVuZCgic2VydmVyLnhtbCIpLnRvRmlsZSgpKSk7CgkJCW1vbml0b3Iud29ya2VkKDEpOwoKCQkJd2ViQXBwRG9jdW1lbnQgPSBuZXcgV2ViQXBwRG9jdW1lbnQocGF0aC5hcHBlbmQoIndlYi54bWwiKSk7CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCgkJCXRvbWNhdFVzZXJzRG9jdW1lbnQgPSBYTUxVdGlsLmdldERvY3VtZW50QnVpbGRlcigpLnBhcnNlKG5ldyBJbnB1dFNvdXJjZShuZXcgRmlsZUlucHV0U3RyZWFtKHBhdGguYXBwZW5kKCJ0b21jYXQtdXNlcnMueG1sIikudG9GaWxlKCkpKSk7CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCQoJCQkvLyBsb2FkIHBvbGljeSBmaWxlCgkJCUJ1ZmZlcmVkUmVhZGVyIGJyID0gbnVsbDsKCQkJdHJ5IHsKCQkJCWJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihuZXcgRmlsZUlucHV0U3RyZWFtKHBhdGguYXBwZW5kKCJjYXRhbGluYS5wb2xpY3kiKS50b0ZpbGUoKSkpKTsKCQkJCVN0cmluZyB0ZW1wID0gYnIucmVhZExpbmUoKTsKCQkJCXBvbGljeUZpbGUgPSAiIjsKCQkJCXdoaWxlICh0ZW1wICE9IG51bGwpIHsKCQkJCQlwb2xpY3lGaWxlICs9IHRlbXAgKyAiXG4iOwoJCQkJCXRlbXAgPSBici5yZWFkTGluZSgpOwoJCQkJfQoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkNvdWxkIG5vdCBsb2FkIHBvbGljeSBmaWxlIiwgZSk7CgkJCX0gZmluYWxseSB7CgkJCQlpZiAoYnIgIT0gbnVsbCkKCQkJCQlici5jbG9zZSgpOwoJCQl9CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCgkJCWlmIChtb25pdG9yLmlzQ2FuY2VsZWQoKSkKCQkJCXJldHVybjsKCQkJbW9uaXRvci5kb25lKCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkNvdWxkIG5vdCBsb2FkIFRvbWNhdCB2NC4wIGNvbmZpZ3VyYXRpb24gZnJvbSAiICsgcGF0aC50b09TU3RyaW5nKCkgKyAiOiAiICsgZS5nZXRNZXNzYWdlKCkpOwoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIE5MUy5iaW5kKE1lc3NhZ2VzLmVycm9yQ291bGROb3RMb2FkQ29uZmlndXJhdGlvbiwgcGF0aC50b09TU3RyaW5nKCkpLCBlKSk7CgkJfQoJfQoKCS8qKgoJICogQHNlZSBUb21jYXRDb25maWd1cmF0aW9uI2xvYWQoSUZvbGRlciwgSVByb2dyZXNzTW9uaXRvcikKCSAqLwoJcHVibGljIHZvaWQgbG9hZChJRm9sZGVyIGZvbGRlciwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJdHJ5IHsKCQkJbW9uaXRvciA9IFByb2dyZXNzVXRpbC5nZXRNb25pdG9yRm9yKG1vbml0b3IpOwoJCQltb25pdG9yLmJlZ2luVGFzayhNZXNzYWdlcy5sb2FkaW5nVGFzaywgODAwKTsKCQoJCQkvLyBjaGVjayBmb3IgY2F0YWxpbmEucG9saWN5IHRvIHZlcmlmeSB0aGF0IHRoaXMgaXMgYSB2NC4wIGNvbmZpZwoJCQlJRmlsZSBmaWxlID0gZm9sZGVyLmdldEZpbGUoImNhdGFsaW5hLnBvbGljeSIpOwoJCQlpZiAoIWZpbGUuZXhpc3RzKCkpCgkJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuV0FSTklORywgVG9tY2F0UGx1Z2luLlBMVUdJTl9JRCwgMCwgTkxTLmJpbmQoTWVzc2FnZXMuZXJyb3JDb3VsZE5vdExvYWRDb25maWd1cmF0aW9uLCBmb2xkZXIuZ2V0RnVsbFBhdGgoKS50b09TU3RyaW5nKCkpLCBudWxsKSk7CgkKCQkJLy8gbG9hZCBzZXJ2ZXIueG1sCgkJCWZpbGUgPSBmb2xkZXIuZ2V0RmlsZSgic2VydmVyLnhtbCIpOwoJCQlJbnB1dFN0cmVhbSBpbiA9IGZpbGUuZ2V0Q29udGVudHMoKTsKCQkJc2VydmVyRmFjdG9yeSA9IG5ldyBGYWN0b3J5KCk7CgkJCXNlcnZlckZhY3Rvcnkuc2V0UGFja2FnZU5hbWUoIm9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIudG9tY2F0LmNvcmUuaW50ZXJuYWwueG1sLnNlcnZlcjQwIik7CgkJCXNlcnZlciA9IChTZXJ2ZXIpIHNlcnZlckZhY3RvcnkubG9hZERvY3VtZW50KGluKTsKCQkJbW9uaXRvci53b3JrZWQoMjAwKTsKCQoJCQkvLyBsb2FkIHdlYi54bWwKCQkJZmlsZSA9IGZvbGRlci5nZXRGaWxlKCJ3ZWIueG1sIik7CgkJCXdlYkFwcERvY3VtZW50ID0gbmV3IFdlYkFwcERvY3VtZW50KGZpbGUpOwoJCQltb25pdG9yLndvcmtlZCgyMDApOwoJCgkJCS8vIGxvYWQgdG9tY2F0LXVzZXJzLnhtbAoJCQlmaWxlID0gZm9sZGVyLmdldEZpbGUoInRvbWNhdC11c2Vycy54bWwiKTsKCQkJaW4gPSBmaWxlLmdldENvbnRlbnRzKCk7CgoJCQl0b21jYXRVc2Vyc0RvY3VtZW50ID0gWE1MVXRpbC5nZXREb2N1bWVudEJ1aWxkZXIoKS5wYXJzZShuZXcgSW5wdXRTb3VyY2UoaW4pKTsKCQkJbW9uaXRvci53b3JrZWQoMjAwKTsKCQkKCQkJLy8gbG9hZCBjYXRhbGluYS5wb2xpY3kKCQkJZmlsZSA9IGZvbGRlci5nZXRGaWxlKCJjYXRhbGluYS5wb2xpY3kiKTsKCQkJaW4gPSBmaWxlLmdldENvbnRlbnRzKCk7CgkJCUJ1ZmZlcmVkUmVhZGVyIGJyID0gbnVsbDsKCQkJdHJ5IHsKCQkJCWJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpbikpOwoJCQkJU3RyaW5nIHRlbXAgPSBici5yZWFkTGluZSgpOwoJCQkJcG9saWN5RmlsZSA9ICIiOwoJCQkJd2hpbGUgKHRlbXAgIT0gbnVsbCkgewoJCQkJCXBvbGljeUZpbGUgKz0gdGVtcCArICJcbiI7CgkJCQkJdGVtcCA9IGJyLnJlYWRMaW5lKCk7CgkJCQl9CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5XQVJOSU5HLCAiQ291bGQgbm90IGxvYWQgcG9saWN5IGZpbGUiLCBlKTsKCQkJfSBmaW5hbGx5IHsKCQkJCWlmIChiciAhPSBudWxsKQoJCQkJCWJyLmNsb3NlKCk7CgkJCX0KCQkJbW9uaXRvci53b3JrZWQoMjAwKTsKCQoJCQlpZiAobW9uaXRvci5pc0NhbmNlbGVkKCkpCgkJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKCJDYW5jZWxsZWQiKTsKCQkJbW9uaXRvci5kb25lKCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkNvdWxkIG5vdCByZWxvYWQgVG9tY2F0IHY0LjEgY29uZmlndXJhdGlvbiBmcm9tOiAiICsgZm9sZGVyLmdldEZ1bGxQYXRoKCkgKyAiOiAiICsgZS5nZXRNZXNzYWdlKCkpOwoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIE5MUy5iaW5kKE1lc3NhZ2VzLmVycm9yQ291bGROb3RMb2FkQ29uZmlndXJhdGlvbiwgZm9sZGVyLmdldEZ1bGxQYXRoKCkudG9PU1N0cmluZygpKSwgZSkpOwoJCX0KCX0KCgkvKioKCSAqIFNhdmUgdG8gdGhlIGdpdmVuIGRpcmVjdG9yeS4KCSAqIAoJICogQHBhcmFtIHBhdGggYSBwYXRoCgkgKiBAcGFyYW0gZm9yY2VEaXJ0eSBib29sZWFuCgkgKiBAcGFyYW0gbW9uaXRvciBhIHByb2dyZXNzIG1vbml0b3IKCSAqIEBleGNlcHRpb24gQ29yZUV4Y2VwdGlvbgoJICovCglwcm90ZWN0ZWQgdm9pZCBzYXZlKElQYXRoIHBhdGgsIGJvb2xlYW4gZm9yY2VEaXJ0eSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJdHJ5IHsKCQkJbW9uaXRvciA9IFByb2dyZXNzVXRpbC5nZXRNb25pdG9yRm9yKG1vbml0b3IpOwoJCQltb25pdG9yLmJlZ2luVGFzayhNZXNzYWdlcy5zYXZpbmdUYXNrLCAzKTsKCQoJCQkvLyBtYWtlIHN1cmUgZGlyZWN0b3J5IGV4aXN0cwoJCQlpZiAoIXBhdGgudG9GaWxlKCkuZXhpc3RzKCkpIHsKCQkJCWZvcmNlRGlydHkgPSB0cnVlOwoJCQkJcGF0aC50b0ZpbGUoKS5ta2RpcigpOwoJCQl9CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCgkJCS8vIHNhdmUgZmlsZXMKCQkJaWYgKGZvcmNlRGlydHkgfHwgaXNTZXJ2ZXJEaXJ0eSkKCQkJCXNlcnZlckZhY3Rvcnkuc2F2ZShwYXRoLmFwcGVuZCgic2VydmVyLnhtbCIpLnRvT1NTdHJpbmcoKSk7CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCgkJCS8vaWYgKGZvcmNlRGlydHkgfHwgaXNXZWJBcHBEaXJ0eSkKCQkJLy8Jd2ViQXBwRmFjdG9yeS5zYXZlKGRpclBhdGggKyAid2ViLnhtbCIpOwoJCQkvL3dlYkFwcERvY3VtZW50LnNhdmUocGF0aC50b09TU3RyaW5nKCksIGZvcmNlRGlydHkgfHwgaXNQb2xpY3lEaXJ0eSk7CgkJCXdlYkFwcERvY3VtZW50LnNhdmUocGF0aC5hcHBlbmQoIndlYi54bWwiKS50b09TU3RyaW5nKCksIGZvcmNlRGlydHkpOwoJCQltb25pdG9yLndvcmtlZCgxKTsKCQoJCQlpZiAoZm9yY2VEaXJ0eSkKCQkJCVhNTFV0aWwuc2F2ZShwYXRoLmFwcGVuZCgidG9tY2F0LXVzZXJzLnhtbCIpLnRvT1NTdHJpbmcoKSwgdG9tY2F0VXNlcnNEb2N1bWVudCk7CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCgkJCWlmIChmb3JjZURpcnR5IHx8IGlzUG9saWN5RGlydHkpIHsKCQkJCUJ1ZmZlcmVkV3JpdGVyIGJ3ID0gbmV3IEJ1ZmZlcmVkV3JpdGVyKG5ldyBGaWxlV3JpdGVyKHBhdGguYXBwZW5kKCJjYXRhbGluYS5wb2xpY3kiKS50b0ZpbGUoKSkpOwoJCQkJYncud3JpdGUocG9saWN5RmlsZSk7CgkJCQlidy5jbG9zZSgpOwoJCQl9CgkJCW1vbml0b3Iud29ya2VkKDEpOwoJCQlpc1NlcnZlckRpcnR5ID0gZmFsc2U7CgkJCWlzUG9saWN5RGlydHkgPSBmYWxzZTsKCQoJCQlpZiAobW9uaXRvci5pc0NhbmNlbGVkKCkpCgkJCQlyZXR1cm47CgkJCW1vbml0b3IuZG9uZSgpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkNvdWxkIG5vdCBzYXZlIFRvbWNhdCB2NC4xIGNvbmZpZ3VyYXRpb24gdG8gIiArIHBhdGgsIGUpOwoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIE5MUy5iaW5kKE1lc3NhZ2VzLmVycm9yQ291bGROb3RTYXZlQ29uZmlndXJhdGlvbiwgbmV3IFN0cmluZ1tdIHtlLmdldExvY2FsaXplZE1lc3NhZ2UoKX0pLCBlKSk7CgkJfQoJfQoJCglwdWJsaWMgdm9pZCBzYXZlKElQYXRoIHBhdGgsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCXNhdmUocGF0aCwgdHJ1ZSwgbW9uaXRvcik7Cgl9CgoJLyoqCgkgKiBTYXZlIHRoZSBpbmZvcm1hdGlvbiBoZWxkIGJ5IHRoaXMgb2JqZWN0IHRvIHRoZSBnaXZlbiBkaXJlY3RvcnkuCgkgKgoJICogQHBhcmFtIGZvbGRlciBhIGZvbGRlcgoJICogQHBhcmFtIG1vbml0b3IgYSBwcm9ncmVzcyBtb25pdG9yCgkgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24KCSAqLwoJcHVibGljIHZvaWQgc2F2ZShJRm9sZGVyIGZvbGRlciwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJdHJ5IHsKCQkJbW9uaXRvciA9IFByb2dyZXNzVXRpbC5nZXRNb25pdG9yRm9yKG1vbml0b3IpOwoJCQltb25pdG9yLmJlZ2luVGFzayhNZXNzYWdlcy5zYXZpbmdUYXNrLCA5MDApOwoJCgkJCS8vIHNhdmUgc2VydmVyLnhtbAoJCQlieXRlW10gZGF0YSA9IHNlcnZlckZhY3RvcnkuZ2V0Q29udGVudHMoKTsKCQkJSW5wdXRTdHJlYW0gaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZGF0YSk7CgkJCUlGaWxlIGZpbGUgPSBmb2xkZXIuZ2V0RmlsZSgic2VydmVyLnhtbCIpOwoJCQlpZiAoZmlsZS5leGlzdHMoKSkgewoJCQkJaWYgKGlzU2VydmVyRGlydHkpCgkJCQkJZmlsZS5zZXRDb250ZW50cyhpbiwgdHJ1ZSwgdHJ1ZSwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgMjAwKSk7CgkJCQllbHNlCgkJCQkJbW9uaXRvci53b3JrZWQoMjAwKTsKCQkJfSBlbHNlCgkJCQlmaWxlLmNyZWF0ZShpbiwgdHJ1ZSwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgMjAwKSk7CgkKCQkJLy8gc2F2ZSB3ZWIueG1sCgkJCXdlYkFwcERvY3VtZW50LnNhdmUoZm9sZGVyLmdldEZpbGUoIndlYi54bWwiKSwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgMjAwKSk7CgkKCQkJLy8gc2F2ZSB0b21jYXQtdXNlcnMueG1sCgkJCWRhdGEgPSBYTUxVdGlsLmdldENvbnRlbnRzKHRvbWNhdFVzZXJzRG9jdW1lbnQpOwoJCQlpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShkYXRhKTsKCQkJZmlsZSA9IGZvbGRlci5nZXRGaWxlKCJ0b21jYXQtdXNlcnMueG1sIik7CgkJCWlmIChmaWxlLmV4aXN0cygpKQoJCQkJbW9uaXRvci53b3JrZWQoMjAwKTsKCQkJCS8vZmlsZS5zZXRDb250ZW50cyhpbiwgdHJ1ZSwgdHJ1ZSwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgMjAwKSk7CgkJCWVsc2UKCQkJCWZpbGUuY3JlYXRlKGluLCB0cnVlLCBQcm9ncmVzc1V0aWwuZ2V0U3ViTW9uaXRvckZvcihtb25pdG9yLCAyMDApKTsKCQoJCQkvLyBzYXZlIGNhdGFsaW5hLnBvbGljeQoJCQlpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShwb2xpY3lGaWxlLmdldEJ5dGVzKCkpOwoJCQlmaWxlID0gZm9sZGVyLmdldEZpbGUoImNhdGFsaW5hLnBvbGljeSIpOwoJCQlpZiAoZmlsZS5leGlzdHMoKSkKCQkJCW1vbml0b3Iud29ya2VkKDIwMCk7CgkJCQkvL2ZpbGUuc2V0Q29udGVudHMoaW4sIHRydWUsIHRydWUsIFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDIwMCkpOwoJCQllbHNlCgkJCQlmaWxlLmNyZWF0ZShpbiwgdHJ1ZSwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgMjAwKSk7CgkKCQkJaWYgKG1vbml0b3IuaXNDYW5jZWxlZCgpKQoJCQkJcmV0dXJuOwoJCQltb25pdG9yLmRvbmUoKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJDb3VsZCBub3Qgc2F2ZSBUb21jYXQgdjQuMSBjb25maWd1cmF0aW9uIHRvICIgKyBmb2xkZXIudG9TdHJpbmcoKSwgZSk7CgkJCXRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgVG9tY2F0UGx1Z2luLlBMVUdJTl9JRCwgMCwgTkxTLmJpbmQoTWVzc2FnZXMuZXJyb3JDb3VsZE5vdFNhdmVDb25maWd1cmF0aW9uLCBuZXcgU3RyaW5nW10ge2UuZ2V0TG9jYWxpemVkTWVzc2FnZSgpfSksIGUpKTsKCQl9Cgl9CgoJcHJvdGVjdGVkIHN0YXRpYyBib29sZWFuIGhhc01EQkxpc3RlbmVyKFNlcnZlciBzZXJ2ZXIpIHsKCQlpZiAoc2VydmVyID09IG51bGwpCgkJCXJldHVybiBmYWxzZTsKCQkKCQlpbnQgY291bnQgPSBzZXJ2ZXIuZ2V0TGlzdGVuZXJDb3VudCgpOwoJCWlmIChjb3VudCA9PSAwKQoJCQlyZXR1cm4gZmFsc2U7CgkJCQoJCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewoJCQlMaXN0ZW5lciBsaXN0ZW5lciA9IHNlcnZlci5nZXRMaXN0ZW5lcihpKTsKCQkJaWYgKGxpc3RlbmVyICE9IG51bGwgJiYgbGlzdGVuZXIuZ2V0Q2xhc3NOYW1lKCkgIT0gbnVsbCAmJiBsaXN0ZW5lci5nZXRDbGFzc05hbWUoKS5pbmRleE9mKCJtYmVhbiIpID49IDApCgkJCQlyZXR1cm4gdHJ1ZTsKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoJCgkvKioKCSAqIEBzZWUgSVRvbWNhdENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSNhZGRNaW1lTWFwcGluZyhpbnQsIElNaW1lTWFwcGluZykKCSAqLwoJcHVibGljIHZvaWQgYWRkTWltZU1hcHBpbmcoaW50IGluZGV4LCBJTWltZU1hcHBpbmcgbWFwKSB7CgkJd2ViQXBwRG9jdW1lbnQuYWRkTWltZU1hcHBpbmcoaW5kZXgsIG1hcCk7CgkJZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQoQUREX01BUFBJTkdfUFJPUEVSVFksIG5ldyBJbnRlZ2VyKGluZGV4KSwgbWFwKTsKCX0KCgkvKioKCSAqIEBzZWUgSVRvbWNhdENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSNhZGRXZWJNb2R1bGUoaW50LCBJVG9tY2F0V2ViTW9kdWxlKQoJICovCglwdWJsaWMgdm9pZCBhZGRXZWJNb2R1bGUoaW50IGluZGV4LCBJVG9tY2F0V2ViTW9kdWxlIG1vZHVsZSkgewoJCXRyeSB7CgkJCWludCBzaXplID0gc2VydmVyLmdldFNlcnZpY2VDb3VudCgpOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJU2VydmljZSBzZXJ2aWNlID0gc2VydmVyLmdldFNlcnZpY2UoaSk7CgkJCQlpZiAoc2VydmljZS5nZXROYW1lKCkuZXF1YWxzSWdub3JlQ2FzZShERUZBVUxUX1NFUlZJQ0UpKSB7CgkJCQkJRW5naW5lIGVuZ2luZSA9IHNlcnZpY2UuZ2V0RW5naW5lKCk7CgkJCQkJSG9zdCBob3N0ID0gZW5naW5lLmdldEhvc3QoKTsKCQkJCQlDb250ZXh0IGNvbnRleHQgPSAoQ29udGV4dCkgaG9zdC5jcmVhdGVFbGVtZW50KGluZGV4LCAiQ29udGV4dCIpOwoJCQkJCWNvbnRleHQuc2V0RG9jQmFzZShtb2R1bGUuZ2V0RG9jdW1lbnRCYXNlKCkpOwoJCQkJCWNvbnRleHQuc2V0UGF0aChtb2R1bGUuZ2V0UGF0aCgpKTsKCQkJCQljb250ZXh0LnNldFJlbG9hZGFibGUobW9kdWxlLmlzUmVsb2FkYWJsZSgpID8gInRydWUiIDogImZhbHNlIik7CgkJCQkJaWYgKG1vZHVsZS5nZXRNZW1lbnRvKCkgIT0gbnVsbCAmJiBtb2R1bGUuZ2V0TWVtZW50bygpLmxlbmd0aCgpID4gMCkKCQkJCQkJY29udGV4dC5zZXRTb3VyY2UobW9kdWxlLmdldE1lbWVudG8oKSk7CgkJCQkJaXNTZXJ2ZXJEaXJ0eSA9IHRydWU7CgkJCQkJZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQoQUREX1dFQl9NT0RVTEVfUFJPUEVSVFksIG51bGwsIG1vZHVsZSk7CgkJCQkJcmV0dXJuOwoJCQkJfQoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgYWRkaW5nIHdlYiBtb2R1bGUgIiArIG1vZHVsZS5nZXRQYXRoKCksIGUpOwoJCX0KCX0KCgkvKioKCSAqIENoYW5nZSB0aGUgZXh0ZW5zaW9uIG9mIGEgbWltZSBtYXBwaW5nLgoJICogCgkgKiBAcGFyYW0gaW5kZXgKCSAqIEBwYXJhbSBtYXAKCSAqLwoJcHVibGljIHZvaWQgbW9kaWZ5TWltZU1hcHBpbmcoaW50IGluZGV4LCBJTWltZU1hcHBpbmcgbWFwKSB7CgkJd2ViQXBwRG9jdW1lbnQubW9kaWZ5TWltZU1hcHBpbmcoaW5kZXgsIG1hcCk7CgkJZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQoTU9ESUZZX01BUFBJTkdfUFJPUEVSVFksIG5ldyBJbnRlZ2VyKGluZGV4KSwgbWFwKTsKCX0KCQoJLyoqCgkgKiBNb2RpZnkgdGhlIHBvcnQgd2l0aCB0aGUgZ2l2ZW4gaWQuCgkgKgoJICogQHBhcmFtIGlkIGphdmEubGFuZy5TdHJpbmcKCSAqIEBwYXJhbSBwb3J0IGludAoJICovCglwdWJsaWMgdm9pZCBtb2RpZnlTZXJ2ZXJQb3J0KFN0cmluZyBpZCwgaW50IHBvcnQpIHsKCQl0cnkgewoJCQlpZiAoInNlcnZlciIuZXF1YWxzKGlkKSkgewoJCQkJc2VydmVyLnNldFBvcnQocG9ydCArICIiKTsKCQkJCWlzU2VydmVyRGlydHkgPSB0cnVlOwoJCQkJZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQoTU9ESUZZX1BPUlRfUFJPUEVSVFksIGlkLCBuZXcgSW50ZWdlcihwb3J0KSk7CgkJCQlyZXR1cm47CgkJCX0KCQoJCQlpbnQgaSA9IGlkLmluZGV4T2YoIi8iKTsKCQkJaW50IHNlcnZOdW0gPSBJbnRlZ2VyLnBhcnNlSW50KGlkLnN1YnN0cmluZygwLCBpKSk7CgkJCWludCBjb25uTnVtID0gSW50ZWdlci5wYXJzZUludChpZC5zdWJzdHJpbmcoaSArIDEpKTsKCQkJCgkJCVNlcnZpY2Ugc2VydmljZSA9IHNlcnZlci5nZXRTZXJ2aWNlKHNlcnZOdW0pOwoJCQlDb25uZWN0b3IgY29ubmVjdG9yID0gc2VydmljZS5nZXRDb25uZWN0b3IoY29ubk51bSk7CgkJCWNvbm5lY3Rvci5zZXRQb3J0KHBvcnQgKyAiIik7CgkJCWlzU2VydmVyRGlydHkgPSB0cnVlOwoJCQlmaXJlUHJvcGVydHlDaGFuZ2VFdmVudChNT0RJRllfUE9SVF9QUk9QRVJUWSwgaWQsIG5ldyBJbnRlZ2VyKHBvcnQpKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBtb2RpZnlpbmcgc2VydmVyIHBvcnQgIiArIGlkLCBlKTsKCQl9Cgl9CgkvKioKCSAqIENoYW5nZSBhIHdlYiBtb2R1bGUuCgkgKiBAcGFyYW0gaW5kZXggaW50CgkgKiBAcGFyYW0gZG9jQmFzZSBqYXZhLmxhbmcuU3RyaW5nCgkgKiBAcGFyYW0gcGF0aCBqYXZhLmxhbmcuU3RyaW5nCgkgKiBAcGFyYW0gcmVsb2FkYWJsZSBib29sZWFuCgkgKi8KCXB1YmxpYyB2b2lkIG1vZGlmeVdlYk1vZHVsZShpbnQgaW5kZXgsIFN0cmluZyBkb2NCYXNlLCBTdHJpbmcgcGF0aCwgYm9vbGVhbiByZWxvYWRhYmxlKSB7CgkJdHJ5IHsKCQkJaW50IHNpemUgPSBzZXJ2ZXIuZ2V0U2VydmljZUNvdW50KCk7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlTZXJ2aWNlIHNlcnZpY2UgPSBzZXJ2ZXIuZ2V0U2VydmljZShpKTsKCQkJCWlmIChzZXJ2aWNlLmdldE5hbWUoKS5lcXVhbHNJZ25vcmVDYXNlKERFRkFVTFRfU0VSVklDRSkpIHsKCQkJCQlFbmdpbmUgZW5naW5lID0gc2VydmljZS5nZXRFbmdpbmUoKTsKCQkJCQlIb3N0IGhvc3QgPSBlbmdpbmUuZ2V0SG9zdCgpOwoJCQkJCUNvbnRleHQgY29udGV4dCA9IGhvc3QuZ2V0Q29udGV4dChpbmRleCk7CgkJCQkJY29udGV4dC5zZXRQYXRoKHBhdGgpOwoJCQkJCWNvbnRleHQuc2V0RG9jQmFzZShkb2NCYXNlKTsKCQkJCQljb250ZXh0LnNldFJlbG9hZGFibGUocmVsb2FkYWJsZSA/ICJ0cnVlIiA6ICJmYWxzZSIpOwoJCQkJCWlzU2VydmVyRGlydHkgPSB0cnVlOwoJCQkJCVdlYk1vZHVsZSBtb2R1bGUgPSBuZXcgV2ViTW9kdWxlKHBhdGgsIGRvY0Jhc2UsIG51bGwsIHJlbG9hZGFibGUpOwoJCQkJCWZpcmVQcm9wZXJ0eUNoYW5nZUV2ZW50KE1PRElGWV9XRUJfTU9EVUxFX1BST1BFUlRZLCBuZXcgSW50ZWdlcihpbmRleCksIG1vZHVsZSk7CgkJCQkJcmV0dXJuOwoJCQkJfQoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgbW9kaWZ5aW5nIHdlYiBtb2R1bGUgIiArIGluZGV4LCBlKTsKCQl9Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIGEgbWltZSBtYXBwaW5nLgoJICogQHBhcmFtIGluZGV4IGludAoJICovCglwdWJsaWMgdm9pZCByZW1vdmVNaW1lTWFwcGluZyhpbnQgaW5kZXgpIHsKCQl3ZWJBcHBEb2N1bWVudC5yZW1vdmVNaW1lTWFwcGluZyhpbmRleCk7CgkJZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQoUkVNT1ZFX01BUFBJTkdfUFJPUEVSVFksIG51bGwsIG5ldyBJbnRlZ2VyKGluZGV4KSk7Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIGEgd2ViIG1vZHVsZS4KCSAqIEBwYXJhbSBpbmRleCBpbnQKCSAqLwoJcHVibGljIHZvaWQgcmVtb3ZlV2ViTW9kdWxlKGludCBpbmRleCkgewoJCXRyeSB7CgkJCWludCBzaXplID0gc2VydmVyLmdldFNlcnZpY2VDb3VudCgpOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJU2VydmljZSBzZXJ2aWNlID0gc2VydmVyLmdldFNlcnZpY2UoaSk7CgkJCQlpZiAoc2VydmljZS5nZXROYW1lKCkuZXF1YWxzSWdub3JlQ2FzZShERUZBVUxUX1NFUlZJQ0UpKSB7CgkJCQkJRW5naW5lIGVuZ2luZSA9IHNlcnZpY2UuZ2V0RW5naW5lKCk7CgkJCQkJSG9zdCBob3N0ID0gZW5naW5lLmdldEhvc3QoKTsKCQkJCQlob3N0LnJlbW92ZUVsZW1lbnQoIkNvbnRleHQiLCBpbmRleCk7CgkJCQkJaXNTZXJ2ZXJEaXJ0eSA9IHRydWU7CgkJCQkJZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQoUkVNT1ZFX1dFQl9NT0RVTEVfUFJPUEVSVFksIG51bGwsIG5ldyBJbnRlZ2VyKGluZGV4KSk7CgkJCQkJcmV0dXJuOwoJCQkJfQoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgcmVtb3ZpbmcgbW9kdWxlIHJlZiAiICsgaW5kZXgsIGUpOwoJCX0KCX0KCglwcm90ZWN0ZWQgSVN0YXR1cyBiYWNrdXBBbmRQdWJsaXNoKElQYXRoIGNvbmZEaXIsIGJvb2xlYW4gZG9CYWNrdXAsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCU11bHRpU3RhdHVzIG1zID0gbmV3IE11bHRpU3RhdHVzKFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIE1lc3NhZ2VzLnB1Ymxpc2hDb25maWd1cmF0aW9uVGFzaywgbnVsbCk7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVIsICJCYWNrdXAgYW5kIHB1Ymxpc2giKTsKCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgoJCWJhY2t1cEFuZFB1Ymxpc2goY29uZkRpciwgZG9CYWNrdXAsIG1zLCBtb25pdG9yLCAzMDApOwoJCS8vIFRPRE8gUmVmYWN0b3Igc3VjY2VzcyBkZXRlY3Rpb24gb25jZSBCdWcgODEwNjAgaXMgYWRkcmVzc2VkCgkJLy8gVGhpcyBhcHByb2FjaCBhdm9pZHMgcmVmYWN0b3JpbmcgdG8gVG9tY2F0Q29uZmlndXJhdGlvbi5iYWNrdXBGb2xkZXIoKQoJCS8vIGFuZCBiYWNrdXBQYXRoKCkgZm9yIG5vdy4KLyoJCWlmIChtcy5pc09LKCkgJiYgbXMuZ2V0Q2hpbGRyZW4oKS5sZW5ndGggPiAwKQoJCQlwdWJsaXNoQ29udGV4dENvbmZpZyhjb25mRGlyLCBtcywgbW9uaXRvcik7Ki8KCgkJbW9uaXRvci5kb25lKCk7CgkJcmV0dXJuIG1zOwoJfQoJCglwcm90ZWN0ZWQgSVN0YXR1cyBwdWJsaXNoQ29udGV4dENvbmZpZyhJUGF0aCBiYXNlRGlyLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgkJbW9uaXRvci5iZWdpblRhc2soTWVzc2FnZXMucHVibGlzaENvbmZpZ3VyYXRpb25UYXNrLCAzMDApOwoKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FUiwgIkFwcGx5IGNvbnRleHQgY29uZmlndXJhdGlvbnMiKTsKCQlJUGF0aCBjb25mRGlyID0gYmFzZURpci5hcHBlbmQoImNvbmYiKTsKCQlJUGF0aCB3ZWJhcHBzRGlyID0gYmFzZURpci5hcHBlbmQoIndlYmFwcHMiKTsKCQl0cnkgewoJCQltb25pdG9yLnN1YlRhc2soTWVzc2FnZXMucHVibGlzaENvbnRleHRDb25maWdUYXNrKTsKCQkJRmFjdG9yeSBmYWN0b3J5ID0gbmV3IEZhY3RvcnkoKTsKCQkJZmFjdG9yeS5zZXRQYWNrYWdlTmFtZSgib3JnLmVjbGlwc2UuanN0LnNlcnZlci50b21jYXQuY29yZS5pbnRlcm5hbC54bWwuc2VydmVyNDAiKTsKCQkJU2VydmVyIHB1Ymxpc2hlZFNlcnZlciA9IChTZXJ2ZXIpIGZhY3RvcnkubG9hZERvY3VtZW50KG5ldyBGaWxlSW5wdXRTdHJlYW0oY29uZkRpci5hcHBlbmQoInNlcnZlci54bWwiKS50b0ZpbGUoKSkpOwoJCQltb25pdG9yLndvcmtlZCgxMDApOwoJCQkKCQkJYm9vbGVhbiBtb2RpZmllZCA9IGZhbHNlOwoKCQkJaW50IHNpemUgPSBwdWJsaXNoZWRTZXJ2ZXIuZ2V0U2VydmljZUNvdW50KCk7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlTZXJ2aWNlIHNlcnZpY2UgPSBwdWJsaXNoZWRTZXJ2ZXIuZ2V0U2VydmljZShpKTsKCQkJCWlmIChzZXJ2aWNlLmdldE5hbWUoKS5lcXVhbHNJZ25vcmVDYXNlKERFRkFVTFRfU0VSVklDRSkpIHsKCQkJCQlFbmdpbmUgZW5naW5lID0gc2VydmljZS5nZXRFbmdpbmUoKTsKCQkJCQlIb3N0IGhvc3QgPSBlbmdpbmUuZ2V0SG9zdCgpOwoJCQkJCWludCBzaXplMiA9IGhvc3QuZ2V0Q29udGV4dENvdW50KCk7CgkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMjsgaisrKSB7CgkJCQkJCUNvbnRleHQgY29udGV4dCA9IGhvc3QuZ2V0Q29udGV4dChqKTsKCQkJCQkJbW9uaXRvci5zdWJUYXNrKE5MUy5iaW5kKE1lc3NhZ2VzLmNoZWNraW5nQ29udGV4dFRhc2ssCgkJCQkJCQkJbmV3IFN0cmluZ1tdIHtjb250ZXh0LmdldFBhdGgoKX0pKTsKCQkJCQkJaWYgKGFkZENvbnRleHRDb25maWcod2ViYXBwc0RpciwgY29udGV4dCkpIHsKCQkJCQkJCW1vZGlmaWVkID0gdHJ1ZTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCQltb25pdG9yLndvcmtlZCgxMDApOwoJCQlpZiAobW9kaWZpZWQpIHsKCQkJCW1vbml0b3Iuc3ViVGFzayhNZXNzYWdlcy5zYXZpbmdDb250ZXh0Q29uZmlnVGFzayk7CgkJCQlmYWN0b3J5LnNhdmUoY29uZkRpci5hcHBlbmQoInNlcnZlci54bWwiKS50b09TU3RyaW5nKCkpOwoJCQl9CgkJCW1vbml0b3IuZG9uZSgpOwoJCQkKCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVIsICJTZXJ2ZXIueG1sIHVwZGF0ZWQgd2l0aCBjb250ZXh0LnhtbCBjb25maWd1cmF0aW9ucyIpOwoJCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLk9LLCBUb21jYXRQbHVnaW4uUExVR0lOX0lELCAwLCBNZXNzYWdlcy5zZXJ2ZXJQb3N0UHJvY2Vzc2luZ0NvbXBsZXRlLCBudWxsKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5XQVJOSU5HLCAiQ291bGQgbm90IGFwcGx5IGNvbnRleHQgY29uZmlndXJhdGlvbnMgcHVibGlzaGVkIFRvbWNhdCB2NS4wIGNvbmZpZ3VyYXRpb24gZnJvbSAiICsgY29uZkRpci50b09TU3RyaW5nKCkgKyAiOiAiICsgZS5nZXRNZXNzYWdlKCkpOwoJCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBUb21jYXRQbHVnaW4uUExVR0lOX0lELCAwLCBOTFMuYmluZChNZXNzYWdlcy5lcnJvclB1Ymxpc2hDb25maWd1cmF0aW9uLCBuZXcgU3RyaW5nW10ge2UuZ2V0TG9jYWxpemVkTWVzc2FnZSgpfSksIGUpOwoJCX0KCX0KCQoJLyoqCgkgKiBJZiB0aGUgc3BlY2lmaWVkIENvbnRleHQgaXMgbGlua2VkIHRvIGEgcHJvamVjdCwgdHJ5IHRvCgkgKiB1cGRhdGUgYW55IGNvbmZpZ3VyYXRpb24gZm91bmQgYSBNRVRBLUlORi9jb250ZXh0LnhtbCBmb3VuZAoJICogcmVsYXRpdmUgdG8gdGhlIHNwZWNpZmllZCB3ZWIgYXBwbGljYXRpb25zIGRpcmVjdG9yeSBhbmQgY29udGV4dCBkb2NCYXNlLgoJICogQHBhcmFtIHdlYmFwcHNEaXIgUGF0aCB0byBzZXJ2ZXIncyB3ZWIgYXBwbGljYXRpb25zIGRpcmVjdG9yeS4KCSAqIEBwYXJhbSBjb250ZXh0IENvbnRleHQgb2JqZWN0IHRvIHJlY2VpdmUgY29udGV4dC54bWwgY29udGVudHMuCgkgKiBAcmV0dXJuIFJldHVybnMgdHJ1ZSBpZiBjb250ZXh0IGlzIG1vZGlmaWVkLgoJICovCglwcm90ZWN0ZWQgYm9vbGVhbiBhZGRDb250ZXh0Q29uZmlnKElQYXRoIHdlYmFwcHNEaXIsIENvbnRleHQgY29udGV4dCkgewoJCWJvb2xlYW4gbW9kaWZpZWQgPSBmYWxzZTsKCQlTdHJpbmcgc291cmNlID0gY29udGV4dC5nZXRTb3VyY2UoKTsKCQlpZiAoc291cmNlICE9IG51bGwgJiYgc291cmNlLmxlbmd0aCgpID4gMCApCgkJewoJCQlTdHJpbmcgZG9jQmFzZSA9IGNvbnRleHQuZ2V0RG9jQmFzZSgpOwoJCQlDb250ZXh0IGNvbnRleHRDb25maWcgPSBsb2FkQ29udGV4dENvbmZpZyh3ZWJhcHBzRGlyLmFwcGVuZChkb2NCYXNlKSk7CgkJCWlmIChudWxsICE9IGNvbnRleHRDb25maWcpIHsKCQkJCWlmIChjb250ZXh0Lmhhc0NoaWxkTm9kZXMoKSkKCQkJCQljb250ZXh0LnJlbW92ZUNoaWxkcmVuKCk7CgkJCQljb250ZXh0Q29uZmlnLmNvcHlDaGlsZHJlblRvKGNvbnRleHQpOwoJCQkJbW9kaWZpZWQgPSB0cnVlOwoJCQl9CgkJfQoJCXJldHVybiBtb2RpZmllZDsKCX0KCQoJLyoqCgkgKiBUcmllcyB0byByZWFkIGEgTUVUQS1JTkYvY29udGV4dC54bWwgZmlsZSByZWxhdGl2ZSB0byB0aGUKCSAqIHNwZWNpZmllZCB3ZWIgYXBwbGljYXRpb24gcGF0aC4gIElmIGZvdW5kLCBpdCBjcmVhdGVzIGEgQ29udGV4dCBvYmplY3QKCSAqIGNvbnRhaW5pbmcgdGhlIGNvbnRleHRzIG9mIHRoYXQgZmlsZS4KCSAqIEBwYXJhbSB3ZWJhcHBEaXIgUGF0aCB0byB0aGUgd2ViIGFwcGxpY2F0aW9uCgkgKiBAcmV0dXJuIENvbnRleHQgZWxlbWVudCBjcmVhdGVkIGZyb20gY29udGV4dC54bWwsIG9yIG51bGwgaWYgbm90IGZvdW5kLgoJICovCglwcm90ZWN0ZWQgQ29udGV4dCBsb2FkQ29udGV4dENvbmZpZyhJUGF0aCB3ZWJhcHBEaXIpIHsKCQlGaWxlIGNvbnRleHRYTUwgPSBuZXcgRmlsZSh3ZWJhcHBEaXIudG9PU1N0cmluZygpKyBGaWxlLnNlcGFyYXRvciArICJNRVRBLUlORiIgKyBGaWxlLnNlcGFyYXRvciArICJjb250ZXh0LnhtbCIpOwoJCWlmIChjb250ZXh0WE1MLmV4aXN0cygpKSB7CgkJCXRyeSB7CgkJCQlJbnB1dFN0cmVhbSBpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oY29udGV4dFhNTCk7CgkJCQlGYWN0b3J5IGN0eEZhY3RvcnkgPSBuZXcgRmFjdG9yeSgpOwoJCQkJY3R4RmFjdG9yeS5zZXRQYWNrYWdlTmFtZSgib3JnLmVjbGlwc2UuanN0LnNlcnZlci50b21jYXQuY29yZS5pbnRlcm5hbC54bWwuc2VydmVyNDAiKTsKCQkJCUNvbnRleHQgY3R4ID0gKENvbnRleHQpY3R4RmFjdG9yeS5sb2FkRG9jdW1lbnQoaXMpOwoJCQkJaXMuY2xvc2UoKTsKCQkJCXJldHVybiBjdHg7CgkJCX0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CgkJCQkvLyBJZ25vcmUsIHNob3VsZCBuZXZlciBvY2N1cgoJCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciByZWFkaW5nIHdlYiBtb2R1bGUncyBjb250ZXh0LnhtbCBmaWxlOiAiICsgY29udGV4dFhNTC5nZXRQYXRoKCksIGUpOwoJCQl9CgkJfQoJCXJldHVybiBudWxsOwogCX0KCQoJcHJvdGVjdGVkIElTdGF0dXMgcHJlcGFyZVJ1bnRpbWVEaXJlY3RvcnkoSVBhdGggY29uZkRpcikgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVSLCAiUHJlcGFyaW5nIHJ1bnRpbWUgZGlyZWN0b3J5Iik7CgkJLy8gUHJlcGFyZSBhIGNhdGFsaW5hLmJhc2UgZGlyZWN0b3J5IHN0cnVjdHVyZQoJCUZpbGUgdGVtcCA9IGNvbmZEaXIuYXBwZW5kKCJjb25mIikudG9GaWxlKCk7CgkJaWYgKCF0ZW1wLmV4aXN0cygpKQoJCQl0ZW1wLm1rZGlycygpOwoJCXRlbXAgPSBjb25mRGlyLmFwcGVuZCgibG9ncyIpLnRvRmlsZSgpOwoJCWlmICghdGVtcC5leGlzdHMoKSkKCQkJdGVtcC5ta2RpcnMoKTsKCQl0ZW1wID0gY29uZkRpci5hcHBlbmQoInRlbXAiKS50b0ZpbGUoKTsKCQlpZiAoIXRlbXAuZXhpc3RzKCkpCgkJCXRlbXAubWtkaXJzKCk7CgkJdGVtcCA9IGNvbmZEaXIuYXBwZW5kKCJ3ZWJhcHBzL1JPT1QvV0VCLUlORiIpLnRvRmlsZSgpOwoJCWlmICghdGVtcC5leGlzdHMoKSkKCQkJdGVtcC5ta2RpcnMoKTsKCQl0ZW1wID0gY29uZkRpci5hcHBlbmQoIndvcmsiKS50b0ZpbGUoKTsKCQlpZiAoIXRlbXAuZXhpc3RzKCkpCgkJCXRlbXAubWtkaXJzKCk7CgoJCXJldHVybiBuZXcgU3RhdHVzKElTdGF0dXMuT0ssIFRvbWNhdFBsdWdpbi5QTFVHSU5fSUQsIDAsIE1lc3NhZ2VzLnJ1bnRpbWVEaXJQcmVwYXJlZCwgbnVsbCk7CQkKCX0KfQ==