LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuYWN0aW9uczsKCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklQcm9qZWN0OwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLio7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLklMYXVuY2hNYW5hZ2VyOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuYWN0aW9uLklBY3Rpb247CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLkVycm9yRGlhbG9nOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuZGlhbG9ncy5JRGlhbG9nQ29uc3RhbnRzOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuZGlhbG9ncy5NZXNzYWdlRGlhbG9nOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5JU2VsZWN0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5JU3RydWN0dXJlZFNlbGVjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLndpbmRvdy5XaW5kb3c7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS53aXphcmQuV2l6YXJkRGlhbG9nOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLio7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuSUNsaWVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5JTGF1bmNoYWJsZUFkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuUHVibGlzaFNlcnZlckpvYjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5TZXJ2ZXJQbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLio7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLndpemFyZC4qOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuU2hlbGw7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5JV29ya2JlbmNoV2luZG93OwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSVdvcmtiZW5jaFdpbmRvd0FjdGlvbkRlbGVnYXRlOwovKioKICogU3VwcG9ydCBmb3Igc3RhcnRpbmcvc3RvcHBpbmcgc2VydmVyIGFuZCBjbGllbnRzIGZvciByZXNvdXJjZXMgcnVubmluZyBvbiBhIHNlcnZlci4KICovCnB1YmxpYyBjbGFzcyBSdW5PblNlcnZlckFjdGlvbkRlbGVnYXRlIGltcGxlbWVudHMgSVdvcmtiZW5jaFdpbmRvd0FjdGlvbkRlbGVnYXRlIHsKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nW10gbGF1bmNoTW9kZXMgPSB7CgkJSUxhdW5jaE1hbmFnZXIuUlVOX01PREUsIElMYXVuY2hNYW5hZ2VyLkRFQlVHX01PREUsIElMYXVuY2hNYW5hZ2VyLlBST0ZJTEVfTU9ERSB9OwoKCXByb3RlY3RlZCBPYmplY3Qgc2VsZWN0aW9uOwoKCXByb3RlY3RlZCBJV29ya2JlbmNoV2luZG93IHdpbmRvdzsKCglwcm90ZWN0ZWQgc3RhdGljIE9iamVjdCBnbG9iYWxTZWxlY3Rpb247CgoJcHJvdGVjdGVkIHN0YXRpYyBNYXAgZ2xvYmFsTGF1bmNoTW9kZTsKCQoJcHJvdGVjdGVkIGJvb2xlYW4gdGFza3NSdW47CgoJLyoqCgkgKiBSdW5PblNlcnZlckFjdGlvbkRlbGVnYXRlIGNvbnN0cnVjdG9yIGNvbW1lbnQuCgkgKi8KCXB1YmxpYyBSdW5PblNlcnZlckFjdGlvbkRlbGVnYXRlKCkgewoJCXN1cGVyKCk7Cgl9CgoJLyoqCgkgKiBEaXNwb3NlcyB0aGlzIGFjdGlvbiBkZWxlZ2F0ZS4gIFRoZSBpbXBsZW1lbnRvciBzaG91bGQgdW5ob29rIGFueSByZWZlcmVuY2VzCgkgKiB0byBpdHNlbGYgc28gdGhhdCBnYXJiYWdlIGNvbGxlY3Rpb24gY2FuIG9jY3VyLgoJICovCglwdWJsaWMgdm9pZCBkaXNwb3NlKCkgewoJCXdpbmRvdyA9IG51bGw7Cgl9CgoJLyoqCgkgKiBJbml0aWFsaXplcyB0aGlzIGFjdGlvbiBkZWxlZ2F0ZSB3aXRoIHRoZSB3b3JrYmVuY2ggd2luZG93IGl0IHdpbGwgd29yayBpbi4KCSAqCgkgKiBAcGFyYW0gbmV3V2luZG93IHRoZSB3aW5kb3cgdGhhdCBwcm92aWRlcyB0aGUgY29udGV4dCBmb3IgdGhpcyBkZWxlZ2F0ZQoJICovCglwdWJsaWMgdm9pZCBpbml0KElXb3JrYmVuY2hXaW5kb3cgbmV3V2luZG93KSB7CgkJd2luZG93ID0gbmV3V2luZG93OwoJfQoJCglwdWJsaWMgSVNlcnZlciBnZXRTZXJ2ZXIoSU1vZHVsZSBtb2R1bGUsIFN0cmluZyBsYXVuY2hNb2RlLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlJU2VydmVyIHNlcnZlciA9IG51bGw7CgkJSVByb2plY3QgcHJvamVjdCA9IG1vZHVsZS5nZXRQcm9qZWN0KCk7CgkJaWYgKHByb2plY3QgIT0gbnVsbCkKCQkJc2VydmVyID0gU2VydmVyQ29yZS5nZXRQcm9qZWN0UHJvcGVydGllcyhwcm9qZWN0KS5nZXREZWZhdWx0U2VydmVyKCk7CgkJCgkJLy8gaWdub3JlIHByZWZlcmVuY2UgaWYgdGhlIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgdGhpcyBtb2RlLgoJCWlmIChzZXJ2ZXIgIT0gbnVsbCAmJiAhU2VydmVyVUlQbHVnaW4uaXNDb21wYXRpYmxlV2l0aExhdW5jaE1vZGUoc2VydmVyLCBsYXVuY2hNb2RlKSkKCQkJc2VydmVyID0gbnVsbDsKCQkKCQlpZiAoc2VydmVyICE9IG51bGwgJiYgIVNlcnZlclV0aWwuY29udGFpbnNNb2R1bGUoc2VydmVyLCBtb2R1bGUsIG1vbml0b3IpKSB7CgkJCUlTZXJ2ZXJXb3JraW5nQ29weSB3YyA9IHNlcnZlci5jcmVhdGVXb3JraW5nQ29weSgpOwoJCQl0cnkgewoJCQkJU2VydmVyVXRpbC5tb2RpZnlNb2R1bGVzKHdjLCBuZXcgSU1vZHVsZVtdIHsgbW9kdWxlIH0sIG5ldyBJTW9kdWxlWzBdLCBtb25pdG9yKTsKCQkJCXdjLnNhdmUoZmFsc2UsIG1vbml0b3IpOwoJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJDb3VsZCBub3QgYWRkIG1vZHVsZSB0byBzZXJ2ZXIiLCBjZSk7CgkJCQlzZXJ2ZXIgPSBudWxsOwoJCQl9CgkJfQoJCQoJCVNoZWxsIHNoZWxsOwoJCWlmICh3aW5kb3cgIT0gbnVsbCkKCQkJc2hlbGwgPSB3aW5kb3cuZ2V0U2hlbGwoKTsKCQllbHNlCgkJCXNoZWxsID0gU2VydmVyVUlQbHVnaW4uZ2V0SW5zdGFuY2UoKS5nZXRXb3JrYmVuY2goKS5nZXRBY3RpdmVXb3JrYmVuY2hXaW5kb3coKS5nZXRTaGVsbCgpOwoKCQlpZiAoc2VydmVyID09IG51bGwpIHsKCQkJLy8gdHJ5IHRoZSBmdWxsIHdpemFyZAoJCQlSdW5PblNlcnZlcldpemFyZCB3aXphcmQgPSBuZXcgUnVuT25TZXJ2ZXJXaXphcmQobW9kdWxlLCBsYXVuY2hNb2RlKTsKCQkJQ2xvc2FibGVXaXphcmREaWFsb2cgZGlhbG9nID0gbmV3IENsb3NhYmxlV2l6YXJkRGlhbG9nKHNoZWxsLCB3aXphcmQpOwoJCQlpZiAoZGlhbG9nLm9wZW4oKSA9PSBXaW5kb3cuQ0FOQ0VMKSB7CgkJCQltb25pdG9yLnNldENhbmNlbGVkKHRydWUpOwoJCQkJcmV0dXJuIG51bGw7CgkJCX0KCgkJCXRyeSB7CgkJCQlQbGF0Zm9ybS5nZXRKb2JNYW5hZ2VyKCkuam9pbigib3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5mYW1pbHkiLCBuZXcgTnVsbFByb2dyZXNzTW9uaXRvcigpKTsKCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLldBUk5JTkcsICJFcnJvciB3YWl0aW5nIGZvciBqb2IiLCBlKTsKCQkJfQoJCQlzZXJ2ZXIgPSB3aXphcmQuZ2V0U2VydmVyKCk7CgkJCWJvb2xlYW4gcHJlZmVycmVkID0gd2l6YXJkLmlzUHJlZmVycmVkU2VydmVyKCk7CgkJCXRhc2tzUnVuID0gdHJ1ZTsKCgkJCS8vIHNldCBwcmVmZXJyZWQgc2VydmVyIGlmIHJlcXVlc3RlZAoJCQlpZiAoc2VydmVyICE9IG51bGwgJiYgcHJlZmVycmVkICYmIHByb2plY3QgIT0gbnVsbCkgewoJCQkJdHJ5IHsKCQkJCQlTZXJ2ZXJDb3JlLmdldFByb2plY3RQcm9wZXJ0aWVzKHByb2plY3QpLnNldERlZmF1bHRTZXJ2ZXIoc2VydmVyLCBtb25pdG9yKTsKCQkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJCQlTdHJpbmcgbWVzc2FnZSA9IFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlZXJyb3JDb3VsZE5vdFNhdmVQcmVmZXJlbmNlIik7CgkJCQkJRXJyb3JEaWFsb2cub3BlbkVycm9yKHNoZWxsLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWVycm9yRGlhbG9nVGl0bGUiKSwgbWVzc2FnZSwgY2UuZ2V0U3RhdHVzKCkpOwoJCQkJfQoJCQl9CgkJfQoJCQoJCXRyeSB7CgkJCVBsYXRmb3JtLmdldEpvYk1hbmFnZXIoKS5qb2luKCJvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmZhbWlseSIsIG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCkpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLldBUk5JTkcsICJFcnJvciB3YWl0aW5nIGZvciBqb2IiLCBlKTsKCQl9CgkJCgkJcmV0dXJuIHNlcnZlcjsKCX0KCgkvKioKCSAqIFJ1biB0aGUgcmVzb3VyY2Ugb24gYSBzZXJ2ZXIuCgkgKgoJICogQHBhcmFtIG1vbml0b3Igb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQcm9ncmVzc01vbml0b3IKCSAqLwoJcHJvdGVjdGVkIHZvaWQgcnVuKElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCVN0cmluZyBsYXVuY2hNb2RlID0gZ2V0TGF1bmNoTW9kZSgpOwoJCUlNb2R1bGVBcnRpZmFjdCBtb2R1bGVBcnRpZmFjdCA9IFNlcnZlclBsdWdpbi5sb2FkTW9kdWxlQXJ0aWZhY3Qoc2VsZWN0aW9uKTsKCQkKCQlTaGVsbCBzaGVsbDsKCQlpZiAod2luZG93ICE9IG51bGwpCgkJCXNoZWxsID0gd2luZG93LmdldFNoZWxsKCk7CgkJZWxzZQoJCQlzaGVsbCA9IFNlcnZlclVJUGx1Z2luLmdldEluc3RhbmNlKCkuZ2V0V29ya2JlbmNoKCkuZ2V0QWN0aXZlV29ya2JlbmNoV2luZG93KCkuZ2V0U2hlbGwoKTsKCgkJaWYgKG1vZHVsZUFydGlmYWN0ID09IG51bGwpIHsKCQkJRWNsaXBzZVV0aWwub3BlbkVycm9yKFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlZXJyb3JOb01vZHVsZXMiKSk7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIk5vIG1vZHVsZXMiKTsKCQkJcmV0dXJuOwoJCX0KCQlJTW9kdWxlIG1vZHVsZSA9IG1vZHVsZUFydGlmYWN0LmdldE1vZHVsZSgpOwoKCQkvLyBjaGVjayBmb3Igc2VydmVycyB3aXRoIHRoZSBnaXZlbiBzdGFydCBtb2RlCgkJSVNlcnZlcltdIHNlcnZlcnMgPSBTZXJ2ZXJDb3JlLmdldFNlcnZlcnMoKTsKCQlib29sZWFuIGZvdW5kID0gZmFsc2U7CgkJaWYgKHNlcnZlcnMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IHNlcnZlcnMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemUgJiYgIWZvdW5kOyBpKyspIHsKCQkJCWlmIChTZXJ2ZXJVSVBsdWdpbi5pc0NvbXBhdGlibGVXaXRoTGF1bmNoTW9kZShzZXJ2ZXJzW2ldLCBsYXVuY2hNb2RlKSkgewoJCQkJCXRyeSB7CgkJCQkJCUlNb2R1bGVbXSBwYXJlbnRzID0gc2VydmVyc1tpXS5nZXRSb290TW9kdWxlcyhtb2R1bGUsIG1vbml0b3IpOwoJCQkJCQlpZiAocGFyZW50cyAhPSBudWxsICYmIHBhcmVudHMubGVuZ3RoID4gMCkKCQkJCQkJCWZvdW5kID0gdHJ1ZTsKCQkJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJCQkvLyBpZ25vcmUKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCWlmICghZm91bmQpIHsKCQkJLy8gbm8gZXhpc3Rpbmcgc2VydmVyIHN1cHBvcnRzIHRoZSBwcm9qZWN0IGFuZCBzdGFydCBtb2RlIQoJCQkvLyBjaGVjayBpZiB0aGVyZSBtaWdodCBiZSBhbm90aGVyIG9uZSB0aGF0IGNhbiBiZSBjcmVhdGVkCgkJCUlTZXJ2ZXJUeXBlW10gc2VydmVyVHlwZXMgPSBTZXJ2ZXJDb3JlLmdldFNlcnZlclR5cGVzKCk7CgkJCWJvb2xlYW4gZm91bmQyID0gZmFsc2U7CgkJCWlmIChzZXJ2ZXJUeXBlcyAhPSBudWxsKSB7CgkJCQlpbnQgc2l6ZSA9IHNlcnZlclR5cGVzLmxlbmd0aDsKCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZSAmJiAhZm91bmQyOyBpKyspIHsKCQkJCQlJU2VydmVyVHlwZSB0eXBlID0gc2VydmVyVHlwZXNbaV07CgkJCQkJSU1vZHVsZVR5cGVbXSBtb2R1bGVUeXBlcyA9IHR5cGUuZ2V0UnVudGltZVR5cGUoKS5nZXRNb2R1bGVUeXBlcygpOwoJCQkJCWlmICh0eXBlLnN1cHBvcnRzTGF1bmNoTW9kZShsYXVuY2hNb2RlKSAmJiBTZXJ2ZXJVdGlsLmlzU3VwcG9ydGVkTW9kdWxlKG1vZHVsZVR5cGVzLCBtb2R1bGUuZ2V0TW9kdWxlVHlwZSgpKSkgewoJCQkJCQlmb3VuZDIgPSB0cnVlOwoJCQkJCX0KCQkJCX0KCQkJfQoJCQlpZiAoIWZvdW5kMikgewoJCQkJRWNsaXBzZVV0aWwub3BlbkVycm9yKFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlZXJyb3JOb1NlcnZlciIpKTsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIk5vIHNlcnZlciBmb3Igc3RhcnQgbW9kZSIpOwoJCQkJcmV0dXJuOwoJCQl9CgkJfQoJCQoJCWlmICghU2VydmVyVUlQbHVnaW4uc2F2ZUVkaXRvcnMoKSkKCQkJcmV0dXJuOwoKCQl0YXNrc1J1biA9IGZhbHNlOwoJCUlTZXJ2ZXIgc2VydmVyID0gZ2V0U2VydmVyKG1vZHVsZSwgbGF1bmNoTW9kZSwgbW9uaXRvcik7CgkJaWYgKG1vbml0b3IuaXNDYW5jZWxlZCgpKQoJCQlyZXR1cm47CgkJCgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiU2VydmVyOiAiICsgc2VydmVyKTsKCQkKCQlpZiAoc2VydmVyID09IG51bGwpIHsKCQkJRWNsaXBzZVV0aWwub3BlbkVycm9yKFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlZXJyb3JOb1NlcnZlciIpKTsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiTm8gc2VydmVyIGZvdW5kIik7CgkJCXJldHVybjsKCQl9CgoJCWlmICghU2VydmVyVUlQbHVnaW4ucHJvbXB0SWZEaXJ0eShzaGVsbCwgc2VydmVyKSkKCQkJcmV0dXJuOwoJCQoJCWlmICghdGFza3NSdW4pIHsKCQkJU2VsZWN0VGFza3NXaXphcmQgd2l6YXJkID0gbmV3IFNlbGVjdFRhc2tzV2l6YXJkKHNlcnZlcik7CgkJCXdpemFyZC5hZGRQYWdlcygpOwoJCQlpZiAod2l6YXJkLmhhc1Rhc2tzKCkgJiYgd2l6YXJkLmhhc09wdGlvbmFsVGFza3MoKSkgewoJCQkJV2l6YXJkRGlhbG9nIGRpYWxvZyA9IG5ldyBXaXphcmREaWFsb2coc2hlbGwsIHdpemFyZCk7CgkJCQlpZiAoZGlhbG9nLm9wZW4oKSA9PSBXaW5kb3cuQ0FOQ0VMKQoJCQkJCXJldHVybjsKCQkJfSBlbHNlCgkJCQl3aXphcmQucGVyZm9ybUZpbmlzaCgpOwoJCX0KCQkKCQkvLyBnZXQgdGhlIGxhdW5jaGFibGUgYWRhcHRlciBhbmQgbW9kdWxlIG9iamVjdAoJCUlMYXVuY2hhYmxlQWRhcHRlciBsYXVuY2hhYmxlQWRhcHRlciA9IG51bGw7CgkJT2JqZWN0IGxhdW5jaGFibGUgPSBudWxsOwoJCUlMYXVuY2hhYmxlQWRhcHRlcltdIGFkYXB0ZXJzID0gU2VydmVyUGx1Z2luLmdldExhdW5jaGFibGVBZGFwdGVycygpOwoJCWlmIChhZGFwdGVycyAhPSBudWxsKSB7CgkJCWludCBzaXplMiA9IGFkYXB0ZXJzLmxlbmd0aDsKCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMjsgaisrKSB7CgkJCQlJTGF1bmNoYWJsZUFkYXB0ZXIgYWRhcHRlciA9IGFkYXB0ZXJzW2pdOwoJCQkJdHJ5IHsKCQkJCQlPYmplY3QgbGF1bmNoYWJsZTIgPSBhZGFwdGVyLmdldExhdW5jaGFibGUoc2VydmVyLCBtb2R1bGVBcnRpZmFjdCk7CgkJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiYWRhcHRlcj0gIiArIGFkYXB0ZXIgKyAiLCBsYXVuY2hhYmxlPSAiICsgbGF1bmNoYWJsZTIpOwoJCQkJCWlmIChsYXVuY2hhYmxlMiAhPSBudWxsKSB7CgkJCQkJCWxhdW5jaGFibGVBZGFwdGVyID0gYWRhcHRlcjsKCQkJCQkJbGF1bmNoYWJsZSA9IGxhdW5jaGFibGUyOwoJCQkJCX0KCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgaW4gbGF1bmNoYWJsZSBhZGFwdGVyIiwgZSk7CgkJCQl9CgkJCX0KCQl9CgkJCgkJSUNsaWVudFtdIGNsaWVudHMgPSBuZXcgSUNsaWVudFswXTsKCQlpZiAobGF1bmNoYWJsZSAhPSBudWxsKQoJCQljbGllbnRzID0gZ2V0Q2xpZW50cyhzZXJ2ZXIsIGxhdW5jaGFibGUsIGxhdW5jaE1vZGUpOwoKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJMYXVuY2hhYmxlIGNsaWVudHM6ICIgKyBjbGllbnRzKTsKCgkJSUNsaWVudCBjbGllbnQgPSBudWxsOwoJCWlmIChjbGllbnRzID09IG51bGwgfHwgY2xpZW50cy5sZW5ndGggPT0gMCkgewoJCQlFY2xpcHNlVXRpbC5vcGVuRXJyb3IoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVlcnJvck5vQ2xpZW50IikpOwoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJObyBsYXVuY2hhYmxlIGNsaWVudHMhIik7CgkJCXJldHVybjsKCQl9IGVsc2UgaWYgKGNsaWVudHMubGVuZ3RoID09IDEpIHsKCQkJY2xpZW50ID0gY2xpZW50c1swXTsKCQl9IGVsc2UgewoJCQlTZWxlY3RDbGllbnRXaXphcmQgd2l6YXJkID0gbmV3IFNlbGVjdENsaWVudFdpemFyZChjbGllbnRzKTsKCQkJQ2xvc2FibGVXaXphcmREaWFsb2cgZGlhbG9nID0gbmV3IENsb3NhYmxlV2l6YXJkRGlhbG9nKHNoZWxsLCB3aXphcmQpOwoJCQlkaWFsb2cub3BlbigpOwoJCQljbGllbnQgPSB3aXphcmQuZ2V0U2VsZWN0ZWRDbGllbnQoKTsKCQkJaWYgKGNsaWVudCA9PSBudWxsKQoJCQkJcmV0dXJuOwoJCX0KCgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiUmVhZHkgdG8gbGF1bmNoIik7CgoJCS8vIHN0YXJ0IHNlcnZlciBpZiBpdCdzIG5vdCBhbHJlYWR5IHN0YXJ0ZWQKCQkvLyBhbmQgY3VlIHRoZSBjbGllbnQgdG8gc3RhcnQKCQlJTW9kdWxlW10gbW9kdWxlcyA9IG5ldyBJTW9kdWxlW10geyBtb2R1bGUgfTsgLy8gVE9ETzogZ2V0IHBhcmVudCBoZWlyYXJjaHkgY29ycmVjdAoJCWludCBzdGF0ZSA9IHNlcnZlci5nZXRTZXJ2ZXJTdGF0ZSgpOwoJCWlmIChzdGF0ZSA9PSBJU2VydmVyLlNUQVRFX1NUQVJUSU5HKSB7CgkJCUxhdW5jaENsaWVudEpvYi5sYXVuY2hDbGllbnQoc2VydmVyLCBtb2R1bGVzLCBsYXVuY2hNb2RlLCBtb2R1bGVBcnRpZmFjdCwgbGF1bmNoYWJsZUFkYXB0ZXIsIGNsaWVudCk7CgkJfSBlbHNlIGlmIChzdGF0ZSA9PSBJU2VydmVyLlNUQVRFX1NUQVJURUQpIHsKCQkJYm9vbGVhbiByZXN0YXJ0ID0gZmFsc2U7CgkJCVN0cmluZyBtb2RlID0gc2VydmVyLmdldE1vZGUoKTsKCQkJaWYgKCFJTGF1bmNoTWFuYWdlci5ERUJVR19NT0RFLmVxdWFscyhtb2RlKSAmJiBJTGF1bmNoTWFuYWdlci5ERUJVR19NT0RFLmVxdWFscyhsYXVuY2hNb2RlKSkgewoJCQkJaW50IHJlc3VsdCA9IG9wZW5XYXJuaW5nRGlhbG9nKHNoZWxsLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWRpYWxvZ01vZGVXYXJuaW5nRGVidWciKSk7CgkJCQlpZiAocmVzdWx0ID09IDEpCgkJCQkJbGF1bmNoTW9kZSA9IG1vZGU7CgkJCQllbHNlIGlmIChyZXN1bHQgPT0gMCkKCQkJCQlyZXN0YXJ0ID0gdHJ1ZTsKCQkJCWVsc2UKCQkJCQlyZXR1cm47CgkJCX0gZWxzZSBpZiAoIUlMYXVuY2hNYW5hZ2VyLlBST0ZJTEVfTU9ERS5lcXVhbHMobW9kZSkgJiYgSUxhdW5jaE1hbmFnZXIuUFJPRklMRV9NT0RFLmVxdWFscyhsYXVuY2hNb2RlKSkgewoJCQkJaW50IHJlc3VsdCA9IG9wZW5XYXJuaW5nRGlhbG9nKHNoZWxsLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWRpYWxvZ01vZGVXYXJuaW5nUHJvZmlsZSIpKTsKCQkJCWlmIChyZXN1bHQgPT0gMSkKCQkJCQlsYXVuY2hNb2RlID0gbW9kZTsKCQkJCWVsc2UgaWYgKHJlc3VsdCA9PSAwKQoJCQkJCXJlc3RhcnQgPSB0cnVlOwoJCQkJZWxzZQoJCQkJCXJldHVybjsKCQkJfQoJCQlpZiAocmVzdGFydCkKCQkJCVJlc3RhcnRTZXJ2ZXJKb2IucmVzdGFydFNlcnZlcihzZXJ2ZXIsIGxhdW5jaE1vZGUpOwoJCQkKCQkJUHVibGlzaFNlcnZlckpvYiBwdWJsaXNoSm9iID0gbmV3IFB1Ymxpc2hTZXJ2ZXJKb2Ioc2VydmVyKTsKCQkJcHVibGlzaEpvYi5zY2hlZHVsZSgpOwoJCQlMYXVuY2hDbGllbnRKb2IubGF1bmNoQ2xpZW50KHNlcnZlciwgbW9kdWxlcywgbGF1bmNoTW9kZSwgbW9kdWxlQXJ0aWZhY3QsIGxhdW5jaGFibGVBZGFwdGVyLCBjbGllbnQpOwoJCX0gZWxzZSBpZiAoc3RhdGUgIT0gSVNlcnZlci5TVEFURV9TVE9QUElORykgewoJCQlQdWJsaXNoU2VydmVySm9iIHB1Ymxpc2hKb2IgPSBuZXcgUHVibGlzaFNlcnZlckpvYihzZXJ2ZXIpOwoJCQlwdWJsaXNoSm9iLnNjaGVkdWxlKCk7CgkJCVN0YXJ0U2VydmVySm9iLnN0YXJ0U2VydmVyKHNlcnZlciwgbGF1bmNoTW9kZSk7CgkJCUxhdW5jaENsaWVudEpvYi5sYXVuY2hDbGllbnQoc2VydmVyLCBtb2R1bGVzLCBsYXVuY2hNb2RlLCBtb2R1bGVBcnRpZmFjdCwgbGF1bmNoYWJsZUFkYXB0ZXIsIGNsaWVudCk7CgkJfQoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgbGF1bmNoYWJsZSBjbGllbnRzIGZvciB0aGUgZ2l2ZW4gc2VydmVyIGFuZCBsYXVuY2hhYmxlCgkgKiBvYmplY3QuCgkgKgoJICogQHBhcmFtIHNlcnZlciBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVNlcnZlcgoJICogQHBhcmFtIGxhdW5jaGFibGUKCSAqIEBwYXJhbSBsYXVuY2hNb2RlIFN0cmluZwoJICogQHJldHVybiBhbiBhcnJheSBvZiBjbGllbnRzCgkgKi8KCXB1YmxpYyBzdGF0aWMgSUNsaWVudFtdIGdldENsaWVudHMoSVNlcnZlciBzZXJ2ZXIsIE9iamVjdCBsYXVuY2hhYmxlLCBTdHJpbmcgbGF1bmNoTW9kZSkgewoJCUFycmF5TGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCUlDbGllbnRbXSBjbGllbnRzID0gU2VydmVyUGx1Z2luLmdldENsaWVudHMoKTsKCQlpZiAoY2xpZW50cyAhPSBudWxsKSB7CgkJCWludCBzaXplID0gY2xpZW50cy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJjbGllbnQ9ICIgKyBjbGllbnRzW2ldKTsKCQkJCWlmIChjbGllbnRzW2ldLnN1cHBvcnRzKHNlcnZlciwgbGF1bmNoYWJsZSwgbGF1bmNoTW9kZSkpCgkJCQkJbGlzdC5hZGQoY2xpZW50c1tpXSk7CgkJCX0KCQl9CgkJCgkJSUNsaWVudFtdIGNsaWVudHMyID0gbmV3IElDbGllbnRbbGlzdC5zaXplKCldOwoJCWxpc3QudG9BcnJheShjbGllbnRzMik7CgkJcmV0dXJuIGNsaWVudHMyOwoJfQoKCS8qKgoJICogT3BlbiBhIG1lc3NhZ2UgZGlhbG9nLgoJICogCgkgKiBAcGFyYW0gc2hlbGwKCSAqIEBwYXJhbSBtZXNzYWdlCgkgKiBAcmV0dXJuIGEgZGlhbG9nIHJldHVybiBjb25zdGFudAoJICovCglwcm90ZWN0ZWQgaW50IG9wZW5XYXJuaW5nRGlhbG9nKFNoZWxsIHNoZWxsLCBTdHJpbmcgbWVzc2FnZSkgewoJCU1lc3NhZ2VEaWFsb2cgZGlhbG9nID0gbmV3IE1lc3NhZ2VEaWFsb2coc2hlbGwsIFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlZXJyb3JEaWFsb2dUaXRsZSIpLCBudWxsLAoJCQltZXNzYWdlLAlNZXNzYWdlRGlhbG9nLldBUk5JTkcsIG5ldyBTdHJpbmdbXSB7U2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVkaWFsb2dNb2RlV2FybmluZ1Jlc3RhcnQiKSwKCQkJU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVkaWFsb2dNb2RlV2FybmluZ0NvbnRpbnVlIiksIElEaWFsb2dDb25zdGFudHMuQ0FOQ0VMX0xBQkVMfSwgMCk7CgkJcmV0dXJuIGRpYWxvZy5vcGVuKCk7Cgl9CgoJLyoqCgkgKiBUaGUgZGVsZWdhdGluZyBhY3Rpb24gaGFzIGJlZW4gcGVyZm9ybWVkLiBJbXBsZW1lbnQKCSAqIHRoaXMgbWV0aG9kIHRvIGRvIHRoZSBhY3R1YWwgd29yay4KCSAqCgkgKiBAcGFyYW0gYWN0aW9uIGFjdGlvbiBwcm94eSB0aGF0IGhhbmRsZXMgdGhlIHByZXNlbnRhdGlvbgoJICogcG9ydGlvbiBvZiB0aGUgcGx1Z2luIGFjdGlvbgoJICovCglwdWJsaWMgdm9pZCBydW4oSUFjdGlvbiBhY3Rpb24pIHsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJSdW5uaW5nIG9uIFNlcnZlci4uLiIpOwoJCXRyeSB7CgkJCXJ1bihuZXcgTnVsbFByb2dyZXNzTW9uaXRvcigpKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJSdW4gb24gU2VydmVyIEVycm9yIiwgZSk7CgkJfQoJfQoJCglwcm90ZWN0ZWQgYm9vbGVhbiBpc0VuYWJsZWQoKSB7CgkJdHJ5IHsKCQkJQm9vbGVhbiBiID0gKEJvb2xlYW4pIGdsb2JhbExhdW5jaE1vZGUuZ2V0KGdldExhdW5jaE1vZGUoKSk7CgkJCXJldHVybiBiLmJvb2xlYW5WYWx1ZSgpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCS8vIGlnbm9yZQoJCX0KCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBzdGFydCBtb2RlIHRoYXQgdGhlIHNlcnZlciBzaG91bGQgdXNlLgoJICovCglwcm90ZWN0ZWQgU3RyaW5nIGdldExhdW5jaE1vZGUoKSB7CgkJcmV0dXJuIElMYXVuY2hNYW5hZ2VyLlJVTl9NT0RFOwoJfQoKCS8qKgoJICogRGV0ZXJtaW5lIHdoaWNoIGNsaWVudHMgY2FuIGFjdCBvbiB0aGUgY3VycmVudCBzZWxlY3Rpb24uCgkgKgoJICogQHBhcmFtIGFjdGlvbiBhY3Rpb24gcHJveHkgdGhhdCBoYW5kbGVzIHByZXNlbnRhdGlvbgoJICogICAgcG9ydGlvbiBvZiB0aGUgcGx1Z2luIGFjdGlvbgoJICogQHBhcmFtIHNlbCBjdXJyZW50IHNlbGVjdGlvbiBpbiB0aGUgZGVza3RvcAoJICovCglwdWJsaWMgdm9pZCBzZWxlY3Rpb25DaGFuZ2VkKElBY3Rpb24gYWN0aW9uLCBJU2VsZWN0aW9uIHNlbCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIj4gc2VsZWN0aW9uQ2hhbmdlZCIpOwoJCXNlbGVjdGlvbiA9IG51bGw7CgkJbG9uZyB0aW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CgkJaWYgKHNlbCA9PSBudWxsIHx8IHNlbC5pc0VtcHR5KCkgfHwgIShzZWwgaW5zdGFuY2VvZiBJU3RydWN0dXJlZFNlbGVjdGlvbikpIHsKCQkJYWN0aW9uLnNldEVuYWJsZWQoZmFsc2UpOwoJCQlnbG9iYWxTZWxlY3Rpb24gPSBudWxsOwoJCQlyZXR1cm47CgkJfQoKCQlJU3RydWN0dXJlZFNlbGVjdGlvbiBzZWxlY3QgPSAoSVN0cnVjdHVyZWRTZWxlY3Rpb24pIHNlbDsKCQlJdGVyYXRvciBpdGVyYXRvciA9IHNlbGVjdC5pdGVyYXRvcigpOwoJCXNlbGVjdGlvbiA9IGl0ZXJhdG9yLm5leHQoKTsKCQlpZiAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7IC8vIG1vcmUgdGhhbiBvbmUgc2VsZWN0aW9uIChzaG91bGQgbmV2ZXIgaGFwcGVuKQoJCQlhY3Rpb24uc2V0RW5hYmxlZChmYWxzZSk7CgkJCXNlbGVjdGlvbiA9IG51bGw7CgkJCWdsb2JhbFNlbGVjdGlvbiA9IG51bGw7CgkJCXJldHVybjsKCQl9CgoJCWlmIChzZWxlY3Rpb24gIT0gZ2xvYmFsU2VsZWN0aW9uKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIlNlbGVjdGlvbjogIiArIHNlbGVjdGlvbik7CgkJCWlmIChzZWxlY3Rpb24gIT0gbnVsbCkJCgkJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJTZWxlY3Rpb24gdHlwZTogIiArIHNlbGVjdGlvbi5nZXRDbGFzcygpLmdldE5hbWUoKSk7CgkJCWdsb2JhbFNlbGVjdGlvbiA9IHNlbGVjdGlvbjsKCQkJZ2xvYmFsTGF1bmNoTW9kZSA9IG5ldyBIYXNoTWFwKCk7CgkJCWlmICghU2VydmVyUGx1Z2luLmhhc01vZHVsZUFydGlmYWN0KGdsb2JhbFNlbGVjdGlvbikpIHsKCQkJCWFjdGlvbi5zZXRFbmFibGVkKGZhbHNlKTsKCQkJCXJldHVybjsKCQkJfQoJCQkKCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiY2hlY2tpbmcgZm9yIG1vZHVsZSBhcnRpZmFjdCIpOwoJCQlJTW9kdWxlQXJ0aWZhY3QgbW9kdWxlQXJ0aWZhY3QgPSBTZXJ2ZXJQbHVnaW4uZ2V0TW9kdWxlQXJ0aWZhY3QoZ2xvYmFsU2VsZWN0aW9uKTsKCQkJSU1vZHVsZSBtb2R1bGUgPSBudWxsOwoJCQlpZiAobW9kdWxlQXJ0aWZhY3QgIT0gbnVsbCkKCQkJCW1vZHVsZSA9IG1vZHVsZUFydGlmYWN0LmdldE1vZHVsZSgpOwoJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJtb2R1bGVBcnRpZmFjdD0gIiArIG1vZHVsZUFydGlmYWN0ICsgIiwgbW9kdWxlPSAiICsgbW9kdWxlKTsKCQkJaWYgKG1vZHVsZSAhPSBudWxsKQoJCQkJZmluZEdsb2JhbExhdW5jaE1vZGVzKG1vZHVsZSk7CgkJCWVsc2UgewoJCQkJZ2xvYmFsTGF1bmNoTW9kZS5wdXQoSUxhdW5jaE1hbmFnZXIuUlVOX01PREUsIG5ldyBCb29sZWFuKHRydWUpKTsKCQkJCWdsb2JhbExhdW5jaE1vZGUucHV0KElMYXVuY2hNYW5hZ2VyLkRFQlVHX01PREUsIG5ldyBCb29sZWFuKHRydWUpKTsKCQkJCWdsb2JhbExhdW5jaE1vZGUucHV0KElMYXVuY2hNYW5hZ2VyLlBST0ZJTEVfTU9ERSwgbmV3IEJvb2xlYW4odHJ1ZSkpOwoJCQl9CgkJfQoKCQlhY3Rpb24uc2V0RW5hYmxlZChpc0VuYWJsZWQoKSk7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiPCBzZWxlY3Rpb25DaGFuZ2VkICIgKyAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSB0aW1lKSk7Cgl9CgkKCS8qKgoJICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZXJlIGlzIGEgc2VydmVyIGZhY3RvcnkgYXZhaWxhYmxlIGZvciB0aGUgZ2l2ZW4gbW9kdWxlCgkgKiBhbmQgdGhlIHZhcmlvdXMgc3RhcnQgbW9kZXMuCgkgKi8KCXByb3RlY3RlZCB2b2lkIGZpbmRHbG9iYWxMYXVuY2hNb2RlcyhJTW9kdWxlIG1vZHVsZSkgewoJCUlTZXJ2ZXJUeXBlW10gc2VydmVyVHlwZXMgPSBTZXJ2ZXJDb3JlLmdldFNlcnZlclR5cGVzKCk7CgkJaWYgKHNlcnZlclR5cGVzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBzZXJ2ZXJUeXBlcy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlJU2VydmVyVHlwZSB0eXBlID0gc2VydmVyVHlwZXNbaV07CgkJCQlpZiAoaXNWYWxpZFNlcnZlclR5cGUodHlwZSwgbW9kdWxlKSkgewoJCQkJCWZvciAoYnl0ZSBiID0gMDsgYiA8IGxhdW5jaE1vZGVzLmxlbmd0aDsgYisrKSB7CgkJCQkJCWlmICh0eXBlLnN1cHBvcnRzTGF1bmNoTW9kZShsYXVuY2hNb2Rlc1tiXSkpIHsKCQkJCQkJCWdsb2JhbExhdW5jaE1vZGUucHV0KGxhdW5jaE1vZGVzW2JdLCBuZXcgQm9vbGVhbih0cnVlKSk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHNlcnZlciB0eXBlIGNhbiBsYXVuY2ggdGhlIG1vZHVsZS4gCgkgKi8KCXByb3RlY3RlZCBib29sZWFuIGlzVmFsaWRTZXJ2ZXJUeXBlKElTZXJ2ZXJUeXBlIHR5cGUsIElNb2R1bGUgbW9kdWxlKSB7CgkJdHJ5IHsKCQkJSVJ1bnRpbWVUeXBlIHJ1bnRpbWVUeXBlID0gdHlwZS5nZXRSdW50aW1lVHlwZSgpOwoJCQlTZXJ2ZXJVdGlsLmlzU3VwcG9ydGVkTW9kdWxlKHJ1bnRpbWVUeXBlLmdldE1vZHVsZVR5cGVzKCksIG1vZHVsZS5nZXRNb2R1bGVUeXBlKCkpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJcmV0dXJuIHRydWU7Cgl9CgoJcHJvdGVjdGVkIGJvb2xlYW4gc3VwcG9ydHNMYXVuY2hNb2RlKElTZXJ2ZXIgc2VydmVyLCBTdHJpbmcgbGF1bmNoTW9kZSkgewoJCXJldHVybiBzZXJ2ZXIuZ2V0U2VydmVyVHlwZSgpLnN1cHBvcnRzTGF1bmNoTW9kZShsYXVuY2hNb2RlKTsKCX0KfQ==