LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDEwIEFuZHJlYSBCaXR0YXUsIFVuaXZlcnNpdHkgQ29sbGVnZSBMb25kb24sIGFuZCBvdGhlcnMKICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwogKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKICoKICogQ29udHJpYnV0b3JzOgogKiAgICAgQW5kcmVhIEJpdHRhdSAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbiBmcm9tIHRoZSBQc3ljaG9QYXRoIFhQYXRoIDIuMAogKiAgICAgTXVrdWwgR2FuZGhpIC0gYnVnIDI3NjEzNCAtIGltcHJvdmVtZW50cyB0byBzY2hlbWEgYXdhcmUgcHJpbWl0aXZlIHR5cGUgc3VwcG9ydAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBhdHRyaWJ1dGUvZWxlbWVudCBub2RlcyAKICogICAgIERhdmlkIENhcnZlciAtIGJ1ZyAyNjI3NjUgLSBmaXhlZCBjb21wYXJpc29uIG9uIHNlcXVlbmNlIHJhbmdlIHZhbHVlcy4KICogICAgIEplc3BlciBTIE1vbGxlciAtIGJ1ZyAyODMyMTQgLSBmaXggZXEgZm9yIHVudHlwZWQgYXRvbWljIHZhbHVlcwogKiAgICAgSmVzcGVyIFN0ZWVuIE1vZWxsZXIgLSBidWcgMjg1MTQ1IC0gaW1wbGVtZW50IGZ1bGwgYXJpdHkgY2hlY2tpbmcKICogICAgIEplc3BlciBTdGVlbiBNb2VsbGVyIC0gYnVnIDI4MDU1NSAtIEFkZCBwbHVnZ2FibGUgY29sbGF0aW9uIHN1cHBvcnQKICogICAgIE11a3VsIEdhbmRoaSAtIGJ1ZyAyODA3OTggLSBQc3ljaG9QYXRoIHN1cHBvcnQgZm9yIEpESyAxLjQKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC54bWwueHBhdGgyLnByb2Nlc3Nvci5pbnRlcm5hbC5mdW5jdGlvbjsKCmltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOwppbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwoKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwueHBhdGgyLmFwaS5EeW5hbWljQ29udGV4dDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwueHBhdGgyLmFwaS5FdmFsdWF0aW9uQ29udGV4dDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwueHBhdGgyLmFwaS5JdGVtOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnhtbC54cGF0aDIuYXBpLlJlc3VsdEJ1ZmZlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwueHBhdGgyLmFwaS5SZXN1bHRTZXF1ZW5jZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwueHBhdGgyLnByb2Nlc3Nvci5EeW5hbWljRXJyb3I7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QueG1sLnhwYXRoMi5wcm9jZXNzb3IuUmVzdWx0U2VxdWVuY2VGYWN0b3J5OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnhtbC54cGF0aDIucHJvY2Vzc29yLmludGVybmFsLlR5cGVFcnJvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwueHBhdGgyLnByb2Nlc3Nvci5pbnRlcm5hbC50eXBlcy5BbnlUeXBlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnhtbC54cGF0aDIucHJvY2Vzc29yLmludGVybmFsLnR5cGVzLk51bWVyaWNUeXBlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnhtbC54cGF0aDIucHJvY2Vzc29yLmludGVybmFsLnR5cGVzLlFOYW1lOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnhtbC54cGF0aDIucHJvY2Vzc29yLmludGVybmFsLnR5cGVzLlhTQm9vbGVhbjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwueHBhdGgyLnByb2Nlc3Nvci5pbnRlcm5hbC50eXBlcy5YU0RvdWJsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwueHBhdGgyLnByb2Nlc3Nvci5pbnRlcm5hbC50eXBlcy5YU1N0cmluZzsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwueHBhdGgyLnByb2Nlc3Nvci5pbnRlcm5hbC50eXBlcy5YU1VudHlwZWRBdG9taWM7CgovKioKICogQ2xhc3MgZm9yIHRoZSBFcXVhbGl0eSBmdW5jdGlvbi4KICovCnB1YmxpYyBjbGFzcyBGc0VxIGV4dGVuZHMgRnVuY3Rpb24gewoJLyoqCgkgKiBDb25zdHJ1Y3RvciBmb3IgRnNFcS4KCSAqLwoJcHVibGljIEZzRXEoKSB7CgkJc3VwZXIobmV3IFFOYW1lKCJlcSIpLCAyKTsKCX0KCgkvKioKCSAqIEV2YWx1YXRlIGFyZ3VtZW50cy4KCSAqIAoJICogQHBhcmFtIGFyZ3MKCSAqICAgICAgICAgICAgYXJndW1lbnQgZXhwcmVzc2lvbnMuCgkgKiBAdGhyb3dzIER5bmFtaWNFcnJvcgoJICogICAgICAgICAgICAgRHluYW1pYyBlcnJvci4KCSAqIEByZXR1cm4gUmVzdWx0IG9mIGV2YWx1YXRpb24uCgkgKi8KCXB1YmxpYyBSZXN1bHRTZXF1ZW5jZSBldmFsdWF0ZShDb2xsZWN0aW9uIGFyZ3MsIEV2YWx1YXRpb25Db250ZXh0IGVjKSB0aHJvd3MgRHluYW1pY0Vycm9yIHsKCQlhc3NlcnQgYXJncy5zaXplKCkgPj0gbWluX2FyaXR5KCkgJiYgYXJncy5zaXplKCkgPD0gbWF4X2FyaXR5KCk7CgoJCXJldHVybiBmc19lcV92YWx1ZShhcmdzLCBlYy5nZXREeW5hbWljQ29udGV4dCgpKTsKCX0KCgkvKioKCSAqIENvbnZlcnRzIGFyZ3VtZW50cyB0byB2YWx1ZXMuCgkgKiAKCSAqIEBwYXJhbSBhcmdzCgkgKiAgICAgICAgICAgIFJlc3VsdCBmcm9tIGV4cHJlc3Npb25zIGV2YWx1YXRpb24uCgkgKiBAdGhyb3dzIER5bmFtaWNFcnJvcgoJICogICAgICAgICAgICAgRHluYW1pYyBlcnJvci4KCSAqIEByZXR1cm4gUmVzdWx0IG9mIGNvbnZlcnNpb24uCgkgKi8KCXByaXZhdGUgc3RhdGljIENvbGxlY3Rpb24gdmFsdWVfY29udmVydF9hcmdzKENvbGxlY3Rpb24gYXJncykKCQkJdGhyb3dzIER5bmFtaWNFcnJvciB7CgkJQ29sbGVjdGlvbiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0KGFyZ3Muc2l6ZSgpKTsKCgkJLy8gYXRvbWl6ZSBhcmd1bWVudHMKCQlmb3IgKEl0ZXJhdG9yIGkgPSBhcmdzLml0ZXJhdG9yKCk7IGkuaGFzTmV4dCgpOykgewoJCQlSZXN1bHRTZXF1ZW5jZSBycyA9IChSZXN1bHRTZXF1ZW5jZSkgaS5uZXh0KCk7CgoJCQkvL0ZuRGF0YS5mYXN0X2F0b21pemUocnMpOwoJCQlycyA9IEZuRGF0YS5hdG9taXplKHJzKTsKCgkJCWlmIChycy5lbXB0eSgpKQoJCQkJcmV0dXJuIG5ldyBBcnJheUxpc3QoKTsKCgkJCWlmIChycy5zaXplKCkgPiAxKQoJCQkJdGhyb3cgbmV3IER5bmFtaWNFcnJvcihUeXBlRXJyb3IuaW52YWxpZF90eXBlKG51bGwpKTsKCgkJCUl0ZW0gYXJnID0gcnMuZmlyc3QoKTsKCgkJCWlmIChhcmcgaW5zdGFuY2VvZiBYU1VudHlwZWRBdG9taWMpCgkJCQlhcmcgPSBuZXcgWFNTdHJpbmcoYXJnLmdldFN0cmluZ1ZhbHVlKCkpOwoKCQkJcmVzdWx0LmFkZChhcmcpOwoJCX0KCgkJcmV0dXJuIHJlc3VsdDsKCX0KCgkvKioKCSAqIENvbnZlcnNpb24gb3BlcmF0aW9uIGZvciB0aGUgdmFsdWVzIG9mIHRoZSBhcmd1bWVudHMuCgkgKiAKCSAqIEBwYXJhbSBhcmdzCgkgKiAgICAgICAgICAgIFJlc3VsdCBmcm9tIGNvbnZlcnQgdmFsdWUgb3BlcmF0aW9uLgoJICogQHRocm93cyBEeW5hbWljRXJyb3IKCSAqICAgICAgICAgICAgIER5bmFtaWMgZXJyb3IuCgkgKiBAcmV0dXJuIFJlc3VsdCBvZiBjb252ZXJzaW9uLgoJICovCglwdWJsaWMgc3RhdGljIFJlc3VsdFNlcXVlbmNlIGZzX2VxX3ZhbHVlKENvbGxlY3Rpb24gYXJncywgRHluYW1pY0NvbnRleHQgY29udGV4dCkKCQkJdGhyb3dzIER5bmFtaWNFcnJvciB7CgkJcmV0dXJuIGRvX2NtcF92YWx1ZV9vcChhcmdzLCBDbXBFcS5jbGFzcywgImVxIiwgY29udGV4dCk7Cgl9CgoJLyoqCgkgKiBBIGZhc3QgRXF1YWxpdHkgb3BlcmF0aW9uLCBubyBjb252ZXJzaW9uIGZvciB0aGUgaW5wdXRzIHBlcmZvcm1lZC4KCSAqIAoJICogQHBhcmFtIG9uZQoJICogICAgICAgICAgICBpbnB1dDEgb2YgYW55IHR5cGUuCgkgKiBAcGFyYW0gdHdvCgkgKiAgICAgICAgICAgIGlucHV0MiBvZiBhbnkgdHlwZS4KCSAqIEB0aHJvd3MgRHluYW1pY0Vycm9yCgkgKiAgICAgICAgICAgICBEeW5hbWljIGVycm9yLgoJICogQHJldHVybiBSZXN1bHQgb2YgRXF1YWxpdHkgb3BlcmF0aW9uLgoJICovCglwdWJsaWMgc3RhdGljIGJvb2xlYW4gZnNfZXFfZmFzdChBbnlUeXBlIG9uZSwgQW55VHlwZSB0d28sIER5bmFtaWNDb250ZXh0IGNvbnRleHQpCgkJCXRocm93cyBEeW5hbWljRXJyb3IgewoKCQlvbmUgPSBGbkRhdGEuYXRvbWl6ZSgoSXRlbSlvbmUpOwoJCXR3byA9IEZuRGF0YS5hdG9taXplKChJdGVtKXR3byk7CgoJCWlmIChvbmUgaW5zdGFuY2VvZiBYU1VudHlwZWRBdG9taWMpCgkJCW9uZSA9IG5ldyBYU1N0cmluZyhvbmUuZ2V0U3RyaW5nVmFsdWUoKSk7CgoJCWlmICh0d28gaW5zdGFuY2VvZiBYU1VudHlwZWRBdG9taWMpCgkJCXR3byA9IG5ldyBYU1N0cmluZyh0d28uZ2V0U3RyaW5nVmFsdWUoKSk7CgoJCWlmICghKG9uZSBpbnN0YW5jZW9mIENtcEVxKSkKCQkJRHluYW1pY0Vycm9yLnRocm93X3R5cGVfZXJyb3IoKTsKCgkJQ21wRXEgY21wb25lID0gKENtcEVxKSBvbmU7CgoJCXJldHVybiBjbXBvbmUuZXEodHdvLCBjb250ZXh0KTsKCX0KCgkvKioKCSAqIE1ha2luZyBzdXJlIHRoYXQgdGhlIHR5cGVzIGFyZSB0aGUgc2FtZSBiZWZvcmUgY29tcGFyaW5nIHRoZSBpbnB1dHMuCgkgKiAKCSAqIEBwYXJhbSBhCgkgKiAgICAgICAgICAgIGlucHV0MSBvZiBhbnkgdHlwZS4KCSAqIEBwYXJhbSBiCgkgKiAgICAgICAgICAgIGlucHV0MiBvZiBhbnkgdHlwZS4KCSAqIEBwYXJhbSBkYwoJICogICAgICAgICAgICAgIER5bmFtaWMgQ29udGV4dAoJICogQHRocm93cyBEeW5hbWljRXJyb3IKCSAqICAgICAgICAgICAgIER5bmFtaWMgZXJyb3IuCgkgKiBAcmV0dXJuIFJlc3VsdCBvZiBFcXVhbGl0eSBvcGVyYXRpb24uCgkgKi8KCXByaXZhdGUgc3RhdGljIGJvb2xlYW4gZG9fZ2VuZXJhbF9wYWlyKEFueVR5cGUgYSwgQW55VHlwZSBiLAoJCQlNZXRob2QgY29tcGFyYXRvciwgRHluYW1pY0NvbnRleHQgZWMpIHRocm93cyBEeW5hbWljRXJyb3IgewoKCQkvLyBzZWN0aW9uIDMuNS4yCgoJCS8vIHJ1bGUgYQoJCS8vIGlmIG9uZSBpcyB1bnR5cGVkIGFuZCBvdGhlciBpcyBudW1lcmljLCBjYXN0IHVudHlwZWQgdG8KCQkvLyBkb3VibGUKCQlpZiAoKGEgaW5zdGFuY2VvZiBYU1VudHlwZWRBdG9taWMgJiYgYiBpbnN0YW5jZW9mIE51bWVyaWNUeXBlKQoJCQkJfHwgKGIgaW5zdGFuY2VvZiBYU1VudHlwZWRBdG9taWMgJiYgYSBpbnN0YW5jZW9mIE51bWVyaWNUeXBlKSkgewoJCQlpZiAoYSBpbnN0YW5jZW9mIFhTVW50eXBlZEF0b21pYykKCQkJCWEgPSBuZXcgWFNEb3VibGUoYS5nZXRTdHJpbmdWYWx1ZSgpKTsKCQkJZWxzZQoJCQkJYiA9IG5ldyBYU0RvdWJsZShiLmdldFN0cmluZ1ZhbHVlKCkpOwoKCQl9CgoJCS8vIHJ1bGUgYgoJCS8vIGlmIG9uZSBpcyB1bnR5cGVkIGFuZCBvdGhlciBpcyBzdHJpbmcgb3IgdW50eXBlZCwgdGhlbiBjYXN0CgkJLy8gdW50eXBlZCB0byBzdHJpbmcKCQllbHNlIGlmICgoYSBpbnN0YW5jZW9mIFhTVW50eXBlZEF0b21pYwoJCQkJJiYgKGIgaW5zdGFuY2VvZiBYU1N0cmluZyB8fCBiIGluc3RhbmNlb2YgWFNVbnR5cGVkQXRvbWljKSB8fCAoYiBpbnN0YW5jZW9mIFhTVW50eXBlZEF0b21pYyAmJiAoYSBpbnN0YW5jZW9mIFhTU3RyaW5nIHx8IGEgaW5zdGFuY2VvZiBYU1VudHlwZWRBdG9taWMpKSkpIHsKCgkJCWlmIChhIGluc3RhbmNlb2YgWFNVbnR5cGVkQXRvbWljKQoJCQkJYSA9IG5ldyBYU1N0cmluZyhhLmdldFN0cmluZ1ZhbHVlKCkpOwoJCQlpZiAoYiBpbnN0YW5jZW9mIFhTVW50eXBlZEF0b21pYykKCQkJCWIgPSBuZXcgWFNTdHJpbmcoYi5nZXRTdHJpbmdWYWx1ZSgpKTsKCQl9CgoJCS8vIHJ1bGUgYwoJCS8vIGlmIG9uZSBpcyB1bnR5cGVkIGFuZCBvdGhlciBpcyBub3Qgc3RyaW5nLHVudHlwZWQsbnVtZXJpYwoJCS8vIGNhc3QgdW50eXBlZCB0byBkeW5hbWljIHR5cGUgb2Ygb3RoZXIKCgkJLy8gWFhYPwoJCS8vIFRPRE86IFRoaXMgbWFrZXMgbm8gc2Vuc2UgYXMgaW1wbGVtZW50ZWQgYmVmb3JlCgkJZWxzZSBpZiAoYSBpbnN0YW5jZW9mIFhTVW50eXBlZEF0b21pYykgewovLwkJCVJlc3VsdFNlcXVlbmNlIGNvbnZlcnRlZCA9IFJlc3VsdFNlcXVlbmNlRmFjdG9yeS5jcmVhdGVfbmV3KGEpOwovLwkJCWFzc2VydCBjb252ZXJ0ZWQuc2l6ZSgpID09IDE7Ci8vCQkJYSA9IGNvbnZlcnRlZC5maXJzdCgpOwoJCX0gZWxzZSBpZiAoYiBpbnN0YW5jZW9mIFhTVW50eXBlZEF0b21pYykgewovLwkJCVJlc3VsdFNlcXVlbmNlIGNvbnZlcnRlZCA9IFJlc3VsdFNlcXVlbmNlRmFjdG9yeS5jcmVhdGVfbmV3KGIpOwovLwkJCWFzc2VydCBjb252ZXJ0ZWQuc2l6ZSgpID09IDE7Ci8vCQkJYiA9IGNvbnZlcnRlZC5maXJzdCgpOwoJCX0KCgkJLy8gcnVsZSBkCgkJLy8gaWYgdmFsdWUgY29tcGFyaXNvbiBpcyB0cnVlLCByZXR1cm4gdHJ1ZS4KCgkJUmVzdWx0U2VxdWVuY2Ugb25lID0gUmVzdWx0U2VxdWVuY2VGYWN0b3J5LmNyZWF0ZV9uZXcoYSk7CgkJUmVzdWx0U2VxdWVuY2UgdHdvID0gUmVzdWx0U2VxdWVuY2VGYWN0b3J5LmNyZWF0ZV9uZXcoYik7CgoJCUNvbGxlY3Rpb24gYXJncyA9IG5ldyBBcnJheUxpc3QoKTsKCQlhcmdzLmFkZChvbmUpOwoJCWFyZ3MuYWRkKHR3byk7CgoJCU9iamVjdCBtYXJnc1tdID0geyBhcmdzLCBlYyB9OwoKCQlSZXN1bHRTZXF1ZW5jZSByZXN1bHQgPSBudWxsOwoJCXRyeSB7CgkJCXJlc3VsdCA9IChSZXN1bHRTZXF1ZW5jZSkgY29tcGFyYXRvci5pbnZva2UobnVsbCwgbWFyZ3MpOwoJCX0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZXJyKSB7CgkJCWFzc2VydCBmYWxzZTsKCQl9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGVycikgewoJCQlUaHJvd2FibGUgZXggPSBlcnIuZ2V0VGFyZ2V0RXhjZXB0aW9uKCk7CgoJCQlpZiAoZXggaW5zdGFuY2VvZiBSdW50aW1lRXhjZXB0aW9uKQoJCQkJdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pIGV4OwoJCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihleCk7CgkJfQoKCQlpZiAoKChYU0Jvb2xlYW4pIHJlc3VsdC5maXJzdCgpKS52YWx1ZSgpKQoJCQlyZXR1cm4gdHJ1ZTsKCgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogQSBnZW5lcmFsIGVxdWFsaXR5IGZ1bmN0aW9uLgoJICogCgkgKiBAcGFyYW0gYXJncwoJICogICAgICAgICAgICBpbnB1dCBhcmd1bWVudHMuCgkgKiBAcGFyYW0gZGMKCSAqICAgICAgICAgRHluYW1pYyBjb250ZXh0IAoJICogQHJldHVybiBSZXN1bHQgb2YgZ2VuZXJhbCBlcXVhbGl0eSBvcGVyYXRpb24uCgkgKi8KCXB1YmxpYyBzdGF0aWMgUmVzdWx0U2VxdWVuY2UgZnNfZXFfZ2VuZXJhbChDb2xsZWN0aW9uIGFyZ3MsIER5bmFtaWNDb250ZXh0IGRjKQoJCQl7CgkJcmV0dXJuIGRvX2NtcF9nZW5lcmFsX29wKGFyZ3MsIEZzRXEuY2xhc3MsICJmc19lcV92YWx1ZSIsIGRjKTsKCX0KCgkvLyB2b29kb28gMwoJLyoqCgkgKiBBY3R1YWwgZXF1YWxpdHkgb3BlcmF0aW9uIGZvciBmc19lcV9nZW5lcmFsLgoJICogCgkgKiBAcGFyYW0gYXJncwoJICogICAgICAgICAgICBpbnB1dCBhcmd1bWVudHMuCgkgKiBAcGFyYW0gdHlwZQoJICogICAgICAgICAgICB0eXBlIG9mIHRoZSBhcmd1bWVudHMuCgkgKiBAcGFyYW0gbW5hbWUKCSAqICAgICAgICAgICAgTWV0aG9kIG5hbWUgZm9yIHRlbXBsYXRlIHNpbXVsYXRpb24uCgkgKiBAdGhyb3dzIER5bmFtaWNFcnJvcgoJICogICAgICAgICAgICAgRHluYW1pYyBlcnJvci4KCSAqIEByZXR1cm4gUmVzdWx0IG9mIHRoZSBvcGVyYXRpb24uCgkgKi8KCXB1YmxpYyBzdGF0aWMgUmVzdWx0U2VxdWVuY2UgZG9fY21wX2dlbmVyYWxfb3AoQ29sbGVjdGlvbiBhcmdzLCBDbGFzcyB0eXBlLAoJCQlTdHJpbmcgbW5hbWUsIER5bmFtaWNDb250ZXh0IGRjKSB0aHJvd3MgRHluYW1pY0Vycm9yIHsKCgkJLy8gZG8gdGhlIHZvb2RvbwoJCU1ldGhvZCBjb21wYXJhdG9yID0gbnVsbDsKCgkJdHJ5IHsKCQkJQ2xhc3MgbWFyZ3NkZWZbXSA9IHsgQ29sbGVjdGlvbi5jbGFzcywgRHluYW1pY0NvbnRleHQuY2xhc3MgfTsKCgkJCWNvbXBhcmF0b3IgPSB0eXBlLmdldE1ldGhvZChtbmFtZSwgbWFyZ3NkZWYpOwoKCQl9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZXJyKSB7CgkJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJDYW6/J3QgZmluZCBtZXRob2QgOiAiICsgbW5hbWUsIGVycik7CgkJfQoKCQkvLyBzYW5pdHkgY2hlY2sgYXJncyBhbmQgZ2V0IHRoZW0KCQlpZiAoYXJncy5zaXplKCkgIT0gMikKCQkJRHluYW1pY0Vycm9yLnRocm93X3R5cGVfZXJyb3IoKTsKCgkJSXRlcmF0b3IgYXJnaXRlciA9IGFyZ3MuaXRlcmF0b3IoKTsKCgkJb3JnLmVjbGlwc2Uud3N0LnhtbC54cGF0aDIuYXBpLlJlc3VsdFNlcXVlbmNlIG9uZSA9IChvcmcuZWNsaXBzZS53c3QueG1sLnhwYXRoMi5hcGkuUmVzdWx0U2VxdWVuY2UpIGFyZ2l0ZXIubmV4dCgpOwoJCW9yZy5lY2xpcHNlLndzdC54bWwueHBhdGgyLmFwaS5SZXN1bHRTZXF1ZW5jZSB0d28gPSAob3JnLmVjbGlwc2Uud3N0LnhtbC54cGF0aDIuYXBpLlJlc3VsdFNlcXVlbmNlKSBhcmdpdGVyLm5leHQoKTsKCgkJLy8gWFhYID8KCQlpZiAob25lLmVtcHR5KCkgfHwgdHdvLmVtcHR5KCkpCgkJCXJldHVybiBSZXN1bHRTZXF1ZW5jZUZhY3RvcnkuY3JlYXRlX25ldyhuZXcgWFNCb29sZWFuKGZhbHNlKSk7CgoJCS8vIGF0b21pemUKCQlvbmUgPSBGbkRhdGEuYXRvbWl6ZShvbmUpOwoJCXR3byA9IEZuRGF0YS5hdG9taXplKHR3byk7CgoJCS8vIHdlIGdvdHRhIGZpbmQgYSBwYWlyIHRoYXQgc2F0aXNmaWVkIHRoZSBjb25kaXRpb24KCQlmb3IgKEl0ZXJhdG9yIGkgPSBvbmUuaXRlcmF0b3IoKTsgaS5oYXNOZXh0KCk7KSB7CgkJCUFueVR5cGUgYSA9IChBbnlUeXBlKSBpLm5leHQoKTsKCQkJZm9yIChJdGVyYXRvciBqID0gdHdvLml0ZXJhdG9yKCk7IGouaGFzTmV4dCgpOykgewoJCQkJQW55VHlwZSBiID0gKEFueVR5cGUpIGoubmV4dCgpOwoKCQkJCWlmIChkb19nZW5lcmFsX3BhaXIoYSwgYiwgY29tcGFyYXRvciwgZGMpKQoJCQkJCXJldHVybiBSZXN1bHRTZXF1ZW5jZUZhY3RvcnkKCQkJCQkJCS5jcmVhdGVfbmV3KG5ldyBYU0Jvb2xlYW4odHJ1ZSkpOwoJCQl9CgkJfQoKCQlyZXR1cm4gUmVzdWx0U2VxdWVuY2VGYWN0b3J5LmNyZWF0ZV9uZXcobmV3IFhTQm9vbGVhbihmYWxzZSkpOwoJfQoKCS8vIHZvb2RvbyAyCgkvKioKCSAqIEFjdHVhbCBlcXVhbGl0eSBvcGVyYXRpb24gZm9yIGZzX2VxX3ZhbHVlLgoJICogCgkgKiBAcGFyYW0gYXJncwoJICogICAgICAgICAgICBpbnB1dCBhcmd1bWVudHMuCgkgKiBAcGFyYW0gdHlwZQoJICogICAgICAgICAgICB0eXBlIG9mIHRoZSBhcmd1bWVudHMuCgkgKiBAcGFyYW0gbW5hbWUKCSAqICAgICAgICAgICAgTWV0aG9kIG5hbWUgZm9yIHRlbXBsYXRlIHNpbXVsYXRpb24uCgkgKiBAcGFyYW0gZHluYW1pY0NvbnRleHQgCgkgKiAgICAgICAgICAgICBEeW5hbWljIGVycm9yLgoJICogQHRocm93cyBEeW5hbWljRXJyb3IKCSAqICAgICAgICAgICAgIER5bmFtaWMgZXJyb3IuCgkgKiBAcmV0dXJuIFJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgoJICovCglwdWJsaWMgc3RhdGljIFJlc3VsdFNlcXVlbmNlIGRvX2NtcF92YWx1ZV9vcChDb2xsZWN0aW9uIGFyZ3MsIENsYXNzIHR5cGUsCgkJCVN0cmluZyBtbmFtZSwgRHluYW1pY0NvbnRleHQgY29udGV4dCkgdGhyb3dzIER5bmFtaWNFcnJvciB7CgoJCS8vIHNhbml0eSBjaGVjayBhcmdzICsgY29udmVydCBlbQoJCWlmIChhcmdzLnNpemUoKSAhPSAyKQoJCQlEeW5hbWljRXJyb3IudGhyb3dfdHlwZV9lcnJvcigpOwoKCQlDb2xsZWN0aW9uIGNhcmdzID0gdmFsdWVfY29udmVydF9hcmdzKGFyZ3MpOwoKCQlpZiAoY2FyZ3Muc2l6ZSgpID09IDApCgkJCXJldHVybiBSZXN1bHRCdWZmZXIuRU1QVFk7CgoJCS8vIG1ha2Ugc3VyZSBhcnVnbWVudHMgYXJlIGNvbXBhcmFibGUgYnkgZXF1YWxpdHkKCQlJdGVyYXRvciBhcmdpID0gY2FyZ3MuaXRlcmF0b3IoKTsKCQlJdGVtIGFyZyA9ICgoUmVzdWx0U2VxdWVuY2UpIGFyZ2kubmV4dCgpKS5maXJzdCgpOwoJCVJlc3VsdFNlcXVlbmNlIGFyZzIgPSAoUmVzdWx0U2VxdWVuY2UpIGFyZ2kubmV4dCgpOwoKCQlpZiAoYXJnMi5zaXplKCkgIT0gMSkKCQkJRHluYW1pY0Vycm9yLnRocm93X3R5cGVfZXJyb3IoKTsKCgkJaWYgKCEodHlwZS5pc0luc3RhbmNlKGFyZykpKQoJCQlEeW5hbWljRXJyb3IudGhyb3dfdHlwZV9lcnJvcigpOwoKCQl0cnkgewoJCQlDbGFzcyBtYXJnc2RlZltdID0geyBBbnlUeXBlLmNsYXNzLCBEeW5hbWljQ29udGV4dC5jbGFzcyB9OwoJCQlNZXRob2QgbWV0aG9kID0gbnVsbDsKCgkJCW1ldGhvZCA9IHR5cGUuZ2V0TWV0aG9kKG1uYW1lLCBtYXJnc2RlZik7CgoJCQlPYmplY3QgbWFyZ3NbXSA9IHsgYXJnMi5maXJzdCgpLCBjb250ZXh0IH07CgkJCUJvb2xlYW4gY21wcmVzID0gKEJvb2xlYW4pIG1ldGhvZC5pbnZva2UoYXJnLCBtYXJncyk7CgoJCQlyZXR1cm4gUmVzdWx0U2VxdWVuY2VGYWN0b3J5LmNyZWF0ZV9uZXcobmV3IFhTQm9vbGVhbihjbXByZXMKCQkJCQkuYm9vbGVhblZhbHVlKCkpKTsKCQl9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZXJyKSB7CgkJCWFzc2VydCBmYWxzZTsKCQkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oImNhbm5vdCBjb21wYXJlIHVzaW5nIG1ldGhvZCAiICsgbW5hbWUsIGVycik7CgkJfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlcnIpIHsKCQkJYXNzZXJ0IGZhbHNlOwoJCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiY2Fubm90IGNvbXBhcmUgdXNpbmcgbWV0aG9kICIgKyBtbmFtZSwgZXJyKTsKCQl9IGNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGVycikgewoJCQlUaHJvd2FibGUgZXggPSBlcnIuZ2V0VGFyZ2V0RXhjZXB0aW9uKCk7CgoJCQlpZiAoZXggaW5zdGFuY2VvZiBEeW5hbWljRXJyb3IpCgkJCQl0aHJvdyAoRHluYW1pY0Vycm9yKSBleDsKCgkJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJjYW5ub3QgY29tcGFyZSB1c2luZyBtZXRob2QgIiArIG1uYW1lLCBleCk7CgkJfQoJfQp9Cg==