LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA0IEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4goCBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAqIAogKiBDb250cmlidXRvcnM6CiAqICAgICBHb3JrZW0gRXJjYW4gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICAgIE5hY2kgTS4gRGFpCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECiAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCiAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBFVEVSQVRJT04gQS5TLiBPUgogKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCiAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgogKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAogKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKgogKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQogKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4gIEZvciBtb3JlCiAqIGluZm9ybWF0aW9uIG9uIGV0ZXJhdGlvbiwgcGxlYXNlIHNlZQogKiA8aHR0cDovL3d3dy5ldGVyYXRpb24uY29tLz4uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLmludGVybmFsLnVpOwoKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKCmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmdlbmVyaWMuc2VydmVydHlwZS5kZWZpbml0aW9uLlByb3BlcnR5OwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLnNlcnZlcnR5cGUuZGVmaW5pdGlvbi5TZXJ2ZXJSdW50aW1lOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLnVpLkdlbmVyaWNTZXJ2ZXJVSU1lc3NhZ2VzOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LlNXVDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuTW9kaWZ5RXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLk1vZGlmeUxpc3RlbmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25FdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uTGlzdGVuZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWREYXRhOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkTGF5b3V0OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQnV0dG9uOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29udHJvbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkRpcmVjdG9yeURpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkZpbGVEaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Hcm91cDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxhYmVsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVGV4dDsKCgpwdWJsaWMgY2xhc3MgU2VydmVyVHlwZURlZmluaXRpb25Hcm91cCAKewogICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09OVEVYVF9TRVJWRVIgPSBQcm9wZXJ0eS5DT05URVhUX1NFUlZFUjsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENPTlRFWFRfUlVOVElNRSA9IFByb3BlcnR5LkNPTlRFWFRfUlVOVElNRTsKCiAgICBwcml2YXRlIFNlcnZlclJ1bnRpbWUgZlNlcnZlclR5cGVEZWZpbml0aW9uOwogICAgcHJpdmF0ZSBMaXN0IGZQcm9wZXJ0eUNvbnRyb2xzID0gbmV3IEFycmF5TGlzdCgpOwogICAgcHJpdmF0ZSBNYXAgZlByb3BlcnR5TWFwID1uZXcgSGFzaE1hcCgpOwogICAgcHJpdmF0ZSBTdHJpbmcgZkNvbnRleHQ9InVuZGVmaW5lZCI7CiAgICBwcml2YXRlIEdyb3VwIGZEZWZpbml0aW9uR3JvdXA7CiAgICBwcml2YXRlIFNlcnZlckRlZmluaXRpb25UeXBlQXdhcmVXaXphcmRGcmFnbWVudCBmQXdhcmVXaXphcmRGcmFnbWVudDsKICAgIHByaXZhdGUgY2xhc3MgUHJvcGVydHlNb2RpZnlMaXN0ZW5lciBpbXBsZW1lbnRzIE1vZGlmeUxpc3RlbmVyCiAgICB7CiAgICAgICAgLyogKG5vbi1KYXZhZG9jKQogICAgICAgICAqIEBzZWUgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Nb2RpZnlMaXN0ZW5lciNtb2RpZnlUZXh0KG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuTW9kaWZ5RXZlbnQpCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgbW9kaWZ5VGV4dChNb2RpZnlFdmVudCBlKSB7CiAgICAgICAgICAgIGZBd2FyZVdpemFyZEZyYWdtZW50LnNlcnZlckRlZmluaXRpb25UeXBlUHJvcGVydGllc0NoYW5nZWQoKTsKICAgICAgICAgICAgCiAgICAgICAgfQogICAgICAgIAogICAgfQogICAgCiAgICAvKioKICAgICAqIENvbnN0cnVjdCBhIGNvbXBvc2l0ZSBmb3IgdGhlIGdpdmVuIFNlcnZlclR5cGVEZWZpbml0aW9uCiAgICAgKiAKICAgICAqIEBwYXJhbSBkZWZpbml0aW9uCiAgICAgKiBAcGFyYW0gaW5pdGlhbFByb3BlcnRpZXMgaW5pdGlhbCB2YWx1ZXMgbnVsbCBtZWFucyB1c2UgZGVmYXVsdAogICAgICogQHBhcmFtIHBhcmVudAogICAgICogQHBhcmFtIHN0eWxlCiAgICAgKi8KICAgIHB1YmxpYyBTZXJ2ZXJUeXBlRGVmaW5pdGlvbkdyb3VwKFNlcnZlckRlZmluaXRpb25UeXBlQXdhcmVXaXphcmRGcmFnbWVudCBmcmFnbWVudCwgU2VydmVyUnVudGltZSBkZWZpbml0aW9uLCBTdHJpbmcgY29udGV4dCwgTWFwIGluaXRpYWxQcm9wZXJ0aWVzLCBDb21wb3NpdGUgcGFyZW50KSAKICAgIHsKICAgICAgICBmQXdhcmVXaXphcmRGcmFnbWVudCA9IGZyYWdtZW50OwogICAgICAgIGluaXRTZXJ2ZXJUeXBlRGVmaW5pdGlvbihkZWZpbml0aW9uLGNvbnRleHQsaW5pdGlhbFByb3BlcnRpZXMpOwogICAgICAgIGNyZWF0ZUNvbnRyb2wocGFyZW50KTsKICAgIH0KICAgIHByaXZhdGUgdm9pZCBpbml0UHJvcGVydGllcyhNYXAgaW5pdGlhbFByb3BlcnRpZXMpCiAgICB7CiAgICAgICAgaWYoaW5pdGlhbFByb3BlcnRpZXMhPSBudWxsKQogICAgICAgICAgICB0aGlzLmZQcm9wZXJ0eU1hcD1pbml0aWFsUHJvcGVydGllczsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZQcm9wZXJ0eU1hcD1uZXcgSGFzaE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiBDaGFuZ2VzIHRoZSB2YWx1ZXMgd2l0aCB0aGUgZ2l2ZW4gb25lcy4gUmVuZGVycyB0aGUgVUkgCiAgICAgKiB3aXRoIHRoZSBnaXZlbiBuZXcgdmFsdWVzLgogICAgICogIAogICAgICogQHBhcmFtIGRlZmluaXRpb24KICAgICAqIEBwYXJhbSBjb250ZXh0CiAgICAgKiBAcGFyYW0gaW5pdGlhbFByb3BlcnRpZXMKICAgICAqLwogICAgcHVibGljIHZvaWQgcmVzZXQoU2VydmVyUnVudGltZSBkZWZpbml0aW9uLCBTdHJpbmcgY29udGV4dCwgTWFwIGluaXRpYWxQcm9wZXJ0aWVzKQogICAgewogICAgICAgIGluaXRTZXJ2ZXJUeXBlRGVmaW5pdGlvbihkZWZpbml0aW9uLCBjb250ZXh0LCBpbml0aWFsUHJvcGVydGllcyk7CiAgICAgICAgZkRlZmluaXRpb25Hcm91cC5zZXRUZXh0KGRlZmluaXRpb24uZ2V0TmFtZSgpKTsKICAgICAgICBDb250cm9sW10gYWxsQ29udHJvbHMgPSBmRGVmaW5pdGlvbkdyb3VwLmdldENoaWxkcmVuKCk7CiAgICAgICAgZm9yKGludCBpPSAwOyBpPGFsbENvbnRyb2xzLmxlbmd0aDtpKyspCiAgICAgICAgewogICAgICAgICAgICBDb250cm9sIGMgPSBhbGxDb250cm9sc1tpXTsKICAgICAgICAgICAgYy5kaXNwb3NlKCk7CiAgICAgICAgfQogICAgICAgIGZQcm9wZXJ0eUNvbnRyb2xzLmNsZWFyKCk7CiAgICAgICAgY3JlYXRlUHJvcGVydHlDb250cm9scyhmRGVmaW5pdGlvbkdyb3VwKTsKICAgICAgICAKICAgICAgICBmRGVmaW5pdGlvbkdyb3VwLmxheW91dCh0cnVlKTsKICAgICAgICAKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBAcGFyYW0gZGVmaW5pdGlvbgogICAgICogQHBhcmFtIGNvbnRleHQKICAgICAqIEBwYXJhbSBpbml0aWFsUHJvcGVydGllcwogICAgICovCiAgICBwcml2YXRlIHZvaWQgaW5pdFNlcnZlclR5cGVEZWZpbml0aW9uKFNlcnZlclJ1bnRpbWUgZGVmaW5pdGlvbiwgU3RyaW5nIGNvbnRleHQsIE1hcCBpbml0aWFsUHJvcGVydGllcykgewogICAgICAgIGZTZXJ2ZXJUeXBlRGVmaW5pdGlvbiA9IGRlZmluaXRpb247CiAgICAgICAgaW5pdFByb3BlcnRpZXMoaW5pdGlhbFByb3BlcnRpZXMpOwogICAgICAgIHRoaXMuZkNvbnRleHQgPSBjb250ZXh0OwogICAgfQogICAgLyoqCiAgICAgKiBAcGFyYW0gcGFyZW50CiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBjcmVhdGVDb250cm9sKENvbXBvc2l0ZSBwYXJlbnQpIHsKCiAgICAgICAgZkRlZmluaXRpb25Hcm91cCA9IG5ldyBHcm91cChwYXJlbnQsIFNXVC5TSEFET1dfRVRDSEVEX0lOKTsKICAgICAgICBmRGVmaW5pdGlvbkdyb3VwLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfQk9USCkpOwogICAgICAgIGZEZWZpbml0aW9uR3JvdXAuc2V0TGF5b3V0KG5ldyBHcmlkTGF5b3V0KDMsZmFsc2UpKTsKICAgICAgICBpZihmU2VydmVyVHlwZURlZmluaXRpb24hPW51bGwpCiAgICAgICAgeyAgIAogICAgICAgICAgICBmRGVmaW5pdGlvbkdyb3VwLnNldFRleHQoZlNlcnZlclR5cGVEZWZpbml0aW9uLmdldE5hbWUoKSk7CgogICAgICAgICAgICBjcmVhdGVQcm9wZXJ0eUNvbnRyb2xzKGZEZWZpbml0aW9uR3JvdXApOwogICAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogQHBhcmFtIGRlZlBhbmVsCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBjcmVhdGVQcm9wZXJ0eUNvbnRyb2xzKENvbXBvc2l0ZSBkZWZpbml0aW9uQ29tcG9zaXRlKSB7CgkJTGlzdCBwcm9wZXJ0aWVzID0gZlNlcnZlclR5cGVEZWZpbml0aW9uLmdldFByb3BlcnR5KCk7CgkJZm9yKGludCBpID0gMDsgaTxwcm9wZXJ0aWVzLnNpemUoKTsgaSsrKQoJCXsKCQkgICAgUHJvcGVydHkgcHJvcGVydHkgPSAoUHJvcGVydHkpcHJvcGVydGllcy5nZXQoaSk7CQkgICAgCgkJICAgIGlmKHRoaXMuZkNvbnRleHQuZXF1YWxzKHByb3BlcnR5LmdldENvbnRleHQoKSkpCgkJICAgICAgICBjcmVhdGVQcm9wZXJ0eUNvbnRyb2woZGVmaW5pdGlvbkNvbXBvc2l0ZSxwcm9wZXJ0eSk7CgkJfQogICAgICAgIAogICAgfQogICAgIAogICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZVByb3BlcnR5Q29udHJvbChDb21wb3NpdGUgcGFyZW50LCBQcm9wZXJ0eSBwcm9wZXJ0eSkKICAgIHsKICAgIAlpZiggImRpcmVjdG9yeSIuZXF1YWxzKHByb3BlcnR5LmdldFR5cGUoKSkpIHsKICAgIAkJVGV4dCBwYXRoID0gY3JlYXRlTGFiZWxlZFBhdGgocHJvcGVydHkuZ2V0TGFiZWwoKSxnZXRQcm9wZXJ0eVZhbHVlKHByb3BlcnR5KSxwYXJlbnQpOwogICAgCQlwYXRoLnNldERhdGEocHJvcGVydHkpOwogICAgCQlmUHJvcGVydHlDb250cm9scy5hZGQocGF0aCk7CiAgICAJfSBlbHNlIGlmKCAiZmlsZSIuZXF1YWxzKHByb3BlcnR5LmdldFR5cGUoKSkpIHsKICAgIAkgICAgVGV4dCBmaWxlID0gY3JlYXRlTGFiZWxlZEZpbGUocHJvcGVydHkuZ2V0TGFiZWwoKSxnZXRQcm9wZXJ0eVZhbHVlKHByb3BlcnR5KSxwYXJlbnQpOwogICAgCQlmaWxlLnNldERhdGEocHJvcGVydHkpOwogICAgCQlmUHJvcGVydHlDb250cm9scy5hZGQoZmlsZSk7CiAgICAJfSBlbHNlIGlmKCAic3RyaW5nIi5lcXVhbHMocHJvcGVydHkuZ2V0VHlwZSgpKSkgewogICAgCSAgICBUZXh0IHN0ciA9IGNyZWF0ZUxhYmVsZWRUZXh0KHByb3BlcnR5LmdldExhYmVsKCksZ2V0UHJvcGVydHlWYWx1ZShwcm9wZXJ0eSkscGFyZW50KTsKICAgIAkJc3RyLnNldERhdGEocHJvcGVydHkpOwogICAgCQlmUHJvcGVydHlDb250cm9scy5hZGQoc3RyKTsKICAgIAl9IGVsc2UgaWYoICJib29sZWFuIi5lcXVhbHMocHJvcGVydHkuZ2V0VHlwZSgpKSkgewogICAgCSAgICBCdXR0b24gYm9vbCA9Y3JlYXRlTGFiZWxlZENoZWNrKHByb3BlcnR5LmdldExhYmVsKCksKCJ0cnVlIi5lcXVhbHMoIGdldFByb3BlcnR5VmFsdWUocHJvcGVydHkpKSksCXBhcmVudCk7CiAgICAJCWJvb2wuc2V0RGF0YShwcm9wZXJ0eSk7CiAgICAJCWZQcm9wZXJ0eUNvbnRyb2xzLmFkZChib29sKTsKICAgIAl9IGVsc2UgIHsKICAgIAkgICAgVGV4dCBkZWZhdWx0VGV4dD0gY3JlYXRlTGFiZWxlZFRleHQocHJvcGVydHkuZ2V0TGFiZWwoKSxnZXRQcm9wZXJ0eVZhbHVlKHByb3BlcnR5KSxwYXJlbnQpOwogICAgCQlkZWZhdWx0VGV4dC5zZXREYXRhKHByb3BlcnR5KTsKICAgIAkJZlByb3BlcnR5Q29udHJvbHMuYWRkKGRlZmF1bHRUZXh0KTsKICAgICAJfQogICAgfQoJcHJpdmF0ZSBTdHJpbmcgZ2V0UHJvcGVydHlWYWx1ZShQcm9wZXJ0eSBwcm9wZXJ0eSkKCXsKCQlTdHJpbmcgdmFsdWUgPSBwcm9wZXJ0eS5nZXREZWZhdWx0KCk7CgkJaWYoZlByb3BlcnR5TWFwIT1udWxsICYmIGZQcm9wZXJ0eU1hcC5pc0VtcHR5KCk9PWZhbHNlKQoJCQl2YWx1ZT0oU3RyaW5nKWZQcm9wZXJ0eU1hcC5nZXQocHJvcGVydHkuZ2V0SWQoKSk7IAoJCXJldHVybiB2YWx1ZTsKCX0KICAgIHByb3RlY3RlZCBCdXR0b24gY3JlYXRlTGFiZWxlZENoZWNrKFN0cmluZyB0aXRsZSwgYm9vbGVhbiB2YWx1ZSwKICAgIAkJQ29tcG9zaXRlIGRlZlBhbmVsKSB7CiAgICAJR3JpZERhdGEgZ3JpZERhdGE7CiAgICAJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwoZGVmUGFuZWwsIFNXVC5XUkFQKTsKICAgIAlncmlkRGF0YSA9IG5ldyBHcmlkRGF0YSgpOwogICAgCWxhYmVsLnNldExheW91dERhdGEoZ3JpZERhdGEpOwogICAgCWxhYmVsLnNldFRleHQodGl0bGUpOwoKICAgIAlCdXR0b24gZkJ1dHRvbiA9IG5ldyBCdXR0b24oZGVmUGFuZWwsIFNXVC5DSEVDSyk7CiAgICAJCiAgICAJZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMCiAgICAJCQl8IEdyaWREYXRhLkdSQUJfSE9SSVpPTlRBTCk7CiAgICAJZ3JpZERhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwogICAgCWZCdXR0b24uc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7CiAgICAJZkJ1dHRvbi5zZXRTZWxlY3Rpb24odmFsdWUpOwogICAgCWZCdXR0b24uYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkxpc3RlbmVyKCkgewogICAgICAgICAgICBwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CiAgICAgICAgICAgICAgIGZBd2FyZVdpemFyZEZyYWdtZW50LnNlcnZlckRlZmluaXRpb25UeXBlUHJvcGVydGllc0NoYW5nZWQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIHZvaWQgd2lkZ2V0RGVmYXVsdFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKICAgICAgICAgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKCiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIAkKICAgIAlyZXR1cm4gZkJ1dHRvbjsKICAgIH0KICAgIHByb3RlY3RlZCBUZXh0IGNyZWF0ZUxhYmVsZWRGaWxlKFN0cmluZyB0aXRsZSwgU3RyaW5nIHZhbHVlLAogICAgCQlDb21wb3NpdGUgZGVmUGFuZWwpIHsKICAgIAlHcmlkRGF0YSBncmlkRGF0YTsKICAgIAlMYWJlbCBsYWJlbCA9IG5ldyBMYWJlbChkZWZQYW5lbCwgU1dULldSQVApOwogICAgCWdyaWREYXRhID0gbmV3IEdyaWREYXRhKCk7CiAgICAJbGFiZWwuc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7CiAgICAJbGFiZWwuc2V0VGV4dCh0aXRsZSk7CiAgICAKICAgIAlmaW5hbCBUZXh0IGZUZXh0ID0gbmV3IFRleHQoZGVmUGFuZWwsIFNXVC5TSEFET1dfSU4gfCBTV1QuQk9SREVSKTsKICAgIAlncmlkRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwKICAgIAkJCXwgR3JpZERhdGEuR1JBQl9IT1JJWk9OVEFMKTsKICAgIAlncmlkRGF0YS5ob3Jpem9udGFsU3BhbiA9IDE7CiAgICAJZlRleHQuc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7CiAgICAJZlRleHQuc2V0VGV4dCh2YWx1ZSk7CiAgICAJZlRleHQuYWRkTW9kaWZ5TGlzdGVuZXIobmV3IFByb3BlcnR5TW9kaWZ5TGlzdGVuZXIoKSk7CiAgICAJQnV0dG9uIGZCdXR0b24gPSBuZXcgQnV0dG9uKGRlZlBhbmVsLCBTV1QuUFVTSCk7CiAgICAJZkJ1dHRvbi5zZXRUZXh0KEdlbmVyaWNTZXJ2ZXJVSU1lc3NhZ2VzLmdldFN0cmluZygic2VydmVyVHlwZUdyb3VwLmxhYmVsLmJyb3dzZSIpKTsKICAgIAlmQnV0dG9uLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKCkpOwogICAgCWZCdXR0b24uYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkxpc3RlbmVyKCkgewogICAgCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CiAgICAJCQlGaWxlRGlhbG9nIGRsZyA9IG5ldyBGaWxlRGlhbG9nKGZEZWZpbml0aW9uR3JvdXAuZ2V0U2hlbGwoKSk7CiAgICAJCQlkbGcuc2V0RmlsZU5hbWUoZlRleHQuZ2V0VGV4dCgpKTsKICAgIAkJCVN0cmluZyByZXMgPSBkbGcub3BlbigpOwogICAgCQkJaWYgKHJlcyAhPSBudWxsKSB7CiAgICAJCQkJZlRleHQuc2V0VGV4dChyZXMpOwogICAgCQkJfQogICAgCQl9CiAgICAKICAgIAkJcHVibGljIHZvaWQgd2lkZ2V0RGVmYXVsdFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKICAgIAkJCXdpZGdldFNlbGVjdGVkKGUpOwogICAgCQl9CiAgICAKICAgIAl9KTsKICAgIAogICAgCXJldHVybiBmVGV4dDsKICAgIH0KICAgIHByb3RlY3RlZCBUZXh0IGNyZWF0ZUxhYmVsZWRQYXRoKFN0cmluZyB0aXRsZSwgU3RyaW5nIHZhbHVlLAogICAgCQlDb21wb3NpdGUgcGFyZW50KSB7CiAgICAJR3JpZERhdGEgZ3JpZERhdGE7CiAgICAJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwocGFyZW50LCBTV1QuV1JBUCk7CiAgICAJZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoKTsKICAgIAlsYWJlbC5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTsKICAgIAlsYWJlbC5zZXRUZXh0KHRpdGxlKTsKICAgIAogICAgCWZpbmFsIFRleHQgZlRleHQgPSBuZXcgVGV4dChwYXJlbnQsIFNXVC5TSEFET1dfSU4gfCBTV1QuQk9SREVSKTsKICAgIAlncmlkRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwogICAgCWdyaWREYXRhLmhvcml6b250YWxTcGFuID0gMTsKICAgIAlmVGV4dC5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTsKICAgIAlmVGV4dC5zZXRUZXh0KHZhbHVlKTsKICAgIAlmVGV4dC5hZGRNb2RpZnlMaXN0ZW5lcihuZXcgUHJvcGVydHlNb2RpZnlMaXN0ZW5lcigpKTsKICAgIAlCdXR0b24gZkJ1dHRvbiA9IG5ldyBCdXR0b24ocGFyZW50LCBTV1QuUFVTSCk7CiAgICAJZkJ1dHRvbi5zZXRUZXh0KEdlbmVyaWNTZXJ2ZXJVSU1lc3NhZ2VzLmdldFN0cmluZygic2VydmVyVHlwZUdyb3VwLmxhYmVsLmJyb3dzZSIpKTsKICAgIAlmQnV0dG9uLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKCkpOwogICAgCWZCdXR0b24uYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkxpc3RlbmVyKCkgewogICAgCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CiAgICAJCQlEaXJlY3RvcnlEaWFsb2cgZGxnID0gbmV3IERpcmVjdG9yeURpYWxvZyhmRGVmaW5pdGlvbkdyb3VwLmdldFNoZWxsKCkpOwogICAgCQkJZGxnLnNldEZpbHRlclBhdGgoZlRleHQuZ2V0VGV4dCgpKTsKICAgIAkJCVN0cmluZyByZXMgPSBkbGcub3BlbigpOwogICAgCQkJaWYgKHJlcyAhPSBudWxsKSB7CiAgICAJCQkJZlRleHQuc2V0VGV4dChyZXMpOwogICAgCQkJfQogICAgCQl9CiAgICAKICAgIAkJcHVibGljIHZvaWQgd2lkZ2V0RGVmYXVsdFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKICAgIAkJCXdpZGdldFNlbGVjdGVkKGUpOwogICAgCQl9CiAgICAKICAgIAl9KTsKICAgIAogICAgCXJldHVybiBmVGV4dDsKICAgIH0KICAgIHByb3RlY3RlZCBUZXh0IGNyZWF0ZUxhYmVsZWRUZXh0KFN0cmluZyB0aXRsZSwgU3RyaW5nIHZhbHVlLAogICAgCQlDb21wb3NpdGUgZGVmUGFuZWwpIHsKICAgIAlHcmlkRGF0YSBncmlkRGF0YTsKICAgIAlMYWJlbCBsYWJlbCA9IG5ldyBMYWJlbChkZWZQYW5lbCwgU1dULldSQVApOwogICAgCWdyaWREYXRhID0gbmV3IEdyaWREYXRhKCk7CiAgICAJbGFiZWwuc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7CiAgICAJbGFiZWwuc2V0VGV4dCh0aXRsZSk7CiAgICAKICAgIAlUZXh0IGZUZXh0ID0gbmV3IFRleHQoZGVmUGFuZWwsIFNXVC5TSEFET1dfSU4gfCBTV1QuQk9SREVSKTsKICAgIAlncmlkRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwKICAgIAkJCXwgR3JpZERhdGEuR1JBQl9IT1JJWk9OVEFMKTsKICAgIAlncmlkRGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CiAgICAJZlRleHQuc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7CiAgICAJZlRleHQuc2V0VGV4dCh2YWx1ZSk7CiAgICAJZlRleHQuYWRkTW9kaWZ5TGlzdGVuZXIobmV3IFByb3BlcnR5TW9kaWZ5TGlzdGVuZXIoKSk7CiAgICAJcmV0dXJuIGZUZXh0OwogICAgfQogICAgcHVibGljIE1hcCBnZXRQcm9wZXJ0aWVzKCkKICAgIHsKICAgIAlmb3IoaW50IGk9MDsgaTxmUHJvcGVydHlDb250cm9scy5zaXplKCk7aSsrKQogICAgCXsKICAgIAkJaWYoZlByb3BlcnR5Q29udHJvbHMuZ2V0KGkpaW5zdGFuY2VvZiBCdXR0b24pCiAgICAJCXsKICAgIAkJCUJ1dHRvbiBidXR0b24gPSAoQnV0dG9uKWZQcm9wZXJ0eUNvbnRyb2xzLmdldChpKTsKICAgIAkJCVByb3BlcnR5IHByb3AgPSAoUHJvcGVydHkpYnV0dG9uLmdldERhdGEoKTsKICAgIAkJCWZQcm9wZXJ0eU1hcC5wdXQocHJvcC5nZXRJZCgpLEJvb2xlYW4udG9TdHJpbmcoYnV0dG9uLmdldFNlbGVjdGlvbigpKSk7CiAgICAJCX0KICAgIAkJZWxzZQogICAgCQl7CiAgICAJCQlUZXh0IHRleHQgPSAoVGV4dClmUHJvcGVydHlDb250cm9scy5nZXQoaSk7CiAgICAJCQlQcm9wZXJ0eSBwcm9wID0gKFByb3BlcnR5KXRleHQuZ2V0RGF0YSgpOwogICAgCQkJZlByb3BlcnR5TWFwLnB1dChwcm9wLmdldElkKCksdGV4dC5nZXRUZXh0KCkpOwogICAgCQl9CiAgICAJfQogICAgCXJldHVybiBmUHJvcGVydHlNYXA7CiAgICB9Cn0K