LyoKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCiAqCiAqIENvbnRyaWJ1dG9yczoKICogICBJQk0gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICoKICogJElkOiBOYW1lZEVsZW1lbnQuamF2YSx2IDEuMTIgMjAwNS8wNi8wMiAxNTowMjo0NyBraHVzc2V5IEV4cCAkCiAqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLnVtbDI7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5jb21tb24udXRpbC5EaWFnbm9zdGljQ2hhaW47CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLnV0aWwuRUxpc3Q7CgppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVjb3JlLkVDbGFzczsKCi8qKgogKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgogKiBBIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtb2RlbCBvYmplY3QgJzxlbT48Yj5OYW1lZCBFbGVtZW50PC9iPjwvZW0+Jy4KICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CiAqCiAqIDwhLS0gYmVnaW4tbW9kZWwtZG9jIC0tPgogKiBBIG5hbWVkIGVsZW1lbnQgcmVwcmVzZW50cyBlbGVtZW50cyB0aGF0IG1heSBoYXZlIGEgbmFtZS4gVGhlIG5hbWUgaXMgdXNlZCBmb3IgaWRlbnRpZmljYXRpb24gb2YgdGhlIG5hbWVkIGVsZW1lbnQgd2l0aGluIHRoZSBuYW1lc3BhY2UgaW4gd2hpY2ggaXQgaXMgZGVmaW5lZC4gQSBuYW1lZCBlbGVtZW50IGFsc28gaGFzIGEgcXVhbGlmaWVkIG5hbWUgdGhhdCBhbGxvd3MgaXQgdG8gYmUgdW5hbWJpZ3VvdXNseSBpZGVudGlmaWVkIHdpdGhpbiBhIGhpZXJhcmNoeSBvZiBuZXN0ZWQgbmFtZXNwYWNlcy4gTmFtZWRFbGVtZW50IGlzIGFuIGFic3RyYWN0IG1ldGFjbGFzcy4gCiAqIDwhLS0gZW5kLW1vZGVsLWRvYyAtLT4KICoKICogPHA+CiAqIFRoZSBmb2xsb3dpbmcgZmVhdHVyZXMgYXJlIHN1cHBvcnRlZDoKICogPHVsPgogKiAgIDxsaT57QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5OYW1lZEVsZW1lbnQjZ2V0TmFtZSA8ZW0+TmFtZTwvZW0+fTwvbGk+CiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS51bWwyLk5hbWVkRWxlbWVudCNnZXRRdWFsaWZpZWROYW1lIDxlbT5RdWFsaWZpZWQgTmFtZTwvZW0+fTwvbGk+CiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS51bWwyLk5hbWVkRWxlbWVudCNnZXRWaXNpYmlsaXR5IDxlbT5WaXNpYmlsaXR5PC9lbT59PC9saT4KICogICA8bGk+e0BsaW5rIG9yZy5lY2xpcHNlLnVtbDIuTmFtZWRFbGVtZW50I2dldENsaWVudERlcGVuZGVuY2llcyA8ZW0+Q2xpZW50IERlcGVuZGVuY3k8L2VtPn08L2xpPgogKiAgIDxsaT57QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5OYW1lZEVsZW1lbnQjZ2V0TmFtZUV4cHJlc3Npb24gPGVtPk5hbWUgRXhwcmVzc2lvbjwvZW0+fTwvbGk+CiAqIDwvdWw+CiAqIDwvcD4KICoKICogQHNlZSBvcmcuZWNsaXBzZS51bWwyLlVNTDJQYWNrYWdlI2dldE5hbWVkRWxlbWVudCgpCiAqIEBtb2RlbCBhYnN0cmFjdD0idHJ1ZSIKICogQGdlbmVyYXRlZAogKi8KcHVibGljIGludGVyZmFjZSBOYW1lZEVsZW1lbnQgZXh0ZW5kcyBUZW1wbGF0ZWFibGVFbGVtZW50ewoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAZ2VuZXJhdGVkCgkgKi8KCVN0cmluZyBjb3B5cmlnaHQgPSAiQ29weXJpZ2h0IChjKSBJQk0gQ29ycG9yYXRpb24gYW5kIG90aGVycy4iOyAvLyROT04tTkxTLTEkCgoJLyoqCgkgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgJzxlbT48Yj5OYW1lPC9iPjwvZW0+JyBhdHRyaWJ1dGUuCgkgKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyA8Y29kZT4iIjwvY29kZT4uCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPHA+CgkgKiBJZiB0aGUgbWVhbmluZyBvZiB0aGUgJzxlbT5OYW1lPC9lbT4nIGF0dHJpYnV0ZSBpc24ndCBjbGVhciwKCSAqIHRoZXJlIHJlYWxseSBzaG91bGQgYmUgbW9yZSBvZiBhIGRlc2NyaXB0aW9uIGhlcmUuLi4KCSAqIDwvcD4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogPCEtLSBiZWdpbi1tb2RlbC1kb2MgLS0+CgkgKiBUaGUgbmFtZSBvZiB0aGUgTmFtZWRFbGVtZW50LgoJICogPCEtLSBlbmQtbW9kZWwtZG9jIC0tPgoJICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlICc8ZW0+TmFtZTwvZW0+JyBhdHRyaWJ1dGUuCgkgKiBAc2VlICNzZXROYW1lKFN0cmluZykKCSAqIEBzZWUgb3JnLmVjbGlwc2UudW1sMi5VTUwyUGFja2FnZSNnZXROYW1lZEVsZW1lbnRfTmFtZSgpCgkgKiBAbW9kZWwgZGVmYXVsdD0iIiBkYXRhVHlwZT0ib3JnLmVjbGlwc2UudW1sMi5TdHJpbmciCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCVN0cmluZyBnZXROYW1lKCk7CgoJLyoqCgkgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgJ3tAbGluayBvcmcuZWNsaXBzZS51bWwyLk5hbWVkRWxlbWVudCNnZXROYW1lIDxlbT5OYW1lPC9lbT59JyBhdHRyaWJ1dGUuCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAcGFyYW0gdmFsdWUgdGhlIG5ldyB2YWx1ZSBvZiB0aGUgJzxlbT5OYW1lPC9lbT4nIGF0dHJpYnV0ZS4KCSAqIEBzZWUgI2dldE5hbWUoKQoJICogQGdlbmVyYXRlZAoJICovCgl2b2lkIHNldE5hbWUoU3RyaW5nIHZhbHVlKTsKCgoJLyoqCgkgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgJzxlbT48Yj5RdWFsaWZpZWQgTmFtZTwvYj48L2VtPicgYXR0cmlidXRlLgoJICogVGhlIGRlZmF1bHQgdmFsdWUgaXMgPGNvZGU+IiI8L2NvZGU+LgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDxwPgoJICogSWYgdGhlIG1lYW5pbmcgb2YgdGhlICc8ZW0+UXVhbGlmaWVkIE5hbWU8L2VtPicgYXR0cmlidXRlIGlzbid0IGNsZWFyLAoJICogdGhlcmUgcmVhbGx5IHNob3VsZCBiZSBtb3JlIG9mIGEgZGVzY3JpcHRpb24gaGVyZS4uLgoJICogPC9wPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiA8IS0tIGJlZ2luLW1vZGVsLWRvYyAtLT4KCSAqIEEgbmFtZSB3aGljaCBhbGxvd3MgdGhlIE5hbWVkRWxlbWVudCB0byBiZSBpZGVudGlmaWVkIHdpdGhpbiBhIGhpZXJhcmNoeSBvZiBuZXN0ZWQgTmFtZXNwYWNlcy4gSXQgaXMgY29uc3RydWN0ZWQgZnJvbSB0aGUgbmFtZXMgb2YgdGhlIGNvbnRhaW5pbmcgbmFtZXNwYWNlcyBzdGFydGluZyBhdCB0aGUgcm9vdCBvZiB0aGUgaGllcmFyY2h5IGFuZCBlbmRpbmcgd2l0aCB0aGUgbmFtZSBvZiB0aGUgTmFtZWRFbGVtZW50IGl0c2VsZi4gVGhpcyBpcyBhIGRlcml2ZWQgYXR0cmlidXRlLgoJICogPCEtLSBlbmQtbW9kZWwtZG9jIC0tPgoJICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlICc8ZW0+UXVhbGlmaWVkIE5hbWU8L2VtPicgYXR0cmlidXRlLgoJICogQHNlZSBvcmcuZWNsaXBzZS51bWwyLlVNTDJQYWNrYWdlI2dldE5hbWVkRWxlbWVudF9RdWFsaWZpZWROYW1lKCkKCSAqIEBtb2RlbCBkZWZhdWx0PSIiIGRhdGFUeXBlPSJvcmcuZWNsaXBzZS51bWwyLlN0cmluZyIgdHJhbnNpZW50PSJ0cnVlIiBjaGFuZ2VhYmxlPSJmYWxzZSIgdm9sYXRpbGU9InRydWUiIGRlcml2ZWQ9InRydWUiCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCVN0cmluZyBnZXRRdWFsaWZpZWROYW1lKCk7CgoKCS8qKgoJICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlICc8ZW0+PGI+VmlzaWJpbGl0eTwvYj48L2VtPicgYXR0cmlidXRlLgoJICogVGhlIGxpdGVyYWxzIGFyZSBmcm9tIHRoZSBlbnVtZXJhdGlvbiB7QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5WaXNpYmlsaXR5S2luZH0uCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPHA+CgkgKiBJZiB0aGUgbWVhbmluZyBvZiB0aGUgJzxlbT5WaXNpYmlsaXR5PC9lbT4nIGF0dHJpYnV0ZSBpc24ndCBjbGVhciwKCSAqIHRoZXJlIHJlYWxseSBzaG91bGQgYmUgbW9yZSBvZiBhIGRlc2NyaXB0aW9uIGhlcmUuLi4KCSAqIDwvcD4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogPCEtLSBiZWdpbi1tb2RlbC1kb2MgLS0+CgkgKiBEZXRlcm1pbmVzIHRoZSB2aXNpYmlsaXR5IG9mIHRoZSBOYW1lZEVsZW1lbnQgd2l0aGluIGRpZmZlcmVudCBOYW1lc3BhY2VzIHdpdGhpbiB0aGUgb3ZlcmFsbCBtb2RlbC4gUGFja2FnZSBEZXBlbmRlbmNpZXMgKJNEZXBlbmRlbmNpZXOUIG9uIHBhZ2UgOTQpCgkgKiA8IS0tIGVuZC1tb2RlbC1kb2MgLS0+CgkgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgJzxlbT5WaXNpYmlsaXR5PC9lbT4nIGF0dHJpYnV0ZS4KCSAqIEBzZWUgb3JnLmVjbGlwc2UudW1sMi5WaXNpYmlsaXR5S2luZAoJICogQHNlZSAjc2V0VmlzaWJpbGl0eShWaXNpYmlsaXR5S2luZCkKCSAqIEBzZWUgb3JnLmVjbGlwc2UudW1sMi5VTUwyUGFja2FnZSNnZXROYW1lZEVsZW1lbnRfVmlzaWJpbGl0eSgpCgkgKiBAbW9kZWwKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJVmlzaWJpbGl0eUtpbmQgZ2V0VmlzaWJpbGl0eSgpOwoKCS8qKgoJICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlICd7QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5OYW1lZEVsZW1lbnQjZ2V0VmlzaWJpbGl0eSA8ZW0+VmlzaWJpbGl0eTwvZW0+fScgYXR0cmlidXRlLgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgdmFsdWUgb2YgdGhlICc8ZW0+VmlzaWJpbGl0eTwvZW0+JyBhdHRyaWJ1dGUuCgkgKiBAc2VlIG9yZy5lY2xpcHNlLnVtbDIuVmlzaWJpbGl0eUtpbmQKCSAqIEBzZWUgI2dldFZpc2liaWxpdHkoKQoJICogQGdlbmVyYXRlZAoJICovCgl2b2lkIHNldFZpc2liaWxpdHkoVmlzaWJpbGl0eUtpbmQgdmFsdWUpOwoKCgkvKioKCSAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSAnPGVtPjxiPkNsaWVudCBEZXBlbmRlbmN5PC9iPjwvZW0+JyByZWZlcmVuY2UgbGlzdC4KCSAqIFRoZSBsaXN0IGNvbnRlbnRzIGFyZSBvZiB0eXBlIHtAbGluayBvcmcuZWNsaXBzZS51bWwyLkRlcGVuZGVuY3l9LgoJICogSXQgaXMgYmlkaXJlY3Rpb25hbCBhbmQgaXRzIG9wcG9zaXRlIGlzICd7QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5EZXBlbmRlbmN5I2dldENsaWVudHMgPGVtPkNsaWVudDwvZW0+fScuCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPHA+CgkgKiBJZiB0aGUgbWVhbmluZyBvZiB0aGUgJzxlbT5DbGllbnQgRGVwZW5kZW5jeTwvZW0+JyByZWZlcmVuY2UgbGlzdCBpc24ndCBjbGVhciwKCSAqIHRoZXJlIHJlYWxseSBzaG91bGQgYmUgbW9yZSBvZiBhIGRlc2NyaXB0aW9uIGhlcmUuLi4KCSAqIDwvcD4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlICc8ZW0+Q2xpZW50IERlcGVuZGVuY3k8L2VtPicgcmVmZXJlbmNlIGxpc3QuCgkgKiBAc2VlIG9yZy5lY2xpcHNlLnVtbDIuVU1MMlBhY2thZ2UjZ2V0TmFtZWRFbGVtZW50X0NsaWVudERlcGVuZGVuY3koKQoJICogQHNlZSBvcmcuZWNsaXBzZS51bWwyLkRlcGVuZGVuY3kjZ2V0Q2xpZW50cwoJICogQG1vZGVsIHR5cGU9Im9yZy5lY2xpcHNlLnVtbDIuRGVwZW5kZW5jeSIgb3Bwb3NpdGU9ImNsaWVudCIgb3JkZXJlZD0iZmFsc2UiCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCUVMaXN0IGdldENsaWVudERlcGVuZGVuY2llcygpOwoKCiAgICAvKioKICAgICAqIFJldHJpZXZlcyB0aGUge0BsaW5rIG9yZy5lY2xpcHNlLnVtbDIuRGVwZW5kZW5jeX0gd2l0aCB0aGUgc3BlY2lmaWVkICc8ZW0+PGI+TmFtZTwvYj48L2VtPicgZnJvbSB0aGUgJzxlbT48Yj5DbGllbnQgRGVwZW5kZW5jeTwvYj48L2VtPicgcmVmZXJlbmNlIGxpc3QuCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAcGFyYW0gbmFtZSBUaGUgJzxlbT48Yj5OYW1lPC9iPjwvZW0+JyBvZiB0aGUge0BsaW5rIG9yZy5lY2xpcHNlLnVtbDIuRGVwZW5kZW5jeX0gdG8gcmV0cmlldmUuCgkgKiBAcmV0dXJuIFRoZSB7QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5EZXBlbmRlbmN5fSB3aXRoIHRoZSBzcGVjaWZpZWQgJzxlbT48Yj5OYW1lPC9iPjwvZW0+Jywgb3IgPGNvZGU+bnVsbDwvY29kZT4uCgkgKiBAc2VlICNnZXRDbGllbnREZXBlbmRlbmNpZXMoKQoJICogQGdlbmVyYXRlZAogICAgICovCiAgICBEZXBlbmRlbmN5IGdldENsaWVudERlcGVuZGVuY3koU3RyaW5nIHVucXVhbGlmaWVkTmFtZSk7CiAgICAgIAoJLyoqCgkgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgJzxlbT48Yj5OYW1lIEV4cHJlc3Npb248L2I+PC9lbT4nIGNvbnRhaW5tZW50IHJlZmVyZW5jZS4KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8cD4KCSAqIElmIHRoZSBtZWFuaW5nIG9mIHRoZSAnPGVtPk5hbWUgRXhwcmVzc2lvbjwvZW0+JyBjb250YWlubWVudCByZWZlcmVuY2UgaXNuJ3QgY2xlYXIsCgkgKiB0aGVyZSByZWFsbHkgc2hvdWxkIGJlIG1vcmUgb2YgYSBkZXNjcmlwdGlvbiBoZXJlLi4uCgkgKiA8L3A+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIDwhLS0gYmVnaW4tbW9kZWwtZG9jIC0tPgoJICogVGhlIGV4cHJlc3Npb24gdXNlZCB0byBkZWZpbmUgdGhlIG5hbWUgb2YgdGhpcyBuYW1lZCBlbGVtZW50LgoJICogPCEtLSBlbmQtbW9kZWwtZG9jIC0tPgoJICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlICc8ZW0+TmFtZSBFeHByZXNzaW9uPC9lbT4nIGNvbnRhaW5tZW50IHJlZmVyZW5jZS4KCSAqIEBzZWUgI3NldE5hbWVFeHByZXNzaW9uKFN0cmluZ0V4cHJlc3Npb24pCgkgKiBAc2VlIG9yZy5lY2xpcHNlLnVtbDIuVU1MMlBhY2thZ2UjZ2V0TmFtZWRFbGVtZW50X05hbWVFeHByZXNzaW9uKCkKCSAqIEBtb2RlbCBjb250YWlubWVudD0idHJ1ZSIKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJU3RyaW5nRXhwcmVzc2lvbiBnZXROYW1lRXhwcmVzc2lvbigpOwoKCS8qKgoJICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlICd7QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5OYW1lZEVsZW1lbnQjZ2V0TmFtZUV4cHJlc3Npb24gPGVtPk5hbWUgRXhwcmVzc2lvbjwvZW0+fScgY29udGFpbm1lbnQgcmVmZXJlbmNlLgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgdmFsdWUgb2YgdGhlICc8ZW0+TmFtZSBFeHByZXNzaW9uPC9lbT4nIGNvbnRhaW5tZW50IHJlZmVyZW5jZS4KCSAqIEBzZWUgI2dldE5hbWVFeHByZXNzaW9uKCkKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJdm9pZCBzZXROYW1lRXhwcmVzc2lvbihTdHJpbmdFeHByZXNzaW9uIHZhbHVlKTsKCgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEge0BsaW5rIG9yZy5lY2xpcHNlLnVtbDIuU3RyaW5nRXhwcmVzc2lvbn0gYW5kIHNldHMgdGhlICc8ZW0+PGI+TmFtZSBFeHByZXNzaW9uPC9iPjwvZW0+JyBjb250YWlubWVudCByZWZlcmVuY2UuCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAcGFyYW0gZUNsYXNzIFRoZSBFY29yZSBjbGFzcyBvZiB0aGUge0BsaW5rIG9yZy5lY2xpcHNlLnVtbDIuU3RyaW5nRXhwcmVzc2lvbn0gdG8gY3JlYXRlLgoJICogQHJldHVybiBUaGUgbmV3IHtAbGluayBvcmcuZWNsaXBzZS51bWwyLlN0cmluZ0V4cHJlc3Npb259LgoJICogQHNlZSAjZ2V0TmFtZUV4cHJlc3Npb24oKQoJICogQGdlbmVyYXRlZCBOT1QKCSAqIEBkZXByZWNhdGVkIFVzZSAjY3JlYXRlTmFtZUV4cHJlc3Npb24oKSBpbnN0ZWFkLgogICAgICovCiAgICBTdHJpbmdFeHByZXNzaW9uIGNyZWF0ZU5hbWVFeHByZXNzaW9uKEVDbGFzcyBlQ2xhc3MpOwoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIHtAbGluayBvcmcuZWNsaXBzZS51bWwyLlN0cmluZ0V4cHJlc3Npb259IGFuZCBzZXRzIHRoZSAnPGVtPjxiPk5hbWUgRXhwcmVzc2lvbjwvYj48L2VtPicgY29udGFpbm1lbnQgcmVmZXJlbmNlLgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHJldHVybiBUaGUgbmV3IHtAbGluayBvcmcuZWNsaXBzZS51bWwyLlN0cmluZ0V4cHJlc3Npb259LgoJICogQHNlZSAjZ2V0TmFtZUV4cHJlc3Npb24oKQoJICogQGdlbmVyYXRlZAogICAgICovCiAgICBTdHJpbmdFeHByZXNzaW9uIGNyZWF0ZU5hbWVFeHByZXNzaW9uKCk7CgoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiA8IS0tIGJlZ2luLW1vZGVsLWRvYyAtLT4KCSAqIEEgcXVlcnkgYmFzZWQgb24gdGhlIGZvbGxvd2luZyBPQ0wgZXhwcmVzc2lvbjoKCSAqIDxjb2RlPgoJICogaWYgc2VsZi5uYW1lc3BhY2UtPmlzRW1wdHkoKQoJICogdGhlbiBTZXF1ZW5jZXt9CgkgKiBlbHNlIHNlbGYubmFtZXNwYWNlLmFsbE5hbWVzcGFjZXMoKS0+cHJlcGVuZChzZWxmLm5hbWVzcGFjZSkKCSAqIGVuZGlmCgkgKiA8L2NvZGU+CgkgKiA8IS0tIGVuZC1tb2RlbC1kb2MgLS0+CgkgKiBAbW9kZWwgZGF0YVR5cGU9Im9yZy5lY2xpcHNlLnVtbDIuU2VxdWVuY2UiIG1hbnk9ImZhbHNlIgoJICogQGdlbmVyYXRlZAoJICovCglMaXN0IGFsbE5hbWVzcGFjZXMoKTsKCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIDwhLS0gYmVnaW4tbW9kZWwtZG9jIC0tPgoJICogQSBxdWVyeSBiYXNlZCBvbiB0aGUgZm9sbG93aW5nIE9DTCBleHByZXNzaW9uOgoJICogPGNvZGU+CgkgKiBpZiBzZWxmLm9jbElzS2luZE9mKG4ub2NsVHlwZSkgb3Igbi5vY2xJc0tpbmRPZihzZWxmLm9jbFR5cGUpCgkgKiB0aGVuIG5zLmdldE5hbWVzT2ZNZW1iZXIoc2VsZiktPmludGVyc2VjdGlvbihucy5nZXROYW1lc09mTWVtYmVyKG4pKS0+aXNFbXB0eSgpCgkgKiBlbHNlIHRydWUKCSAqIGVuZGlmCgkgKiA8L2NvZGU+CgkgKiA8IS0tIGVuZC1tb2RlbC1kb2MgLS0+CgkgKiBAbW9kZWwgZGF0YVR5cGU9Im9yZy5lY2xpcHNlLnVtbDIuQm9vbGVhbiIKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJYm9vbGVhbiBpc0Rpc3Rpbmd1aXNoYWJsZUZyb20oTmFtZWRFbGVtZW50IG4sIE5hbWVzcGFjZSBucyk7CgoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiA8IS0tIGJlZ2luLW1vZGVsLWRvYyAtLT4KCSAqIEEgcXVlcnkgYmFzZWQgb24gdGhlIGZvbGxvd2luZyBPQ0wgZXhwcmVzc2lvbjoKCSAqIDxjb2RlPgoJICogJzo6JwoJICogPC9jb2RlPgoJICogPCEtLSBlbmQtbW9kZWwtZG9jIC0tPgoJICogQG1vZGVsIGRhdGFUeXBlPSJvcmcuZWNsaXBzZS51bWwyLlN0cmluZyIKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJU3RyaW5nIHNlcGFyYXRvcigpOwoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogPCEtLSBiZWdpbi1tb2RlbC1kb2MgLS0+CgkgKiBBIHF1ZXJ5IGJhc2VkIG9uIHRoZSBmb2xsb3dpbmcgT0NMIGV4cHJlc3Npb246CgkgKiA8Y29kZT4KCSAqIGlmIHNlbGYubmFtZS0+bm90RW1wdHkoKSBhbmQgc2VsZi5hbGxOYW1lc3BhY2VzKCktPnNlbGVjdChucyB8IG5zLm5hbWUtPmlzRW1wdHkoKSktPmlzRW1wdHkoKQoJICogdGhlbiAKCSAqICAgICBzZWxmLmFsbE5hbWVzcGFjZXMoKS0+aXRlcmF0ZSggbnMgOiBOYW1lc3BhY2U7IHJlc3VsdDogU3RyaW5nID0gc2VsZi5uYW1lIHwgbnMubmFtZS0+dW5pb24oc2VsZi5zZXBhcmF0b3IoKSktPnVuaW9uKHJlc3VsdCkpCgkgKiBlbHNlCgkgKiAgICAgU2V0e30KCSAqIGVuZGlmCgkgKiA8L2NvZGU+CgkgKiA8IS0tIGVuZC1tb2RlbC1kb2MgLS0+CgkgKiBAbW9kZWwgZGF0YVR5cGU9Im9yZy5lY2xpcHNlLnVtbDIuU3RyaW5nIgoJICogQGdlbmVyYXRlZAoJICovCglTdHJpbmcgcXVhbGlmaWVkTmFtZSgpOwoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogPCEtLSBiZWdpbi1tb2RlbC1kb2MgLS0+CgkgKiBBbiBpbnZhcmlhbnQgY29uc3RyYWludCBiYXNlZCBvbiB0aGUgZm9sbG93aW5nIE9DTCBleHByZXNzaW9uOgoJICogPGNvZGU+CgkgKiBuYW1lc3BhY2UtPmlzRW1wdHkoKSBpbXBsaWVzIHZpc2liaWxpdHktPmlzRW1wdHkoKQoJICogPC9jb2RlPgoJICogPCEtLSBlbmQtbW9kZWwtZG9jIC0tPgoJICogQG1vZGVsIGRhdGFUeXBlPSJvcmcuZWNsaXBzZS51bWwyLkJvb2xlYW4iCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCWJvb2xlYW4gdmFsaWRhdGVWaXNpYmlsaXR5TmVlZHNPd25lcnNoaXAoRGlhZ25vc3RpY0NoYWluIGRpYWdub3N0aWNzLCBNYXAgY29udGV4dCk7CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgJzxlbT48Yj5OYW1lc3BhY2U8L2I+PC9lbT4nIHJlZmVyZW5jZS4KCSAqIEl0IGlzIGJpZGlyZWN0aW9uYWwgYW5kIGl0cyBvcHBvc2l0ZSBpcyAne0BsaW5rIG9yZy5lY2xpcHNlLnVtbDIuTmFtZXNwYWNlI2dldE93bmVkTWVtYmVycyA8ZW0+T3duZWQgTWVtYmVyPC9lbT59Jy4KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIDwhLS0gYmVnaW4tbW9kZWwtZG9jIC0tPgoJICogU3BlY2lmaWVzIHRoZSBuYW1lc3BhY2UgdGhhdCBvd25zIHRoZSBOYW1lZEVsZW1lbnQuIFN1YnNldHMgRWxlbWVudDo6b3duZXIuIFRoaXMgaXMgYSBkZXJpdmVkIHVuaW9uLgoJICogPCEtLSBlbmQtbW9kZWwtZG9jIC0tPgoJICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlICc8ZW0+TmFtZXNwYWNlPC9lbT4nIHJlZmVyZW5jZS4KCSAqIEBzZWUgb3JnLmVjbGlwc2UudW1sMi5VTUwyUGFja2FnZSNnZXROYW1lZEVsZW1lbnRfTmFtZXNwYWNlKCkKCSAqIEBzZWUgb3JnLmVjbGlwc2UudW1sMi5OYW1lc3BhY2UjZ2V0T3duZWRNZW1iZXJzCgkgKiBAbW9kZWwgb3Bwb3NpdGU9Im93bmVkTWVtYmVyIiB0cmFuc2llbnQ9InRydWUiIGNoYW5nZWFibGU9ImZhbHNlIiBkZXJpdmVkPSJ0cnVlIgoJICogQGdlbmVyYXRlZAoJICovCglOYW1lc3BhY2UgZ2V0TmFtZXNwYWNlKCk7CgoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogPCEtLSBiZWdpbi1tb2RlbC1kb2MgLS0+CgkgKiBBbiBpbnZhcmlhbnQgY29uc3RyYWludCBiYXNlZCBvbiB0aGUgZm9sbG93aW5nIE9DTCBleHByZXNzaW9uOgoJICogPGNvZGU+CgkgKiBzZWxmLm5hbWUtPmlzRW1wdHkoKSBvciBzZWxmLmFsbE5hbWVzcGFjZXMoKS0+c2VsZWN0KG5zIHwgbnMubmFtZS0+aXNFbXB0eSgpKS0+bm90RW1wdHkoKQoJICogCWltcGxpZXMgc2VsZi5xdWFsaWZpZWROYW1lLT5pc0VtcHR5KCkKCSAqIDwvY29kZT4KCSAqIDwhLS0gZW5kLW1vZGVsLWRvYyAtLT4KCSAqIEBtb2RlbCBkYXRhVHlwZT0ib3JnLmVjbGlwc2UudW1sMi5Cb29sZWFuIgoJICogQGdlbmVyYXRlZAoJICovCglib29sZWFuIHZhbGlkYXRlTm9OYW1lKERpYWdub3N0aWNDaGFpbiBkaWFnbm9zdGljcywgTWFwIGNvbnRleHQpOwoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogPCEtLSBiZWdpbi1tb2RlbC1kb2MgLS0+CgkgKiBBbiBpbnZhcmlhbnQgY29uc3RyYWludCBiYXNlZCBvbiB0aGUgZm9sbG93aW5nIE9DTCBleHByZXNzaW9uOgoJICogPGNvZGU+CgkgKiAoc2VsZi5uYW1lLT5ub3RFbXB0eSgpIGFuZCBzZWxmLmFsbE5hbWVzcGFjZXMoKS0+c2VsZWN0KG5zIHwgbnMubmFtZS0+aXNFbXB0eSgpKS0+aXNFbXB0eSgpKSBpbXBsaWVzCgkgKiBzZWxmLnF1YWxpZmllZE5hbWUgPQoJICogIHNlbGYuYWxsTmFtZXNwYWNlcygpLT5pdGVyYXRlKCBucyA6IE5hbWVzcGFjZTsgcmVzdWx0OiBTdHJpbmcgPSBzZWxmLm5hbWUgfAoJICogCQlucy5uYW1lLT51bmlvbihzZWxmLnNlcGFyYXRvcigpKS0+dW5pb24ocmVzdWx0KSkKCSAqIDwvY29kZT4KCSAqIDwhLS0gZW5kLW1vZGVsLWRvYyAtLT4KCSAqIEBtb2RlbCBkYXRhVHlwZT0ib3JnLmVjbGlwc2UudW1sMi5Cb29sZWFuIgoJICogQGdlbmVyYXRlZAoJICovCglib29sZWFuIHZhbGlkYXRlUXVhbGlmaWVkTmFtZShEaWFnbm9zdGljQ2hhaW4gZGlhZ25vc3RpY3MsIE1hcCBjb250ZXh0KTsKCgkvLyA8IS0tIGJlZ2luLWN1c3RvbS1vcGVyYXRpb25zIC0tPgoKCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNFUEFSQVRPUiA9ICI6OiI7IC8vJE5PTi1OTFMtMSQKCgkvKioKCSAqIFJldHJpZXZlcyBhIGxvY2FsaXplZCBsYWJlbCBmb3IgdGhpcyBuYW1lZCBlbGVtZW50LgoJICogCgkgKiBAcmV0dXJuIEEgbG9jYWxpemVkIGxhYmVsIGZvciB0aGlzIG5hbWVkIGVsZW1lbnQuCgkgKi8KCXB1YmxpYyBTdHJpbmcgZ2V0TGFiZWwoKTsKCgkvKioKCSAqIFJldHJpZXZlcyBhIGxhYmVsIGZvciB0aGlzIG5hbWVkIGVsZW1lbnQsIGxvY2FsaXplZCBpZiBpbmRpY2F0ZWQuCgkgKiAKCSAqIEBwYXJhbSBsb2NhbGl6ZQoJICogICAgICAgICAgICBXaGV0aGVyIHRoZSBsYWJlbCBzaG91bGQgYmUgbG9jYWxpemVkLgoJICogQHJldHVybiBBIChsb2NhbGl6ZWQpIGxhYmVsIGZvciB0aGlzIG5hbWVkIGVsZW1lbnQuCgkgKi8KCXB1YmxpYyBTdHJpbmcgZ2V0TGFiZWwoYm9vbGVhbiBsb2NhbGl6ZSk7CgoJLy8gPCEtLSBlbmQtY3VzdG9tLW9wZXJhdGlvbnMgLS0+Cgp9IC8vIE5hbWVkRWxlbWVudAo=