cGFja2FnZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsOwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMgSUJNIENvcnBvcmF0aW9uIGFuZCBvdGhlcnMuCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIKAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwogKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAqgKgogKiBDb250cmlidXRvcnM6CiAqICAgIElCTSAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLklMYXVuY2hNYW5hZ2VyOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuYWN0aW9uLkFjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmFjdGlvbi5JQWN0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuYWN0aW9uLklNZW51TWFuYWdlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmFjdGlvbi5NZW51TWFuYWdlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVNlbGVjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVNlbGVjdGlvblByb3ZpZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5JU3RydWN0dXJlZFNlbGVjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuU3RydWN0dXJlZFNlbGVjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JRWxlbWVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5hY3Rpb25zLk5ld1NlcnZlckFjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwudmlldy5zZXJ2ZXJzLkRlbGV0ZUFjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwudmlldy5zZXJ2ZXJzLk9wZW5BY3Rpb247CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLnZpZXcuc2VydmVycy5QdWJsaXNoQWN0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC52aWV3LnNlcnZlcnMuUmVzdGFydEFjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwudmlldy5zZXJ2ZXJzLlN0YXJ0QWN0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC52aWV3LnRyZWUuU2VydmVyRWxlbWVudEFkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLnZpZXcudHJlZS5TZXJ2ZXJUcmVlQWN0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuU2hlbGw7CgovKioKICogCiAqLwpwdWJsaWMgY2xhc3MgU2VydmVyVHJlZSB7CgkvKioKCSAqIENvbnN0YW50cyBmb3IgYWN0aW9ucwoJICovCglwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQUNUSU9OX09QRU4gPSAwOwoJcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIEFDVElPTl9ERUxFVEUgPSAxOwoJcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIEFDVElPTl9CT09LTUFSSyA9IDI7CgoJcHJpdmF0ZSBTZXJ2ZXJUcmVlKCkgeyB9CgkKCXB1YmxpYyBzdGF0aWMgdm9pZCBmaWxsQ29udGV4dE1lbnUoU2hlbGwgc2hlbGwsIElTZWxlY3Rpb24gc2VsZWN0aW9uLCBJTWVudU1hbmFnZXIgbWVudSkgewoJCU1lbnVNYW5hZ2VyIG5ld01lbnUgPSBuZXcgTWVudU1hbmFnZXIoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhY3Rpb25OZXciKSk7CgkJZmlsbE5ld0NvbnRleHRNZW51KHNoZWxsLCBzZWxlY3Rpb24sIG5ld01lbnUpOwoJCW1lbnUuYWRkKG5ld01lbnUpOwoJCWZpbGxPdGhlckNvbnRleHRNZW51KHNoZWxsLCBzZWxlY3Rpb24sIG1lbnUpOwoJfQoJCglwdWJsaWMgc3RhdGljIHZvaWQgZmlsbE5ld0NvbnRleHRNZW51KFNoZWxsIHNoZWxsLCBJU2VsZWN0aW9uIHNlbGVjdGlvbiwgSU1lbnVNYW5hZ2VyIG1lbnUpIHsKCQlJQWN0aW9uIG5ld1NlcnZlckFjdGlvbiA9IG5ldyBOZXdTZXJ2ZXJBY3Rpb24oKTsKCQluZXdTZXJ2ZXJBY3Rpb24uc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvbk5ld1NlcnZlciIpKTsKCQltZW51LmFkZChuZXdTZXJ2ZXJBY3Rpb24pOwoJfQoKCXB1YmxpYyBzdGF0aWMgdm9pZCBmaWxsT3RoZXJDb250ZXh0TWVudShTaGVsbCBzaGVsbCwgSVNlbGVjdGlvbiBzZWxlY3Rpb24sIElNZW51TWFuYWdlciBtZW51KSB7CgkJaWYgKHNlbGVjdGlvbiA9PSBudWxsKQoJCQlyZXR1cm47CgoJCWlmIChzZWxlY3Rpb24uaXNFbXB0eSgpIHx8ICEoc2VsZWN0aW9uIGluc3RhbmNlb2YgSVN0cnVjdHVyZWRTZWxlY3Rpb24pKQoJCQlyZXR1cm47CgoJCS8vSVN0cnVjdHVyZWRTZWxlY3Rpb24gc2VsID0gKElTdHJ1Y3R1cmVkU2VsZWN0aW9uKSBzZWxlY3Rpb247CgkJCgkJLy9ib29sZWFuIHNpbmdsZVNlbGVjdCA9IChzZWwuc2l6ZSgpID09IDEpOwoJCS8vT2JqZWN0IGZpcnN0ID0gc2VsLmdldEZpcnN0RWxlbWVudCgpOwoKCQkvLyBvcGVuIG1lbnUKCQkvKmlmIChzaW5nbGVTZWxlY3QgJiYgZmlyc3QgaW5zdGFuY2VvZiBTZXJ2ZXJSZXNvdXJjZUFkYXB0ZXIpIHsKCQkJU2VydmVyUmVzb3VyY2VBZGFwdGVyIGFkYXB0ZXIgPSAoU2VydmVyUmVzb3VyY2VBZGFwdGVyKSBmaXJzdDsKCQkJSVNlcnZlclJlc291cmNlIHJlc291cmNlID0gYWRhcHRlci5nZXRTZXJ2ZXJSZXNvdXJjZSgpOwoJCQltZW51LmFkZChuZXcgT3BlbkFjdGlvbihyZXNvdXJjZSkpOwoJCQltZW51LmFkZChuZXcgU2VwYXJhdG9yKCkpOwoJCX0KCQkKCQkvLyBkZWxldGUgbWVudQoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQlib29sZWFuIGNhbkRlbGV0ZSA9IHRydWU7CgkJSXRlcmF0b3IgaXRlcmF0b3IyID0gc2VsLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yMi5oYXNOZXh0KCkpIHsKCQkJT2JqZWN0IG9iaiA9IGl0ZXJhdG9yMi5uZXh0KCk7CgkJCQoJCQlpZiAob2JqIGluc3RhbmNlb2YgU2VydmVyUmVzb3VyY2VBZGFwdGVyKQoJCQkJbGlzdC5hZGQoKChTZXJ2ZXJSZXNvdXJjZUFkYXB0ZXIpIG9iaikuZ2V0U2VydmVyUmVzb3VyY2UoKSk7CgkJCWVsc2UKCQkJCWNhbkRlbGV0ZSA9IGZhbHNlOwoJCX0KCQlpZiAoY2FuRGVsZXRlKSB7CgkJCUlTZXJ2ZXJSZXNvdXJjZVtdIHJlcyA9IG5ldyBJU2VydmVyUmVzb3VyY2VbbGlzdC5zaXplKCldOwoJCQlsaXN0LnRvQXJyYXkocmVzKTsKCQkJbWVudS5hZGQobmV3IERlbGV0ZUFjdGlvbihzaGVsbCwgcmVzKSk7CgkJfQoKCQlpZiAoc2luZ2xlU2VsZWN0ICYmIGZpcnN0IGluc3RhbmNlb2YgSVNlcnZlckVsZW1lbnRUYWcpCgkJCW1lbnUuYWRkKG5ldyBTZXBhcmF0b3IoKSk7CgoJCWlmIChzaW5nbGVTZWxlY3QgJiYgZmlyc3QgaW5zdGFuY2VvZiBTZXJ2ZXJSZXNvdXJjZUFkYXB0ZXIpIHsKCQkJU2VydmVyUmVzb3VyY2VBZGFwdGVyIGFkYXB0ZXIgPSAoU2VydmVyUmVzb3VyY2VBZGFwdGVyKSBmaXJzdDsKCQkJSVNlcnZlclJlc291cmNlIHJlc291cmNlID0gYWRhcHRlci5nZXRTZXJ2ZXJSZXNvdXJjZSgpOwoKCQkJSVNlcnZlciBzZXJ2ZXIgPSBudWxsOwoJCQlpZiAocmVzb3VyY2UgaW5zdGFuY2VvZiBJU2VydmVyKQoJCQkJc2VydmVyID0gKElTZXJ2ZXIpIHJlc291cmNlOwoKCQkJLy8gc3dpdGNoIGNvbmZpZ3VyYXRpb24gbWVudQoJCQlpZiAoc2VydmVyICE9IG51bGwpIHsKCQkJCWFkZFNlcnZlckFjdGlvbnMoc2hlbGwsIG1lbnUsIHNlcnZlcik7CgoJCQkJTWVudU1hbmFnZXIgbWVudU1hbmFnZXIgPSBuZXcgTWVudU1hbmFnZXIoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhY3Rpb25Td2l0Y2hDb25maWd1cmF0aW9uIikpOwoJCQkJbWVudU1hbmFnZXIuYWRkKG5ldyBTd2l0Y2hDb25maWd1cmF0aW9uQWN0aW9uKHNoZWxsLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXZpZXdOb0NvbmZpZ3VyYXRpb24iKSwgc2VydmVyLCBudWxsKSk7CgoJCQkJTGlzdCBjb25maWdzID0gU2VydmVyVXRpbC5nZXRTdXBwb3J0ZWRTZXJ2ZXJDb25maWd1cmF0aW9ucyhzZXJ2ZXIpOwoJCQkJSXRlcmF0b3IgaXRlcmF0b3IgPSBjb25maWdzLml0ZXJhdG9yKCk7CgkJCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCQkJSVNlcnZlckNvbmZpZ3VyYXRpb24gY29uZmlnID0gKElTZXJ2ZXJDb25maWd1cmF0aW9uKSBpdGVyYXRvci5uZXh0KCk7CgkJCQkJbWVudU1hbmFnZXIuYWRkKG5ldyBTd2l0Y2hDb25maWd1cmF0aW9uQWN0aW9uKHNoZWxsLCBTZXJ2ZXJVdGlsLmdldE5hbWUoY29uZmlnKSwgc2VydmVyLCBjb25maWcpKTsKCQkJCX0KCgkJCQltZW51LmFkZChtZW51TWFuYWdlcik7CgkJCX0KCQkJCgkJCWlmIChzZXJ2ZXIgIT0gbnVsbCAmJiBzZXJ2ZXIgaW5zdGFuY2VvZiBJTW9kdWxlUmVzdGFydGFibGUpIHsKCQkJCW1lbnUuYWRkKG5ldyBTZXBhcmF0b3IoKSk7CgoJCQkJTWVudU1hbmFnZXIgcmVzdGFydFByb2plY3RNZW51ID0gbmV3IE1lbnVNYW5hZ2VyKFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlYWN0aW9uUmVzdGFydFByb2plY3QiKSk7CgoJCQkJSU1vZHVsZVJlc3RhcnRhYmxlIHJlc3RhcnRhYmxlID0gKElNb2R1bGVSZXN0YXJ0YWJsZSkgc2VydmVyOwoKCQkJCUlTZXJ2ZXJDb25maWd1cmF0aW9uIGNvbmZpZ3VyYXRpb24gPSBTZXJ2ZXJVdGlsLmdldFNlcnZlckNvbmZpZ3VyYXRpb24oc2VydmVyKTsKCQkJCWlmIChjb25maWd1cmF0aW9uICE9IG51bGwpIHsKCQkJCQlJdGVyYXRvciBpdGVyYXRvciA9IFNlcnZlclV0aWwuZ2V0QWxsQ29udGFpbmVkTW9kdWxlcyhjb25maWd1cmF0aW9uKS5pdGVyYXRvcigpOwoJCQkJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJCQkJSU1vZHVsZSBtb2R1bGUgPSAoSU1vZHVsZSkgaXRlcmF0b3IubmV4dCgpOwoJCQkJCQlBY3Rpb24gYWN0aW9uID0gbmV3IFJlc3RhcnRNb2R1bGVBY3Rpb24ocmVzdGFydGFibGUsIG1vZHVsZSk7CgkJCQkJCXJlc3RhcnRQcm9qZWN0TWVudS5hZGQoYWN0aW9uKTsKCQkJCQl9CgkJCQl9CgkJCQlpZiAocmVzdGFydFByb2plY3RNZW51LmlzRW1wdHkoKSkKCQkJCQltZW51LmFkZChuZXcgRGlzYWJsZWRNZW51TWFuYWdlcihTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvblJlc3RhcnRQcm9qZWN0IikpKTsKCQkJCWVsc2UKCQkJCQltZW51LmFkZChyZXN0YXJ0UHJvamVjdE1lbnUpOwoJCQl9CgkJfQoJCWlmIChzaW5nbGVTZWxlY3QgJiYgZmlyc3QgaW5zdGFuY2VvZiBNb2R1bGVSZXNvdXJjZUFkYXB0ZXIpIHsKCQkJTW9kdWxlUmVzb3VyY2VBZGFwdGVyIGFkYXB0ZXIgPSAoTW9kdWxlUmVzb3VyY2VBZGFwdGVyKSBmaXJzdDsKCQkJSVNlcnZlckNvbmZpZ3VyYXRpb24gY29uZmlndXJhdGlvbiA9IGFkYXB0ZXIuZ2V0U2VydmVyQ29uZmlndXJhdGlvbigpOwoJCQlJTW9kdWxlIG1vZHVsZSA9IGFkYXB0ZXIuZ2V0TW9kdWxlKCk7CgkJCQoJCQlJTW9kdWxlW10gbW9kdWxlcyA9IGNvbmZpZ3VyYXRpb24uZ2V0TW9kdWxlcygpOwoJCQlib29sZWFuIGZvdW5kID0gZmFsc2U7CgkJCWlmIChtb2R1bGVzICE9IG51bGwgJiYgbW9kdWxlICE9IG51bGwpIHsKCQkJCWludCBzaXplID0gbW9kdWxlcy5sZW5ndGg7CgkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJCWlmIChtb2R1bGUuZXF1YWxzKG1vZHVsZXNbaV0pICYmIGNvbmZpZ3VyYXRpb24uY2FuUmVtb3ZlTW9kdWxlKG1vZHVsZSkpCgkJCQkJCWZvdW5kID0gdHJ1ZTsKCQkJCX0KCQkJfQoJCgkJCWlmIChmb3VuZCkKCQkJCW1lbnUuYWRkKG5ldyBNb2RpZnlDb25maWd1cmF0aW9uTW9kdWxlc0FjdGlvbihzaGVsbCwgY29uZmlndXJhdGlvbiwgbW9kdWxlLCBmYWxzZSkpOwoJCX0KCQkKCQlpZiAoc2luZ2xlU2VsZWN0ICYmIGZpcnN0IGluc3RhbmNlb2YgU2VydmVyUmVzb3VyY2VBZGFwdGVyKSB7CgkJCVNlcnZlclJlc291cmNlQWRhcHRlciBhZGFwdGVyID0gKFNlcnZlclJlc291cmNlQWRhcHRlcikgZmlyc3Q7CgkJCUlTZXJ2ZXJSZXNvdXJjZSByZXNvdXJjZSA9IGFkYXB0ZXIuZ2V0U2VydmVyUmVzb3VyY2UoKTsKCgkJCUlTZXJ2ZXIgc2VydmVyID0gbnVsbDsKCQkJSVNlcnZlckNvbmZpZ3VyYXRpb24gY29uZmlndXJhdGlvbiA9IG51bGw7CgkJCWlmIChyZXNvdXJjZSBpbnN0YW5jZW9mIElTZXJ2ZXJDb25maWd1cmF0aW9uKQoJCQkJY29uZmlndXJhdGlvbiA9IChJU2VydmVyQ29uZmlndXJhdGlvbikgcmVzb3VyY2U7CgkJCWVsc2UgaWYgKHJlc291cmNlIGluc3RhbmNlb2YgSVNlcnZlcikgewoJCQkJc2VydmVyID0gKElTZXJ2ZXIpIHJlc291cmNlOwoJCQkJY29uZmlndXJhdGlvbiA9IFNlcnZlclV0aWwuZ2V0U2VydmVyQ29uZmlndXJhdGlvbihzZXJ2ZXIpOwoJCQl9CgkJCQoJCQlTZXJ2ZXJBY3Rpb24uYWRkU2VydmVyTWVudUl0ZW1zKHNoZWxsLCBtZW51LCBzZXJ2ZXIsIGNvbmZpZ3VyYXRpb24pOwoJCX0qLwoJfQoKCXByb3RlY3RlZCBzdGF0aWMgdm9pZCBhZGRTZXJ2ZXJBY3Rpb25zKFNoZWxsIHNoZWxsLCBJTWVudU1hbmFnZXIgbWVudSwgSVNlcnZlciBzZXJ2ZXIpIHsKCQlmaW5hbCBJU2VsZWN0aW9uIHNlbGVjdGlvbiA9IG5ldyBTdHJ1Y3R1cmVkU2VsZWN0aW9uKHNlcnZlcik7CgkJSVNlbGVjdGlvblByb3ZpZGVyIHByb3ZpZGVyID0gbmV3IElTZWxlY3Rpb25Qcm92aWRlcigpIHsKCQkJcHVibGljIHZvaWQgYWRkU2VsZWN0aW9uQ2hhbmdlZExpc3RlbmVyKElTZWxlY3Rpb25DaGFuZ2VkTGlzdGVuZXIgbGlzdGVuZXIpIHsgfQoJCQlwdWJsaWMgSVNlbGVjdGlvbiBnZXRTZWxlY3Rpb24oKSB7CgkJCQlyZXR1cm4gc2VsZWN0aW9uOwoJCQl9CgkJCXB1YmxpYyB2b2lkIHJlbW92ZVNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lcihJU2VsZWN0aW9uQ2hhbmdlZExpc3RlbmVyIGxpc3RlbmVyKSB7IH0KCQkJcHVibGljIHZvaWQgc2V0U2VsZWN0aW9uKElTZWxlY3Rpb24gc2VsKSB7IH0KCQl9OwoJCgkJLy8gY3JlYXRlIHRoZSBkZWJ1ZyBhY3Rpb24KCQlBY3Rpb24gZGVidWdBY3Rpb24gPSBuZXcgU3RhcnRBY3Rpb24oc2hlbGwsIHByb3ZpZGVyLCAiZGVidWciLCBJTGF1bmNoTWFuYWdlci5ERUJVR19NT0RFKTsKCQlkZWJ1Z0FjdGlvbi5zZXRUb29sVGlwVGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvbkRlYnVnVG9vbFRpcCIpKTsKCQlkZWJ1Z0FjdGlvbi5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlYWN0aW9uRGVidWciKSk7CgkJZGVidWdBY3Rpb24uc2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0VMQ0xfU1RBUlRfREVCVUcpKTsKCQlkZWJ1Z0FjdGlvbi5zZXRIb3ZlckltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19DTENMX1NUQVJUX0RFQlVHKSk7CgkJZGVidWdBY3Rpb24uc2V0RGlzYWJsZWRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfRExDTF9TVEFSVF9ERUJVRykpOwoJCW1lbnUuYWRkKGRlYnVnQWN0aW9uKTsKCQoJCS8vIGNyZWF0ZSB0aGUgc3RhcnQgYWN0aW9uCgkJQWN0aW9uIHJ1bkFjdGlvbiA9IG5ldyBTdGFydEFjdGlvbihzaGVsbCwgcHJvdmlkZXIsICJzdGFydCIsIElMYXVuY2hNYW5hZ2VyLlJVTl9NT0RFKTsKCQlydW5BY3Rpb24uc2V0VG9vbFRpcFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhY3Rpb25TdGFydFRvb2xUaXAiKSk7CgkJcnVuQWN0aW9uLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhY3Rpb25TdGFydCIpKTsKCQlydW5BY3Rpb24uc2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0VMQ0xfU1RBUlQpKTsKCQlydW5BY3Rpb24uc2V0SG92ZXJJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfQ0xDTF9TVEFSVCkpOwoJCXJ1bkFjdGlvbi5zZXREaXNhYmxlZEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19ETENMX1NUQVJUKSk7CgkJbWVudS5hZGQocnVuQWN0aW9uKTsKCQkKCQkvLyBjcmVhdGUgdGhlIHByb2ZpbGUgYWN0aW9uCgkJQWN0aW9uIHByb2ZpbGVBY3Rpb24gPSBuZXcgU3RhcnRBY3Rpb24oc2hlbGwsIHByb3ZpZGVyLCAicHJvZmlsZSIsIElMYXVuY2hNYW5hZ2VyLlBST0ZJTEVfTU9ERSk7CgkJcHJvZmlsZUFjdGlvbi5zZXRUb29sVGlwVGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvblByb2ZpbGVUb29sVGlwIikpOwoJCXByb2ZpbGVBY3Rpb24uc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvblByb2ZpbGUiKSk7CgkJcHJvZmlsZUFjdGlvbi5zZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfRUxDTF9TVEFSVF9QUk9GSUxFKSk7CgkJcHJvZmlsZUFjdGlvbi5zZXRIb3ZlckltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19DTENMX1NUQVJUX1BST0ZJTEUpKTsKCQlwcm9maWxlQWN0aW9uLnNldERpc2FibGVkSW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0RMQ0xfU1RBUlRfUFJPRklMRSkpOwoJCW1lbnUuYWRkKHByb2ZpbGVBY3Rpb24pOwoJCgkJLy8gY3JlYXRlIHRoZSByZXN0YXJ0IGFjdGlvbgoJCU1lbnVNYW5hZ2VyIG1lbnVNYW5hZ2VyID0gbmV3IE1lbnVNYW5hZ2VyKFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlYWN0aW9uUmVzdGFydCIpKTsKCQkKCQlBY3Rpb24gcmVzdGFydEFjdGlvbiA9IG5ldyBSZXN0YXJ0QWN0aW9uKHNoZWxsLCBwcm92aWRlciwgInJlc3RhcnQiLCBJTGF1bmNoTWFuYWdlci5SVU5fTU9ERSk7CgkJcmVzdGFydEFjdGlvbi5zZXRUb29sVGlwVGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvblJlc3RhcnRUb29sVGlwIikpOwoJCXJlc3RhcnRBY3Rpb24uc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvblJlc3RhcnQiKSk7CgkJcmVzdGFydEFjdGlvbi5zZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfRUxDTF9SRVNUQVJUKSk7CgkJcmVzdGFydEFjdGlvbi5zZXRIb3ZlckltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19DTENMX1JFU1RBUlQpKTsKCQlyZXN0YXJ0QWN0aW9uLnNldERpc2FibGVkSW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0RMQ0xfUkVTVEFSVCkpOwoJCW1lbnVNYW5hZ2VyLmFkZChyZXN0YXJ0QWN0aW9uKTsKCQkvL21lbnUuYWRkKHJlc3RhcnRBY3Rpb24pOwoJCW1lbnUuYWRkKG1lbnVNYW5hZ2VyKTsKCgkJLy8gY3JlYXRlIHRoZSBzdG9wIGFjdGlvbgoJCS8qQWN0aW9uIHN0b3BBY3Rpb24gPSBuZXcgU3RvcEFjdGlvbihzaGVsbCwgcHJvdmlkZXIsICJzdG9wIiwgSVNlcnZlckZhY3RvcnkuU0VSVkVSX1NUQVRFX1NFVF9NQU5BR0VEKTsKCQlzdG9wQWN0aW9uLnNldFRvb2xUaXBUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlYWN0aW9uU3RvcFRvb2xUaXAiKSk7CgkJc3RvcEFjdGlvbi5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlYWN0aW9uU3RvcCIpKTsKCQlzdG9wQWN0aW9uLnNldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19FTENMX1NUT1ApKTsKCQlzdG9wQWN0aW9uLnNldEhvdmVySW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0NMQ0xfU1RPUCkpOwoJCXN0b3BBY3Rpb24uc2V0RGlzYWJsZWRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfRExDTF9TVE9QKSk7CgkJbWVudS5hZGQoc3RvcEFjdGlvbik7CgoJCS8vIGNyZWF0ZSB0aGUgZGlzY29ubmVjdCBhY3Rpb24KCQlBY3Rpb24gZGlzY29ubmVjdEFjdGlvbiA9IG5ldyBTdG9wQWN0aW9uKHNoZWxsLCBwcm92aWRlciwgImRpc2Nvbm5lY3QiLCBJU2VydmVyRmFjdG9yeS5TRVJWRVJfU1RBVEVfU0VUX0FUVEFDSEVEKTsKCQlkaXNjb25uZWN0QWN0aW9uLnNldFRvb2xUaXBUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlYWN0aW9uU3RvcFRvb2xUaXAyIikpOwoJCWRpc2Nvbm5lY3RBY3Rpb24uc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvblN0b3AyIikpOwoJCWRpc2Nvbm5lY3RBY3Rpb24uc2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0VMQ0xfRElTQ09OTkVDVCkpOwoJCWRpc2Nvbm5lY3RBY3Rpb24uc2V0SG92ZXJJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfQ0xDTF9ESVNDT05ORUNUKSk7CgkJZGlzY29ubmVjdEFjdGlvbi5zZXREaXNhYmxlZEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19ETENMX0RJU0NPTk5FQ1QpKTsKCQltZW51LmFkZChkaXNjb25uZWN0QWN0aW9uKTsqLwoKCQkvLyBjcmVhdGUgdGhlIHB1Ymxpc2ggYWN0aW9uCgkJQWN0aW9uIHB1Ymxpc2hBY3Rpb24gPSBuZXcgUHVibGlzaEFjdGlvbihzaGVsbCwgcHJvdmlkZXIsICJwdWJsaXNoIik7CgkJcHVibGlzaEFjdGlvbi5zZXRUb29sVGlwVGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvblB1Ymxpc2hUb29sVGlwIikpOwoJCXB1Ymxpc2hBY3Rpb24uc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvblB1Ymxpc2giKSk7CgkJcHVibGlzaEFjdGlvbi5zZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfRUxDTF9QVUJMSVNIKSk7CgkJcHVibGlzaEFjdGlvbi5zZXRIb3ZlckltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19DTENMX1BVQkxJU0gpKTsKCQlwdWJsaXNoQWN0aW9uLnNldERpc2FibGVkSW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0RMQ0xfUFVCTElTSCkpOwoJCW1lbnUuYWRkKHB1Ymxpc2hBY3Rpb24pOwoJfQoKCXB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0FjdGlvbkVuYWJsZWQoSVNlbGVjdGlvbiBzZWxlY3Rpb24sIGJ5dGUgYWN0aW9uKSB7CgkJaWYgKHNlbGVjdGlvbiA9PSBudWxsIHx8IGFjdGlvbiA8IDApCgkJCXJldHVybiBmYWxzZTsKCgkJaWYgKHNlbGVjdGlvbi5pc0VtcHR5KCkgfHwgIShzZWxlY3Rpb24gaW5zdGFuY2VvZiBJU3RydWN0dXJlZFNlbGVjdGlvbikpCgkJCXJldHVybiBmYWxzZTsKCgkJSVN0cnVjdHVyZWRTZWxlY3Rpb24gc2VsID0gKElTdHJ1Y3R1cmVkU2VsZWN0aW9uKSBzZWxlY3Rpb247CgkJCgkJaWYgKGFjdGlvbiA9PSBBQ1RJT05fT1BFTikgewoJCQlpZiAoc2VsLnNpemUoKSAhPSAxKQoJCQkJcmV0dXJuIGZhbHNlOwoKCQkJT2JqZWN0IG9iaiA9IHNlbC5nZXRGaXJzdEVsZW1lbnQoKTsKCgkJCXJldHVybiAob2JqIGluc3RhbmNlb2YgU2VydmVyRWxlbWVudEFkYXB0ZXIpOwoJCX0gZWxzZSBpZiAoYWN0aW9uID09IEFDVElPTl9ERUxFVEUpIHsKCQkJaWYgKHNlbC5zaXplKCkgPT0gMCkKCQkJCXJldHVybiBmYWxzZTsKCQkJCgkJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gc2VsLml0ZXJhdG9yKCk7CgkJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJCU9iamVjdCBvYmogPSBpdGVyYXRvci5uZXh0KCk7CgkJCQkKCQkJCWlmICghKG9iaiBpbnN0YW5jZW9mIFNlcnZlckVsZW1lbnRBZGFwdGVyKSAmJiAhKG9iaiBpbnN0YW5jZW9mIElTZXJ2ZXIpKQoJCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCglwdWJsaWMgc3RhdGljIGJvb2xlYW4gcGVyZm9ybUFjdGlvbihTaGVsbCBzaGVsbCwgSVNlbGVjdGlvbiBzZWxlY3Rpb24sIGJ5dGUgYWN0aW9uKSB7CgkJLy9pZiAoIWlzQWN0aW9uRW5hYmxlZChzZWxlY3Rpb24sIGFjdGlvbikpCgkJLy8JcmV0dXJuIGZhbHNlOwoKCQlpZiAoc2VsZWN0aW9uID09IG51bGwgfHwgYWN0aW9uIDwgMCkKCQkJcmV0dXJuIGZhbHNlOwoKCQlpZiAoc2VsZWN0aW9uLmlzRW1wdHkoKSB8fCAhKHNlbGVjdGlvbiBpbnN0YW5jZW9mIElTdHJ1Y3R1cmVkU2VsZWN0aW9uKSkKCQkJcmV0dXJuIGZhbHNlOwoKCQlJU3RydWN0dXJlZFNlbGVjdGlvbiBzZWwgPSAoSVN0cnVjdHVyZWRTZWxlY3Rpb24pIHNlbGVjdGlvbjsKCgkJaWYgKGFjdGlvbiA9PSBBQ1RJT05fT1BFTikgewoJCQlpZiAoc2VsLnNpemUoKSAhPSAxKQoJCQkJcmV0dXJuIGZhbHNlOwoKCQkJT2JqZWN0IG9iaiA9IHNlbC5nZXRGaXJzdEVsZW1lbnQoKTsKCQkJaWYgKG9iaiBpbnN0YW5jZW9mIElTZXJ2ZXIpIHsKCQkJCUFjdGlvbiBvcGVuID0gbmV3IE9wZW5BY3Rpb24oKElTZXJ2ZXIpIG9iaik7CgkJCQlvcGVuLnJ1bigpOwoJCQkJcmV0dXJuIHRydWU7CgkJCX0gZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgU2VydmVyRWxlbWVudEFkYXB0ZXIpIHsKCQkJCVNlcnZlckVsZW1lbnRBZGFwdGVyIGFkYXB0ZXIgPSAoU2VydmVyRWxlbWVudEFkYXB0ZXIpIG9iajsKCQkJCUlFbGVtZW50IGVsZW1lbnQgPSBhZGFwdGVyLmdldFNlcnZlclJlc291cmNlKCk7CgkJCQlpZiAoZWxlbWVudCBpbnN0YW5jZW9mIElTZXJ2ZXIpIHsKCQkJCQlBY3Rpb24gb3BlbiA9IG5ldyBPcGVuQWN0aW9uKChJU2VydmVyKSBlbGVtZW50KTsKCQkJCQlvcGVuLnJ1bigpOwoJCQkJCXJldHVybiB0cnVlOwoJCQkJfQoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJCXJldHVybiBmYWxzZTsKCQl9IGVsc2UgaWYgKGFjdGlvbiA9PSBBQ1RJT05fREVMRVRFKSB7CgkJCWlmIChzZWwuc2l6ZSgpID09IDApCgkJCQlyZXR1cm4gZmFsc2U7CgkJCQoJCQlMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gc2VsLml0ZXJhdG9yKCk7CgkJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJCU9iamVjdCBvYmogPSBpdGVyYXRvci5uZXh0KCk7CgkJCQkKCQkJCWlmIChvYmogaW5zdGFuY2VvZiBJRWxlbWVudCkKCQkJCQlsaXN0LmFkZChvYmopOwoJCQkJZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgU2VydmVyRWxlbWVudEFkYXB0ZXIpCgkJCQkJbGlzdC5hZGQoKChTZXJ2ZXJFbGVtZW50QWRhcHRlcikgb2JqKS5nZXRTZXJ2ZXJSZXNvdXJjZSgpKTsKCQkJfQoJCQkKCQkJSUVsZW1lbnRbXSByZXMgPSBuZXcgSUVsZW1lbnRbbGlzdC5zaXplKCldOwoJCQlsaXN0LnRvQXJyYXkocmVzKTsKCQkJCgkJCUFjdGlvbiBkZWxldGUgPSBuZXcgRGVsZXRlQWN0aW9uKHNoZWxsLCByZXMpOwoJCQlkZWxldGUucnVuKCk7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJcmV0dXJuIGZhbHNlOwoJfQoJCgkvKioKCSAqIFJldHVybnMgYW4gYWN0aW9uIG9mIHRoZSBzcGVjaWZpZWQgdHlwZSwgd2hpY2ggY2FuIGJlIHVzZWQgZm9yIGdsb2JhbAoJICovCglwdWJsaWMgc3RhdGljIElBY3Rpb24gZ2V0QWN0aW9uKFNoZWxsIHNoZWxsLCBJU2VsZWN0aW9uUHJvdmlkZXIgcHJvdmlkZXIsIGJ5dGUgYWN0aW9uKSB7CgkJaWYgKGFjdGlvbiA9PSBBQ1RJT05fREVMRVRFKSB7CgkJCXJldHVybiBuZXcgU2VydmVyVHJlZUFjdGlvbihzaGVsbCwgcHJvdmlkZXIsIFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlYWN0aW9uRGVsZXRlIiksIFNlcnZlclRyZWUuQUNUSU9OX0RFTEVURSk7CgkJfQoJCXJldHVybiBudWxsOwoJfQp9Cg==