LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA2LCAyMDA4IE9yYWNsZS4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlCiAqIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAsIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uCiAqIGFuZCBpcyBhdmFpbGFibGUgYXQgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwuCiAqIAogKiBDb250cmlidXRvcnM6CiAqICAgICBPcmFjbGUgLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS5qcHQuZGIuaW50ZXJuYWw7CgppbXBvcnQgamF2YS50ZXh0LkNvbGxhdG9yOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmRhdGF0b29scy5jb25uZWN0aXZpdHkuc3FtLmNvcmUuZGVmaW5pdGlvbi5EYXRhYmFzZURlZmluaXRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5kYXRhdG9vbHMuY29ubmVjdGl2aXR5LnNxbS5pbnRlcm5hbC5jb3JlLlJEQkNvcmVQbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS5qcHQuZGIuQ2F0YWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpwdC5kYi5EYXRhYmFzZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpwdC5kYi5EYXRhYmFzZU9iamVjdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmpwdC51dGlsaXR5LmludGVybmFsLkNvbGxlY3Rpb25Ub29sczsKaW1wb3J0IG9yZy5lY2xpcHNlLmpwdC51dGlsaXR5LmludGVybmFsLlN0cmluZ1Rvb2xzOwppbXBvcnQgb3JnLmVjbGlwc2UuanB0LnV0aWxpdHkuaW50ZXJuYWwuaXRlcmF0b3JzLkFycmF5SXRlcmF0b3I7CmltcG9ydCBvcmcuZWNsaXBzZS5qcHQudXRpbGl0eS5pbnRlcm5hbC5pdGVyYXRvcnMuVHJhbnNmb3JtYXRpb25JdGVyYXRvcjsKCi8qKgogKiBXcmFwIGEgRFRQIERhdGFiYXNlLgogKiAKICogQ2F0YWxvZ3MgdnMuIFNjaGVtYXRhOgogKiBUeXBpY2FsbHksIGlmIGEgRFRQIGRhdGFiYXNlIGRvZXMgbm90IHN1cHBvcnQgImNhdGFsb2dzIiwKICogby5lLmRhdGF0b29scy5tb2RlbGJhc2Uuc3FsLnNjaGVtYS5EYXRhYmFzZSNnZXRDYXRhbG9ncygpIHdpbGwgcmV0dXJuIGEKICogc2luZ2xlIGNhdGFsb2cgd2l0aG91dCBhIG5hbWUgKGFjdHVhbGx5LCBpdCdzIGFuIGVtcHR5IHN0cmluZykuIFRoaXMgY2F0YWxvZwogKiB3aWxsIGNvbnRhaW4gYWxsIHRoZSBkYXRhYmFzZSdzIHNjaGVtYXRhLiBXZSB0cnkgdG8gaWdub3JlIHRoaXMgY2F0YWxvZyBhbmQKICogcmV0dXJuIHRoZSBzY2hlbWF0YSBmcm9tIHRoZSBkYXRhYmFzZSBkaXJlY3RseS4gKE5vdGUgTXlTUUwgZG9lcyBub3Qgc2VlbQogKiB0byBiZSBjb25zaXN0ZW50IHdpdGggdGhpcyBwYXR0ZXJuLikKICogCiAqIE5vdGU6CiAqIFdlIHVzZSAibmFtZSIgd2hlbiBkZWFsaW5nIHdpdGggdGhlIHVubW9kaWZpZWQgbmFtZSBvZiBhIGRhdGFiYXNlIG9iamVjdAogKiBhcyBzdXBwbGllZCBieSB0aGUgZGF0YWJhc2UgaXRzZWxmIChpLmUuIGl0IGlzIG5vdCBkZWxpbWl0ZWQgYW5kIGl0IGlzIGFsd2F5cwogKiBjYXNlLXNlbnNpdGl2ZSkuCiAqIFdlIHVzZSAiaWRlbnRpZmllciIgd2hlbiBkZWFsaW5nIHdpdGggYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBkYXRhYmFzZQogKiBvYmplY3QgbmFtZSAoaS5lLiBpdCBtYXkgYmUgZGVsaW1pdGVkIGFuZCwgZGVwZW5kaW5nIG9uIHRoZSB2ZW5kb3IsIGl0IG1heQogKiBiZSBjYXNlLWluc2Vuc2l0aXZlKS4KICovCmZpbmFsIGNsYXNzIERUUERhdGFiYXNlV3JhcHBlcgoJZXh0ZW5kcyBEVFBTY2hlbWFDb250YWluZXJXcmFwcGVyCglpbXBsZW1lbnRzIERhdGFiYXNlCnsKCS8vIHRoZSB3cmFwcGVkIERUUCBkYXRhYmFzZQoJcHJpdmF0ZSBmaW5hbCBvcmcuZWNsaXBzZS5kYXRhdG9vbHMubW9kZWxiYXNlLnNxbC5zY2hlbWEuRGF0YWJhc2UgZHRwRGF0YWJhc2U7CgoJLy8gbGF6eS1pbml0aWFsaXplZCwgc29ydGVkCglwcml2YXRlIERUUENhdGFsb2dXcmFwcGVyW10gY2F0YWxvZ3M7CgoJLy8gbGF6eS1pbml0aWFsaXplZCAtIGJ1dCBpdCBjYW4gYmUgJ251bGwnIHNvIHdlIHVzZSBhIGZsYWcKCXByaXZhdGUgRFRQQ2F0YWxvZ1dyYXBwZXIgZGVmYXVsdENhdGFsb2c7Cglwcml2YXRlIGJvb2xlYW4gZGVmYXVsdENhdGFsb2dDYWxjdWxhdGVkID0gZmFsc2U7CgoKCXByaXZhdGUgc3RhdGljIGZpbmFsIERUUENhdGFsb2dXcmFwcGVyW10gRU1QVFlfQ0FUQUxPR1MgPSBuZXcgRFRQQ2F0YWxvZ1dyYXBwZXJbMF07CgoKCS8vICoqKioqKioqKiogY29uc3RydWN0b3IgKioqKioqKioqKgoKCURUUERhdGFiYXNlV3JhcHBlcihEVFBDb25uZWN0aW9uUHJvZmlsZVdyYXBwZXIgY29ubmVjdGlvblByb2ZpbGUsIG9yZy5lY2xpcHNlLmRhdGF0b29scy5tb2RlbGJhc2Uuc3FsLnNjaGVtYS5EYXRhYmFzZSBkdHBEYXRhYmFzZSkgewoJCXN1cGVyKGNvbm5lY3Rpb25Qcm9maWxlLCBkdHBEYXRhYmFzZSk7CgkJdGhpcy5kdHBEYXRhYmFzZSA9IGR0cERhdGFiYXNlOwoJfQoKCgkvLyAqKioqKioqKioqIERUUFdyYXBwZXIgaW1wbGVtZW50YXRpb24gKioqKioqKioqKgoKCS8qIFRPRE8KCSAqIFdlIG1pZ2h0IHdhbnQgdG8gbGlzdGVuIHRvIHRoZSAidmlydHVhbCIgY2F0YWxvZzsgYnV0IHRoYXQncyBwcm9iYWJseQoJICogbm90IG5lY2Vzc2FyeSBzaW5jZSB0aGVyZSBpcyBub3QgZWFzeSB3YXkgZm9yIHRoZSB1c2VyIHRvIHJlZnJlc2ggaXQKCSAqIChpLmUuIGl0IGlzIG5vdCBkaXNwbGF5ZWQgaW4gdGhlIERUUCBVSSkuCgkgKi8KCUBPdmVycmlkZQoJc3luY2hyb25pemVkIHZvaWQgY2F0YWxvZ09iamVjdENoYW5nZWQoKSB7CgkJc3VwZXIuY2F0YWxvZ09iamVjdENoYW5nZWQoKTsKCQl0aGlzLmdldENvbm5lY3Rpb25Qcm9maWxlKCkuZGF0YWJhc2VDaGFuZ2VkKHRoaXMpOwoJfQoKCUBPdmVycmlkZQoJcHVibGljIERUUERhdGFiYXNlV3JhcHBlciBnZXREYXRhYmFzZSgpIHsKCQlyZXR1cm4gdGhpczsKCX0KCgoJLy8gKioqKioqKioqKiBEVFBTY2hlbWFDb250YWluZXJXcmFwcGVyIGltcGxlbWVudGF0aW9uICoqKioqKioqKioKCglAT3ZlcnJpZGUKCUBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQoJTGlzdDxvcmcuZWNsaXBzZS5kYXRhdG9vbHMubW9kZWxiYXNlLnNxbC5zY2hlbWEuU2NoZW1hPiBnZXREVFBTY2hlbWF0YSgpIHsKCQlMaXN0PG9yZy5lY2xpcHNlLmRhdGF0b29scy5tb2RlbGJhc2Uuc3FsLnNjaGVtYS5DYXRhbG9nPiBkdHBDYXRhbG9ncyA9IHRoaXMuZ2V0RFRQQ2F0YWxvZ3MoKTsKCQkvLyBpZiB0aGVyZSBhcmUgbm8gY2F0YWxvZ3MsIHRoZSBkYXRhYmFzZSBtdXN0IGhvbGQgdGhlIHNjaGVtYXRhIGRpcmVjdGx5CgkJaWYgKChkdHBDYXRhbG9ncyA9PSBudWxsKSB8fCBkdHBDYXRhbG9ncy5pc0VtcHR5KCkpIHsKCQkJcmV0dXJuIHRoaXMuZHRwRGF0YWJhc2UuZ2V0U2NoZW1hcygpOwoJCX0KCQlvcmcuZWNsaXBzZS5kYXRhdG9vbHMubW9kZWxiYXNlLnNxbC5zY2hlbWEuQ2F0YWxvZyB2aXJ0dWFsQ2F0YWxvZyA9IGdldFZpcnR1YWxDYXRhbG9nKGR0cENhdGFsb2dzKTsKCQlyZXR1cm4gKHZpcnR1YWxDYXRhbG9nICE9IG51bGwpID8gdmlydHVhbENhdGFsb2cuZ2V0U2NoZW1hcygpIDogQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7Cgl9CgoJQE92ZXJyaWRlCglEVFBTY2hlbWFXcmFwcGVyIGdldFNjaGVtYShvcmcuZWNsaXBzZS5kYXRhdG9vbHMubW9kZWxiYXNlLnNxbC5zY2hlbWEuU2NoZW1hIGR0cFNjaGVtYSkgewoJCXJldHVybiB0aGlzLmdldFNjaGVtYV8oZHRwU2NoZW1hKTsKCX0KCglAT3ZlcnJpZGUKCURUUFRhYmxlV3JhcHBlciBnZXRUYWJsZShvcmcuZWNsaXBzZS5kYXRhdG9vbHMubW9kZWxiYXNlLnNxbC50YWJsZXMuVGFibGUgZHRwVGFibGUpIHsKCQlyZXR1cm4gdGhpcy5nZXRUYWJsZV8oZHRwVGFibGUpOwoJfQoKCUBPdmVycmlkZQoJRFRQQ29sdW1uV3JhcHBlciBnZXRDb2x1bW4ob3JnLmVjbGlwc2UuZGF0YXRvb2xzLm1vZGVsYmFzZS5zcWwudGFibGVzLkNvbHVtbiBkdHBDb2x1bW4pIHsKCQlyZXR1cm4gdGhpcy5nZXRDb2x1bW5fKGR0cENvbHVtbik7Cgl9CgoKCS8vICoqKioqKioqKiogRGF0YWJhc2VPYmplY3QgaW1wbGVtZW50YXRpb24gKioqKioqKioqKgoKCXB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKCQlyZXR1cm4gdGhpcy5kdHBEYXRhYmFzZS5nZXROYW1lKCk7Cgl9CgoKCS8vICoqKioqKioqKiogRGF0YWJhc2UgaW1wbGVtZW50YXRpb24gKioqKioqKioqKgoKCXB1YmxpYyBTdHJpbmcgZ2V0VmVuZG9yTmFtZSgpIHsKCQlyZXR1cm4gdGhpcy5kdHBEYXRhYmFzZS5nZXRWZW5kb3IoKTsKCX0KCglwdWJsaWMgU3RyaW5nIGdldFZlcnNpb24oKSB7CgkJcmV0dXJuIHRoaXMuZHRwRGF0YWJhc2UuZ2V0VmVyc2lvbigpOwoJfQoKCS8vIG92ZXJyaWRlIHRvIG1ha2UgbWV0aG9kIHB1YmxpYyBzaW5jZSBpdCdzIGluIHRoZSBEYXRhYmFzZSBpbnRlcmZhY2UKCUBPdmVycmlkZQoJcHVibGljIDxUIGV4dGVuZHMgRGF0YWJhc2VPYmplY3Q+IFQgc2VsZWN0RGF0YWJhc2VPYmplY3RGb3JJZGVudGlmaWVyKFRbXSBkYXRhYmFzZU9iamVjdHMsIFN0cmluZyBpZGVudGlmaWVyKSB7CgkJcmV0dXJuIHN1cGVyLnNlbGVjdERhdGFiYXNlT2JqZWN0Rm9ySWRlbnRpZmllcihkYXRhYmFzZU9iamVjdHMsIGlkZW50aWZpZXIpOwoJfQoKCS8vICoqKioqIGNhdGFsb2dzCgoJcHVibGljIGJvb2xlYW4gc3VwcG9ydHNDYXRhbG9ncygpIHsKCQlyZXR1cm4gc3VwcG9ydHNDYXRhbG9ncyh0aGlzLmdldERUUENhdGFsb2dzKCkpOwoJfQoKCXByaXZhdGUgc3RhdGljIGJvb2xlYW4gc3VwcG9ydHNDYXRhbG9ncyhMaXN0PG9yZy5lY2xpcHNlLmRhdGF0b29scy5tb2RlbGJhc2Uuc3FsLnNjaGVtYS5DYXRhbG9nPiBkdHBDYXRhbG9ncykgewoJCS8vIGlmIHRoZXJlIGFyZSBubyBjYXRhbG9ncywgdGhleSBtdXN0IG5vdCBiZSBzdXBwb3J0ZWQKCQlpZiAoKGR0cENhdGFsb2dzID09IG51bGwpIHx8IGR0cENhdGFsb2dzLmlzRW1wdHkoKSkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvLyBpZiB3ZSBvbmx5IGhhdmUgYSBzaW5nbGUgY2F0YWxvZyB3aXRoIGFuIGVtcHR5IG5hbWUsCgkJLy8gdGhleSBhcmUgbm90IHJlYWxseSBzdXBwb3J0ZWQgZWl0aGVyLi4uCgkJcmV0dXJuICEgbGlzdENvbnRhaW5zT25seUFWaXJ0dWFsQ2F0YWxvZyhkdHBDYXRhbG9ncyk7Cgl9CgoJLyoqCgkgKiBwcmUtY29uZGl0aW9uOiAnZHRwQ2F0YWxvZ3MnIGlzIG5vdCBudWxsCgkgKi8KCXByaXZhdGUgc3RhdGljIGJvb2xlYW4gbGlzdENvbnRhaW5zT25seUFWaXJ0dWFsQ2F0YWxvZyhMaXN0PG9yZy5lY2xpcHNlLmRhdGF0b29scy5tb2RlbGJhc2Uuc3FsLnNjaGVtYS5DYXRhbG9nPiBkdHBDYXRhbG9ncykgewoJCXJldHVybiBnZXRWaXJ0dWFsQ2F0YWxvZyhkdHBDYXRhbG9ncykgIT0gbnVsbDsKCX0KCgkvKioKCSAqIHByZS1jb25kaXRpb246ICdkdHBDYXRhbG9ncycgaXMgbm90IG51bGwKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgb3JnLmVjbGlwc2UuZGF0YXRvb2xzLm1vZGVsYmFzZS5zcWwuc2NoZW1hLkNhdGFsb2cgZ2V0VmlydHVhbENhdGFsb2coTGlzdDxvcmcuZWNsaXBzZS5kYXRhdG9vbHMubW9kZWxiYXNlLnNxbC5zY2hlbWEuQ2F0YWxvZz4gZHRwQ2F0YWxvZ3MpIHsKCQlpZiAoZHRwQ2F0YWxvZ3Muc2l6ZSgpID09IDEpIHsKCQkJb3JnLmVjbGlwc2UuZGF0YXRvb2xzLm1vZGVsYmFzZS5zcWwuc2NoZW1hLkNhdGFsb2cgZHRwQ2F0YWxvZyA9IGR0cENhdGFsb2dzLmdldCgwKTsKCQkJaWYgKGR0cENhdGFsb2cuZ2V0TmFtZSgpLmVxdWFscygiIikpIHsgLy8kTk9OLU5MUy0xJAoJCQkJcmV0dXJuIGR0cENhdGFsb2c7CgkJCX0KCQl9CgkJcmV0dXJuIG51bGw7Cgl9CgoJcHVibGljIEl0ZXJhdG9yPENhdGFsb2c+IGNhdGFsb2dzKCkgewoJCXJldHVybiBuZXcgQXJyYXlJdGVyYXRvcjxDYXRhbG9nPih0aGlzLmdldENhdGFsb2dzKCkpOwoJfQoKCXByaXZhdGUgSXRlcmF0b3I8RFRQQ2F0YWxvZ1dyYXBwZXI+IGNhdGFsb2dXcmFwcGVycygpIHsKCQlyZXR1cm4gbmV3IEFycmF5SXRlcmF0b3I8RFRQQ2F0YWxvZ1dyYXBwZXI+KHRoaXMuZ2V0Q2F0YWxvZ3MoKSk7Cgl9CgoJcHJpdmF0ZSBzeW5jaHJvbml6ZWQgRFRQQ2F0YWxvZ1dyYXBwZXJbXSBnZXRDYXRhbG9ncygpIHsKCQlpZiAodGhpcy5jYXRhbG9ncyA9PSBudWxsKSB7CgkJCXRoaXMuY2F0YWxvZ3MgPSB0aGlzLmJ1aWxkQ2F0YWxvZ3MoKTsKCQl9CgkJcmV0dXJuIHRoaXMuY2F0YWxvZ3M7Cgl9CgoJcHJpdmF0ZSBEVFBDYXRhbG9nV3JhcHBlcltdIGJ1aWxkQ2F0YWxvZ3MoKSB7CgkJTGlzdDxvcmcuZWNsaXBzZS5kYXRhdG9vbHMubW9kZWxiYXNlLnNxbC5zY2hlbWEuQ2F0YWxvZz4gZHRwQ2F0YWxvZ3MgPSB0aGlzLmdldERUUENhdGFsb2dzKCk7CgkJaWYgKCAhIHN1cHBvcnRzQ2F0YWxvZ3MoZHRwQ2F0YWxvZ3MpKSB7CgkJCXJldHVybiBFTVBUWV9DQVRBTE9HUzsKCQl9CgkJRFRQQ2F0YWxvZ1dyYXBwZXJbXSByZXN1bHQgPSBuZXcgRFRQQ2F0YWxvZ1dyYXBwZXJbZHRwQ2F0YWxvZ3Muc2l6ZSgpXTsKCQlmb3IgKGludCBpID0gcmVzdWx0Lmxlbmd0aDsgaS0tID4gMDspIHsKCQkJcmVzdWx0W2ldID0gbmV3IERUUENhdGFsb2dXcmFwcGVyKHRoaXMsIGR0cENhdGFsb2dzLmdldChpKSk7CgkJfQoJCXJldHVybiBDb2xsZWN0aW9uVG9vbHMuc29ydChyZXN1bHQpOwoJfQoKCS8vIG1pbmltaXplIHNjb3BlIG9mIHN1cHByZXNzZWQgd2FybmluZ3MKCUBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQoJcHJpdmF0ZSBMaXN0PG9yZy5lY2xpcHNlLmRhdGF0b29scy5tb2RlbGJhc2Uuc3FsLnNjaGVtYS5DYXRhbG9nPiBnZXREVFBDYXRhbG9ncygpIHsKCQlyZXR1cm4gdGhpcy5kdHBEYXRhYmFzZS5nZXRDYXRhbG9ncygpOwoJfQoKCXB1YmxpYyBpbnQgY2F0YWxvZ3NTaXplKCkgewoJCXJldHVybiB0aGlzLmdldENhdGFsb2dzKCkubGVuZ3RoOwoJfQoKCS8qKgoJICogcmV0dXJuIHRoZSBjYXRhbG9nIGZvciB0aGUgc3BlY2lmaWVkIERUUCBjYXRhbG9nCgkgKi8KCURUUENhdGFsb2dXcmFwcGVyIGdldENhdGFsb2cob3JnLmVjbGlwc2UuZGF0YXRvb2xzLm1vZGVsYmFzZS5zcWwuc2NoZW1hLkNhdGFsb2cgZHRwQ2F0YWxvZykgewoJCWZvciAoRFRQQ2F0YWxvZ1dyYXBwZXIgY2F0YWxvZyA6IHRoaXMuZ2V0Q2F0YWxvZ3MoKSkgewoJCQlpZiAoY2F0YWxvZy53cmFwcyhkdHBDYXRhbG9nKSkgewoJCQkJcmV0dXJuIGNhdGFsb2c7CgkJCX0KCQl9CgkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaW52YWxpZCBEVFAgY2F0YWxvZzogIiArIGR0cENhdGFsb2cpOyAgLy8kTk9OLU5MUy0xJAoJfQoKCXB1YmxpYyBEVFBDYXRhbG9nV3JhcHBlciBnZXRDYXRhbG9nTmFtZWQoU3RyaW5nIG5hbWUpIHsKCQlyZXR1cm4gdGhpcy5zZWxlY3REYXRhYmFzZU9iamVjdE5hbWVkKHRoaXMuZ2V0Q2F0YWxvZ3MoKSwgbmFtZSk7Cgl9CgoJcHVibGljIEl0ZXJhdG9yPFN0cmluZz4gc29ydGVkQ2F0YWxvZ0lkZW50aWZpZXJzKCkgewoJCS8vIHRoZSBjYXRhbG9ncyBhcmUgYWxyZWFkeSBzb3J0ZWQKCQlyZXR1cm4gbmV3IFRyYW5zZm9ybWF0aW9uSXRlcmF0b3I8RFRQQ2F0YWxvZ1dyYXBwZXIsIFN0cmluZz4odGhpcy5jYXRhbG9nV3JhcHBlcnMoKSkgewoJCQlAT3ZlcnJpZGUKCQkJcHJvdGVjdGVkIFN0cmluZyB0cmFuc2Zvcm0oRFRQQ2F0YWxvZ1dyYXBwZXIgbmV4dCkgewoJCQkJIHJldHVybiBuZXh0LmdldElkZW50aWZpZXIoKTsKCQkJfQoJCX07Cgl9CgoJcHVibGljIERUUENhdGFsb2dXcmFwcGVyIGdldENhdGFsb2dGb3JJZGVudGlmaWVyKFN0cmluZyBpZGVudGlmaWVyKSB7CgkJcmV0dXJuIHRoaXMuc2VsZWN0RGF0YWJhc2VPYmplY3RGb3JJZGVudGlmaWVyKHRoaXMuZ2V0Q2F0YWxvZ3MoKSwgaWRlbnRpZmllcik7Cgl9CgoJcHVibGljIHN5bmNocm9uaXplZCBEVFBDYXRhbG9nV3JhcHBlciBnZXREZWZhdWx0Q2F0YWxvZygpIHsKCQlpZiAoICEgdGhpcy5kZWZhdWx0Q2F0YWxvZ0NhbGN1bGF0ZWQpIHsKCQkJdGhpcy5kZWZhdWx0Q2F0YWxvZ0NhbGN1bGF0ZWQgPSB0cnVlOwoJCQl0aGlzLmRlZmF1bHRDYXRhbG9nID0gdGhpcy5idWlsZERlZmF1bHRDYXRhbG9nKCk7CgkJfQoJCXJldHVybiB0aGlzLmRlZmF1bHRDYXRhbG9nOwoJfQoKCXByaXZhdGUgRFRQQ2F0YWxvZ1dyYXBwZXIgYnVpbGREZWZhdWx0Q2F0YWxvZygpIHsKCQlyZXR1cm4gdGhpcy5zdXBwb3J0c0NhdGFsb2dzKCkgPyB0aGlzLmdldFZlbmRvcigpLmdldERlZmF1bHRDYXRhbG9nKHRoaXMpIDogbnVsbDsKCX0KCgkvLyAqKioqKiBzY2hlbWF0YQoKCUBPdmVycmlkZQoJc3luY2hyb25pemVkIERUUFNjaGVtYVdyYXBwZXJbXSBnZXRTY2hlbWF0YSgpIHsKCQlEVFBDYXRhbG9nV3JhcHBlciBjYXQgPSB0aGlzLmdldERlZmF1bHRDYXRhbG9nKCk7CgkJcmV0dXJuIChjYXQgIT0gbnVsbCkgPyBjYXQuZ2V0U2NoZW1hdGEoKSA6IHN1cGVyLmdldFNjaGVtYXRhKCk7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gdGhlIHNwZWNpZmllZCBzY2hlbWEgY29udGFpbmVyJ3MgZGVmYXVsdCBzY2hlbWEuCgkgKi8KCURUUFNjaGVtYVdyYXBwZXIgZ2V0RGVmYXVsdFNjaGVtYShEVFBTY2hlbWFDb250YWluZXJXcmFwcGVyIHNjaGVtYUNvbnRhaW5lcikgewoJCXJldHVybiB0aGlzLmdldFZlbmRvcigpLmdldERlZmF1bHRTY2hlbWEoc2NoZW1hQ29udGFpbmVyKTsKCX0KCgoJLy8gKioqKioqKioqKiBuYW1lcyB2cy4gaWRlbnRpZmllcnMgKioqKioqKioqKgoKCS8qKgoJICogQ29udmVydCB0aGUgc3BlY2lmaWVkIG5hbWUgdG8gYW4gaWRlbnRpZmllci4gUmV0dXJuIG51bGwgaWYgdGhlIHJlc3VsdGluZwoJICogaWRlbnRpZmllciBtYXRjaGVzIHRoZSBzcGVjaWZpZWQgZGVmYXVsdCBuYW1lLgoJICovCglTdHJpbmcgY29udmVydE5hbWVUb0lkZW50aWZpZXIoU3RyaW5nIG5hbWUsIFN0cmluZyBkZWZhdWx0TmFtZSkgewoJCXJldHVybiB0aGlzLmdldFZlbmRvcigpLmNvbnZlcnROYW1lVG9JZGVudGlmaWVyKG5hbWUsIGRlZmF1bHROYW1lKTsKCX0KCgkvKioKCSAqIENvbnZlcnQgdGhlIHNwZWNpZmllZCBuYW1lIHRvIGFuIGlkZW50aWZpZXIuCgkgKi8KCXB1YmxpYyBTdHJpbmcgY29udmVydE5hbWVUb0lkZW50aWZpZXIoU3RyaW5nIG5hbWUpIHsKCQlyZXR1cm4gdGhpcy5nZXRWZW5kb3IoKS5jb252ZXJ0TmFtZVRvSWRlbnRpZmllcihuYW1lKTsKCX0KCgkvKioKCSAqIFJldHVybiB0aGUgZGF0YWJhc2Ugb2JqZWN0IGlkZW50aWZpZWQgYnkgdGhlIHNwZWNpZmllZCBpZGVudGlmaWVyLiBJZgoJICogdGhlIGlkZW50aWZpZXIgaXMgImRlbGltaXRlZCIgKHR5cGljYWxseSB3aXRoIGRvdWJsZS1xdW90ZXMpLCBpdCB3aWxsIGJlCgkgKiB1c2VkIHdpdGhvdXQgYW55IGZvbGRpbmcuIElmIHRoZSBuYW1lIGlzICJub3JtYWwiIChpLmUuIG5vdCBkZWxpbWl0ZWQpLAoJICogaXQgd2lsbCBiZSBmb2xkZWQgdG8gdGhlIGFwcHJvcHJpYXRlIGNhc2UgKHR5cGljYWxseSB1cHBlcmNhc2UpLgoJICogCgkgKiBTaW5jZSB0aGUgZGF0YWJhc2UgaGFzIHRoZSBhcHByb3ByaWF0ZSBzdGF0ZSB0byBjb21wYXJlIGlkZW50aWZpZXJzIGFuZAoJICogbmFtZXMsIHRoZSBjb25uZWN0aW9uIHByb2ZpbGUgZGVsZWdhdGVzIHRvIGhlcmUgd2hlbiB1c2luZyB0aGUgZGVmYXVsdAoJICogImRhdGFiYXNlIGZpbmRlciIuCgkgKi8KCTxUIGV4dGVuZHMgRGF0YWJhc2VPYmplY3Q+IFQgc2VsZWN0RGF0YWJhc2VPYmplY3RGb3JJZGVudGlmaWVyXyhUW10gZGF0YWJhc2VPYmplY3RzLCBTdHJpbmcgaWRlbnRpZmllcikgewoJCXJldHVybiB0aGlzLnNlbGVjdERhdGFiYXNlT2JqZWN0TmFtZWQoZGF0YWJhc2VPYmplY3RzLCB0aGlzLmNvbnZlcnRJZGVudGlmaWVyVG9OYW1lKGlkZW50aWZpZXIpKTsKCX0KCgkvKioKCSAqIENvbnZlcnQgdGhlIHNwZWNpZmllZCBpZGVudGlmaWVyIHRvIGEgbmFtZS4KCSAqLwoJU3RyaW5nIGNvbnZlcnRJZGVudGlmaWVyVG9OYW1lKFN0cmluZyBpZGVudGlmaWVyKSB7CgkJcmV0dXJuIHRoaXMuZ2V0VmVuZG9yKCkuY29udmVydElkZW50aWZpZXJUb05hbWUoaWRlbnRpZmllcik7Cgl9CgoKCS8vICoqKioqKioqKiogQ29tcGFyYWJsZSBpbXBsZW1lbnRhdGlvbiAqKioqKioqKioqCgoJcHVibGljIGludCBjb21wYXJlVG8oRGF0YWJhc2UgZGF0YWJhc2UpIHsKCQlyZXR1cm4gQ29sbGF0b3IuZ2V0SW5zdGFuY2UoKS5jb21wYXJlKHRoaXMuZ2V0TmFtZSgpLCBkYXRhYmFzZS5nZXROYW1lKCkpOwoJfQoKCgkvLyAqKioqKioqKioqIGludGVybmFsIG1ldGhvZHMgKioqKioqKioqKgoKCURhdGFiYXNlRGVmaW5pdGlvbiBnZXREVFBEZWZpbml0aW9uKCkgewoJCXJldHVybiBSREJDb3JlUGx1Z2luLmdldERlZmF1bHQoKS5nZXREYXRhYmFzZURlZmluaXRpb25SZWdpc3RyeSgpLmdldERlZmluaXRpb24odGhpcy5kdHBEYXRhYmFzZSk7Cgl9CgoJcHJpdmF0ZSBWZW5kb3IgZ2V0VmVuZG9yKCkgewoJCXJldHVybiBnZXRWZW5kb3IodGhpcy5nZXRWZW5kb3JOYW1lKCkpOwoJfQoKCgkvLyAqKioqKioqKioqIGxpc3RlbmluZyAqKioqKioqKioqCgoJQE92ZXJyaWRlCglzeW5jaHJvbml6ZWQgdm9pZCBzdGFydExpc3RlbmluZygpIHsKCQlpZiAodGhpcy5jYXRhbG9ncyAhPSBudWxsKSB7CgkJCXRoaXMuc3RhcnRDYXRhbG9ncygpOwoJCX0KCQlzdXBlci5zdGFydExpc3RlbmluZygpOwoJfQoKCXByaXZhdGUgdm9pZCBzdGFydENhdGFsb2dzKCkgewoJCWZvciAoRFRQQ2F0YWxvZ1dyYXBwZXIgY2F0YWxvZyA6IHRoaXMuY2F0YWxvZ3MpIHsKCQkJY2F0YWxvZy5zdGFydExpc3RlbmluZygpOwoJCX0KCX0KCglAT3ZlcnJpZGUKCXN5bmNocm9uaXplZCB2b2lkIHN0b3BMaXN0ZW5pbmcoKSB7CgkJaWYgKHRoaXMuY2F0YWxvZ3MgIT0gbnVsbCkgewoJCQl0aGlzLnN0b3BDYXRhbG9ncygpOwoJCX0KCQlzdXBlci5zdG9wTGlzdGVuaW5nKCk7Cgl9CgoJcHJpdmF0ZSB2b2lkIHN0b3BDYXRhbG9ncygpIHsKCQlmb3IgKERUUENhdGFsb2dXcmFwcGVyIGNhdGFsb2cgOiB0aGlzLmNhdGFsb2dzKSB7CgkJCWNhdGFsb2cuc3RvcExpc3RlbmluZygpOwoJCX0KCX0KCgoJLy8gKioqKioqKioqKiBjbGVhciAqKioqKioqKioqCgoJQE92ZXJyaWRlCgl2b2lkIGNsZWFyKCkgewoJCXRoaXMuZGVmYXVsdENhdGFsb2dDYWxjdWxhdGVkID0gZmFsc2U7CgkJdGhpcy5kZWZhdWx0Q2F0YWxvZyA9IG51bGw7CgkJaWYgKHRoaXMuY2F0YWxvZ3MgIT0gbnVsbCkgewoJCQl0aGlzLmNsZWFyQ2F0YWxvZ3MoKTsKCQl9CgkJc3VwZXIuY2xlYXIoKTsKCX0KCglwcml2YXRlIHZvaWQgY2xlYXJDYXRhbG9ncygpIHsKCQl0aGlzLnN0b3BDYXRhbG9ncygpOwoJCWZvciAoRFRQQ2F0YWxvZ1dyYXBwZXIgY2F0YWxvZyA6IHRoaXMuY2F0YWxvZ3MpIHsKCQkJY2F0YWxvZy5jbGVhcigpOwoJCX0KCQl0aGlzLmNhdGFsb2dzID0gbnVsbDsKCX0KCgoJLy8gKioqKioqKioqKiB2ZW5kb3JzICoqKioqKioqKioKCglwcml2YXRlIHN0YXRpYyBWZW5kb3IgZ2V0VmVuZG9yKFN0cmluZyBuYW1lKSB7CgkJVmVuZG9yIHZlbmRvciA9IGdldFZlbmRvcnMoKS5nZXQobmFtZSk7CgkJcmV0dXJuICh2ZW5kb3IgIT0gbnVsbCkgPyB2ZW5kb3IgOiBEZWZhdWx0LklOU1RBTkNFOwoJfQoKCS8qKgoJICoga2V5ZWQgYnkgdmVuZG9yIG5hbWUKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgSGFzaE1hcDxTdHJpbmcsIFZlbmRvcj4gVmVuZG9yczsKCglwcml2YXRlIHN0YXRpYyBzeW5jaHJvbml6ZWQgSGFzaE1hcDxTdHJpbmcsIFZlbmRvcj4gZ2V0VmVuZG9ycygpIHsKCQlpZiAoVmVuZG9ycyA9PSBudWxsKSB7CgkJCVZlbmRvcnMgPSBidWlsZFZlbmRvcnMoKTsKCQl9CgkJcmV0dXJuIFZlbmRvcnM7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgSGFzaE1hcDxTdHJpbmcsIFZlbmRvcj4gYnVpbGRWZW5kb3JzKCkgewoJCUhhc2hNYXA8U3RyaW5nLCBWZW5kb3I+IG1hcCA9IG5ldyBIYXNoTWFwPFN0cmluZywgVmVuZG9yPigyMCk7CgkJcHV0VmVuZG9yKG1hcCwgRGVyYnkuSU5TVEFOQ0UpOwoJCXB1dFZlbmRvcihtYXAsIEhTUUxEQi5JTlNUQU5DRSk7CgkJcHV0VmVuZG9yKG1hcCwgREIyLlVEQik7CgkJcHV0VmVuZG9yKG1hcCwgREIyLlVEQl9JX1NFUklFUyk7CgkJcHV0VmVuZG9yKG1hcCwgREIyLlVEQl9aX1NFUklFUyk7CgkJcHV0VmVuZG9yKG1hcCwgSW5mb3JtaXguSU5TVEFOQ0UpOwoJCXB1dFZlbmRvcihtYXAsIFNRTFNlcnZlci5JTlNUQU5DRSk7CgkJcHV0VmVuZG9yKG1hcCwgTXlTUUwuSU5TVEFOQ0UpOwoJCXB1dFZlbmRvcihtYXAsIE9yYWNsZS5JTlNUQU5DRSk7CgkJcHV0VmVuZG9yKG1hcCwgUG9zdGdyZXMuSU5TVEFOQ0UpOwoJCXB1dFZlbmRvcihtYXAsIE1heERCLklOU1RBTkNFKTsKCQlwdXRWZW5kb3IobWFwLCBTeWJhc2UuQVNBKTsKCQlwdXRWZW5kb3IobWFwLCBTeWJhc2UuQVNFKTsKCQlyZXR1cm4gbWFwOwoJfQoKCXByaXZhdGUgc3RhdGljIHZvaWQgcHV0VmVuZG9yKEhhc2hNYXA8U3RyaW5nLCBWZW5kb3I+IG1hcCwgVmVuZG9yIHZlbmRvcikgewoJCVN0cmluZyBuYW1lID0gdmVuZG9yLmdldE5hbWUoKTsKCQlpZiAobWFwLnB1dChuYW1lLCB2ZW5kb3IpICE9IG51bGwpIHsKCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRHVwbGljYXRlIHZlbmRvcjogIiArIG5hbWUpOyAvLyROT04tTkxTLTEkCgkJfQoJfQoKCgkvLyAqKioqKioqKioqIHZlbmRvciBjbGFzc2VzICoqKioqKioqKioKCgkvKioKCSAqIERlbGVnYXRlIHZlbmRvci1zcGVjaWZpYyBiZWhhdmlvciB0byBpbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBjbGFzcyIKCSAqICAgLSBkZWZhdWx0IGNhdGFsb2cgYW5kIHNjaGVtYQoJICogICAtIGNvbnZlcnRpbmcgbmFtZXMgdG8gaWRlbnRpZmllcnMgYW5kIHZpY2UtdmVyc2EKCSAqIAoJICogTm90ZToKCSAqIFdlIHVzZSAibmFtZSIgd2hlbiBkZWFsaW5nIHdpdGggdGhlIHVubW9kaWZpZWQgbmFtZSBvZiBhIGRhdGFiYXNlIG9iamVjdAoJICogYXMgc3VwcGxpZWQgYnkgdGhlIGRhdGFiYXNlIGl0c2VsZiAoaS5lLiBpdCBpcyBub3QgZGVsaW1pdGVkIGFuZCBpdCBpcyBhbHdheXMKCSAqIGNhc2Utc2Vuc2l0aXZlKS4KCSAqIFdlIHVzZSAiaWRlbnRpZmllciIgd2hlbiBkZWFsaW5nIHdpdGggYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBkYXRhYmFzZQoJICogb2JqZWN0IG5hbWUgKGkuZS4gaXQgbWF5IGJlIGRlbGltaXRlZCBhbmQsIGRlcGVuZGluZyBvbiB0aGUgdmVuZG9yLCBpdCBtYXkKCSAqIGJlIGNhc2UtaW5zZW5zaXRpdmUpLgoJICovCglwcml2YXRlIGFic3RyYWN0IHN0YXRpYyBjbGFzcyBWZW5kb3IgewoKCQlWZW5kb3IoKSB7CgkJCXN1cGVyKCk7CgkJfQoKCQkvKioKCQkgKiBSZXR1cm4gdGhlIHZlbmRvcidzIG5hbWUuIFRoaXMgbXVzdCBtYXRjaCB0aGUgbmFtZSBzcGVjaWZpZWQgYnkgdGhlCgkJICogRFRQIGNvbm5lY3Rpb24gcHJvZmlsZS4KCQkgKi8KCQlhYnN0cmFjdCBTdHJpbmcgZ2V0TmFtZSgpOwoKCQkvKioKCQkgKiBUaGUgU1FMIHNwZWMgc2F5cyBhICJub3JtYWwiIChub24tZGVsaW1pdGVkKSBpZGVudGlmaWVyIHNob3VsZCBiZQoJCSAqIGZvbGRlZCB0byB1cHBlcmNhc2U7IGJ1dCBzb21lIGRhdGFiYXNlcyBkbyBvdGhlcndpc2UgKGUuZy4gU3liYXNlKS4KCQkgKi8KCQlGb2xkZXIgZ2V0Rm9sZGVyKCkgewoJCQlyZXR1cm4gRm9sZGVyLlVQUEVSOwoJCX0KCgoJCS8vICoqKioqKioqKiogZGVmYXVsdCBjYXRhbG9nIGFuZCBzY2hlbWEgKioqKioqKioqKgoKCQkvKioKCQkgKiBSZXR1cm4gd2hldGhlciB0aGUgdmVuZG9yIHN1cHBvcnRzIGNhdGFsb2dzLgoJCSAqLwoJCWFic3RyYWN0IGJvb2xlYW4gc3VwcG9ydHNDYXRhbG9ncygpOwoKCQlEVFBDYXRhbG9nV3JhcHBlciBnZXREZWZhdWx0Q2F0YWxvZyhEVFBEYXRhYmFzZVdyYXBwZXIgZGF0YWJhc2UpIHsKCQkJaWYgKCAhIHRoaXMuc3VwcG9ydHNDYXRhbG9ncygpKSB7CgkJCQl0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKCQkJfQoJCQlyZXR1cm4gZGF0YWJhc2UuZ2V0Q2F0YWxvZ0ZvcklkZW50aWZpZXIodGhpcy5nZXREZWZhdWx0Q2F0YWxvZ0lkZW50aWZpZXIoZGF0YWJhc2UpKTsKCQl9CgoJCS8qKgoJCSAqIFR5cGljYWxseSwgdGhlIG5hbWUgb2YgdGhlIGRlZmF1bHQgY2F0YWxvZyBpcyB0aGUgdXNlciBuYW1lLgoJCSAqLwoJCVN0cmluZyBnZXREZWZhdWx0Q2F0YWxvZ0lkZW50aWZpZXIoRFRQRGF0YWJhc2VXcmFwcGVyIGRhdGFiYXNlKSB7CgkJCWlmICggISB0aGlzLnN1cHBvcnRzQ2F0YWxvZ3MoKSkgewoJCQkJdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CgkJCX0KCQkJcmV0dXJuIGRhdGFiYXNlLmdldENvbm5lY3Rpb25Qcm9maWxlKCkuZ2V0VXNlck5hbWUoKTsKCQl9CgoJCURUUFNjaGVtYVdyYXBwZXIgZ2V0RGVmYXVsdFNjaGVtYShEVFBTY2hlbWFDb250YWluZXJXcmFwcGVyIHNjKSB7CgkJCXJldHVybiBzYy5nZXRTY2hlbWFGb3JJZGVudGlmaWVyKHRoaXMuZ2V0RGVmYXVsdFNjaGVtYUlkZW50aWZpZXIoc2MpKTsKCQl9CgoJCS8qKgoJCSAqIFR5cGljYWxseSwgdGhlIG5hbWUgb2YgdGhlIGRlZmF1bHQgc2NoZW1hIGlzIHRoZSB1c2VyIG5hbWUuCgkJICovCgkJU3RyaW5nIGdldERlZmF1bHRTY2hlbWFJZGVudGlmaWVyKERUUFNjaGVtYUNvbnRhaW5lcldyYXBwZXIgc2MpIHsKCQkJcmV0dXJuIHNjLmdldERhdGFiYXNlKCkuZ2V0Q29ubmVjdGlvblByb2ZpbGUoKS5nZXRVc2VyTmFtZSgpOwoJCX0KCgoJCS8vICoqKioqKioqKiogbmFtZSAtPiBpZGVudGlmaWVyICoqKioqKioqKioKCgkJLyoqCgkJICogQHNlZSBEVFBEYXRhYmFzZVdyYXBwZXIjY29udmVydE5hbWVUb0lkZW50aWZpZXIoU3RyaW5nLCBTdHJpbmcpCgkJICovCgkJZmluYWwgU3RyaW5nIGNvbnZlcnROYW1lVG9JZGVudGlmaWVyKFN0cmluZyBuYW1lLCBTdHJpbmcgZGVmYXVsdE5hbWUpIHsKCQkJcmV0dXJuIHRoaXMubmFtZVJlcXVpcmVzRGVsaW1pdGVycyhuYW1lKSA/IHRoaXMuZGVsaW1pdE5hbWUobmFtZSkKCQkJCQkJCTogdGhpcy5ub3JtYWxOYW1lc01hdGNoKG5hbWUsIGRlZmF1bHROYW1lKSA/IG51bGwgOiBuYW1lOwoJCX0KCgkJLyoqCgkJICogQHNlZSBEVFBEYXRhYmFzZVdyYXBwZXIjY29udmVydE5hbWVUb0lkZW50aWZpZXIoU3RyaW5nKQoJCSAqLwoJCWZpbmFsIFN0cmluZyBjb252ZXJ0TmFtZVRvSWRlbnRpZmllcihTdHJpbmcgbmFtZSkgewoJCQlyZXR1cm4gdGhpcy5uYW1lUmVxdWlyZXNEZWxpbWl0ZXJzKG5hbWUpID8gdGhpcy5kZWxpbWl0TmFtZShuYW1lKSA6IG5hbWU7CgkJfQoKCQkvKioKCQkgKiBSZXR1cm4gd2hldGhlciB0aGUgc3BlY2lmaWVkIGRhdGFiYXNlIG9iamVjdCBuYW1lIG11c3QgYmUgZGVsaW1pdGVkCgkJICogd2hlbiB1c2VkIGluIGFuIFNRTCBzdGF0ZW1lbnQuCgkJICogSWYgdGhlIG5hbWUgaGFzIGFueSAic3BlY2lhbCIgY2hhcmFjdGVycyAoYXMgb3Bwb3NlZCB0byBsZXR0ZXJzLAoJCSAqIGRpZ2l0cywgYW5kIG90aGVyIGFsbG93ZWQgY2hhcmFjdGVycyBbZS5nLiB1bmRlcnNjb3Jlc10pLCBpdCByZXF1aXJlcwoJCSAqIGRlbGltaXRlcnMuCgkJICogSWYgdGhlIG5hbWUgaXMgbWl4ZWQgY2FzZSBhbmQgdGhlIGRhdGFiYXNlIGZvbGRzIHVuZGVsaW1pdGVkIG5hbWVzCgkJICogKHRvIGVpdGhlciB1cHBlcmNhc2Ugb3IgbG93ZXJjYXNlKSwgaXQgcmVxdWlyZXMgZGVsaW1pdGVycy4KCQkgKi8KCQlmaW5hbCBib29sZWFuIG5hbWVSZXF1aXJlc0RlbGltaXRlcnMoU3RyaW5nIG5hbWUpIHsKCQkJcmV0dXJuIChuYW1lLmxlbmd0aCgpID09IDApICAvLyAgYW4gZW1wdHkgc3RyaW5nIG11c3QgYmUgZGVsaW1pdGVkKD8pCgkJCQkJCXx8IHRoaXMubmFtZUNvbnRhaW5zQW55U3BlY2lhbENoYXJhY3RlcnMobmFtZSkKCQkJCQkJfHwgdGhpcy5uYW1lSXNOb3RGb2xkZWQobmFtZSk7CgkJfQoKCQkvKioKCQkgKiBSZXR1cm4gd2hldGhlciB0aGUgc3BlY2lmaWVkIG5hbWUgY29udGFpbnMgYW55ICJzcGVjaWFsIiBjaGFyYWN0ZXJzCgkJICogdGhhdCByZXF1aXJlIHRoZSBuYW1lIHRvIGJlIGRlbGltaXRlZC4KCQkgKiBQcmUtY29uZGl0aW9uOiB0aGUgc3BlY2lmaWVkIG5hbWUgaXMgbm90IGVtcHR5CgkJICovCgkJZmluYWwgYm9vbGVhbiBuYW1lQ29udGFpbnNBbnlTcGVjaWFsQ2hhcmFjdGVycyhTdHJpbmcgbmFtZSkgewoJCQljaGFyW10gc3RyaW5nID0gbmFtZS50b0NoYXJBcnJheSgpOwoJCQlpZiAodGhpcy5jaGFyYWN0ZXJJc1NwZWNpYWxOYW1lU3RhcnQoc3RyaW5nWzBdKSkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQkJZm9yIChpbnQgaSA9IHN0cmluZy5sZW5ndGg7IGktLSA+IDE7ICkgeyAgLy8gbm90ZTogc3RvcCBhdCAxCgkJCQlpZiAodGhpcy5jaGFyYWN0ZXJJc1NwZWNpYWxOYW1lUGFydChzdHJpbmdbaV0pKSB7CgkJCQkJcmV0dXJuIHRydWU7CgkJCQl9CgkJCX0KCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoqCgkJICogUmV0dXJuIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgInNwZWNpYWwiIGZvciB0aGUgZmlyc3QKCQkgKiBjaGFyYWN0ZXIgb2YgYSBuYW1lLgoJCSAqIFR5cGljYWxseSwgZGF0YWJhc2VzIGFyZSBtb3JlIHJlc3RyaWN0aXZlIGFib3V0IHdoYXQgY2hhcmFjdGVycyBjYW4KCQkgKiBiZSB1c2VkIHRvICpzdGFydCogYW4gaWRlbnRpZmllciAoYXMgb3Bwb3NlZCB0byB0aGUgY2hhcmFjdGVycwoJCSAqIGFsbG93ZWQgZm9yIHRoZSByZW1haW5kZXIgb2YgdGhlIGlkZW50aWZpZXIpLgoJCSAqLwoJCWZpbmFsIGJvb2xlYW4gY2hhcmFjdGVySXNTcGVjaWFsTmFtZVN0YXJ0KGNoYXIgYykgewoJCQlyZXR1cm4gISB0aGlzLmNoYXJhY3RlcklzTm9ybWFsTmFtZVN0YXJ0KGMpOwoJCX0KCgkJLyoqCgkJICogUmV0dXJuIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgaXMgIm5vcm1hbCIgZm9yIHRoZSBmaXJzdAoJCSAqIGNoYXJhY3RlciBvZiBhIG5hbWUuCgkJICogVGhlIGZpcnN0IGNoYXJhY3RlciBvZiBhbiBpZGVudGlmaWVyIGNhbiBiZToKCQkgKiAgIC0gYSBsZXR0ZXIKCQkgKiAgIC0gYW55IG9mIHRoZSBvdGhlciwgdmVuZG9yLXNwZWNpZmljLCAibm9ybWFsIiBzdGFydCBjaGFyYWN0ZXJzCgkJICovCgkJYm9vbGVhbiBjaGFyYWN0ZXJJc05vcm1hbE5hbWVTdGFydChjaGFyIGMpIHsKCQkJLy8gYWxsIHZlbmRvcnMgYWxsb3cgYSBsZXR0ZXIKCQkJcmV0dXJuIENoYXJhY3Rlci5pc0xldHRlcihjKQoJCQkJCXx8IHRoaXMuY2hhcmFjdGVySXNOb3JtYWxOYW1lU3RhcnRfKGMpOwoJCX0KCgkJcHJpdmF0ZSBib29sZWFuIGNoYXJhY3RlcklzTm9ybWFsTmFtZVN0YXJ0XyhjaGFyIGMpIHsKCQkJcmV0dXJuIGFycmF5Q29udGFpbnModGhpcy5nZXROb3JtYWxOYW1lU3RhcnRDaGFyYWN0ZXJzKCksIGMpOwoJCX0KCgkJLyoqCgkJICogUmV0dXJuIHRoZSAibm9ybWFsIiBjaGFyYWN0ZXJzLCBiZXlvbmQgbGV0dGVycywgZm9yIHRoZQoJCSAqIGZpcnN0IGNoYXJhY3RlciBvZiBhIG5hbWUuCgkJICogUmV0dXJuIG51bGwgaWYgdGhlcmUgYXJlIG5vIGFkZGl0aW9uYWwgY2hhcmFjdGVycy4KCQkgKi8KCQljaGFyW10gZ2V0Tm9ybWFsTmFtZVN0YXJ0Q2hhcmFjdGVycygpIHsKCQkJcmV0dXJuIG51bGw7CgkJfQoKCQkvKioKCQkgKiBSZXR1cm4gd2hldGhlciB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyAic3BlY2lhbCIgZm9yIHRoZSBzZWNvbmQgYW5kCgkJICogc3Vic2VxdWVudCBjaGFyYWN0ZXJzIG9mIGEgbmFtZS4KCQkgKi8KCQlmaW5hbCBib29sZWFuIGNoYXJhY3RlcklzU3BlY2lhbE5hbWVQYXJ0KGNoYXIgYykgewoJCQlyZXR1cm4gISB0aGlzLmNoYXJhY3RlcklzTm9ybWFsTmFtZVBhcnQoYyk7CgkJfQoKCQkvKioKCQkgKiBSZXR1cm4gd2hldGhlciB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpcyAibm9ybWFsIiBmb3IgdGhlIHNlY29uZCBhbmQKCQkgKiBzdWJzZXF1ZW50IGNoYXJhY3RlcnMgb2YgYSBuYW1lLgoJCSAqIFRoZSBzZWNvbmQgYW5kIHN1YnNlcXVlbnQgY2hhcmFjdGVycyBvZiBhICJub3JtYWwiIG5hbWUgY2FuIGJlOgoJCSAqICAgLSBhIGxldHRlcgoJCSAqICAgLSBhIGRpZ2l0CgkJICogICAtIGFueSBvZiB0aGUgb3RoZXIsIHZlbmRvci1zcGVjaWZpYywgIm5vcm1hbCIgc3RhcnQgY2hhcmFjdGVycwoJCSAqICAgLSBhbnkgb2YgdGhlIG90aGVyLCB2ZW5kb3Itc3BlY2lmaWMsICJub3JtYWwiIHBhcnQgY2hhcmFjdGVycwoJCSAqLwoJCWJvb2xlYW4gY2hhcmFjdGVySXNOb3JtYWxOYW1lUGFydChjaGFyIGMpIHsKCQkJLy8gYWxsIHZlbmRvcnMgYWxsb3cgYSBsZXR0ZXIgb3IgZGlnaXQKCQkJcmV0dXJuIENoYXJhY3Rlci5pc0xldHRlck9yRGlnaXQoYykKCQkJCQl8fCB0aGlzLmNoYXJhY3RlcklzTm9ybWFsTmFtZVN0YXJ0XyhjKQoJCQkJCXx8IHRoaXMuY2hhcmFjdGVySXNOb3JtYWxOYW1lUGFydF8oYyk7CgkJfQoKCQlwcml2YXRlIGJvb2xlYW4gY2hhcmFjdGVySXNOb3JtYWxOYW1lUGFydF8oY2hhciBjKSB7CgkJCXJldHVybiBhcnJheUNvbnRhaW5zKHRoaXMuZ2V0Tm9ybWFsTmFtZVBhcnRDaGFyYWN0ZXJzKCksIGMpOwoJCX0KCgkJLyoqCgkJICogUmV0dXJuIHRoZSAibm9ybWFsIiBjaGFyYWN0ZXJzLCBiZXlvbmQgbGV0dGVycyBhbmQgZGlnaXRzIGFuZCB0aGUKCQkgKiAibm9ybWFsIiBmaXJzdCBjaGFyYWN0ZXJzLCBmb3IgdGhlIHNlY29uZCBhbmQgc3Vic2VxdWVudCBjaGFyYWN0ZXJzCgkJICogb2YgYW4gaWRlbnRpZmllci4gUmV0dXJuIG51bGwgaWYgdGhlcmUgYXJlIG5vIGFkZGl0aW9uYWwgY2hhcmFjdGVycy4KCQkgKi8KCQljaGFyW10gZ2V0Tm9ybWFsTmFtZVBhcnRDaGFyYWN0ZXJzKCkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJCS8qKgoJCSAqIFJldHVybiB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgbmFtZSBpcyBub3QgZm9sZGVkIHRvIHRoZSBkYXRhYmFzZSdzCgkJICogY2FzZSwgcmVxdWlyaW5nIGl0IHRvIGJlIGRlbGltaXRlZC4KCQkgKi8KCQlmaW5hbCBib29sZWFuIG5hbWVJc05vdEZvbGRlZChTdHJpbmcgbmFtZSkgewoJCQlyZXR1cm4gISB0aGlzLmdldEZvbGRlcigpLnN0cmluZ0lzRm9sZGVkKG5hbWUpOwoJCX0KCgkJLyoqCgkJICogUmV0dXJuIHdoZXRoZXIgdGhlIHNwZWNpZmllZCAibm9ybWFsIiBuYW1lcyBtYXRjaC4KCQkgKi8KCQlmaW5hbCBib29sZWFuIG5vcm1hbE5hbWVzTWF0Y2goU3RyaW5nIG5hbWUxLCBTdHJpbmcgbmFtZTIpIHsKCQkJcmV0dXJuIHRoaXMubm9ybWFsSWRlbnRpZmllcnNBcmVDYXNlU2Vuc2l0aXZlKCkgPwoJCQkJCQkJbmFtZTEuZXF1YWxzKG5hbWUyKQoJCQkJCQk6CgkJCQkJCQluYW1lMS5lcXVhbHNJZ25vcmVDYXNlKG5hbWUyKTsKCQl9CgoJCS8qKgoJCSAqIFR5cGljYWxseSwgIm5vcm1hbCIgaWRlbnRpZmllcnMgYXJlIGNhc2UtaW5zZW5zaXRpdmUuCgkJICovCgkJZmluYWwgYm9vbGVhbiBub3JtYWxJZGVudGlmaWVyc0FyZUNhc2VTZW5zaXRpdmUoKSB7CgkJCXJldHVybiB0aGlzLmdldEZvbGRlcigpLmlzQ2FzZVNlbnNpdGl2ZSgpOwoJCX0KCgkJLyoqCgkJICogV3JhcCB0aGUgc3BlY2lmaWVkIG5hbWUgaW4gZGVsaW1pdGVycyAodHlwaWNhbGx5IGRvdWJsZS1xdW90ZXMpLAoJCSAqIGNvbnZlcnRpbmcgaXQgdG8gYW4gaWRlbnRpZmllci4KCQkgKi8KCQlTdHJpbmcgZGVsaW1pdE5hbWUoU3RyaW5nIG5hbWUpIHsKCQkJcmV0dXJuIFN0cmluZ1Rvb2xzLnF1b3RlKG5hbWUpOwoJCX0KCgoJCS8vICoqKioqKioqKiogaWRlbnRpZmllciAtPiBuYW1lICoqKioqKioqKioKCgkJLyoqCgkJICogQHNlZSBEVFBEYXRhYmFzZVdyYXBwZXIjc2VsZWN0RGF0YWJhc2VPYmplY3RGb3JJZGVudGlmaWVyXyhEYXRhYmFzZU9iamVjdFtdLCBTdHJpbmcpCgkJICovCgkJLy8gbm90IHN1cmUgaG93IHRvIGhhbmRsZSBhbiBlbXB0eSBzdHJpbmc6CgkJLy8gYm90aCAiIiBhbmQgIlwiXCIiIGFyZSBjb252ZXJ0ZWQgdG8gIiIgLi4uCgkJLy8gY29udmVydCAiIiB0byAnbnVsbCcgc2luY2UgZW1wdHkgc3RyaW5ncyBtdXN0IGJlIGRlbGltaXRlZD8KCQlmaW5hbCBTdHJpbmcgY29udmVydElkZW50aWZpZXJUb05hbWUoU3RyaW5nIGlkZW50aWZpZXIpIHsKCQkJcmV0dXJuIChpZGVudGlmaWVyID09IG51bGwpID8gbnVsbCA6CgkJCQkJCXRoaXMuaWRlbnRpZmllcklzRGVsaW1pdGVkKGlkZW50aWZpZXIpID8KCQkJCQkJCVN0cmluZ1Rvb2xzLnVuZGVsaW1pdChpZGVudGlmaWVyKQoJCQkJCQk6CgkJCQkJCQl0aGlzLmdldEZvbGRlcigpLmZvbGQoaWRlbnRpZmllcik7CgkJfQoKCQkvKioKCQkgKiBSZXR1cm4gd2hldGhlciB0aGUgc3BlY2lmaWVkIGlkZW50aWZpZXIgaXMgImRlbGltaXRlZCIuCgkJICogVGhlIFNRTC05MiBzcGVjIHNheXMgaWRlbnRpZmllcnMgc2hvdWxkIGJlIGRlbGltaXRlZCBieQoJCSAqIGRvdWJsZS1xdW90ZXM7IGJ1dCBzb21lIGRhdGFiYXNlcyBhbGxvdyBvdGhlcndpc2UgKGUuZy4gU3liYXNlKS4KCQkgKi8KCQlib29sZWFuIGlkZW50aWZpZXJJc0RlbGltaXRlZChTdHJpbmcgaWRlbnRpZmllcikgewoJCQlyZXR1cm4gU3RyaW5nVG9vbHMuc3RyaW5nSXNRdW90ZWQoaWRlbnRpZmllcik7CgkJfQoKCgkJLy8gKioqKioqKioqKiBtaXNjICoqKioqKioqKioKCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKCQkJcmV0dXJuIHRoaXMuZ2V0TmFtZSgpOwoJCX0KCgkJLyoqCgkJICogc3RhdGljIGNvbnZlbmllbmNlIG1ldGhvZCAtIGFycmF5IG51bGwgY2hlY2sKCQkgKi8KCQlzdGF0aWMgYm9vbGVhbiBhcnJheUNvbnRhaW5zKGNoYXJbXSBhcnJheSwgY2hhciBjKSB7CgkJCXJldHVybiAoYXJyYXkgIT0gbnVsbCkgJiYgQ29sbGVjdGlvblRvb2xzLmNvbnRhaW5zKGFycmF5LCBjKTsKCQl9CgoJCS8qKgoJCSAqIEhhbmRsZSBkYXRhYmFzZS1zcGVjaWZpYyBjYXNlLWZvbGRpbmcgaXNzdWVzLgoJCSAqLwoJCWVudW0gRm9sZGVyIHsKCQkJVVBQRVIgewoJCQkJQE92ZXJyaWRlIFN0cmluZyBmb2xkKFN0cmluZyBzdHJpbmcpIHsgcmV0dXJuIHN0cmluZy50b1VwcGVyQ2FzZSgpOyB9CgkJCQlAT3ZlcnJpZGUgYm9vbGVhbiBzdHJpbmdJc0ZvbGRlZChTdHJpbmcgc3RyaW5nKSB7IHJldHVybiBTdHJpbmdUb29scy5zdHJpbmdJc1VwcGVyY2FzZShzdHJpbmcpOyB9CgkJCQlAT3ZlcnJpZGUgYm9vbGVhbiBpc0Nhc2VTZW5zaXRpdmUoKSB7IHJldHVybiBmYWxzZTsgfQoJCQl9LAoJCQlMT1dFUiB7CgkJCQlAT3ZlcnJpZGUgU3RyaW5nIGZvbGQoU3RyaW5nIHN0cmluZykgeyByZXR1cm4gc3RyaW5nLnRvTG93ZXJDYXNlKCk7IH0KCQkJCUBPdmVycmlkZSBib29sZWFuIHN0cmluZ0lzRm9sZGVkKFN0cmluZyBzdHJpbmcpIHsgcmV0dXJuIFN0cmluZ1Rvb2xzLnN0cmluZ0lzTG93ZXJjYXNlKHN0cmluZyk7IH0KCQkJCUBPdmVycmlkZSBib29sZWFuIGlzQ2FzZVNlbnNpdGl2ZSgpIHsgcmV0dXJuIGZhbHNlOyB9CgkJCX0sCgkJCU5PTkUgewoJCQkJQE92ZXJyaWRlIFN0cmluZyBmb2xkKFN0cmluZyBzdHJpbmcpIHsgcmV0dXJuIHN0cmluZzsgfQoJCQkJQE92ZXJyaWRlIGJvb2xlYW4gc3RyaW5nSXNGb2xkZWQoU3RyaW5nIHN0cmluZykgeyByZXR1cm4gdHJ1ZTsgfQoJCQkJQE92ZXJyaWRlIGJvb2xlYW4gaXNDYXNlU2Vuc2l0aXZlKCkgeyByZXR1cm4gdHJ1ZTsgfQoJCQl9OwoJCQlhYnN0cmFjdCBTdHJpbmcgZm9sZChTdHJpbmcgc3RyaW5nKTsKCQkJYWJzdHJhY3QgYm9vbGVhbiBzdHJpbmdJc0ZvbGRlZChTdHJpbmcgc3RyaW5nKTsKCQkJYWJzdHJhY3QgYm9vbGVhbiBpc0Nhc2VTZW5zaXRpdmUoKTsKCQl9CgoJfQoKCXByaXZhdGUgc3RhdGljIGNsYXNzIERlZmF1bHQgZXh0ZW5kcyBWZW5kb3IgewoJCXN0YXRpYyBmaW5hbCBWZW5kb3IgSU5TVEFOQ0UgPSBuZXcgRGVmYXVsdCgpOwoKCQlwcml2YXRlIERlZmF1bHQoKSB7CgkJCXN1cGVyKCk7CgkJfQoKCQlAT3ZlcnJpZGUKCQlTdHJpbmcgZ2V0TmFtZSgpIHsKCQkJcmV0dXJuICJEZWZhdWx0IFZlbmRvciI7IC8vJE5PTi1OTFMtMSQKCQl9CgoJCUBPdmVycmlkZQoJCWJvb2xlYW4gc3VwcG9ydHNDYXRhbG9ncygpIHsKCQkJcmV0dXJuIHRydWU7ICAvLyBobW1tLi4uICB+Ymp2CgkJfQoKCX0KCglwcml2YXRlIHN0YXRpYyBjbGFzcyBEZXJieSBleHRlbmRzIFZlbmRvciB7CgkJc3RhdGljIGZpbmFsIFZlbmRvciBJTlNUQU5DRSA9IG5ldyBEZXJieSgpOwoKCQlwcml2YXRlIERlcmJ5KCkgewoJCQlzdXBlcigpOwoJCX0KCgkJQE92ZXJyaWRlCgkJU3RyaW5nIGdldE5hbWUoKSB7CgkJCXJldHVybiAiRGVyYnkiOyAvLyROT04tTkxTLTEkCgkJfQoKCQlAT3ZlcnJpZGUKCQlib29sZWFuIHN1cHBvcnRzQ2F0YWxvZ3MoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qKgoJCSAqIFRoZSBkZWZhdWx0IHVzZXIgbmFtZSBvbiBEZXJieSBpcyAiQVBQIi4KCQkgKi8KCQlAT3ZlcnJpZGUKCQlTdHJpbmcgZ2V0RGVmYXVsdFNjaGVtYUlkZW50aWZpZXIoRFRQU2NoZW1hQ29udGFpbmVyV3JhcHBlciBzYykgewoJCQlTdHJpbmcgdXNlciA9IHN1cGVyLmdldERlZmF1bHRTY2hlbWFJZGVudGlmaWVyKHNjKTsKCQkJcmV0dXJuICgodXNlciA9PSBudWxsKSB8fCAodXNlci5sZW5ndGgoKSA9PSAwKSkgPwoJCQkJCQkJREVGQVVMVF9VU0VSX05BTUUKCQkJCQkJOgoJCQkJCQkJdXNlcjsKCQl9CgkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfVVNFUl9OQU1FID0gIkFQUCI7ICAvLyROT04tTkxTLTEkCgoJCUBPdmVycmlkZQoJCWNoYXJbXSBnZXROb3JtYWxOYW1lUGFydENoYXJhY3RlcnMoKSB7CgkJCXJldHVybiBOT1JNQUxfTkFNRV9QQVJUX0NIQVJBQ1RFUlM7CgkJfQoJCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBOT1JNQUxfTkFNRV9QQVJUX0NIQVJBQ1RFUlMgPSBuZXcgY2hhcltdIHsgJ18nIH07CgoJfQoKCXByaXZhdGUgc3RhdGljIGNsYXNzIEhTUUxEQiBleHRlbmRzIFZlbmRvciB7CgkJc3RhdGljIGZpbmFsIFZlbmRvciBJTlNUQU5DRSA9IG5ldyBIU1FMREIoKTsKCgkJcHJpdmF0ZSBIU1FMREIoKSB7CgkJCXN1cGVyKCk7CgkJfQoKCQlAT3ZlcnJpZGUKCQlTdHJpbmcgZ2V0TmFtZSgpIHsKCQkJcmV0dXJuICJIU1FMREIiOyAvLyROT04tTkxTLTEkCgkJfQoKCQlAT3ZlcnJpZGUKCQlib29sZWFuIHN1cHBvcnRzQ2F0YWxvZ3MoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCUBPdmVycmlkZQoJCVN0cmluZyBnZXREZWZhdWx0U2NoZW1hSWRlbnRpZmllcihEVFBTY2hlbWFDb250YWluZXJXcmFwcGVyIHNjKSB7CgkJCXJldHVybiBQVUJMSUNfU0NIRU1BX05BTUU7CgkJfQoJCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQVUJMSUNfU0NIRU1BX05BTUUgPSAiUFVCTElDIjsgIC8vJE5PTi1OTFMtMSQKCgl9CgoJcHJpdmF0ZSBzdGF0aWMgY2xhc3MgREIyIGV4dGVuZHMgVmVuZG9yIHsKCQlzdGF0aWMgZmluYWwgVmVuZG9yIFVEQl9JX1NFUklFUyA9IG5ldyBEQjIoIkRCMiBVREIgaVNlcmllcyIpOyAvLyROT04tTkxTLTEkCgkJc3RhdGljIGZpbmFsIFZlbmRvciBVREIgPSBuZXcgREIyKCJEQjIgVURCIik7IC8vJE5PTi1OTFMtMSQKCQlzdGF0aWMgZmluYWwgVmVuZG9yIFVEQl9aX1NFUklFUyA9IG5ldyBEQjIoIkRCMiBVREIgelNlcmllcyIpOyAvLyROT04tTkxTLTEkCgoJCXByaXZhdGUgZmluYWwgU3RyaW5nIG5hbWU7CgoJCXByaXZhdGUgREIyKFN0cmluZyBuYW1lKSB7CgkJCXN1cGVyKCk7CgkJCXRoaXMubmFtZSA9IG5hbWU7CgkJfQoKCQlAT3ZlcnJpZGUKCQlTdHJpbmcgZ2V0TmFtZSgpIHsKCQkJcmV0dXJuIHRoaXMubmFtZTsKCQl9CgoJCUBPdmVycmlkZQoJCWJvb2xlYW4gc3VwcG9ydHNDYXRhbG9ncygpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJQE92ZXJyaWRlCgkJY2hhcltdIGdldE5vcm1hbE5hbWVQYXJ0Q2hhcmFjdGVycygpIHsKCQkJcmV0dXJuIE5PUk1BTF9OQU1FX1BBUlRfQ0hBUkFDVEVSUzsKCQl9CgkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIE5PUk1BTF9OQU1FX1BBUlRfQ0hBUkFDVEVSUyA9IG5ldyBjaGFyW10geyAnXycgfTsKCgl9CgoJcHJpdmF0ZSBzdGF0aWMgY2xhc3MgSW5mb3JtaXggZXh0ZW5kcyBWZW5kb3IgewoJCXN0YXRpYyBmaW5hbCBWZW5kb3IgSU5TVEFOQ0UgPSBuZXcgSW5mb3JtaXgoKTsKCgkJcHJpdmF0ZSBJbmZvcm1peCgpIHsKCQkJc3VwZXIoKTsKCQl9CgoJCUBPdmVycmlkZQoJCVN0cmluZyBnZXROYW1lKCkgewoJCQlyZXR1cm4gIkluZm9ybWl4IjsgLy8kTk9OLU5MUy0xJAoJCX0KCgkJQE92ZXJyaWRlCgkJYm9vbGVhbiBzdXBwb3J0c0NhdGFsb2dzKCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlAT3ZlcnJpZGUKCQlGb2xkZXIgZ2V0Rm9sZGVyKCkgewoJCQlyZXR1cm4gRm9sZGVyLkxPV0VSOwoJCX0KCgkJQE92ZXJyaWRlCgkJY2hhcltdIGdldE5vcm1hbE5hbWVTdGFydENoYXJhY3RlcnMoKSB7CgkJCXJldHVybiBOT1JNQUxfTkFNRV9TVEFSVF9DSEFSQUNURVJTOwoJCX0KCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gTk9STUFMX05BTUVfU1RBUlRfQ0hBUkFDVEVSUyA9IG5ldyBjaGFyW10geyAnXycgfTsKCgkJQE92ZXJyaWRlCgkJY2hhcltdIGdldE5vcm1hbE5hbWVQYXJ0Q2hhcmFjdGVycygpIHsKCQkJcmV0dXJuIE5PUk1BTF9OQU1FX1BBUlRfQ0hBUkFDVEVSUzsKCQl9CgkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIE5PUk1BTF9OQU1FX1BBUlRfQ0hBUkFDVEVSUyA9IG5ldyBjaGFyW10geyAnJCcgfTsKCgl9CgoJcHJpdmF0ZSBzdGF0aWMgY2xhc3MgU1FMU2VydmVyIGV4dGVuZHMgVmVuZG9yIHsKCQlzdGF0aWMgZmluYWwgVmVuZG9yIElOU1RBTkNFID0gbmV3IFNRTFNlcnZlcigpOwoKCQlwcml2YXRlIFNRTFNlcnZlcigpIHsKCQkJc3VwZXIoKTsKCQl9CgoJCUBPdmVycmlkZQoJCVN0cmluZyBnZXROYW1lKCkgewoJCQlyZXR1cm4gIlNRTCBTZXJ2ZXIiOyAvLyROT04tTkxTLTEkCgkJfQoKCQlAT3ZlcnJpZGUKCQlib29sZWFuIHN1cHBvcnRzQ2F0YWxvZ3MoKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJLyoqCgkJICogVGhlIGRlZmF1bHQgc2NoZW1hIG9uIFNRTCBTZXJ2ZXIgZm9yIGFueSBkYXRhYmFzZSAoY2F0YWxvZykgaXMgJ2RibycuCgkJICovCgkJQE92ZXJyaWRlCgkJU3RyaW5nIGdldERlZmF1bHRTY2hlbWFJZGVudGlmaWVyKERUUFNjaGVtYUNvbnRhaW5lcldyYXBwZXIgc2MpIHsKCQkJcmV0dXJuIERFRkFVTFRfU0NIRU1BX05BTUU7CgkJfQoJCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1NDSEVNQV9OQU1FID0gImRibyI7ICAvLyROT04tTkxTLTEkCgoJCS8qKgoJCSAqIEJ5IGRlZmF1bHQsIFNRTCBTZXJ2ZXIgaWRlbnRpZmllcnMgYXJlIGNhc2Utc2Vuc2l0aXZlLCBldmVuIHdpdGhvdXQKCQkgKiBkZWxpbWl0ZXJzLiBUaGlzIGNhbiBkZXBlbmQgb24gdGhlIGNvbGxhdGlvbiBzZXR0aW5nLi4uLgoJCSAqLwoJCUBPdmVycmlkZQoJCUZvbGRlciBnZXRGb2xkZXIoKSB7CgkJCXJldHVybiBGb2xkZXIuTk9ORTsKCQl9CgoJCUBPdmVycmlkZQoJCWNoYXJbXSBnZXROb3JtYWxOYW1lU3RhcnRDaGFyYWN0ZXJzKCkgewoJCQlyZXR1cm4gTk9STUFMX05BTUVfU1RBUlRfQ0hBUkFDVEVSUzsKCQl9CgkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIE5PUk1BTF9OQU1FX1NUQVJUX0NIQVJBQ1RFUlMgPSBuZXcgY2hhcltdIHsgJ18nLCAnQCcsICcjJyB9OwoKCQlAT3ZlcnJpZGUKCQljaGFyW10gZ2V0Tm9ybWFsTmFtZVBhcnRDaGFyYWN0ZXJzKCkgewoJCQlyZXR1cm4gTk9STUFMX05BTUVfUEFSVF9DSEFSQUNURVJTOwoJCX0KCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gTk9STUFMX05BTUVfUEFSVF9DSEFSQUNURVJTID0gbmV3IGNoYXJbXSB7ICckJyB9OwoKCQkvKioKCQkgKiBCeSBkZWZhdWx0LCBTUUwgU2VydmVyIGRlbGltaXRzIGlkZW50aWZpZXJzIHdpdGggYnJhY2tldHMgKFtdKTsgYnV0IGl0CgkJICogY2FuIGFsc28gYmUgY29uZmlndXJlZCB0byB1c2UgZG91YmxlLXF1b3Rlcy4KCQkgKi8KCQlAT3ZlcnJpZGUKCQlib29sZWFuIGlkZW50aWZpZXJJc0RlbGltaXRlZChTdHJpbmcgaWRlbnRpZmllcikgewoJCQlyZXR1cm4gU3RyaW5nVG9vbHMuc3RyaW5nSXNCcmFja2V0ZWQoaWRlbnRpZmllcikKCQkJCQkJfHwgc3VwZXIuaWRlbnRpZmllcklzRGVsaW1pdGVkKGlkZW50aWZpZXIpOwoJCX0KCgl9CgoJcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTXlTUUwgZXh0ZW5kcyBWZW5kb3IgewoJCXN0YXRpYyBmaW5hbCBWZW5kb3IgSU5TVEFOQ0UgPSBuZXcgTXlTUUwoKTsKCgkJcHJpdmF0ZSBNeVNRTCgpIHsKCQkJc3VwZXIoKTsKCQl9CgoJCUBPdmVycmlkZQoJCVN0cmluZyBnZXROYW1lKCkgewoJCQlyZXR1cm4gIk15U3FsIjsgLy8kTk9OLU5MUy0xJAoJCX0KCgkJQE92ZXJyaWRlCgkJYm9vbGVhbiBzdXBwb3J0c0NhdGFsb2dzKCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKioKCQkgKiBNeVNRTCBpcyBhIGJpdCB1bnVzdWFsLCBzbyB3ZSBmb3JjZSBleGFjdCBtYXRjaGVzLgoJCSAqIChlLmcuIE15U1FMIGZvbGRzIGRhdGFiYXNlIGFuZCB0YWJsZSBuYW1lcyB0byBsb3dlcmNhc2Ugb24gV2luZG93cwoJCSAqIGJ5IGRlZmF1bHQ7IGJ1dCB0aGF0IGRlZmF1bHQgY2FuIGJlIGNoYW5nZWQgYnkgdGhlCgkJICogJ2xvd2VyX2Nhc2VfdGFibGVfbmFtZXMnIHN5c3RlbSB2YXJpYWJsZS4gVGhpcyBpcyBiZWNhdXNlIGRhdGFiYXNlcyBhcmUKCQkgKiBzdG9yZWQgYXMgZGlyZWN0b3JpZXMgYW5kIHRhYmxlcyBhcmUgc3RvcmVkIGFzIGZpbGVzIGluIHRoZSB1bmRlcmx5aW5nCgkJICogTy9TOyBhbmQgdGhlIGNhc2Utc2Vuc2l0aXZpdHkgb2YgdGhlIG5hbWVzIGlzIGRldGVybWluZWQgYnkgdGhlIGJlaGF2aW9yCgkJICogb2YgZmlsZW5hbWVzIG9uIHRoZSBPL1MuIFRoZW4sIHRvIGNvbXBsaWNhdGUgdGhpbmdzLAoJCSAqIG5vbmUgb2YgdGhlIG90aGVyIGlkZW50aWZpZXJzLCBsaWtlIHRhYmxlIGFuZCBjb2x1bW4gbmFtZXMsIGFyZSBmb2xkZWQ7CgkJICogYnV0IHRoZXkgYXJlIGNhc2UtaW5zZW5zaXRpdmUsIHVubGVzcyBkZWxpbWl0ZWQuIFNlZQoJCSAqIGh0dHA6Ly9kZXYubXlzcWwuY29tL2RvYy9yZWZtYW4vNi4wL2VuL2lkZW50aWZpZXItY2FzZS1zZW5zaXRpdml0eS5odG1sLikKCQkgKi8KCQlAT3ZlcnJpZGUKCQlGb2xkZXIgZ2V0Rm9sZGVyKCkgewoJCQlyZXR1cm4gRm9sZGVyLk5PTkU7CgkJfQoKCQkvKioKCQkgKiBUaGUgRFRQIG1vZGVsIGZvciBNeVNRTCBoYXMgYSBkYXRhYmFzZSB0aGF0IGNvbnRhaW5zIG5vIGNhdGFsb2dzCgkJICogYnV0IGRpcmVjdGx5IGhvbGRzIGEgc2luZ2xlIHNjaGVtYSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGRhdGFiYXNlLgoJCSAqIEFsdGhvdWdoIHlvdSBjYW4gcXVhbGlmeSBpZGVudGlmaWVycyB3aXRoIGEgZGF0YWJhc2UgbmFtZQoJCSAqIGluIE15U1FMLCBvbmx5IHRoZSBkYXRhYmFzZSBzcGVjaWZpZWQgYXQgbG9naW4gc2VlbXMgdG8gYmUgYXZhaWxhYmxlCgkJICogaW4gdGhlIERUUCBtb2RlbC4uLi4gCgkJICogTkI6IEluIE15U1FMIERETCwgU0NIRU1BIGlzIGEgc3lub255bSBmb3IgREFUQUJBU0U7IGJ1dCB0aGUgSkRCQwoJCSAqIG1ldGhvZCBEYXRhYmFzZU1ldGFEYXRhLmdldFNjaGVtYXMoKSByZXR1cm5zIGFuIGVtcHR5IGxpc3QsCgkJICogd2hpbGUgZ2V0Q2F0YWxvZ3MoKSByZXR1cm5zIGEgbGlzdCBvZiB0aGUgYXZhaWxhYmxlIGRhdGFiYXNlcy4KCQkgKiBZb3UgY2FuIGFsc28gdXNlIHRoZSBKREJDIG1ldGhvZCBDb25uZWN0aW9uLnNldENhdGFsb2coU3RyaW5nKSB0bwoJCSAqIHNldCB0aGUgZGVmYXVsdCBkYXRhYmFzZS4KCQkgKi8KCQlAT3ZlcnJpZGUKCQlTdHJpbmcgZ2V0RGVmYXVsdFNjaGVtYUlkZW50aWZpZXIoRFRQU2NoZW1hQ29udGFpbmVyV3JhcHBlciBzYykgewoJCQlyZXR1cm4gc2MuZ2V0RGF0YWJhc2UoKS5nZXROYW1lKCk7ICAvLyBobW1tLi4uIH5ianYKCQl9CgoJCS8qKgoJCSAqIE15U1FMIGlzIHRoZSBvbmx5IHZlbmRvciB0aGF0IGFsbG93cyBhIGRpZ2l0LgoJCSAqIEFsdGhvdWdoLCB0aGUgbmFtZSBjYW5ubm90IGJlICphbGwqIGRpZ2l0cy4KCQkgKi8KCQlAT3ZlcnJpZGUKCQlib29sZWFuIGNoYXJhY3RlcklzTm9ybWFsTmFtZVN0YXJ0KGNoYXIgYykgewoJCQlyZXR1cm4gQ2hhcmFjdGVyLmlzRGlnaXQoYykgfHwgc3VwZXIuY2hhcmFjdGVySXNOb3JtYWxOYW1lU3RhcnQoYyk7CgkJfQoKCQlAT3ZlcnJpZGUKCQljaGFyW10gZ2V0Tm9ybWFsTmFtZVN0YXJ0Q2hhcmFjdGVycygpIHsKCQkJcmV0dXJuIE5PUk1BTF9OQU1FX1NUQVJUX0NIQVJBQ1RFUlM7CgkJfQoJCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBOT1JNQUxfTkFNRV9TVEFSVF9DSEFSQUNURVJTID0gbmV3IGNoYXJbXSB7ICdfJywgJyQnIH07CgoJCS8qKgoJCSAqIEJ5IGRlZmF1bHQsIE15U1FMIGRlbGltaXRzIGlkZW50aWZpZXJzIHdpdGggYmFja3RpY2tzIChgKTsgYnV0IGl0CgkJICogY2FuIGFsc28gYmUgY29uZmlndXJlZCB0byB1c2UgZG91YmxlLXF1b3Rlcy4KCQkgKi8KCQlAT3ZlcnJpZGUKCQlib29sZWFuIGlkZW50aWZpZXJJc0RlbGltaXRlZChTdHJpbmcgaWRlbnRpZmllcikgewoJCQlyZXR1cm4gU3RyaW5nVG9vbHMuc3RyaW5nSXNEZWxpbWl0ZWQoaWRlbnRpZmllciwgQkFDS1RJQ0spCgkJCQkJCXx8IHN1cGVyLmlkZW50aWZpZXJJc0RlbGltaXRlZChpZGVudGlmaWVyKTsKCQl9CgkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhciBCQUNLVElDSyA9ICdgJzsKCgl9CgoJcHJpdmF0ZSBzdGF0aWMgY2xhc3MgT3JhY2xlIGV4dGVuZHMgVmVuZG9yIHsKCQlzdGF0aWMgZmluYWwgVmVuZG9yIElOU1RBTkNFID0gbmV3IE9yYWNsZSgpOwoKCQlwcml2YXRlIE9yYWNsZSgpIHsKCQkJc3VwZXIoKTsKCQl9CgoJCUBPdmVycmlkZQoJCVN0cmluZyBnZXROYW1lKCkgewoJCQlyZXR1cm4gIk9yYWNsZSI7IC8vJE5PTi1OTFMtMSQKCQl9CgoJCUBPdmVycmlkZQoJCWJvb2xlYW4gc3VwcG9ydHNDYXRhbG9ncygpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJQE92ZXJyaWRlCgkJY2hhcltdIGdldE5vcm1hbE5hbWVQYXJ0Q2hhcmFjdGVycygpIHsKCQkJcmV0dXJuIE5PUk1BTF9OQU1FX1BBUlRfQ0hBUkFDVEVSUzsKCQl9CgkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIE5PUk1BTF9OQU1FX1BBUlRfQ0hBUkFDVEVSUyA9IG5ldyBjaGFyW10geyAnXycsICckJywgJyMnIH07CgoJfQoKCXByaXZhdGUgc3RhdGljIGNsYXNzIFBvc3RncmVzIGV4dGVuZHMgVmVuZG9yIHsKCQlzdGF0aWMgZmluYWwgVmVuZG9yIElOU1RBTkNFID0gbmV3IFBvc3RncmVzKCk7CgoJCXByaXZhdGUgUG9zdGdyZXMoKSB7CgkJCXN1cGVyKCk7CgkJfQoKCQlAT3ZlcnJpZGUKCQlTdHJpbmcgZ2V0TmFtZSgpIHsKCQkJcmV0dXJuICJwb3N0Z3JlcyI7IC8vJE5PTi1OTFMtMSQKCQl9CgoJCUBPdmVycmlkZQoJCUZvbGRlciBnZXRGb2xkZXIoKSB7CgkJCXJldHVybiBGb2xkZXIuTE9XRVI7CgkJfQoKCQlAT3ZlcnJpZGUKCQlib29sZWFuIHN1cHBvcnRzQ2F0YWxvZ3MoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qKgoJCSAqIFBvc3RncmVTUUwgaGFzIGEgInNjaGVtYSBzZWFyY2ggcGF0aCIuIFRoZSBkZWZhdWx0IGlzOgoJCSAqICAgICAiJHVzZXIiLHB1YmxpYwoJCSAqIElmICIkdXNlciIgaXMgbm90IGZvdW5kLCByZXR1cm4gInB1YmxpYyIuCgkJICovCgkJQE92ZXJyaWRlCgkJRFRQU2NoZW1hV3JhcHBlciBnZXREZWZhdWx0U2NoZW1hKERUUFNjaGVtYUNvbnRhaW5lcldyYXBwZXIgc2MpIHsKCQkJRFRQU2NoZW1hV3JhcHBlciB1c2VyU2NoZW1hID0gc3VwZXIuZ2V0RGVmYXVsdFNjaGVtYShzYyk7CgkJCXJldHVybiAodXNlclNjaGVtYSAhPSBudWxsKSA/IHVzZXJTY2hlbWEgOiBzYy5nZXRTY2hlbWFOYW1lZChQVUJMSUNfU0NIRU1BX05BTUUpOwoJCX0KCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFVCTElDX1NDSEVNQV9OQU1FID0gInB1YmxpYyI7ICAvLyROT04tTkxTLTEkCgoJCUBPdmVycmlkZQoJCWNoYXJbXSBnZXROb3JtYWxOYW1lU3RhcnRDaGFyYWN0ZXJzKCkgewoJCQlyZXR1cm4gTk9STUFMX05BTUVfU1RBUlRfQ0hBUkFDVEVSUzsKCQl9CgkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIE5PUk1BTF9OQU1FX1NUQVJUX0NIQVJBQ1RFUlMgPSBuZXcgY2hhcltdIHsgJ18nIH07CgoJCUBPdmVycmlkZQoJCWNoYXJbXSBnZXROb3JtYWxOYW1lUGFydENoYXJhY3RlcnMoKSB7CgkJCXJldHVybiBOT1JNQUxfTkFNRV9QQVJUX0NIQVJBQ1RFUlM7CgkJfQoJCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBOT1JNQUxfTkFNRV9QQVJUX0NIQVJBQ1RFUlMgPSBuZXcgY2hhcltdIHsgJyQnIH07CgoJfQoKCXByaXZhdGUgc3RhdGljIGNsYXNzIE1heERCIGV4dGVuZHMgVmVuZG9yIHsKCQlzdGF0aWMgZmluYWwgVmVuZG9yIElOU1RBTkNFID0gbmV3IE1heERCKCk7CgoJCXByaXZhdGUgTWF4REIoKSB7CgkJCXN1cGVyKCk7CgkJfQoKCQlAT3ZlcnJpZGUKCQlTdHJpbmcgZ2V0TmFtZSgpIHsKCQkJcmV0dXJuICJNYXhEQiI7IC8vJE5PTi1OTFMtMSQKCQl9CgoJCUBPdmVycmlkZQoJCWJvb2xlYW4gc3VwcG9ydHNDYXRhbG9ncygpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJQE92ZXJyaWRlCgkJY2hhcltdIGdldE5vcm1hbE5hbWVTdGFydENoYXJhY3RlcnMoKSB7CgkJCXJldHVybiBOT1JNQUxfTkFNRV9TVEFSVF9DSEFSQUNURVJTOwoJCX0KCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gTk9STUFMX05BTUVfU1RBUlRfQ0hBUkFDVEVSUyA9IG5ldyBjaGFyW10geyAnIycsICdAJywgJyQnIH07CgoJCUBPdmVycmlkZQoJCWNoYXJbXSBnZXROb3JtYWxOYW1lUGFydENoYXJhY3RlcnMoKSB7CgkJCXJldHVybiBOT1JNQUxfTkFNRV9QQVJUX0NIQVJBQ1RFUlM7CgkJfQoJCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBOT1JNQUxfTkFNRV9QQVJUX0NIQVJBQ1RFUlMgPSBuZXcgY2hhcltdIHsgJ18nIH07CgoJfQoKCXByaXZhdGUgc3RhdGljIGNsYXNzIFN5YmFzZSBleHRlbmRzIFZlbmRvciB7CgkJc3RhdGljIGZpbmFsIFZlbmRvciBBU0EgPSBuZXcgU3liYXNlKCJTeWJhc2VfQVNBIik7IC8vJE5PTi1OTFMtMSQKCQlzdGF0aWMgZmluYWwgVmVuZG9yIEFTRSA9IG5ldyBTeWJhc2UoIlN5YmFzZV9BU0UiKTsgLy8kTk9OLU5MUy0xJAoKCQlwcml2YXRlIGZpbmFsIFN0cmluZyBuYW1lOwoKCQlwcml2YXRlIFN5YmFzZShTdHJpbmcgbmFtZSkgewoJCQlzdXBlcigpOwoJCQl0aGlzLm5hbWUgPSBuYW1lOwoJCX0KCgkJQE92ZXJyaWRlCgkJU3RyaW5nIGdldE5hbWUoKSB7CgkJCXJldHVybiB0aGlzLm5hbWU7CgkJfQoKCQlAT3ZlcnJpZGUKCQlib29sZWFuIHN1cHBvcnRzQ2F0YWxvZ3MoKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJLyoqCgkJICogVGhlIHR5cGljYWwgZGVmYXVsdCBzY2hlbWEgb24gU3liYXNlIGZvciBhbnkgZGF0YWJhc2UgKGNhdGFsb2cpIGlzCgkJICogJ2RibycuCgkJICogCgkJICogQWN0dWFsbHksIHRoZSBkZWZhdWx0IHNjaGVtYSBpcyBtb3JlIGxpa2UgYSBzZWFyY2ggcGF0aDoKCQkgKiBUaGUgc2VydmVyIGxvb2tzIGZvciBhIHNjaGVtYSBvYmplY3QgKGUuZyB0YWJsZSkgZmlyc3QgaW4gdGhlIHVzZXIncwoJCSAqIHNjaGVtYSwgdGhlIGl0IGxvb2sgZm9yIHRoZSBzY2hlbWEgb2JqZWN0IGluIHRoZSBkYXRhYmFzZSBvd25lcidzCgkJICogc2NoZW1hIChkYm8pLiBBcyBhIHJlc3VsdCwgaXQncyByZWFsbHkgbm90IHBvc3NpYmxlIHRvIHNwZWNpZnkKCQkgKiB0aGUgImRlZmF1bHQiIHNjaGVtYSB3aXRob3V0IGtub3dpbmcgdGhlIHNjaGVtYSBvYmplY3Qgd2UgYXJlCgkJICogbG9va2luZyBmb3IuCgkJICogCgkJICogKE5vdGU6IHRoZSBjdXJyZW50ICd1c2VyJyBpcyBub3QgdGhlIHNhbWUgdGhpbmcgYXMgdGhlIGN1cnJlbnQKCQkgKiAnbG9naW4nIC0gc2VlIHNwX2FkZHVzZXIgYW5kIHNwX2FkZGxvZ2luOyBzbyB3ZSBwcm9iYWJseSBjYW4ndAoJCSAqIHVzZSBDb25uZWN0aW9uUHJvZmlsZSNnZXRVc2VyTmFtZSgpLikKCQkgKi8KCQlAT3ZlcnJpZGUKCQlTdHJpbmcgZ2V0RGVmYXVsdFNjaGVtYUlkZW50aWZpZXIoRFRQU2NoZW1hQ29udGFpbmVyV3JhcHBlciBzYykgewoJCQlyZXR1cm4gREVGQVVMVF9TQ0hFTUFfTkFNRTsKCQl9CgkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfU0NIRU1BX05BTUUgPSAiZGJvIjsgIC8vJE5PTi1OTFMtMSQKCgkJLyoqCgkJICogQnkgZGVmYXVsdCwgU3liYXNlIGlkZW50aWZpZXJzIGFyZSBjYXNlLXNlbnNpdGl2ZSwgZXZlbiB3aXRob3V0CgkJICogZGVsaW1pdGVycy4gVGhpcyBjYW4gZGVwZW5kIG9uIHRoZSBjb2xsYXRpb24gc2V0dGluZy4uLi4KCQkgKi8KCQlAT3ZlcnJpZGUKCQlGb2xkZXIgZ2V0Rm9sZGVyKCkgewoJCQlyZXR1cm4gRm9sZGVyLk5PTkU7CgkJfQoKCQlAT3ZlcnJpZGUKCQljaGFyW10gZ2V0Tm9ybWFsTmFtZVN0YXJ0Q2hhcmFjdGVycygpIHsKCQkJcmV0dXJuIE5PUk1BTF9OQU1FX1NUQVJUX0NIQVJBQ1RFUlM7CgkJfQoJCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBOT1JNQUxfTkFNRV9TVEFSVF9DSEFSQUNURVJTID0gbmV3IGNoYXJbXSB7ICdfJywgJ0AnIH07CgoJCUBPdmVycmlkZQoJCWNoYXJbXSBnZXROb3JtYWxOYW1lUGFydENoYXJhY3RlcnMoKSB7CgkJCXJldHVybiBOT1JNQUxfTkFNRV9QQVJUX0NIQVJBQ1RFUlM7CgkJfQoJCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBOT1JNQUxfTkFNRV9QQVJUX0NIQVJBQ1RFUlMgPSBuZXcgY2hhcltdIHsgJyQnLCAnpScsICejJywgJyMnIH07CgoJCS8qKgoJCSAqIEJ5IGRlZmF1bHQsIFN5YmFzZSBkZWxpbWl0cyBpZGVudGlmaWVycyB3aXRoIGJyYWNrZXRzIChbXSk7IGJ1dCBpdAoJCSAqIGNhbiBhbHNvIGJlIGNvbmZpZ3VyZWQgdG8gdXNlIGRvdWJsZS1xdW90ZXMuCgkJICovCgkJQE92ZXJyaWRlCgkJYm9vbGVhbiBpZGVudGlmaWVySXNEZWxpbWl0ZWQoU3RyaW5nIGlkZW50aWZpZXIpIHsKCQkJcmV0dXJuIFN0cmluZ1Rvb2xzLnN0cmluZ0lzQnJhY2tldGVkKGlkZW50aWZpZXIpCgkJCQkJCXx8IHN1cGVyLmlkZW50aWZpZXJJc0RlbGltaXRlZChpZGVudGlmaWVyKTsKCQl9CgoJfQoKfQo=