LyoKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiAgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKICoKICogQ29udHJpYnV0b3JzOgogKiAgIElCTSAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKgogKiAkSWQ6IEV4cGFuc2lvblJlZ2lvbi5qYXZhLHYgMS40IDIwMDQvMDYvMDYgMDE6MzU6MDMga2h1c3NleSBFeHAgJAogKi8KcGFja2FnZSBvcmcuZWNsaXBzZS51bWwyOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5jb21tb24udXRpbC5FTGlzdDsKCi8qKgogKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgogKiBBIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtb2RlbCBvYmplY3QgJzxlbT48Yj5FeHBhbnNpb24gUmVnaW9uPC9iPjwvZW0+Jy4KICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CiAqCiAqIDwhLS0gYmVnaW4tbW9kZWwtZG9jIC0tPgogKiBBbiBleHBhbnNpb24gcmVnaW9uIGlzIGEgc3RyaWN0bHkgbmVzdGVkIHJlZ2lvbiBvZiBhbiBhY3Rpdml0eSB3aXRoIGV4cGxpY2l0IGlucHV0IGFuZCBvdXRwdXRzIChtb2RlbGVkIGFzIEV4cGFuc2lvbk5vZGVzKS4gRWFjaCBpbnB1dCBpcyBhIGNvbGxlY3Rpb24gb2YgdmFsdWVzLiBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgaW5wdXQgcGlucywgZWFjaCBvZiB0aGVtIG11c3QgaG9sZCB0aGUgc2FtZSBraW5kIG9mIGNvbGxlY3Rpb24sIGFsdGhvdWdoIHRoZSB0eXBlcyBvZiB0aGUgZWxlbWVudHMgaW4gdGhlIGRpZmZlcmVudCBjb2xsZWN0aW9ucyBtYXkgdmFyeS4gVGhlIGV4cGFuc2lvbiByZWdpb24gaXMgZXhlY3V0ZWQgb25jZSBmb3IgZWFjaCBlbGVtZW50IChvciBwb3NpdGlvbikgaW4gdGhlIGlucHV0IGNvbGxlY3Rpb24uIElmIGFuIGV4cGFuc2lvbiByZWdpb24gaGFzIG91dHB1dHMsIHRoZXkgbXVzdCBiZSBjb2xsZWN0aW9ucyBvZiB0aGUgc2FtZSBraW5kIGFuZCBtdXN0IGNvbnRhaW4gZWxlbWVudHMgb2YgdGhlIHNhbWUgdHlwZSBhcyB0aGUgY29ycmVzcG9uZGluZyBpbnB1dHMuIFRoZSBudW1iZXIgb2Ygb3V0cHV0IGNvbGxlY3Rpb25zIGF0IHJ1bnRpbWUgY2FuIGRpZmZlciBmcm9tIHRoZSBudW1iZXIgb2YgaW5wdXQgY29sbGVjdGlvbnMuIE9uIGVhY2ggZXhlY3V0aW9uIG9mIHRoZSByZWdpb24sIGFuIG91dHB1dCB2YWx1ZSBmcm9tIHRoZSByZWdpb24gaXMgaW5zZXJ0ZWQgaW50byBhbiBvdXRwdXQgY29sbGVjdGlvbiBhdCB0aGUgc2FtZSBwb3NpdGlvbiBhcyB0aGUgaW5wdXQgZWxlbWVudHMuIElmIHRoZSByZWdpb24gZXhlY3V0aW9uIGVuZHMgd2l0aCBubyBvdXRwdXQsIHRoZW4gbm90aGluZyBpcyBhZGRlZCB0byB0aGUgb3V0cHV0IGNvbGxlY3Rpb24uIElmIGFsbCB0aGUgZXhlY3V0aW9ucyBwcm92aWRlIGFuIG91dHB1dCB0byB0aGUgY29sbGVjdGlvbiwgdGhlbiB0aGUgb3V0cHV0IGNvbGxlY3Rpb25zIHdpbGwgaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgZWxlbWVudHMgYXMgdGhlIGlucHV0IGNvbGxlY3Rpb25zLiBUaGUgaW5wdXRzIGFuZCBvdXRwdXRzIHRvIGFuIGV4cGFuc2lvbiByZWdpb24gYXJlIG1vZGVsZWQgYXMgRXhwYW5zaW9uTm9kZXMuIEZyb20gk291dHNpZGWUIG9mIHRoZSByZWdpb24sIHRoZSB2YWx1ZXMgb24gdGhlc2Ugbm9kZXMgYXBwZWFyIGFzIGNvbGxlY3Rpb25zLiBGcm9tIJNpbnNpZGWUIHRoZSByZWdpb24gdGhlIHZhbHVlcyBhcHBlYXIgYXMgZWxlbWVudHMgb2YgdGhlIGNvbGxlY3Rpb25zLiBPYmplY3QgZmxvdyBlZGdlcyBjb25uZWN0IHBpbnMgb3V0c2lkZSB0aGUgcmVnaW9uIHRvIGlucHV0IGFuZCBvdXRwdXQgZXhwYW5zaW9uIG5vZGVzIGFzIGNvbGxlY3Rpb25zLiBPYmplY3QgZmxvdyBlZGdlcyBjb25uZWN0IHBpbnMgaW5zaWRlIHRoZSByZWdpb24gdG8gaW5wdXQgYW5kIG91dHB1dCBleHBhbnNpb24gbm9kZXMgYXMgaW5kaXZpZHVhbCBlbGVtZW50cy4gRnJvbSB0aGUgaW5zaWRlIG9mIHRoZSByZWdpb24sIHRoZXNlIG5vZGVzIGFyZSB2aXNpYmxlIGFzIGluZGl2aWR1YWwgdmFsdWVzLiBJZiBhbiBleHBhbnNpb24gbm9kZSBoYXMgYSBuYW1lLCBpdCBpcyB0aGUgbmFtZSBvZiB0aGUgaW5kaXZpZHVhbCBlbGVtZW50IHdpdGhpbiB0aGUgcmVnaW9uLiBBbnkgb2JqZWN0IGZsb3cgZWRnZXMgdGhhdCBjcm9zcyB0aGUgYm91bmRhcnkgb2YgdGhlIHJlZ2lvbiwgd2l0aG91dCBwYXNzaW5nIHRocm91Z2ggZXhwYW5zaW9uIG5vZGVzLCBwcm92aWRlIHZhbHVlcyB0aGF0IGFyZSBmaXhlZCB3aXRoaW4gdGhlIGRpZmZlcmVudCBleGVjdXRpb25zIG9mIHRoZSByZWdpb24uIAogKiA8IS0tIGVuZC1tb2RlbC1kb2MgLS0+CiAqCiAqIDxwPgogKiBUaGUgZm9sbG93aW5nIGZlYXR1cmVzIGFyZSBzdXBwb3J0ZWQ6CiAqIDx1bD4KICogICA8bGk+e0BsaW5rIG9yZy5lY2xpcHNlLnVtbDIuRXhwYW5zaW9uUmVnaW9uI2dldE1vZGUgPGVtPk1vZGU8L2VtPn08L2xpPgogKiAgIDxsaT57QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5FeHBhbnNpb25SZWdpb24jZ2V0T3V0cHV0RWxlbWVudHMgPGVtPk91dHB1dCBFbGVtZW50PC9lbT59PC9saT4KICogICA8bGk+e0BsaW5rIG9yZy5lY2xpcHNlLnVtbDIuRXhwYW5zaW9uUmVnaW9uI2dldElucHV0RWxlbWVudHMgPGVtPklucHV0IEVsZW1lbnQ8L2VtPn08L2xpPgogKiA8L3VsPgogKiA8L3A+CiAqCiAqIEBzZWUgb3JnLmVjbGlwc2UudW1sMi5VTUwyUGFja2FnZSNnZXRFeHBhbnNpb25SZWdpb24oKQogKiBAbW9kZWwgCiAqIEBnZW5lcmF0ZWQKICovCnB1YmxpYyBpbnRlcmZhY2UgRXhwYW5zaW9uUmVnaW9uIGV4dGVuZHMgU3RydWN0dXJlZEFjdGl2aXR5Tm9kZXsKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglTdHJpbmcgY29weXJpZ2h0ID0gIkNvcHlyaWdodCAoYykgMjAwMywgMjAwNCBJQk0gQ29ycG9yYXRpb24gYW5kIG90aGVycy4iOyAvLyROT04tTkxTLTEkCgoJLyoqCgkgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgJzxlbT48Yj5Nb2RlPC9iPjwvZW0+JyBhdHRyaWJ1dGUuCgkgKiBUaGUgbGl0ZXJhbHMgYXJlIGZyb20gdGhlIGVudW1lcmF0aW9uIHtAbGluayBvcmcuZWNsaXBzZS51bWwyLkV4cGFuc2lvbktpbmR9LgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDxwPgoJICogSWYgdGhlIG1lYW5pbmcgb2YgdGhlICc8ZW0+TW9kZTwvZW0+JyBhdHRyaWJ1dGUgaXNuJ3QgY2xlYXIsCgkgKiB0aGVyZSByZWFsbHkgc2hvdWxkIGJlIG1vcmUgb2YgYSBkZXNjcmlwdGlvbiBoZXJlLi4uCgkgKiA8L3A+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIDwhLS0gYmVnaW4tbW9kZWwtZG9jIC0tPgoJICogVGhlIHdheSBpbiB3aGljaCB0aGUgZXhlY3V0aW9ucyBpbnRlcmFjdDogcGFyYWxsZWwglyBhbGwgaW50ZXJhY3Rpb25zIGFyZSBpbmRlcGVuZGVudCBpdGVyYXRpdmUglyB0aGUgaW50ZXJhY3Rpb25zIG9jY3VyIGluIG9yZGVyIG9mIHRoZSBlbGVtZW50cyBzdHJlYW0glyBhIHN0cmVhbSBvZiB2YWx1ZXMgZmxvd3MgaW50byBhIHNpbmdsZSBleGVjdXRpb24KCSAqIDwhLS0gZW5kLW1vZGVsLWRvYyAtLT4KCSAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSAnPGVtPk1vZGU8L2VtPicgYXR0cmlidXRlLgoJICogQHNlZSBvcmcuZWNsaXBzZS51bWwyLkV4cGFuc2lvbktpbmQKCSAqIEBzZWUgI3NldE1vZGUoRXhwYW5zaW9uS2luZCkKCSAqIEBzZWUgb3JnLmVjbGlwc2UudW1sMi5VTUwyUGFja2FnZSNnZXRFeHBhbnNpb25SZWdpb25fTW9kZSgpCgkgKiBAbW9kZWwgCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCUV4cGFuc2lvbktpbmQgZ2V0TW9kZSgpOwoKCS8qKgoJICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlICd7QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5FeHBhbnNpb25SZWdpb24jZ2V0TW9kZSA8ZW0+TW9kZTwvZW0+fScgYXR0cmlidXRlLgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgdmFsdWUgb2YgdGhlICc8ZW0+TW9kZTwvZW0+JyBhdHRyaWJ1dGUuCgkgKiBAc2VlIG9yZy5lY2xpcHNlLnVtbDIuRXhwYW5zaW9uS2luZAoJICogQHNlZSAjZ2V0TW9kZSgpCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXZvaWQgc2V0TW9kZShFeHBhbnNpb25LaW5kIHZhbHVlKTsKCgkvKioKCSAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSAnPGVtPjxiPk91dHB1dCBFbGVtZW50PC9iPjwvZW0+JyByZWZlcmVuY2UgbGlzdC4KCSAqIFRoZSBsaXN0IGNvbnRlbnRzIGFyZSBvZiB0eXBlIHtAbGluayBvcmcuZWNsaXBzZS51bWwyLkV4cGFuc2lvbk5vZGV9LgoJICogSXQgaXMgYmlkaXJlY3Rpb25hbCBhbmQgaXRzIG9wcG9zaXRlIGlzICd7QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5FeHBhbnNpb25Ob2RlI2dldFJlZ2lvbkFzT3V0cHV0IDxlbT5SZWdpb24gQXMgT3V0cHV0PC9lbT59Jy4KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8cD4KCSAqIElmIHRoZSBtZWFuaW5nIG9mIHRoZSAnPGVtPk91dHB1dCBFbGVtZW50PC9lbT4nIHJlZmVyZW5jZSBsaXN0IGlzbid0IGNsZWFyLAoJICogdGhlcmUgcmVhbGx5IHNob3VsZCBiZSBtb3JlIG9mIGEgZGVzY3JpcHRpb24gaGVyZS4uLgoJICogPC9wPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiA8IS0tIGJlZ2luLW1vZGVsLWRvYyAtLT4KCSAqIEFuIG9iamVjdCBub2RlIHRoYXQgYWNjZXB0cyBhIHNlcGFyYXRlIGVsZW1lbnQgb2YgdGhlIG91dHB1dCBjb2xsZWN0aW9uIGR1cmluZyBlYWNoIG9mIHRoZSBtdWx0aXBsZSBleGVjdXRpb25zIG9mIHRoZSByZWdpb24uIFRoZSB2YWx1ZXMgYXJlIGZvcm1lZCBpbnRvIGEgY29sbGVjdGlvbiB0aGF0IGlzIGF2YWlsYWJsZSB3aGVuIHRoZSBleGVjdXRpb24gb2YgdGhlIHJlZ2lvbiBpcyBjb21wbGV0ZS4KCSAqIDwhLS0gZW5kLW1vZGVsLWRvYyAtLT4KCSAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSAnPGVtPk91dHB1dCBFbGVtZW50PC9lbT4nIHJlZmVyZW5jZSBsaXN0LgoJICogQHNlZSBvcmcuZWNsaXBzZS51bWwyLlVNTDJQYWNrYWdlI2dldEV4cGFuc2lvblJlZ2lvbl9PdXRwdXRFbGVtZW50KCkKCSAqIEBzZWUgb3JnLmVjbGlwc2UudW1sMi5FeHBhbnNpb25Ob2RlI2dldFJlZ2lvbkFzT3V0cHV0CgkgKiBAbW9kZWwgdHlwZT0ib3JnLmVjbGlwc2UudW1sMi5FeHBhbnNpb25Ob2RlIiBvcHBvc2l0ZT0icmVnaW9uQXNPdXRwdXQiIG9yZGVyZWQ9ImZhbHNlIgoJICogQGdlbmVyYXRlZAoJICovCglFTGlzdCBnZXRPdXRwdXRFbGVtZW50cygpOwoKICAgIC8qKgogICAgICogUmV0cmlldmVzIHRoZSB7QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5FeHBhbnNpb25Ob2RlfSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBmcm9tIHRoZSAnPGVtPjxiPk91dHB1dCBFbGVtZW50PC9iPjwvZW0+JyByZWZlcmVuY2UgbGlzdC4KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBwYXJhbSB1bnF1YWxpZmllZE5hbWUgVGhlIHVucXVhbGlmaWVkIG5hbWUgb2YgdGhlIHtAbGluayBvcmcuZWNsaXBzZS51bWwyLkV4cGFuc2lvbk5vZGV9IHRvIHJldHJpZXZlLgoJICogQHJldHVybiBUaGUge0BsaW5rIG9yZy5lY2xpcHNlLnVtbDIuRXhwYW5zaW9uTm9kZX0gd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUsIG9yIDxjb2RlPm51bGw8L2NvZGU+LgoJICogQHNlZSAjZ2V0T3V0cHV0RWxlbWVudHMoKQoJICogQGdlbmVyYXRlZAogICAgICovCiAgICBFeHBhbnNpb25Ob2RlIGdldE91dHB1dEVsZW1lbnQoU3RyaW5nIHVucXVhbGlmaWVkTmFtZSk7CiAgICAgIAoJLyoqCgkgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgJzxlbT48Yj5JbnB1dCBFbGVtZW50PC9iPjwvZW0+JyByZWZlcmVuY2UgbGlzdC4KCSAqIFRoZSBsaXN0IGNvbnRlbnRzIGFyZSBvZiB0eXBlIHtAbGluayBvcmcuZWNsaXBzZS51bWwyLkV4cGFuc2lvbk5vZGV9LgoJICogSXQgaXMgYmlkaXJlY3Rpb25hbCBhbmQgaXRzIG9wcG9zaXRlIGlzICd7QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5FeHBhbnNpb25Ob2RlI2dldFJlZ2lvbkFzSW5wdXQgPGVtPlJlZ2lvbiBBcyBJbnB1dDwvZW0+fScuCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPHA+CgkgKiBJZiB0aGUgbWVhbmluZyBvZiB0aGUgJzxlbT5JbnB1dCBFbGVtZW50PC9lbT4nIHJlZmVyZW5jZSBsaXN0IGlzbid0IGNsZWFyLAoJICogdGhlcmUgcmVhbGx5IHNob3VsZCBiZSBtb3JlIG9mIGEgZGVzY3JpcHRpb24gaGVyZS4uLgoJICogPC9wPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiA8IS0tIGJlZ2luLW1vZGVsLWRvYyAtLT4KCSAqIEFuIG9iamVjdCBub2RlIHRoYXQgaG9sZHMgYSBzZXBhcmF0ZSBlbGVtZW50IG9mIHRoZSBpbnB1dCBjb2xsZWN0aW9uIGR1cmluZyBlYWNoIG9mIHRoZSBtdWx0aXBsZSBleGVjdXRpb25zIG9mIHRoZSByZWdpb24uCgkgKiA8IS0tIGVuZC1tb2RlbC1kb2MgLS0+CgkgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgJzxlbT5JbnB1dCBFbGVtZW50PC9lbT4nIHJlZmVyZW5jZSBsaXN0LgoJICogQHNlZSBvcmcuZWNsaXBzZS51bWwyLlVNTDJQYWNrYWdlI2dldEV4cGFuc2lvblJlZ2lvbl9JbnB1dEVsZW1lbnQoKQoJICogQHNlZSBvcmcuZWNsaXBzZS51bWwyLkV4cGFuc2lvbk5vZGUjZ2V0UmVnaW9uQXNJbnB1dAoJICogQG1vZGVsIHR5cGU9Im9yZy5lY2xpcHNlLnVtbDIuRXhwYW5zaW9uTm9kZSIgb3Bwb3NpdGU9InJlZ2lvbkFzSW5wdXQiIHJlcXVpcmVkPSJ0cnVlIiBvcmRlcmVkPSJmYWxzZSIKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJRUxpc3QgZ2V0SW5wdXRFbGVtZW50cygpOwoKICAgIC8qKgogICAgICogUmV0cmlldmVzIHRoZSB7QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5FeHBhbnNpb25Ob2RlfSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBmcm9tIHRoZSAnPGVtPjxiPklucHV0IEVsZW1lbnQ8L2I+PC9lbT4nIHJlZmVyZW5jZSBsaXN0LgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHBhcmFtIHVucXVhbGlmaWVkTmFtZSBUaGUgdW5xdWFsaWZpZWQgbmFtZSBvZiB0aGUge0BsaW5rIG9yZy5lY2xpcHNlLnVtbDIuRXhwYW5zaW9uTm9kZX0gdG8gcmV0cmlldmUuCgkgKiBAcmV0dXJuIFRoZSB7QGxpbmsgb3JnLmVjbGlwc2UudW1sMi5FeHBhbnNpb25Ob2RlfSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4uCgkgKiBAc2VlICNnZXRJbnB1dEVsZW1lbnRzKCkKCSAqIEBnZW5lcmF0ZWQKICAgICAqLwogICAgRXhwYW5zaW9uTm9kZSBnZXRJbnB1dEVsZW1lbnQoU3RyaW5nIHVucXVhbGlmaWVkTmFtZSk7CiAgICAgIAp9IC8vIEV4cGFuc2lvblJlZ2lvbgo=