LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA4LCAyMDA5IFN1biBNaWNyb3N5c3RlbXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIAogKiAKICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIAogKiB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wIGFuZCBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIHYuIDEuMCAKICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24uIAogKiBUaGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSBpcyBhdmFpbGFibGUgYXQgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKICogYW5kIHRoZSBFY2xpcHNlIERpc3RyaWJ1dGlvbiBMaWNlbnNlIGlzIGF2YWlsYWJsZSBhdCAKICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9vcmcvZG9jdW1lbnRzL2VkbC12MTAucGhwLgogKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgTGluZGEgRGVNaWNoaWVsIC0gSmF2YSBQZXJzaXN0ZW5jZSAyLjAgLSBWZXJzaW9uIDIuMCAoT2N0b2JlciAxLCAyMDA5KQogKiAgICAgU3BlY2lmaWNhdGlvbiBhdmFpbGFibGUgZnJvbSBodHRwOi8vamNwLm9yZy9lbi9qc3IvZGV0YWlsP2lkPTMxNwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIGphdmF4LnBlcnNpc3RlbmNlOwoKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZheC5wZXJzaXN0ZW5jZS5tZXRhbW9kZWwuTWV0YW1vZGVsOwppbXBvcnQgamF2YXgucGVyc2lzdGVuY2UuY3JpdGVyaWEuQ3JpdGVyaWFCdWlsZGVyOwppbXBvcnQgamF2YXgucGVyc2lzdGVuY2UuY3JpdGVyaWEuQ3JpdGVyaWFRdWVyeTsKCi8qKgogKiBJbnRlcmZhY2UgdXNlZCB0byBpbnRlcmFjdCB3aXRoIHRoZSBwZXJzaXN0ZW5jZSBjb250ZXh0LgogKgogKiA8cD4gQW4gPGNvZGU+RW50aXR5TWFuYWdlcjwvY29kZT4gaW5zdGFuY2UgaXMgYXNzb2NpYXRlZCB3aXRoIAogKiBhIHBlcnNpc3RlbmNlIGNvbnRleHQuIEEgcGVyc2lzdGVuY2UgY29udGV4dCBpcyBhIHNldCBvZiBlbnRpdHkgCiAqIGluc3RhbmNlcyBpbiB3aGljaCBmb3IgYW55IHBlcnNpc3RlbnQgZW50aXR5IGlkZW50aXR5IHRoZXJlIGlzIAogKiBhIHVuaXF1ZSBlbnRpdHkgaW5zdGFuY2UuIFdpdGhpbiB0aGUgcGVyc2lzdGVuY2UgY29udGV4dCwgdGhlIAogKiBlbnRpdHkgaW5zdGFuY2VzIGFuZCB0aGVpciBsaWZlY3ljbGUgYXJlIG1hbmFnZWQuIAogKiBUaGUgPGNvZGU+RW50aXR5TWFuYWdlcjwvY29kZT4gQVBJIGlzIHVzZWQgCiAqIHRvIGNyZWF0ZSBhbmQgcmVtb3ZlIHBlcnNpc3RlbnQgZW50aXR5IGluc3RhbmNlcywgdG8gZmluZCBlbnRpdGllcyAKICogYnkgdGhlaXIgcHJpbWFyeSBrZXksIGFuZCB0byBxdWVyeSBvdmVyIGVudGl0aWVzLgogKgogKiA8cD4gVGhlIHNldCBvZiBlbnRpdGllcyB0aGF0IGNhbiBiZSBtYW5hZ2VkIGJ5IGEgZ2l2ZW4gCiAqIDxjb2RlPkVudGl0eU1hbmFnZXI8L2NvZGU+IGluc3RhbmNlIGlzIGRlZmluZWQgYnkgYSBwZXJzaXN0ZW5jZSAKICogdW5pdC4gQSBwZXJzaXN0ZW5jZSB1bml0IGRlZmluZXMgdGhlIHNldCBvZiBhbGwgY2xhc3NlcyB0aGF0IGFyZSAKICogcmVsYXRlZCBvciBncm91cGVkIGJ5IHRoZSBhcHBsaWNhdGlvbiwgYW5kIHdoaWNoIG11c3QgYmUgCiAqIGNvbG9jYXRlZCBpbiB0aGVpciBtYXBwaW5nIHRvIGEgc2luZ2xlIGRhdGFiYXNlLgogKgogKiBAc2VlIFF1ZXJ5CiAqIEBzZWUgVHlwZWRRdWVyeQogKiBAc2VlIENyaXRlcmlhUXVlcnkKICogQHNlZSBQZXJzaXN0ZW5jZUNvbnRleHQKICogCiAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDEuMAogKi8KcHVibGljIGludGVyZmFjZSBFbnRpdHlNYW5hZ2VyIHsKCiAgICAvKioKICAgICAqIE1ha2UgYW4gaW5zdGFuY2UgbWFuYWdlZCBhbmQgcGVyc2lzdGVudC4KICAgICAqIEBwYXJhbSBlbnRpdHkgIGVudGl0eSBpbnN0YW5jZQogICAgICogQHRocm93cyBFbnRpdHlFeGlzdHNFeGNlcHRpb24gaWYgdGhlIGVudGl0eSBhbHJlYWR5IGV4aXN0cy4KICAgICAqIChJZiB0aGUgZW50aXR5IGFscmVhZHkgZXhpc3RzLCB0aGUgPGNvZGU+RW50aXR5RXhpc3RzRXhjZXB0aW9uPC9jb2RlPiBtYXkgCiAgICAgKiBiZSB0aHJvd24gd2hlbiB0aGUgcGVyc2lzdCBvcGVyYXRpb24gaXMgaW52b2tlZCwgb3IgdGhlCiAgICAgKiA8Y29kZT5FbnRpdHlFeGlzdHNFeGNlcHRpb248L2NvZGU+IG9yIGFub3RoZXIgPGNvZGU+UGVyc2lzdGVuY2VFeGNlcHRpb248L2NvZGU+IG1heSBiZSAKICAgICAqIHRocm93biBhdCBmbHVzaCBvciBjb21taXQgdGltZS4pIAogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGluc3RhbmNlIGlzIG5vdCBhbgogICAgICogICAgICAgICBlbnRpdHkKICAgICAqIEB0aHJvd3MgVHJhbnNhY3Rpb25SZXF1aXJlZEV4Y2VwdGlvbiBpZiBpbnZva2VkIG9uIGEKICAgICAqICAgICAgICAgY29udGFpbmVyLW1hbmFnZWQgZW50aXR5IG1hbmFnZXIgb2YgdHlwZSAKICAgICAqICAgICAgICAgPGNvZGU+UGVyc2lzdGVuY2VDb250ZXh0VHlwZS5UUkFOU0FDVElPTjwvY29kZT4gYW5kIHRoZXJlIGlzIAogICAgICogICAgICAgICBubyB0cmFuc2FjdGlvbgogICAgICovCiAgICBwdWJsaWMgdm9pZCBwZXJzaXN0KE9iamVjdCBlbnRpdHkpOwogICAgCiAgICAvKioKICAgICAqIE1lcmdlIHRoZSBzdGF0ZSBvZiB0aGUgZ2l2ZW4gZW50aXR5IGludG8gdGhlCiAgICAgKiBjdXJyZW50IHBlcnNpc3RlbmNlIGNvbnRleHQuCiAgICAgKiBAcGFyYW0gZW50aXR5ICBlbnRpdHkgaW5zdGFuY2UKICAgICAqIEByZXR1cm4gdGhlIG1hbmFnZWQgaW5zdGFuY2UgdGhhdCB0aGUgc3RhdGUgd2FzIG1lcmdlZCB0bwogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgaW5zdGFuY2UgaXMgbm90IGFuCiAgICAgKiAgICAgICAgIGVudGl0eSBvciBpcyBhIHJlbW92ZWQgZW50aXR5CiAgICAgKiBAdGhyb3dzIFRyYW5zYWN0aW9uUmVxdWlyZWRFeGNlcHRpb24gaWYgaW52b2tlZCBvbiBhCiAgICAgKiAgICAgICAgIGNvbnRhaW5lci1tYW5hZ2VkIGVudGl0eSBtYW5hZ2VyIG9mIHR5cGUgCiAgICAgKiAgICAgICAgIDxjb2RlPlBlcnNpc3RlbmNlQ29udGV4dFR5cGUuVFJBTlNBQ1RJT048L2NvZGU+IGFuZCB0aGVyZSBpcyAKICAgICAqICAgICAgICAgbm8gdHJhbnNhY3Rpb24KICAgICAqLyAgICAKICAgIHB1YmxpYyA8VD4gVCBtZXJnZShUIGVudGl0eSk7CiAgICAKICAgIC8qKgogICAgICogUmVtb3ZlIHRoZSBlbnRpdHkgaW5zdGFuY2UuCiAgICAgKiBAcGFyYW0gZW50aXR5ICBlbnRpdHkgaW5zdGFuY2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBpbnN0YW5jZSBpcyBub3QgYW4KICAgICAqICAgICAgICAgZW50aXR5IG9yIGlzIGEgZGV0YWNoZWQgZW50aXR5CiAgICAgKiBAdGhyb3dzIFRyYW5zYWN0aW9uUmVxdWlyZWRFeGNlcHRpb24gaWYgaW52b2tlZCBvbiBhCiAgICAgKiAgICAgICAgIGNvbnRhaW5lci1tYW5hZ2VkIGVudGl0eSBtYW5hZ2VyIG9mIHR5cGUgCiAgICAgKiAgICAgICAgIDxjb2RlPlBlcnNpc3RlbmNlQ29udGV4dFR5cGUuVFJBTlNBQ1RJT048L2NvZGU+IGFuZCB0aGVyZSBpcyAKICAgICAqICAgICAgICAgbm8gdHJhbnNhY3Rpb24KICAgICAqLyAgICAKICAgIHB1YmxpYyB2b2lkIHJlbW92ZShPYmplY3QgZW50aXR5KTsKICAgIAogICAgLyoqCiAgICAgKiBGaW5kIGJ5IHByaW1hcnkga2V5LgogICAgICogU2VhcmNoIGZvciBhbiBlbnRpdHkgb2YgdGhlIHNwZWNpZmllZCBjbGFzcyBhbmQgcHJpbWFyeSBrZXkuCiAgICAgKiBJZiB0aGUgZW50aXR5IGluc3RhbmNlIGlzIGNvbnRhaW5lZCBpbiB0aGUgcGVyc2lzdGVuY2UgY29udGV4dCwKICAgICAqIGl0IGlzIHJldHVybmVkIGZyb20gdGhlcmUuCiAgICAgKiBAcGFyYW0gZW50aXR5Q2xhc3MgIGVudGl0eSBjbGFzcwogICAgICogQHBhcmFtIHByaW1hcnlLZXkgIHByaW1hcnkga2V5CiAgICAgKiBAcmV0dXJuIHRoZSBmb3VuZCBlbnRpdHkgaW5zdGFuY2Ugb3IgbnVsbCBpZiB0aGUgZW50aXR5IGRvZXMKICAgICAqICAgICAgICAgbm90IGV4aXN0CiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZmlyc3QgYXJndW1lbnQgZG9lcwogICAgICogICAgICAgICBub3QgZGVub3RlIGFuIGVudGl0eSB0eXBlIG9yIHRoZSBzZWNvbmQgYXJndW1lbnQgaXMgCiAgICAgKiAgICAgICAgIGlzIG5vdCBhIHZhbGlkIHR5cGUgZm9yIHRoYXQgZW50aXR5knMgcHJpbWFyeSBrZXkgb3IKICAgICAqICAgICAgICAgaXMgbnVsbAogICAgICovCiAgICBwdWJsaWMgPFQ+IFQgZmluZChDbGFzczxUPiBlbnRpdHlDbGFzcywgT2JqZWN0IHByaW1hcnlLZXkpOwogICAgCiAgICAvKioKICAgICAqIEZpbmQgYnkgcHJpbWFyeSBrZXksIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy4gCiAgICAgKiBTZWFyY2ggZm9yIGFuIGVudGl0eSBvZiB0aGUgc3BlY2lmaWVkIGNsYXNzIGFuZCBwcmltYXJ5IGtleS4gCiAgICAgKiBJZiB0aGUgZW50aXR5IGluc3RhbmNlIGlzIGNvbnRhaW5lZCBpbiB0aGUgcGVyc2lzdGVuY2UgCiAgICAgKiBjb250ZXh0LCBpdCBpcyByZXR1cm5lZCBmcm9tIHRoZXJlLiAKICAgICAqIElmIGEgdmVuZG9yLXNwZWNpZmljIHByb3BlcnR5IG9yIGhpbnQgaXMgbm90IHJlY29nbml6ZWQsIAogICAgICogaXQgaXMgc2lsZW50bHkgaWdub3JlZC4gCiAgICAgKiBAcGFyYW0gZW50aXR5Q2xhc3MgIGVudGl0eSBjbGFzcwogICAgICogQHBhcmFtIHByaW1hcnlLZXkgICBwcmltYXJ5IGtleQogICAgICogQHBhcmFtIHByb3BlcnRpZXMgIHN0YW5kYXJkIGFuZCB2ZW5kb3Itc3BlY2lmaWMgcHJvcGVydGllcyAKICAgICAqICAgICAgICBhbmQgaGludHMKICAgICAqIEByZXR1cm4gdGhlIGZvdW5kIGVudGl0eSBpbnN0YW5jZSBvciBudWxsIGlmIHRoZSBlbnRpdHkgZG9lcwogICAgICogICAgICAgICBub3QgZXhpc3QgCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZmlyc3QgYXJndW1lbnQgZG9lcyAKICAgICAqICAgICAgICAgbm90IGRlbm90ZSBhbiBlbnRpdHkgdHlwZSBvciB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzCiAgICAgKiAgICAgICAgIGlzIG5vdCBhIHZhbGlkIHR5cGUgZm9yIHRoYXQgZW50aXR5knMgcHJpbWFyeSBrZXkgb3IgCiAgICAgKiAgICAgICAgIGlzIG51bGwgCiAgICAgKiBAc2luY2UgSmF2YSBQZXJzaXN0ZW5jZSAyLjAKICAgICAqLyAKICAgIHB1YmxpYyA8VD4gVCBmaW5kKENsYXNzPFQ+IGVudGl0eUNsYXNzLCBPYmplY3QgcHJpbWFyeUtleSwgCiAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBPYmplY3Q+IHByb3BlcnRpZXMpOyAKICAgIAogICAgLyoqCiAgICAgKiBGaW5kIGJ5IHByaW1hcnkga2V5IGFuZCBsb2NrLgogICAgICogU2VhcmNoIGZvciBhbiBlbnRpdHkgb2YgdGhlIHNwZWNpZmllZCBjbGFzcyBhbmQgcHJpbWFyeSBrZXkKICAgICAqIGFuZCBsb2NrIGl0IHdpdGggcmVzcGVjdCB0byB0aGUgc3BlY2lmaWVkIGxvY2sgdHlwZS4KICAgICAqIElmIHRoZSBlbnRpdHkgaW5zdGFuY2UgaXMgY29udGFpbmVkIGluIHRoZSBwZXJzaXN0ZW5jZSBjb250ZXh0LAogICAgICogaXQgaXMgcmV0dXJuZWQgZnJvbSB0aGVyZSwgYW5kIHRoZSBlZmZlY3Qgb2YgdGhpcyBtZXRob2QgaXMKICAgICAqIHRoZSBzYW1lIGFzIGlmIHRoZSBsb2NrIG1ldGhvZCBoYWQgYmVlbiBjYWxsZWQgb24gdGhlIGVudGl0eS4KICAgICAqIDxwPiBJZiB0aGUgZW50aXR5IGlzIGZvdW5kIHdpdGhpbiB0aGUgcGVyc2lzdGVuY2UgY29udGV4dCBhbmQgdGhlCiAgICAgKiBsb2NrIG1vZGUgdHlwZSBpcyBwZXNzaW1pc3RpYyBhbmQgdGhlIGVudGl0eSBoYXMgYSB2ZXJzaW9uCiAgICAgKiBhdHRyaWJ1dGUsIHRoZSBwZXJzaXN0ZW5jZSBwcm92aWRlciBtdXN0IHBlcmZvcm0gb3B0aW1pc3RpYwogICAgICogdmVyc2lvbiBjaGVja3Mgd2hlbiBvYnRhaW5pbmcgdGhlIGRhdGFiYXNlIGxvY2suICBJZiB0aGVzZSAKICAgICAqIGNoZWNrcyBmYWlsLCB0aGUgPGNvZGU+T3B0aW1pc3RpY0xvY2tFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duLgogICAgICogPHA+SWYgdGhlIGxvY2sgbW9kZSB0eXBlIGlzIHBlc3NpbWlzdGljIGFuZCB0aGUgZW50aXR5IGluc3RhbmNlCiAgICAgKiBpcyBmb3VuZCBidXQgY2Fubm90IGJlIGxvY2tlZDoKICAgICAqIDx1bD4KICAgICAqIDxsaT4gdGhlIDxjb2RlPlBlc3NpbWlzdGljTG9ja0V4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGRhdGFiYXNlCiAgICAgKiAgICBsb2NraW5nIGZhaWx1cmUgY2F1c2VzIHRyYW5zYWN0aW9uLWxldmVsIHJvbGxiYWNrCiAgICAgKiA8bGk+IHRoZSA8Y29kZT5Mb2NrVGltZW91dEV4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGRhdGFiYXNlCiAgICAgKiAgICBsb2NraW5nIGZhaWx1cmUgY2F1c2VzIG9ubHkgc3RhdGVtZW50LWxldmVsIHJvbGxiYWNrCiAgICAgKiA8L3VsPgogICAgICogQHBhcmFtIGVudGl0eUNsYXNzICBlbnRpdHkgY2xhc3MKICAgICAqIEBwYXJhbSBwcmltYXJ5S2V5ICBwcmltYXJ5IGtleQogICAgICogQHBhcmFtIGxvY2tNb2RlICBsb2NrIG1vZGUKICAgICAqIEByZXR1cm4gdGhlIGZvdW5kIGVudGl0eSBpbnN0YW5jZSBvciBudWxsIGlmIHRoZSBlbnRpdHkgZG9lcwogICAgICogICAgICAgICBub3QgZXhpc3QKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBmaXJzdCBhcmd1bWVudCBkb2VzCiAgICAgKiAgICAgICAgIG5vdCBkZW5vdGUgYW4gZW50aXR5IHR5cGUgb3IgdGhlIHNlY29uZCBhcmd1bWVudCBpcyAKICAgICAqICAgICAgICAgbm90IGEgdmFsaWQgdHlwZSBmb3IgdGhhdCBlbnRpdHkncyBwcmltYXJ5IGtleSBvciAKICAgICAqICAgICAgICAgaXMgbnVsbAogICAgICogQHRocm93cyBUcmFuc2FjdGlvblJlcXVpcmVkRXhjZXB0aW9uIGlmIHRoZXJlIGlzIG5vIAogICAgICogICAgICAgICB0cmFuc2FjdGlvbiBhbmQgYSBsb2NrIG1vZGUgb3RoZXIgdGhhbiBOT05FIGlzCiAgICAgKiAgICAgICAgIHNwZWNpZmllZAogICAgICogQHRocm93cyBPcHRpbWlzdGljTG9ja0V4Y2VwdGlvbiBpZiB0aGUgb3B0aW1pc3RpYyB2ZXJzaW9uIAogICAgICogICAgICAgICBjaGVjayBmYWlscwogICAgICogQHRocm93cyBQZXNzaW1pc3RpY0xvY2tFeGNlcHRpb24gaWYgcGVzc2ltaXN0aWMgbG9ja2luZyAKICAgICAqICAgICAgICAgZmFpbHMgYW5kIHRoZSB0cmFuc2FjdGlvbiBpcyByb2xsZWQgYmFjawogICAgICogQHRocm93cyBMb2NrVGltZW91dEV4Y2VwdGlvbiBpZiBwZXNzaW1pc3RpYyBsb2NraW5nIGZhaWxzIGFuZAogICAgICogICAgICAgICBvbmx5IHRoZSBzdGF0ZW1lbnQgaXMgcm9sbGVkIGJhY2sKICAgICAqIEB0aHJvd3MgUGVyc2lzdGVuY2VFeGNlcHRpb24gaWYgYW4gdW5zdXBwb3J0ZWQgbG9jayBjYWxsIAogICAgICogICAgICAgICBpcyBtYWRlCiAgICAgKiBAc2luY2UgSmF2YSBQZXJzaXN0ZW5jZSAyLjAKICAgICAqLwogICAgcHVibGljIDxUPiBUIGZpbmQoQ2xhc3M8VD4gZW50aXR5Q2xhc3MsIE9iamVjdCBwcmltYXJ5S2V5LAogICAgICAgICAgICAgICAgICAgICAgTG9ja01vZGVUeXBlIGxvY2tNb2RlKTsKCiAgICAvKioKICAgICAqIEZpbmQgYnkgcHJpbWFyeSBrZXkgYW5kIGxvY2ssIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy4gCiAgICAgKiBTZWFyY2ggZm9yIGFuIGVudGl0eSBvZiB0aGUgc3BlY2lmaWVkIGNsYXNzIGFuZCBwcmltYXJ5IGtleQogICAgICogYW5kIGxvY2sgaXQgd2l0aCByZXNwZWN0IHRvIHRoZSBzcGVjaWZpZWQgbG9jayB0eXBlLgogICAgICogSWYgdGhlIGVudGl0eSBpbnN0YW5jZSBpcyBjb250YWluZWQgaW4gdGhlIHBlcnNpc3RlbmNlIGNvbnRleHQsCiAgICAgKiBpdCBpcyByZXR1cm5lZCBmcm9tIHRoZXJlLiAgCiAgICAgKiA8cD4gSWYgdGhlIGVudGl0eSBpcyBmb3VuZAogICAgICogd2l0aGluIHRoZSBwZXJzaXN0ZW5jZSBjb250ZXh0IGFuZCB0aGUgbG9jayBtb2RlIHR5cGUKICAgICAqIGlzIHBlc3NpbWlzdGljIGFuZCB0aGUgZW50aXR5IGhhcyBhIHZlcnNpb24gYXR0cmlidXRlLCB0aGUKICAgICAqIHBlcnNpc3RlbmNlIHByb3ZpZGVyIG11c3QgcGVyZm9ybSBvcHRpbWlzdGljIHZlcnNpb24gY2hlY2tzCiAgICAgKiB3aGVuIG9idGFpbmluZyB0aGUgZGF0YWJhc2UgbG9jay4gIElmIHRoZXNlIGNoZWNrcyBmYWlsLAogICAgICogdGhlIDxjb2RlPk9wdGltaXN0aWNMb2NrRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93bi4KICAgICAqIDxwPklmIHRoZSBsb2NrIG1vZGUgdHlwZSBpcyBwZXNzaW1pc3RpYyBhbmQgdGhlIGVudGl0eSBpbnN0YW5jZQogICAgICogaXMgZm91bmQgYnV0IGNhbm5vdCBiZSBsb2NrZWQ6CiAgICAgKiA8dWw+CiAgICAgKiA8bGk+IHRoZSA8Y29kZT5QZXNzaW1pc3RpY0xvY2tFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duIGlmIHRoZSBkYXRhYmFzZQogICAgICogICAgbG9ja2luZyBmYWlsdXJlIGNhdXNlcyB0cmFuc2FjdGlvbi1sZXZlbCByb2xsYmFjawogICAgICogPGxpPiB0aGUgPGNvZGU+TG9ja1RpbWVvdXRFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duIGlmIHRoZSBkYXRhYmFzZQogICAgICogICAgbG9ja2luZyBmYWlsdXJlIGNhdXNlcyBvbmx5IHN0YXRlbWVudC1sZXZlbCByb2xsYmFjawogICAgICogPC91bD4KICAgICAqIDxwPklmIGEgdmVuZG9yLXNwZWNpZmljIHByb3BlcnR5IG9yIGhpbnQgaXMgbm90IHJlY29nbml6ZWQsIAogICAgICogaXQgaXMgc2lsZW50bHkgaWdub3JlZC4gIAogICAgICogPHA+UG9ydGFibGUgYXBwbGljYXRpb25zIHNob3VsZCBub3QgcmVseSBvbiB0aGUgc3RhbmRhcmQgdGltZW91dAogICAgICogaGludC4gRGVwZW5kaW5nIG9uIHRoZSBkYXRhYmFzZSBpbiB1c2UgYW5kIHRoZSBsb2NraW5nCiAgICAgKiBtZWNoYW5pc21zIHVzZWQgYnkgdGhlIHByb3ZpZGVyLCB0aGUgaGludCBtYXkgb3IgbWF5IG5vdAogICAgICogYmUgb2JzZXJ2ZWQuCiAgICAgKiBAcGFyYW0gZW50aXR5Q2xhc3MgIGVudGl0eSBjbGFzcwogICAgICogQHBhcmFtIHByaW1hcnlLZXkgIHByaW1hcnkga2V5CiAgICAgKiBAcGFyYW0gbG9ja01vZGUgIGxvY2sgbW9kZQogICAgICogQHBhcmFtIHByb3BlcnRpZXMgIHN0YW5kYXJkIGFuZCB2ZW5kb3Itc3BlY2lmaWMgcHJvcGVydGllcwogICAgICogICAgICAgIGFuZCBoaW50cwogICAgICogQHJldHVybiB0aGUgZm91bmQgZW50aXR5IGluc3RhbmNlIG9yIG51bGwgaWYgdGhlIGVudGl0eSBkb2VzCiAgICAgKiAgICAgICAgIG5vdCBleGlzdAogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGZpcnN0IGFyZ3VtZW50IGRvZXMKICAgICAqICAgICAgICAgbm90IGRlbm90ZSBhbiBlbnRpdHkgdHlwZSBvciB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIAogICAgICogICAgICAgICBub3QgYSB2YWxpZCB0eXBlIGZvciB0aGF0IGVudGl0eSdzIHByaW1hcnkga2V5IG9yIAogICAgICogICAgICAgICBpcyBudWxsCiAgICAgKiBAdGhyb3dzIFRyYW5zYWN0aW9uUmVxdWlyZWRFeGNlcHRpb24gaWYgdGhlcmUgaXMgbm8gCiAgICAgKiAgICAgICAgIHRyYW5zYWN0aW9uIGFuZCBhIGxvY2sgbW9kZSBvdGhlciB0aGFuIDxjb2RlPk5PTkU8L2NvZGU+IGlzIAogICAgICogICAgICAgICBzcGVjaWZpZWQKICAgICAqIEB0aHJvd3MgT3B0aW1pc3RpY0xvY2tFeGNlcHRpb24gaWYgdGhlIG9wdGltaXN0aWMgdmVyc2lvbiAKICAgICAqICAgICAgICAgY2hlY2sgZmFpbHMKICAgICAqIEB0aHJvd3MgUGVzc2ltaXN0aWNMb2NrRXhjZXB0aW9uIGlmIHBlc3NpbWlzdGljIGxvY2tpbmcgCiAgICAgKiAgICAgICAgIGZhaWxzIGFuZCB0aGUgdHJhbnNhY3Rpb24gaXMgcm9sbGVkIGJhY2sKICAgICAqIEB0aHJvd3MgTG9ja1RpbWVvdXRFeGNlcHRpb24gaWYgcGVzc2ltaXN0aWMgbG9ja2luZyBmYWlscyBhbmQKICAgICAqICAgICAgICAgb25seSB0aGUgc3RhdGVtZW50IGlzIHJvbGxlZCBiYWNrCiAgICAgKiBAdGhyb3dzIFBlcnNpc3RlbmNlRXhjZXB0aW9uIGlmIGFuIHVuc3VwcG9ydGVkIGxvY2sgY2FsbCAKICAgICAqICAgICAgICAgaXMgbWFkZQogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyA8VD4gVCBmaW5kKENsYXNzPFQ+IGVudGl0eUNsYXNzLCBPYmplY3QgcHJpbWFyeUtleSwKICAgICAgICAgICAgICAgICAgICAgIExvY2tNb2RlVHlwZSBsb2NrTW9kZSwgCiAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBPYmplY3Q+IHByb3BlcnRpZXMpOwoKICAgIC8qKgogICAgICogR2V0IGFuIGluc3RhbmNlLCB3aG9zZSBzdGF0ZSBtYXkgYmUgbGF6aWx5IGZldGNoZWQuCiAgICAgKiBJZiB0aGUgcmVxdWVzdGVkIGluc3RhbmNlIGRvZXMgbm90IGV4aXN0IGluIHRoZSBkYXRhYmFzZSwKICAgICAqIHRoZSA8Y29kZT5FbnRpdHlOb3RGb3VuZEV4Y2VwdGlvbjwvY29kZT4gaXMgdGhyb3duIHdoZW4gdGhlIGluc3RhbmNlIAogICAgICogc3RhdGUgaXMgZmlyc3QgYWNjZXNzZWQuIChUaGUgcGVyc2lzdGVuY2UgcHJvdmlkZXIgcnVudGltZSBpcyAKICAgICAqIHBlcm1pdHRlZCB0byB0aHJvdyB0aGUgPGNvZGU+RW50aXR5Tm90Rm91bmRFeGNlcHRpb248L2NvZGU+IHdoZW4gCiAgICAgKiA8Y29kZT5nZXRSZWZlcmVuY2U8L2NvZGU+IGlzIGNhbGxlZC4pCiAgICAgKiBUaGUgYXBwbGljYXRpb24gc2hvdWxkIG5vdCBleHBlY3QgdGhhdCB0aGUgaW5zdGFuY2Ugc3RhdGUgd2lsbAogICAgICogYmUgYXZhaWxhYmxlIHVwb24gZGV0YWNobWVudCwgdW5sZXNzIGl0IHdhcyBhY2Nlc3NlZCBieSB0aGUKICAgICAqIGFwcGxpY2F0aW9uIHdoaWxlIHRoZSBlbnRpdHkgbWFuYWdlciB3YXMgb3Blbi4KICAgICAqIEBwYXJhbSBlbnRpdHlDbGFzcyAgZW50aXR5IGNsYXNzCiAgICAgKiBAcGFyYW0gcHJpbWFyeUtleSAgcHJpbWFyeSBrZXkKICAgICAqIEByZXR1cm4gdGhlIGZvdW5kIGVudGl0eSBpbnN0YW5jZQogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGZpcnN0IGFyZ3VtZW50IGRvZXMKICAgICAqICAgICAgICAgbm90IGRlbm90ZSBhbiBlbnRpdHkgdHlwZSBvciB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzCiAgICAgKiAgICAgICAgIG5vdCBhIHZhbGlkIHR5cGUgZm9yIHRoYXQgZW50aXR5knMgcHJpbWFyeSBrZXkgb3IKICAgICAqICAgICAgICAgaXMgbnVsbAogICAgICogQHRocm93cyBFbnRpdHlOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGUgZW50aXR5IHN0YXRlIAogICAgICogICAgICAgICBjYW5ub3QgYmUgYWNjZXNzZWQKICAgICAqLwogICAgcHVibGljIDxUPiBUIGdldFJlZmVyZW5jZShDbGFzczxUPiBlbnRpdHlDbGFzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QgcHJpbWFyeUtleSk7CgogICAgLyoqCiAgICAgKiBTeW5jaHJvbml6ZSB0aGUgcGVyc2lzdGVuY2UgY29udGV4dCB0byB0aGUKICAgICAqIHVuZGVybHlpbmcgZGF0YWJhc2UuCiAgICAgKiBAdGhyb3dzIFRyYW5zYWN0aW9uUmVxdWlyZWRFeGNlcHRpb24gaWYgdGhlcmUgaXMKICAgICAqICAgICAgICAgbm8gdHJhbnNhY3Rpb24KICAgICAqIEB0aHJvd3MgUGVyc2lzdGVuY2VFeGNlcHRpb24gaWYgdGhlIGZsdXNoIGZhaWxzCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGZsdXNoKCk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGZsdXNoIG1vZGUgdGhhdCBhcHBsaWVzIHRvIGFsbCBvYmplY3RzIGNvbnRhaW5lZAogICAgICogaW4gdGhlIHBlcnNpc3RlbmNlIGNvbnRleHQuIAogICAgICogQHBhcmFtIGZsdXNoTW9kZSAgZmx1c2ggbW9kZQogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRGbHVzaE1vZGUoRmx1c2hNb2RlVHlwZSBmbHVzaE1vZGUpOwoKICAgIC8qKgogICAgICogR2V0IHRoZSBmbHVzaCBtb2RlIHRoYXQgYXBwbGllcyB0byBhbGwgb2JqZWN0cyBjb250YWluZWQKICAgICAqIGluIHRoZSBwZXJzaXN0ZW5jZSBjb250ZXh0LiAKICAgICAqIEByZXR1cm4gZmx1c2hNb2RlCiAgICAgKi8KICAgIHB1YmxpYyBGbHVzaE1vZGVUeXBlIGdldEZsdXNoTW9kZSgpOwoKICAgIC8qKgogICAgICogTG9jayBhbiBlbnRpdHkgaW5zdGFuY2UgdGhhdCBpcyBjb250YWluZWQgaW4gdGhlIHBlcnNpc3RlbmNlCiAgICAgKiBjb250ZXh0IHdpdGggdGhlIHNwZWNpZmllZCBsb2NrIG1vZGUgdHlwZS4KICAgICAqIDxwPklmIGEgcGVzc2ltaXN0aWMgbG9jayBtb2RlIHR5cGUgaXMgc3BlY2lmaWVkIGFuZCB0aGUgZW50aXR5CiAgICAgKiBjb250YWlucyBhIHZlcnNpb24gYXR0cmlidXRlLCB0aGUgcGVyc2lzdGVuY2UgcHJvdmlkZXIgbXVzdCAKICAgICAqIGFsc28gcGVyZm9ybSBvcHRpbWlzdGljIHZlcnNpb24gY2hlY2tzIHdoZW4gb2J0YWluaW5nIHRoZSAKICAgICAqIGRhdGFiYXNlIGxvY2suICBJZiB0aGVzZSBjaGVja3MgZmFpbCwgdGhlIAogICAgICogPGNvZGU+T3B0aW1pc3RpY0xvY2tFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duLgogICAgICogPHA+SWYgdGhlIGxvY2sgbW9kZSB0eXBlIGlzIHBlc3NpbWlzdGljIGFuZCB0aGUgZW50aXR5IGluc3RhbmNlCiAgICAgKiBpcyBmb3VuZCBidXQgY2Fubm90IGJlIGxvY2tlZDoKICAgICAqIDx1bD4KICAgICAqIDxsaT4gdGhlIDxjb2RlPlBlc3NpbWlzdGljTG9ja0V4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGRhdGFiYXNlCiAgICAgKiAgICBsb2NraW5nIGZhaWx1cmUgY2F1c2VzIHRyYW5zYWN0aW9uLWxldmVsIHJvbGxiYWNrCiAgICAgKiA8bGk+IHRoZSA8Y29kZT5Mb2NrVGltZW91dEV4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGRhdGFiYXNlCiAgICAgKiAgICBsb2NraW5nIGZhaWx1cmUgY2F1c2VzIG9ubHkgc3RhdGVtZW50LWxldmVsIHJvbGxiYWNrCiAgICAgKiA8L3VsPgogICAgICogQHBhcmFtIGVudGl0eSAgZW50aXR5IGluc3RhbmNlCiAgICAgKiBAcGFyYW0gbG9ja01vZGUgIGxvY2sgbW9kZQogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGluc3RhbmNlIGlzIG5vdCBhbgogICAgICogICAgICAgICBlbnRpdHkgb3IgaXMgYSBkZXRhY2hlZCBlbnRpdHkKICAgICAqIEB0aHJvd3MgVHJhbnNhY3Rpb25SZXF1aXJlZEV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBubyAKICAgICAqICAgICAgICAgdHJhbnNhY3Rpb24KICAgICAqIEB0aHJvd3MgRW50aXR5Tm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGVudGl0eSBkb2VzIG5vdCBleGlzdCAKICAgICAqICAgICAgICAgaW4gdGhlIGRhdGFiYXNlIHdoZW4gcGVzc2ltaXN0aWMgbG9ja2luZyBpcyAKICAgICAqICAgICAgICAgcGVyZm9ybWVkCiAgICAgKiBAdGhyb3dzIE9wdGltaXN0aWNMb2NrRXhjZXB0aW9uIGlmIHRoZSBvcHRpbWlzdGljIHZlcnNpb24gCiAgICAgKiAgICAgICAgIGNoZWNrIGZhaWxzCiAgICAgKiBAdGhyb3dzIFBlc3NpbWlzdGljTG9ja0V4Y2VwdGlvbiBpZiBwZXNzaW1pc3RpYyBsb2NraW5nIGZhaWxzIAogICAgICogICAgICAgICBhbmQgdGhlIHRyYW5zYWN0aW9uIGlzIHJvbGxlZCBiYWNrCiAgICAgKiBAdGhyb3dzIExvY2tUaW1lb3V0RXhjZXB0aW9uIGlmIHBlc3NpbWlzdGljIGxvY2tpbmcgZmFpbHMgYW5kCiAgICAgKiAgICAgICAgIG9ubHkgdGhlIHN0YXRlbWVudCBpcyByb2xsZWQgYmFjawogICAgICogQHRocm93cyBQZXJzaXN0ZW5jZUV4Y2VwdGlvbiBpZiBhbiB1bnN1cHBvcnRlZCBsb2NrIGNhbGwgCiAgICAgKiAgICAgICAgIGlzIG1hZGUKICAgICAqLwogICAgcHVibGljIHZvaWQgbG9jayhPYmplY3QgZW50aXR5LCBMb2NrTW9kZVR5cGUgbG9ja01vZGUpOwoKICAgIC8qKgogICAgICogTG9jayBhbiBlbnRpdHkgaW5zdGFuY2UgdGhhdCBpcyBjb250YWluZWQgaW4gdGhlIHBlcnNpc3RlbmNlCiAgICAgKiBjb250ZXh0IHdpdGggdGhlIHNwZWNpZmllZCBsb2NrIG1vZGUgdHlwZSBhbmQgd2l0aCBzcGVjaWZpZWQKICAgICAqIHByb3BlcnRpZXMuCiAgICAgKiA8cD5JZiBhIHBlc3NpbWlzdGljIGxvY2sgbW9kZSB0eXBlIGlzIHNwZWNpZmllZCBhbmQgdGhlIGVudGl0eQogICAgICogY29udGFpbnMgYSB2ZXJzaW9uIGF0dHJpYnV0ZSwgdGhlIHBlcnNpc3RlbmNlIHByb3ZpZGVyIG11c3QgCiAgICAgKiBhbHNvIHBlcmZvcm0gb3B0aW1pc3RpYyB2ZXJzaW9uIGNoZWNrcyB3aGVuIG9idGFpbmluZyB0aGUgCiAgICAgKiBkYXRhYmFzZSBsb2NrLiAgSWYgdGhlc2UgY2hlY2tzIGZhaWwsIHRoZSAKICAgICAqIDxjb2RlPk9wdGltaXN0aWNMb2NrRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93bi4KICAgICAqIDxwPklmIHRoZSBsb2NrIG1vZGUgdHlwZSBpcyBwZXNzaW1pc3RpYyBhbmQgdGhlIGVudGl0eSBpbnN0YW5jZQogICAgICogaXMgZm91bmQgYnV0IGNhbm5vdCBiZSBsb2NrZWQ6CiAgICAgKiA8dWw+CiAgICAgKiA8bGk+IHRoZSA8Y29kZT5QZXNzaW1pc3RpY0xvY2tFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duIGlmIHRoZSBkYXRhYmFzZQogICAgICogICAgbG9ja2luZyBmYWlsdXJlIGNhdXNlcyB0cmFuc2FjdGlvbi1sZXZlbCByb2xsYmFjawogICAgICogPGxpPiB0aGUgPGNvZGU+TG9ja1RpbWVvdXRFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duIGlmIHRoZSBkYXRhYmFzZQogICAgICogICAgbG9ja2luZyBmYWlsdXJlIGNhdXNlcyBvbmx5IHN0YXRlbWVudC1sZXZlbCByb2xsYmFjawogICAgICogPC91bD4KICAgICAqIDxwPklmIGEgdmVuZG9yLXNwZWNpZmljIHByb3BlcnR5IG9yIGhpbnQgaXMgbm90IHJlY29nbml6ZWQsIAogICAgICogaXQgaXMgc2lsZW50bHkgaWdub3JlZC4gIAogICAgICogPHA+UG9ydGFibGUgYXBwbGljYXRpb25zIHNob3VsZCBub3QgcmVseSBvbiB0aGUgc3RhbmRhcmQgdGltZW91dAogICAgICogaGludC4gRGVwZW5kaW5nIG9uIHRoZSBkYXRhYmFzZSBpbiB1c2UgYW5kIHRoZSBsb2NraW5nCiAgICAgKiBtZWNoYW5pc21zIHVzZWQgYnkgdGhlIHByb3ZpZGVyLCB0aGUgaGludCBtYXkgb3IgbWF5IG5vdAogICAgICogYmUgb2JzZXJ2ZWQuCiAgICAgKiBAcGFyYW0gZW50aXR5ICBlbnRpdHkgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBsb2NrTW9kZSAgbG9jayBtb2RlCiAgICAgKiBAcGFyYW0gcHJvcGVydGllcyAgc3RhbmRhcmQgYW5kIHZlbmRvci1zcGVjaWZpYyBwcm9wZXJ0aWVzCiAgICAgKiAgICAgICAgYW5kIGhpbnRzCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgaW5zdGFuY2UgaXMgbm90IGFuCiAgICAgKiAgICAgICAgIGVudGl0eSBvciBpcyBhIGRldGFjaGVkIGVudGl0eQogICAgICogQHRocm93cyBUcmFuc2FjdGlvblJlcXVpcmVkRXhjZXB0aW9uIGlmIHRoZXJlIGlzIG5vIAogICAgICogICAgICAgICB0cmFuc2FjdGlvbgogICAgICogQHRocm93cyBFbnRpdHlOb3RGb3VuZEV4Y2VwdGlvbiBpZiB0aGUgZW50aXR5IGRvZXMgbm90IGV4aXN0IAogICAgICogICAgICAgICBpbiB0aGUgZGF0YWJhc2Ugd2hlbiBwZXNzaW1pc3RpYyBsb2NraW5nIGlzIAogICAgICogICAgICAgICBwZXJmb3JtZWQKICAgICAqIEB0aHJvd3MgT3B0aW1pc3RpY0xvY2tFeGNlcHRpb24gaWYgdGhlIG9wdGltaXN0aWMgdmVyc2lvbiAKICAgICAqICAgICAgICAgY2hlY2sgZmFpbHMKICAgICAqIEB0aHJvd3MgUGVzc2ltaXN0aWNMb2NrRXhjZXB0aW9uIGlmIHBlc3NpbWlzdGljIGxvY2tpbmcgZmFpbHMgCiAgICAgKiAgICAgICAgIGFuZCB0aGUgdHJhbnNhY3Rpb24gaXMgcm9sbGVkIGJhY2sKICAgICAqIEB0aHJvd3MgTG9ja1RpbWVvdXRFeGNlcHRpb24gaWYgcGVzc2ltaXN0aWMgbG9ja2luZyBmYWlscyBhbmQKICAgICAqICAgICAgICAgb25seSB0aGUgc3RhdGVtZW50IGlzIHJvbGxlZCBiYWNrCiAgICAgKiBAdGhyb3dzIFBlcnNpc3RlbmNlRXhjZXB0aW9uIGlmIGFuIHVuc3VwcG9ydGVkIGxvY2sgY2FsbCAKICAgICAqICAgICAgICAgaXMgbWFkZQogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGxvY2soT2JqZWN0IGVudGl0eSwgTG9ja01vZGVUeXBlIGxvY2tNb2RlLAogICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBPYmplY3Q+IHByb3BlcnRpZXMpOwoKICAgIC8qKgogICAgICogUmVmcmVzaCB0aGUgc3RhdGUgb2YgdGhlIGluc3RhbmNlIGZyb20gdGhlIGRhdGFiYXNlLCAKICAgICAqIG92ZXJ3cml0aW5nIGNoYW5nZXMgbWFkZSB0byB0aGUgZW50aXR5LCBpZiBhbnkuIAogICAgICogQHBhcmFtIGVudGl0eSAgZW50aXR5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgaW5zdGFuY2UgaXMgbm90CiAgICAgKiAgICAgICAgIGFuIGVudGl0eSBvciB0aGUgZW50aXR5IGlzIG5vdCBtYW5hZ2VkCiAgICAgKiBAdGhyb3dzIFRyYW5zYWN0aW9uUmVxdWlyZWRFeGNlcHRpb24gaWYgaW52b2tlZCBvbiBhCiAgICAgKiAgICAgICAgIGNvbnRhaW5lci1tYW5hZ2VkIGVudGl0eSBtYW5hZ2VyIG9mIHR5cGUgCiAgICAgKiAgICAgICAgIDxjb2RlPlBlcnNpc3RlbmNlQ29udGV4dFR5cGUuVFJBTlNBQ1RJT048L2NvZGU+IGFuZCB0aGVyZSBpcyAKICAgICAqICAgICAgICAgbm8gdHJhbnNhY3Rpb24KICAgICAqIEB0aHJvd3MgRW50aXR5Tm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGVudGl0eSBubyBsb25nZXIKICAgICAqICAgICAgICAgZXhpc3RzIGluIHRoZSBkYXRhYmFzZQogICAgICovICAgIAogICAgcHVibGljIHZvaWQgcmVmcmVzaChPYmplY3QgZW50aXR5KTsKCiAgICAvKioKICAgICAqIFJlZnJlc2ggdGhlIHN0YXRlIG9mIHRoZSBpbnN0YW5jZSBmcm9tIHRoZSBkYXRhYmFzZSwgdXNpbmcgCiAgICAgKiB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMsIGFuZCBvdmVyd3JpdGluZyBjaGFuZ2VzIG1hZGUgdG8KICAgICAqIHRoZSBlbnRpdHksIGlmIGFueS4gCiAgICAgKiA8cD4gSWYgYSB2ZW5kb3Itc3BlY2lmaWMgcHJvcGVydHkgb3IgaGludCBpcyBub3QgcmVjb2duaXplZCwgCiAgICAgKiBpdCBpcyBzaWxlbnRseSBpZ25vcmVkLiAKICAgICAqIEBwYXJhbSBlbnRpdHkgIGVudGl0eSBpbnN0YW5jZQogICAgICogQHBhcmFtIHByb3BlcnRpZXMgIHN0YW5kYXJkIGFuZCB2ZW5kb3Itc3BlY2lmaWMgcHJvcGVydGllcyAKICAgICAqICAgICAgICBhbmQgaGludHMKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBpbnN0YW5jZSBpcyBub3QgCiAgICAgKiAgICAgICAgIGFuIGVudGl0eSBvciB0aGUgZW50aXR5IGlzIG5vdCBtYW5hZ2VkIAogICAgICogQHRocm93cyBUcmFuc2FjdGlvblJlcXVpcmVkRXhjZXB0aW9uIGlmIGludm9rZWQgb24gYSAKICAgICAqICAgICAgICAgY29udGFpbmVyLW1hbmFnZWQgZW50aXR5IG1hbmFnZXIgb2YgdHlwZQogICAgICogICAgICAgICA8Y29kZT5QZXJzaXN0ZW5jZUNvbnRleHRUeXBlLlRSQU5TQUNUSU9OPC9jb2RlPiBhbmQgdGhlcmUgaXMKICAgICAqICAgICAgICAgbm8gdHJhbnNhY3Rpb24gCiAgICAgKiBAdGhyb3dzIEVudGl0eU5vdEZvdW5kRXhjZXB0aW9uIGlmIHRoZSBlbnRpdHkgbm8gbG9uZ2VyIAogICAgICogICAgICAgICBleGlzdHMgaW4gdGhlIGRhdGFiYXNlIAogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4wCiAgICAgKi8gICAgIAogICAgcHVibGljIHZvaWQgcmVmcmVzaChPYmplY3QgZW50aXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgT2JqZWN0PiBwcm9wZXJ0aWVzKTsgCgogICAgLyoqCiAgICAgKiBSZWZyZXNoIHRoZSBzdGF0ZSBvZiB0aGUgaW5zdGFuY2UgZnJvbSB0aGUgZGF0YWJhc2UsIAogICAgICogb3ZlcndyaXRpbmcgY2hhbmdlcyBtYWRlIHRvIHRoZSBlbnRpdHksIGlmIGFueSwgYW5kIAogICAgICogbG9jayBpdCB3aXRoIHJlc3BlY3QgdG8gZ2l2ZW4gbG9jayBtb2RlIHR5cGUuCiAgICAgKiA8cD5JZiB0aGUgbG9jayBtb2RlIHR5cGUgaXMgcGVzc2ltaXN0aWMgYW5kIHRoZSBlbnRpdHkgaW5zdGFuY2UKICAgICAqIGlzIGZvdW5kIGJ1dCBjYW5ub3QgYmUgbG9ja2VkOgogICAgICogPHVsPgogICAgICogPGxpPiB0aGUgPGNvZGU+UGVzc2ltaXN0aWNMb2NrRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93biBpZiB0aGUgZGF0YWJhc2UKICAgICAqICAgIGxvY2tpbmcgZmFpbHVyZSBjYXVzZXMgdHJhbnNhY3Rpb24tbGV2ZWwgcm9sbGJhY2sKICAgICAqIDxsaT4gdGhlIDxjb2RlPkxvY2tUaW1lb3V0RXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93biBpZiB0aGUKICAgICAqICAgIGRhdGFiYXNlIGxvY2tpbmcgZmFpbHVyZSBjYXVzZXMgb25seSBzdGF0ZW1lbnQtbGV2ZWwgCiAgICAgKiAgICByb2xsYmFjay4KICAgICAqIDwvdWw+CiAgICAgKiBAcGFyYW0gZW50aXR5ICBlbnRpdHkgaW5zdGFuY2UKICAgICAqIEBwYXJhbSBsb2NrTW9kZSAgbG9jayBtb2RlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgaW5zdGFuY2UgaXMgbm90CiAgICAgKiAgICAgICAgIGFuIGVudGl0eSBvciB0aGUgZW50aXR5IGlzIG5vdCBtYW5hZ2VkCiAgICAgKiBAdGhyb3dzIFRyYW5zYWN0aW9uUmVxdWlyZWRFeGNlcHRpb24gaWYgdGhlcmUgaXMgbm8gCiAgICAgKiAgICAgICAgIHRyYW5zYWN0aW9uIGFuZCBpZiBpbnZva2VkIG9uIGEgY29udGFpbmVyLW1hbmFnZWQKICAgICAqICAgICAgICAgPGNvZGU+RW50aXR5TWFuYWdlcjwvY29kZT4gaW5zdGFuY2Ugd2l0aAogICAgICogICAgICAgICA8Y29kZT5QZXJzaXN0ZW5jZUNvbnRleHRUeXBlLlRSQU5TQUNUSU9OPC9jb2RlPiBvciB3aXRoIGEgbG9jayBtb2RlIAogICAgICogICAgICAgICBvdGhlciB0aGFuIDxjb2RlPk5PTkU8L2NvZGU+CiAgICAgKiBAdGhyb3dzIEVudGl0eU5vdEZvdW5kRXhjZXB0aW9uIGlmIHRoZSBlbnRpdHkgbm8gbG9uZ2VyIGV4aXN0cwogICAgICogICAgICAgICBpbiB0aGUgZGF0YWJhc2UKICAgICAqIEB0aHJvd3MgUGVzc2ltaXN0aWNMb2NrRXhjZXB0aW9uIGlmIHBlc3NpbWlzdGljIGxvY2tpbmcgZmFpbHMKICAgICAqICAgICAgICAgYW5kIHRoZSB0cmFuc2FjdGlvbiBpcyByb2xsZWQgYmFjawogICAgICogQHRocm93cyBMb2NrVGltZW91dEV4Y2VwdGlvbiBpZiBwZXNzaW1pc3RpYyBsb2NraW5nIGZhaWxzIGFuZAogICAgICogICAgICAgICBvbmx5IHRoZSBzdGF0ZW1lbnQgaXMgcm9sbGVkIGJhY2sKICAgICAqIEB0aHJvd3MgUGVyc2lzdGVuY2VFeGNlcHRpb24gaWYgYW4gdW5zdXBwb3J0ZWQgbG9jayBjYWxsCiAgICAgKiAgICAgICAgIGlzIG1hZGUKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovCiAgICBwdWJsaWMgdm9pZCByZWZyZXNoKE9iamVjdCBlbnRpdHksIExvY2tNb2RlVHlwZSBsb2NrTW9kZSk7CgogICAgLyoqCiAgICAgKiBSZWZyZXNoIHRoZSBzdGF0ZSBvZiB0aGUgaW5zdGFuY2UgZnJvbSB0aGUgZGF0YWJhc2UsIAogICAgICogb3ZlcndyaXRpbmcgY2hhbmdlcyBtYWRlIHRvIHRoZSBlbnRpdHksIGlmIGFueSwgYW5kIAogICAgICogbG9jayBpdCB3aXRoIHJlc3BlY3QgdG8gZ2l2ZW4gbG9jayBtb2RlIHR5cGUgYW5kIHdpdGgKICAgICAqIHNwZWNpZmllZCBwcm9wZXJ0aWVzLgogICAgICogPHA+SWYgdGhlIGxvY2sgbW9kZSB0eXBlIGlzIHBlc3NpbWlzdGljIGFuZCB0aGUgZW50aXR5IGluc3RhbmNlCiAgICAgKiBpcyBmb3VuZCBidXQgY2Fubm90IGJlIGxvY2tlZDoKICAgICAqIDx1bD4KICAgICAqIDxsaT4gdGhlIDxjb2RlPlBlc3NpbWlzdGljTG9ja0V4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGRhdGFiYXNlCiAgICAgKiAgICBsb2NraW5nIGZhaWx1cmUgY2F1c2VzIHRyYW5zYWN0aW9uLWxldmVsIHJvbGxiYWNrCiAgICAgKiA8bGk+IHRoZSA8Y29kZT5Mb2NrVGltZW91dEV4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGRhdGFiYXNlCiAgICAgKiAgICBsb2NraW5nIGZhaWx1cmUgY2F1c2VzIG9ubHkgc3RhdGVtZW50LWxldmVsIHJvbGxiYWNrCiAgICAgKiA8L3VsPgogICAgICogPHA+SWYgYSB2ZW5kb3Itc3BlY2lmaWMgcHJvcGVydHkgb3IgaGludCBpcyBub3QgcmVjb2duaXplZCwgCiAgICAgKiAgICBpdCBpcyBzaWxlbnRseSBpZ25vcmVkLiAgCiAgICAgKiA8cD5Qb3J0YWJsZSBhcHBsaWNhdGlvbnMgc2hvdWxkIG5vdCByZWx5IG9uIHRoZSBzdGFuZGFyZCB0aW1lb3V0CiAgICAgKiBoaW50LiBEZXBlbmRpbmcgb24gdGhlIGRhdGFiYXNlIGluIHVzZSBhbmQgdGhlIGxvY2tpbmcKICAgICAqIG1lY2hhbmlzbXMgdXNlZCBieSB0aGUgcHJvdmlkZXIsIHRoZSBoaW50IG1heSBvciBtYXkgbm90CiAgICAgKiBiZSBvYnNlcnZlZC4KICAgICAqIEBwYXJhbSBlbnRpdHkgIGVudGl0eSBpbnN0YW5jZQogICAgICogQHBhcmFtIGxvY2tNb2RlICBsb2NrIG1vZGUKICAgICAqIEBwYXJhbSBwcm9wZXJ0aWVzICBzdGFuZGFyZCBhbmQgdmVuZG9yLXNwZWNpZmljIHByb3BlcnRpZXMKICAgICAqICAgICAgICBhbmQgaGludHMKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBpbnN0YW5jZSBpcyBub3QKICAgICAqICAgICAgICAgYW4gZW50aXR5IG9yIHRoZSBlbnRpdHkgaXMgbm90IG1hbmFnZWQKICAgICAqIEB0aHJvd3MgVHJhbnNhY3Rpb25SZXF1aXJlZEV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBubyAKICAgICAqICAgICAgICAgdHJhbnNhY3Rpb24gYW5kIGlmIGludm9rZWQgb24gYSBjb250YWluZXItbWFuYWdlZAogICAgICogICAgICAgICA8Y29kZT5FbnRpdHlNYW5hZ2VyPC9jb2RlPiBpbnN0YW5jZSB3aXRoCiAgICAgKiAgICAgICAgIDxjb2RlPlBlcnNpc3RlbmNlQ29udGV4dFR5cGUuVFJBTlNBQ1RJT048L2NvZGU+IG9yIHdpdGggYSBsb2NrIG1vZGUgCiAgICAgKiAgICAgICAgIG90aGVyIHRoYW4gPGNvZGU+Tk9ORTwvY29kZT4KICAgICAqIEB0aHJvd3MgRW50aXR5Tm90Rm91bmRFeGNlcHRpb24gaWYgdGhlIGVudGl0eSBubyBsb25nZXIgZXhpc3RzCiAgICAgKiAgICAgICAgIGluIHRoZSBkYXRhYmFzZQogICAgICogQHRocm93cyBQZXNzaW1pc3RpY0xvY2tFeGNlcHRpb24gaWYgcGVzc2ltaXN0aWMgbG9ja2luZyBmYWlscwogICAgICogICAgICAgICBhbmQgdGhlIHRyYW5zYWN0aW9uIGlzIHJvbGxlZCBiYWNrCiAgICAgKiBAdGhyb3dzIExvY2tUaW1lb3V0RXhjZXB0aW9uIGlmIHBlc3NpbWlzdGljIGxvY2tpbmcgZmFpbHMgYW5kCiAgICAgKiAgICAgICAgIG9ubHkgdGhlIHN0YXRlbWVudCBpcyByb2xsZWQgYmFjawogICAgICogQHRocm93cyBQZXJzaXN0ZW5jZUV4Y2VwdGlvbiBpZiBhbiB1bnN1cHBvcnRlZCBsb2NrIGNhbGwKICAgICAqICAgICAgICAgaXMgbWFkZQogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHJlZnJlc2goT2JqZWN0IGVudGl0eSwgTG9ja01vZGVUeXBlIGxvY2tNb2RlLAogICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBPYmplY3Q+IHByb3BlcnRpZXMpOwogICAgCiAgICAvKioKICAgICAqIENsZWFyIHRoZSBwZXJzaXN0ZW5jZSBjb250ZXh0LCBjYXVzaW5nIGFsbCBtYW5hZ2VkCiAgICAgKiBlbnRpdGllcyB0byBiZWNvbWUgZGV0YWNoZWQuIENoYW5nZXMgbWFkZSB0byBlbnRpdGllcyB0aGF0CiAgICAgKiBoYXZlIG5vdCBiZWVuIGZsdXNoZWQgdG8gdGhlIGRhdGFiYXNlIHdpbGwgbm90IGJlCiAgICAgKiBwZXJzaXN0ZWQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGNsZWFyKCk7CgogICAgLyoqCiAgICAgKiBSZW1vdmUgdGhlIGdpdmVuIGVudGl0eSBmcm9tIHRoZSBwZXJzaXN0ZW5jZSBjb250ZXh0LCBjYXVzaW5nCiAgICAgKiBhIG1hbmFnZWQgZW50aXR5IHRvIGJlY29tZSBkZXRhY2hlZC4gIFVuZmx1c2hlZCBjaGFuZ2VzIG1hZGUgCiAgICAgKiB0byB0aGUgZW50aXR5IGlmIGFueSAoaW5jbHVkaW5nIHJlbW92YWwgb2YgdGhlIGVudGl0eSksIAogICAgICogd2lsbCBub3QgYmUgc3luY2hyb25pemVkIHRvIHRoZSBkYXRhYmFzZS4gIEVudGl0aWVzIHdoaWNoIAogICAgICogcHJldmlvdXNseSByZWZlcmVuY2VkIHRoZSBkZXRhY2hlZCBlbnRpdHkgd2lsbCBjb250aW51ZSB0bwogICAgICogcmVmZXJlbmNlIGl0LgogICAgICogQHBhcmFtIGVudGl0eSAgZW50aXR5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgaW5zdGFuY2UgaXMgbm90IGFuIAogICAgICogICAgICAgICBlbnRpdHkgCiAgICAgKiBAc2luY2UgSmF2YSBQZXJzaXN0ZW5jZSAyLjAKICAgICAqLwogICAgcHVibGljIHZvaWQgZGV0YWNoKE9iamVjdCBlbnRpdHkpOyAKCiAgICAvKioKICAgICAqIENoZWNrIGlmIHRoZSBpbnN0YW5jZSBpcyBhIG1hbmFnZWQgZW50aXR5IGluc3RhbmNlIGJlbG9uZ2luZwogICAgICogdG8gdGhlIGN1cnJlbnQgcGVyc2lzdGVuY2UgY29udGV4dC4KICAgICAqIEBwYXJhbSBlbnRpdHkgIGVudGl0eSBpbnN0YW5jZQogICAgICogQHJldHVybiBib29sZWFuIGluZGljYXRpbmcgaWYgZW50aXR5IGlzIGluIHBlcnNpc3RlbmNlIGNvbnRleHQKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIG5vdCBhbiBlbnRpdHkKICAgICAqLyAgICAKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKE9iamVjdCBlbnRpdHkpOwoKICAgIC8qKgogICAgICogR2V0IHRoZSBjdXJyZW50IGxvY2sgbW9kZSBmb3IgdGhlIGVudGl0eSBpbnN0YW5jZS4KICAgICAqIEBwYXJhbSBlbnRpdHkgIGVudGl0eSBpbnN0YW5jZQogICAgICogQHJldHVybiBsb2NrIG1vZGUKICAgICAqIEB0aHJvd3MgVHJhbnNhY3Rpb25SZXF1aXJlZEV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBubyAKICAgICAqICAgICAgICAgdHJhbnNhY3Rpb24KICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBpbnN0YW5jZSBpcyBub3QgYQogICAgICogICAgICAgICBtYW5hZ2VkIGVudGl0eSBhbmQgYSB0cmFuc2FjdGlvbiBpcyBhY3RpdmUKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovCiAgICBwdWJsaWMgTG9ja01vZGVUeXBlIGdldExvY2tNb2RlKE9iamVjdCBlbnRpdHkpOwoKICAgIC8qKiAKICAgICAqIFNldCBhbiBlbnRpdHkgbWFuYWdlciBwcm9wZXJ0eSBvciBoaW50LiAKICAgICAqIElmIGEgdmVuZG9yLXNwZWNpZmljIHByb3BlcnR5IG9yIGhpbnQgaXMgbm90IHJlY29nbml6ZWQsIGl0IGlzCiAgICAgKiBzaWxlbnRseSBpZ25vcmVkLiAKICAgICAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgbmFtZSBvZiBwcm9wZXJ0eSBvciBoaW50CiAgICAgKiBAcGFyYW0gdmFsdWUgIHZhbHVlIGZvciBwcm9wZXJ0eSBvciBoaW50CiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIAogICAgICogICAgICAgICBub3QgdmFsaWQgZm9yIHRoZSBpbXBsZW1lbnRhdGlvbiAKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovIAogICAgcHVibGljIHZvaWQgc2V0UHJvcGVydHkoU3RyaW5nIHByb3BlcnR5TmFtZSwgT2JqZWN0IHZhbHVlKTsKCiAgICAvKioKICAgICAqIEdldCB0aGUgcHJvcGVydGllcyBhbmQgaGludHMgYW5kIGFzc29jaWF0ZWQgdmFsdWVzIHRoYXQgYXJlIGluIGVmZmVjdCAKICAgICAqIGZvciB0aGUgZW50aXR5IG1hbmFnZXIuIENoYW5naW5nIHRoZSBjb250ZW50cyBvZiB0aGUgbWFwIGRvZXMgCiAgICAgKiBub3QgY2hhbmdlIHRoZSBjb25maWd1cmF0aW9uIGluIGVmZmVjdC4KICAgICAqIEByZXR1cm4gbWFwIG9mIHByb3BlcnRpZXMgYW5kIGhpbnRzIGluIGVmZmVjdCBmb3IgZW50aXR5IG1hbmFnZXIKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovCiAgICBwdWJsaWMgTWFwPFN0cmluZywgT2JqZWN0PiBnZXRQcm9wZXJ0aWVzKCk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+UXVlcnk8L2NvZGU+IGZvciBleGVjdXRpbmcgYQogICAgICogSmF2YSBQZXJzaXN0ZW5jZSBxdWVyeSBsYW5ndWFnZSBzdGF0ZW1lbnQuCiAgICAgKiBAcGFyYW0gcWxTdHJpbmcgYSBKYXZhIFBlcnNpc3RlbmNlIHF1ZXJ5IHN0cmluZwogICAgICogQHJldHVybiB0aGUgbmV3IHF1ZXJ5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgcXVlcnkgc3RyaW5nIGlzCiAgICAgKiAgICAgICAgIGZvdW5kIHRvIGJlIGludmFsaWQKICAgICAqLwogICAgcHVibGljIFF1ZXJ5IGNyZWF0ZVF1ZXJ5KFN0cmluZyBxbFN0cmluZyk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+VHlwZWRRdWVyeTwvY29kZT4gZm9yIGV4ZWN1dGluZyBhCiAgICAgKiBjcml0ZXJpYSBxdWVyeS4KICAgICAqIEBwYXJhbSBjcml0ZXJpYVF1ZXJ5ICBhIGNyaXRlcmlhIHF1ZXJ5IG9iamVjdAogICAgICogQHJldHVybiB0aGUgbmV3IHF1ZXJ5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgY3JpdGVyaWEgcXVlcnkgaXMKICAgICAqICAgICAgICAgZm91bmQgdG8gYmUgaW52YWxpZAogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyA8VD4gVHlwZWRRdWVyeTxUPiBjcmVhdGVRdWVyeShDcml0ZXJpYVF1ZXJ5PFQ+IGNyaXRlcmlhUXVlcnkpOyAKCiAgICAvKioKICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiA8Y29kZT5UeXBlZFF1ZXJ5PC9jb2RlPiBmb3IgZXhlY3V0aW5nIGEKICAgICAqIEphdmEgUGVyc2lzdGVuY2UgcXVlcnkgbGFuZ3VhZ2Ugc3RhdGVtZW50LgogICAgICogVGhlIHNlbGVjdCBsaXN0IG9mIHRoZSBxdWVyeSBtdXN0IGNvbnRhaW4gb25seSBhIHNpbmdsZQogICAgICogaXRlbSwgd2hpY2ggbXVzdCBiZSBhc3NpZ25hYmxlIHRvIHRoZSB0eXBlIHNwZWNpZmllZCBieQogICAgICogdGhlIDxjb2RlPnJlc3VsdENsYXNzPC9jb2RlPiBhcmd1bWVudC4KICAgICAqIEBwYXJhbSBxbFN0cmluZyBhIEphdmEgUGVyc2lzdGVuY2UgcXVlcnkgc3RyaW5nCiAgICAgKiBAcGFyYW0gcmVzdWx0Q2xhc3MgdGhlIHR5cGUgb2YgdGhlIHF1ZXJ5IHJlc3VsdAogICAgICogQHJldHVybiB0aGUgbmV3IHF1ZXJ5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgcXVlcnkgc3RyaW5nIGlzIGZvdW5kCiAgICAgKiAgICAgICAgIHRvIGJlIGludmFsaWQgb3IgaWYgdGhlIHF1ZXJ5IHJlc3VsdCBpcyBmb3VuZCB0bwogICAgICogICAgICAgICBub3QgYmUgYXNzaWduYWJsZSB0byB0aGUgc3BlY2lmaWVkIHR5cGUKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovCiAgICBwdWJsaWMgPFQ+IFR5cGVkUXVlcnk8VD4gY3JlYXRlUXVlcnkoU3RyaW5nIHFsU3RyaW5nLCBDbGFzczxUPiByZXN1bHRDbGFzcyk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgPGNvZGU+UXVlcnk8L2NvZGU+IGZvciBleGVjdXRpbmcgYSBuYW1lZCBxdWVyeQogICAgICogKGluIHRoZSBKYXZhIFBlcnNpc3RlbmNlIHF1ZXJ5IGxhbmd1YWdlIG9yIGluIG5hdGl2ZSBTUUwpLgogICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgYSBxdWVyeSBkZWZpbmVkIGluIG1ldGFkYXRhCiAgICAgKiBAcmV0dXJuIHRoZSBuZXcgcXVlcnkgaW5zdGFuY2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGEgcXVlcnkgaGFzIG5vdCBiZWVuCiAgICAgKiAgICAgICAgIGRlZmluZWQgd2l0aCB0aGUgZ2l2ZW4gbmFtZSBvciBpZiB0aGUgcXVlcnkgc3RyaW5nIGlzCiAgICAgKiAgICAgICAgIGZvdW5kIHRvIGJlIGludmFsaWQKICAgICAqLwogICAgcHVibGljIFF1ZXJ5IGNyZWF0ZU5hbWVkUXVlcnkoU3RyaW5nIG5hbWUpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIDxjb2RlPlR5cGVkUXVlcnk8L2NvZGU+IGZvciBleGVjdXRpbmcgYQogICAgICogSmF2YSBQZXJzaXN0ZW5jZSBxdWVyeSBsYW5ndWFnZSBuYW1lZCBxdWVyeS4KICAgICAqIFRoZSBzZWxlY3QgbGlzdCBvZiB0aGUgcXVlcnkgbXVzdCBjb250YWluIG9ubHkgYSBzaW5nbGUKICAgICAqIGl0ZW0sIHdoaWNoIG11c3QgYmUgYXNzaWduYWJsZSB0byB0aGUgdHlwZSBzcGVjaWZpZWQgYnkKICAgICAqIHRoZSA8Y29kZT5yZXN1bHRDbGFzczwvY29kZT4gYXJndW1lbnQuCiAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiBhIHF1ZXJ5IGRlZmluZWQgaW4gbWV0YWRhdGEKICAgICAqIEBwYXJhbSByZXN1bHRDbGFzcyB0aGUgdHlwZSBvZiB0aGUgcXVlcnkgcmVzdWx0CiAgICAgKiBAcmV0dXJuIHRoZSBuZXcgcXVlcnkgaW5zdGFuY2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGEgcXVlcnkgaGFzIG5vdCBiZWVuCiAgICAgKiAgICAgICAgIGRlZmluZWQgd2l0aCB0aGUgZ2l2ZW4gbmFtZSBvciBpZiB0aGUgcXVlcnkgc3RyaW5nIGlzCiAgICAgKiAgICAgICAgIGZvdW5kIHRvIGJlIGludmFsaWQgb3IgaWYgdGhlIHF1ZXJ5IHJlc3VsdCBpcyBmb3VuZCB0bwogICAgICogICAgICAgICBub3QgYmUgYXNzaWduYWJsZSB0byB0aGUgc3BlY2lmaWVkIHR5cGUKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovCiAgICBwdWJsaWMgPFQ+IFR5cGVkUXVlcnk8VD4gY3JlYXRlTmFtZWRRdWVyeShTdHJpbmcgbmFtZSwgQ2xhc3M8VD4gcmVzdWx0Q2xhc3MpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIDxjb2RlPlF1ZXJ5PC9jb2RlPiBmb3IgZXhlY3V0aW5nCiAgICAgKiBhIG5hdGl2ZSBTUUwgc3RhdGVtZW50LCBlLmcuLCBmb3IgdXBkYXRlIG9yIGRlbGV0ZS4KICAgICAqIEBwYXJhbSBzcWxTdHJpbmcgYSBuYXRpdmUgU1FMIHF1ZXJ5IHN0cmluZwogICAgICogQHJldHVybiB0aGUgbmV3IHF1ZXJ5IGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBRdWVyeSBjcmVhdGVOYXRpdmVRdWVyeShTdHJpbmcgc3FsU3RyaW5nKTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiA8Y29kZT5RdWVyeTwvY29kZT4gZm9yIGV4ZWN1dGluZwogICAgICogYSBuYXRpdmUgU1FMIHF1ZXJ5LgogICAgICogQHBhcmFtIHNxbFN0cmluZyBhIG5hdGl2ZSBTUUwgcXVlcnkgc3RyaW5nCiAgICAgKiBAcGFyYW0gcmVzdWx0Q2xhc3MgdGhlIGNsYXNzIG9mIHRoZSByZXN1bHRpbmcgaW5zdGFuY2UocykKICAgICAqIEByZXR1cm4gdGhlIG5ldyBxdWVyeSBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgUXVlcnkgY3JlYXRlTmF0aXZlUXVlcnkoU3RyaW5nIHNxbFN0cmluZywgQ2xhc3MgcmVzdWx0Q2xhc3MpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIDxjb2RlPlF1ZXJ5PC9jb2RlPiBmb3IgZXhlY3V0aW5nCiAgICAgKiBhIG5hdGl2ZSBTUUwgcXVlcnkuCiAgICAgKiBAcGFyYW0gc3FsU3RyaW5nIGEgbmF0aXZlIFNRTCBxdWVyeSBzdHJpbmcKICAgICAqIEBwYXJhbSByZXN1bHRTZXRNYXBwaW5nIHRoZSBuYW1lIG9mIHRoZSByZXN1bHQgc2V0IG1hcHBpbmcKICAgICAqIEByZXR1cm4gdGhlIG5ldyBxdWVyeSBpbnN0YW5jZQogICAgICovCiAgICBwdWJsaWMgUXVlcnkgY3JlYXRlTmF0aXZlUXVlcnkoU3RyaW5nIHNxbFN0cmluZywgU3RyaW5nIHJlc3VsdFNldE1hcHBpbmcpOwoKICAgIC8qKgogICAgICogSW5kaWNhdGUgdG8gdGhlIGVudGl0eSBtYW5hZ2VyIHRoYXQgYSBKVEEgdHJhbnNhY3Rpb24gaXMKICAgICAqIGFjdGl2ZS4gVGhpcyBtZXRob2Qgc2hvdWxkIGJlIGNhbGxlZCBvbiBhIEpUQSBhcHBsaWNhdGlvbiAKICAgICAqIG1hbmFnZWQgZW50aXR5IG1hbmFnZXIgdGhhdCB3YXMgY3JlYXRlZCBvdXRzaWRlIHRoZSBzY29wZQogICAgICogb2YgdGhlIGFjdGl2ZSB0cmFuc2FjdGlvbiB0byBhc3NvY2lhdGUgaXQgd2l0aCB0aGUgY3VycmVudAogICAgICogSlRBIHRyYW5zYWN0aW9uLgogICAgICogQHRocm93cyBUcmFuc2FjdGlvblJlcXVpcmVkRXhjZXB0aW9uIGlmIHRoZXJlIGlzCiAgICAgKiAgICAgICAgIG5vIHRyYW5zYWN0aW9uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGpvaW5UcmFuc2FjdGlvbigpOwoKICAgIC8qKgogICAgICogUmV0dXJuIGFuIG9iamVjdCBvZiB0aGUgc3BlY2lmaWVkIHR5cGUgdG8gYWxsb3cgYWNjZXNzIHRvIHRoZQogICAgICogcHJvdmlkZXItc3BlY2lmaWMgQVBJLiAgIElmIHRoZSBwcm92aWRlcidzIDxjb2RlPkVudGl0eU1hbmFnZXI8L2NvZGU+CiAgICAgKiBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHRoZSBzcGVjaWZpZWQgY2xhc3MsIHRoZQogICAgICogPGNvZGU+UGVyc2lzdGVuY2VFeGNlcHRpb248L2NvZGU+IGlzIHRocm93bi4KICAgICAqIEBwYXJhbSBjbHMgIHRoZSBjbGFzcyBvZiB0aGUgb2JqZWN0IHRvIGJlIHJldHVybmVkLiAgVGhpcyBpcwogICAgICogbm9ybWFsbHkgZWl0aGVyIHRoZSB1bmRlcmx5aW5nIDxjb2RlPkVudGl0eU1hbmFnZXI8L2NvZGU+IGltcGxlbWVudGF0aW9uCiAgICAgKiBjbGFzcyBvciBhbiBpbnRlcmZhY2UgdGhhdCBpdCBpbXBsZW1lbnRzLgogICAgICogQHJldHVybiBhbiBpbnN0YW5jZSBvZiB0aGUgc3BlY2lmaWVkIGNsYXNzCiAgICAgKiBAdGhyb3dzIFBlcnNpc3RlbmNlRXhjZXB0aW9uIGlmIHRoZSBwcm92aWRlciBkb2VzIG5vdCAKICAgICAqICAgICAgICAgc3VwcG9ydCB0aGUgY2FsbCAKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovCiAgICBwdWJsaWMgPFQ+IFQgdW53cmFwKENsYXNzPFQ+IGNscyk7IAoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSB1bmRlcmx5aW5nIHByb3ZpZGVyIG9iamVjdCBmb3IgdGhlIDxjb2RlPkVudGl0eU1hbmFnZXI8L2NvZGU+LAogICAgICogaWYgYXZhaWxhYmxlLiBUaGUgcmVzdWx0IG9mIHRoaXMgbWV0aG9kIGlzIGltcGxlbWVudGF0aW9uCiAgICAgKiBzcGVjaWZpYy4gVGhlIDxjb2RlPnVud3JhcDwvY29kZT4gbWV0aG9kIGlzIHRvIGJlIHByZWZlcnJlZCBmb3IgbmV3IAogICAgICogYXBwbGljYXRpb25zLgogICAgICogQHJldHVybiB1bmRlcmx5aW5nIHByb3ZpZGVyIG9iamVjdCBmb3IgRW50aXR5TWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgT2JqZWN0IGdldERlbGVnYXRlKCk7CgogICAgLyoqCiAgICAgKiBDbG9zZSBhbiBhcHBsaWNhdGlvbi1tYW5hZ2VkIGVudGl0eSBtYW5hZ2VyLiAKICAgICAqIEFmdGVyIHRoZSBjbG9zZSBtZXRob2QgaGFzIGJlZW4gaW52b2tlZCwgYWxsIG1ldGhvZHMKICAgICAqIG9uIHRoZSA8Y29kZT5FbnRpdHlNYW5hZ2VyPC9jb2RlPiBpbnN0YW5jZSBhbmQgYW55IAogICAgICogPGNvZGU+UXVlcnk8L2NvZGU+IGFuZCA8Y29kZT5UeXBlZFF1ZXJ5PC9jb2RlPgogICAgICogb2JqZWN0cyBvYnRhaW5lZCBmcm9tIGl0IHdpbGwgdGhyb3cgdGhlIDxjb2RlPklsbGVnYWxTdGF0ZUV4Y2VwdGlvbjwvY29kZT4KICAgICAqIGV4Y2VwdCBmb3IgPGNvZGU+Z2V0UHJvcGVydGllczwvY29kZT4sIAogICAgICogPGNvZGU+Z2V0VHJhbnNhY3Rpb248L2NvZGU+LCBhbmQgPGNvZGU+aXNPcGVuPC9jb2RlPiAod2hpY2ggd2lsbCByZXR1cm4gZmFsc2UpLgogICAgICogSWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4gdGhlIGVudGl0eSBtYW5hZ2VyIGlzCiAgICAgKiBhc3NvY2lhdGVkIHdpdGggYW4gYWN0aXZlIHRyYW5zYWN0aW9uLCB0aGUgcGVyc2lzdGVuY2UKICAgICAqIGNvbnRleHQgcmVtYWlucyBtYW5hZ2VkIHVudGlsIHRoZSB0cmFuc2FjdGlvbiBjb21wbGV0ZXMuIAogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIGVudGl0eSBtYW5hZ2VyCiAgICAgKiAgICAgICAgIGlzIGNvbnRhaW5lci1tYW5hZ2VkCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGNsb3NlKCk7CgogICAgLyoqCiAgICAgKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZW50aXR5IG1hbmFnZXIgaXMgb3Blbi4gCiAgICAgKiBAcmV0dXJuIHRydWUgdW50aWwgdGhlIGVudGl0eSBtYW5hZ2VyIGhhcyBiZWVuIGNsb3NlZAogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc09wZW4oKTsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgcmVzb3VyY2UtbGV2ZWwgPGNvZGU+RW50aXR5VHJhbnNhY3Rpb248L2NvZGU+IG9iamVjdC4gCiAgICAgKiBUaGUgPGNvZGU+RW50aXR5VHJhbnNhY3Rpb248L2NvZGU+IGluc3RhbmNlIG1heSBiZSB1c2VkIHNlcmlhbGx5IHRvIAogICAgICogYmVnaW4gYW5kIGNvbW1pdCBtdWx0aXBsZSB0cmFuc2FjdGlvbnMuCiAgICAgKiBAcmV0dXJuIEVudGl0eVRyYW5zYWN0aW9uIGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiBpbnZva2VkIG9uIGEgSlRBCiAgICAgKiAgICAgICAgIGVudGl0eSBtYW5hZ2VyCiAgICAgKi8KICAgIHB1YmxpYyBFbnRpdHlUcmFuc2FjdGlvbiBnZXRUcmFuc2FjdGlvbigpOwoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBlbnRpdHkgbWFuYWdlciBmYWN0b3J5IGZvciB0aGUgZW50aXR5IG1hbmFnZXIuCiAgICAgKiBAcmV0dXJuIEVudGl0eU1hbmFnZXJGYWN0b3J5IGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgZW50aXR5IG1hbmFnZXIgaGFzIAogICAgICogICAgICAgICBiZWVuIGNsb3NlZAogICAgICogQHNpbmNlIEphdmEgUGVyc2lzdGVuY2UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyBFbnRpdHlNYW5hZ2VyRmFjdG9yeSBnZXRFbnRpdHlNYW5hZ2VyRmFjdG9yeSgpOwoKICAgIC8qKgogICAgICogUmV0dXJuIGFuIGluc3RhbmNlIG9mIDxjb2RlPkNyaXRlcmlhQnVpbGRlcjwvY29kZT4gZm9yIHRoZSBjcmVhdGlvbiBvZgogICAgICogPGNvZGU+Q3JpdGVyaWFRdWVyeTwvY29kZT4gb2JqZWN0cy4KICAgICAqIEByZXR1cm4gQ3JpdGVyaWFCdWlsZGVyIGluc3RhbmNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgZW50aXR5IG1hbmFnZXIgaGFzCiAgICAgKiAgICAgICAgIGJlZW4gY2xvc2VkCiAgICAgKiBAc2luY2UgSmF2YSBQZXJzaXN0ZW5jZSAyLjAKICAgICAqLwogICAgcHVibGljIENyaXRlcmlhQnVpbGRlciBnZXRDcml0ZXJpYUJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIFJldHVybiBhbiBpbnN0YW5jZSBvZiA8Y29kZT5NZXRhbW9kZWw8L2NvZGU+IGludGVyZmFjZSBmb3IgYWNjZXNzIHRvIHRoZQogICAgICogbWV0YW1vZGVsIG9mIHRoZSBwZXJzaXN0ZW5jZSB1bml0LgogICAgICogQHJldHVybiBNZXRhbW9kZWwgaW5zdGFuY2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBlbnRpdHkgbWFuYWdlciBoYXMKICAgICAqICAgICAgICAgYmVlbiBjbG9zZWQKICAgICAqIEBzaW5jZSBKYXZhIFBlcnNpc3RlbmNlIDIuMAogICAgICovCiAgICBwdWJsaWMgTWV0YW1vZGVsIGdldE1ldGFtb2RlbCgpOwp9Cg==